1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/sunddi.h>
27 #if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
28 #include <string.h>
29 #include <strings.h>
30 #include <stddef.h>
31 #endif /* _KERNEL */
32 #include <smbsrv/smb_door.h>
33 #include <smbsrv/alloc.h>
34 #include <sys/socket.h>
35 #include <sys/sysmacros.h>
36
37 #define SMB_XDRMAX32_SZ 0xFFFFFFFF
38
39 bool_t smb_list_xdr(XDR *, list_t *, const size_t, const size_t,
40 const xdrproc_t);
41
42 bool_t
smb_buf32_xdr(XDR * xdrs,smb_buf32_t * objp)43 smb_buf32_xdr(XDR *xdrs, smb_buf32_t *objp)
44 {
45 uint_t maxsize = SMB_XDRMAX32_SZ;
46 uint_t size;
47
48 if (xdrs->x_op != XDR_DECODE)
49 maxsize = size = (uint_t)objp->len;
50
51 if (xdr_bytes(xdrs, (char **)&objp->val, &size, maxsize)) {
52 if (xdrs->x_op == XDR_DECODE)
53 objp->len = (uint32_t)size;
54 return (TRUE);
55 }
56
57 return (FALSE);
58 }
59
60 /*
61 * When decoding into a string, ensure that objp->buf is NULL or
62 * is pointing at a buffer large enough to receive the string.
63 * Don't leave it as an uninitialized pointer.
64 *
65 * If objp->buf is NULL, xdr_string will allocate memory for the
66 * string. Otherwise it will copy into the available buffer.
67 */
68 bool_t
smb_string_xdr(XDR * xdrs,smb_string_t * objp)69 smb_string_xdr(XDR *xdrs, smb_string_t *objp)
70 {
71 if (!xdr_string(xdrs, &objp->buf, ~0))
72 return (FALSE);
73 return (TRUE);
74 }
75
76 const char *
smb_doorhdr_opname(uint32_t op)77 smb_doorhdr_opname(uint32_t op)
78 {
79 struct {
80 uint32_t op;
81 const char *name;
82 } ops[] = {
83 { SMB_DR_NULL, "null" },
84 { SMB_DR_ASYNC_RESPONSE, "async_response" },
85 { SMB_DR_USER_AUTH_LOGON, "user_auth_logon" },
86 { SMB_DR_USER_NONAUTH_LOGON, "user_nonauth_logon" },
87 { SMB_DR_USER_AUTH_LOGOFF, "user_auth_logoff" },
88 { SMB_DR_LOOKUP_SID, "lookup_sid" },
89 { SMB_DR_LOOKUP_NAME, "lookup_name" },
90 { SMB_DR_JOIN, "join" },
91 { SMB_DR_GET_DCINFO, "get_dcinfo" },
92 { SMB_DR_VSS_GET_COUNT, "vss_get_count" },
93 { SMB_DR_VSS_GET_SNAPSHOTS, "vss_get_snapshots" },
94 { SMB_DR_VSS_MAP_GMTTOKEN, "vss_map_gmttoken" },
95 { SMB_DR_ADS_FIND_HOST, "ads_find_host" },
96 { SMB_DR_QUOTA_QUERY, "quota_query" },
97 { SMB_DR_QUOTA_SET, "quota_set" },
98 { SMB_DR_DFS_GET_REFERRALS, "dfs_get_referrals" },
99 { SMB_DR_SHR_HOSTACCESS, "share_hostaccess" },
100 { SMB_DR_SHR_EXEC, "share_exec" },
101 { SMB_DR_NOTIFY_DC_CHANGED, "notify_dc_changed" }
102 };
103 int i;
104
105 for (i = 0; i < (sizeof (ops) / sizeof (ops[0])); ++i) {
106 if (ops[i].op == op)
107 return (ops[i].name);
108 }
109
110 return ("unknown");
111 }
112
113 /*
114 * Encode a door header structure into an XDR buffer.
115 */
116 int
smb_doorhdr_encode(smb_doorhdr_t * hdr,uint8_t * buf,uint32_t buflen)117 smb_doorhdr_encode(smb_doorhdr_t *hdr, uint8_t *buf, uint32_t buflen)
118 {
119 XDR xdrs;
120 int rc = 0;
121
122 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
123
124 if (!smb_doorhdr_xdr(&xdrs, hdr))
125 rc = -1;
126
127 xdr_destroy(&xdrs);
128 return (rc);
129 }
130
131 /*
132 * Decode an XDR buffer into a door header structure.
133 */
134 int
smb_doorhdr_decode(smb_doorhdr_t * hdr,uint8_t * buf,uint32_t buflen)135 smb_doorhdr_decode(smb_doorhdr_t *hdr, uint8_t *buf, uint32_t buflen)
136 {
137 XDR xdrs;
138 int rc = 0;
139
140 bzero(hdr, sizeof (smb_doorhdr_t));
141 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
142
143 if (!smb_doorhdr_xdr(&xdrs, hdr))
144 rc = -1;
145
146 xdr_destroy(&xdrs);
147 return (rc);
148 }
149
150 bool_t
smb_doorhdr_xdr(XDR * xdrs,smb_doorhdr_t * objp)151 smb_doorhdr_xdr(XDR *xdrs, smb_doorhdr_t *objp)
152 {
153 if (!xdr_uint32_t(xdrs, &objp->dh_magic))
154 return (FALSE);
155 if (!xdr_uint32_t(xdrs, &objp->dh_flags))
156 return (FALSE);
157 if (!xdr_uint32_t(xdrs, &objp->dh_fid))
158 return (FALSE);
159 if (!xdr_uint32_t(xdrs, &objp->dh_op))
160 return (FALSE);
161 if (!xdr_uint32_t(xdrs, &objp->dh_txid))
162 return (FALSE);
163 if (!xdr_uint32_t(xdrs, &objp->dh_datalen))
164 return (FALSE);
165 if (!xdr_uint32_t(xdrs, &objp->dh_resid))
166 return (FALSE);
167 if (!xdr_uint32_t(xdrs, &objp->dh_door_rc))
168 return (FALSE);
169 if (!xdr_uint32_t(xdrs, &objp->dh_status))
170 return (FALSE);
171 return (TRUE);
172 }
173
174 /*
175 * Encode an smb_netuserinfo_t into a buffer.
176 */
177 int
smb_netuserinfo_encode(smb_netuserinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)178 smb_netuserinfo_encode(smb_netuserinfo_t *info, uint8_t *buf,
179 uint32_t buflen, uint_t *nbytes)
180 {
181 XDR xdrs;
182 int rc = 0;
183
184 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
185
186 if (!smb_netuserinfo_xdr(&xdrs, info))
187 rc = -1;
188
189 if (nbytes != NULL)
190 *nbytes = xdr_getpos(&xdrs);
191 xdr_destroy(&xdrs);
192 return (rc);
193 }
194
195 /*
196 * Decode an XDR buffer into an smb_netuserinfo_t.
197 */
198 int
smb_netuserinfo_decode(smb_netuserinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)199 smb_netuserinfo_decode(smb_netuserinfo_t *info, uint8_t *buf,
200 uint32_t buflen, uint_t *nbytes)
201 {
202 XDR xdrs;
203 int rc = 0;
204
205 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
206
207 bzero(info, sizeof (smb_netuserinfo_t));
208 if (!smb_netuserinfo_xdr(&xdrs, info))
209 rc = -1;
210
211 if (nbytes != NULL)
212 *nbytes = xdr_getpos(&xdrs);
213 xdr_destroy(&xdrs);
214 return (rc);
215 }
216
217 bool_t
smb_inaddr_xdr(XDR * xdrs,smb_inaddr_t * objp)218 smb_inaddr_xdr(XDR *xdrs, smb_inaddr_t *objp)
219 {
220 if (!xdr_int32_t(xdrs, &objp->a_family))
221 return (FALSE);
222 if (objp->a_family == AF_INET) {
223 if (!xdr_uint32_t(xdrs, (in_addr_t *)&objp->a_ipv4))
224 return (FALSE);
225 } else {
226 if (!xdr_vector(xdrs, (char *)&objp->a_ipv6,
227 sizeof (objp->a_ipv6), sizeof (char), (xdrproc_t)xdr_char))
228 return (FALSE);
229 }
230 return (TRUE);
231 }
232
233 /*
234 * XDR encode/decode for smb_netuserinfo_t.
235 */
236 bool_t
smb_netuserinfo_xdr(XDR * xdrs,smb_netuserinfo_t * objp)237 smb_netuserinfo_xdr(XDR *xdrs, smb_netuserinfo_t *objp)
238 {
239 if (!xdr_uint64_t(xdrs, &objp->ui_session_id))
240 return (FALSE);
241 if (!xdr_uint16_t(xdrs, &objp->ui_smb_uid))
242 return (FALSE);
243 if (!xdr_uint16_t(xdrs, &objp->ui_domain_len))
244 return (FALSE);
245 if (!xdr_string(xdrs, &objp->ui_domain, ~0))
246 return (FALSE);
247 if (!xdr_uint16_t(xdrs, &objp->ui_account_len))
248 return (FALSE);
249 if (!xdr_string(xdrs, &objp->ui_account, ~0))
250 return (FALSE);
251 if (!xdr_uint32_t(xdrs, &objp->ui_posix_uid))
252 return (FALSE);
253 if (!xdr_uint16_t(xdrs, &objp->ui_workstation_len))
254 return (FALSE);
255 if (!xdr_string(xdrs, &objp->ui_workstation, ~0))
256 return (FALSE);
257 if (!smb_inaddr_xdr(xdrs, &objp->ui_ipaddr))
258 return (FALSE);
259 if (!xdr_int32_t(xdrs, &objp->ui_native_os))
260 return (FALSE);
261 if (!xdr_int64_t(xdrs, &objp->ui_logon_time))
262 return (FALSE);
263 if (!xdr_uint32_t(xdrs, &objp->ui_numopens))
264 return (FALSE);
265 if (!xdr_uint32_t(xdrs, &objp->ui_flags))
266 return (FALSE);
267 return (TRUE);
268 }
269
270 /*
271 * Encode an smb_netconnectinfo_t into a buffer.
272 */
273 int
smb_netconnectinfo_encode(smb_netconnectinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)274 smb_netconnectinfo_encode(smb_netconnectinfo_t *info, uint8_t *buf,
275 uint32_t buflen, uint_t *nbytes)
276 {
277 XDR xdrs;
278 int rc = 0;
279
280 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
281
282 if (!smb_netconnectinfo_xdr(&xdrs, info))
283 rc = -1;
284
285 if (nbytes != NULL)
286 *nbytes = xdr_getpos(&xdrs);
287 xdr_destroy(&xdrs);
288 return (rc);
289 }
290
291 /*
292 * Decode an XDR buffer into an smb_netconnectinfo_t.
293 */
294 int
smb_netconnectinfo_decode(smb_netconnectinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)295 smb_netconnectinfo_decode(smb_netconnectinfo_t *info, uint8_t *buf,
296 uint32_t buflen, uint_t *nbytes)
297 {
298 XDR xdrs;
299 int rc = 0;
300
301 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
302
303 bzero(info, sizeof (smb_netconnectinfo_t));
304 if (!smb_netconnectinfo_xdr(&xdrs, info))
305 rc = -1;
306
307 if (nbytes != NULL)
308 *nbytes = xdr_getpos(&xdrs);
309 xdr_destroy(&xdrs);
310 return (rc);
311 }
312
313 /*
314 * XDR encode/decode for smb_netconnectinfo_t.
315 */
316 bool_t
smb_netconnectinfo_xdr(XDR * xdrs,smb_netconnectinfo_t * objp)317 smb_netconnectinfo_xdr(XDR *xdrs, smb_netconnectinfo_t *objp)
318 {
319 if (!xdr_uint32_t(xdrs, &objp->ci_id))
320 return (FALSE);
321 if (!xdr_uint32_t(xdrs, &objp->ci_type))
322 return (FALSE);
323 if (!xdr_uint32_t(xdrs, &objp->ci_numopens))
324 return (FALSE);
325 if (!xdr_uint32_t(xdrs, &objp->ci_numusers))
326 return (FALSE);
327 if (!xdr_uint32_t(xdrs, &objp->ci_time))
328 return (FALSE);
329 if (!xdr_uint32_t(xdrs, &objp->ci_namelen))
330 return (FALSE);
331 if (!xdr_uint32_t(xdrs, &objp->ci_sharelen))
332 return (FALSE);
333 if (!xdr_string(xdrs, &objp->ci_username, MAXNAMELEN))
334 return (FALSE);
335 if (!xdr_string(xdrs, &objp->ci_share, MAXNAMELEN))
336 return (FALSE);
337 return (TRUE);
338 }
339
340 /*
341 * Encode an smb_netfileinfo_t into a buffer.
342 */
343 int
smb_netfileinfo_encode(smb_netfileinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)344 smb_netfileinfo_encode(smb_netfileinfo_t *info, uint8_t *buf,
345 uint32_t buflen, uint_t *nbytes)
346 {
347 XDR xdrs;
348 int rc = 0;
349
350 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
351
352 if (!smb_netfileinfo_xdr(&xdrs, info))
353 rc = -1;
354
355 if (nbytes != NULL)
356 *nbytes = xdr_getpos(&xdrs);
357 xdr_destroy(&xdrs);
358 return (rc);
359 }
360
361 /*
362 * Decode an XDR buffer into an smb_netfileinfo_t.
363 */
364 int
smb_netfileinfo_decode(smb_netfileinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)365 smb_netfileinfo_decode(smb_netfileinfo_t *info, uint8_t *buf,
366 uint32_t buflen, uint_t *nbytes)
367 {
368 XDR xdrs;
369 int rc = 0;
370
371 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
372
373 bzero(info, sizeof (smb_netfileinfo_t));
374 if (!smb_netfileinfo_xdr(&xdrs, info))
375 rc = -1;
376
377 if (nbytes != NULL)
378 *nbytes = xdr_getpos(&xdrs);
379 xdr_destroy(&xdrs);
380 return (rc);
381 }
382
383 /*
384 * XDR encode/decode for smb_netfileinfo_t.
385 */
386 bool_t
smb_netfileinfo_xdr(XDR * xdrs,smb_netfileinfo_t * objp)387 smb_netfileinfo_xdr(XDR *xdrs, smb_netfileinfo_t *objp)
388 {
389 if (!xdr_uint16_t(xdrs, &objp->fi_fid))
390 return (FALSE);
391 if (!xdr_uint32_t(xdrs, &objp->fi_uniqid))
392 return (FALSE);
393 if (!xdr_uint32_t(xdrs, &objp->fi_permissions))
394 return (FALSE);
395 if (!xdr_uint32_t(xdrs, &objp->fi_numlocks))
396 return (FALSE);
397 if (!xdr_uint32_t(xdrs, &objp->fi_pathlen))
398 return (FALSE);
399 if (!xdr_uint32_t(xdrs, &objp->fi_namelen))
400 return (FALSE);
401 if (!xdr_string(xdrs, &objp->fi_path, MAXPATHLEN))
402 return (FALSE);
403 if (!xdr_string(xdrs, &objp->fi_username, MAXNAMELEN))
404 return (FALSE);
405 return (TRUE);
406 }
407
408 bool_t
smb_gmttoken_query_xdr(XDR * xdrs,smb_gmttoken_query_t * objp)409 smb_gmttoken_query_xdr(XDR *xdrs, smb_gmttoken_query_t *objp)
410 {
411 if (!xdr_uint32_t(xdrs, &objp->gtq_count)) {
412 return (FALSE);
413 }
414 if (!xdr_string(xdrs, &objp->gtq_path, ~0)) {
415 return (FALSE);
416 }
417 return (TRUE);
418 }
419
420 static bool_t
smb_gmttoken_xdr(XDR * xdrs,smb_gmttoken_t * objp)421 smb_gmttoken_xdr(XDR *xdrs, smb_gmttoken_t *objp)
422 {
423 if (!xdr_string(xdrs, objp, SMB_VSS_GMT_SIZE)) {
424 return (FALSE);
425 }
426 return (TRUE);
427 }
428
429 bool_t
smb_gmttoken_response_xdr(XDR * xdrs,smb_gmttoken_response_t * objp)430 smb_gmttoken_response_xdr(XDR *xdrs, smb_gmttoken_response_t *objp)
431 {
432 if (!xdr_uint32_t(xdrs, &objp->gtr_count)) {
433 return (FALSE);
434 }
435 if (!xdr_array(xdrs, (char **)&objp->gtr_gmttokens.gtr_gmttokens_val,
436 (uint_t *)&objp->gtr_gmttokens.gtr_gmttokens_len, ~0,
437 sizeof (smb_gmttoken_t), (xdrproc_t)smb_gmttoken_xdr)) {
438 return (FALSE);
439 }
440 return (TRUE);
441 }
442
443 bool_t
smb_gmttoken_snapname_xdr(XDR * xdrs,smb_gmttoken_snapname_t * objp)444 smb_gmttoken_snapname_xdr(XDR *xdrs, smb_gmttoken_snapname_t *objp)
445 {
446 if (!xdr_string(xdrs, &objp->gts_path, MAXPATHLEN)) {
447 return (FALSE);
448 }
449 if (!xdr_string(xdrs, &objp->gts_gmttoken, SMB_VSS_GMT_SIZE)) {
450 return (FALSE);
451 }
452 if (!xdr_uint64_t(xdrs, &objp->gts_toktime)) {
453 return (FALSE);
454 }
455 return (TRUE);
456 }
457
458 bool_t
smb_quota_xdr(XDR * xdrs,smb_quota_t * objp)459 smb_quota_xdr(XDR *xdrs, smb_quota_t *objp)
460 {
461 if (!xdr_vector(xdrs, (char *)objp->q_sidstr, SMB_SID_STRSZ,
462 sizeof (char), (xdrproc_t)xdr_char))
463 return (FALSE);
464 if (!xdr_uint32_t(xdrs, &objp->q_sidtype))
465 return (FALSE);
466 if (!xdr_uint64_t(xdrs, &objp->q_used))
467 return (FALSE);
468 if (!xdr_uint64_t(xdrs, &objp->q_thresh))
469 return (FALSE);
470 if (!xdr_uint64_t(xdrs, &objp->q_limit))
471 return (FALSE);
472
473 return (TRUE);
474 }
475
476 bool_t
smb_quota_sid_xdr(XDR * xdrs,smb_quota_sid_t * objp)477 smb_quota_sid_xdr(XDR *xdrs, smb_quota_sid_t *objp)
478 {
479 if (!xdr_vector(xdrs, (char *)objp->qs_sidstr, SMB_SID_STRSZ,
480 sizeof (char), (xdrproc_t)xdr_char))
481 return (FALSE);
482 return (TRUE);
483 }
484
485 bool_t
smb_quota_query_xdr(XDR * xdrs,smb_quota_query_t * objp)486 smb_quota_query_xdr(XDR *xdrs, smb_quota_query_t *objp)
487 {
488 if (!xdr_string(xdrs, &objp->qq_root_path, ~0))
489 return (FALSE);
490 if (!xdr_uint32_t(xdrs, &objp->qq_query_op))
491 return (FALSE);
492 if (!xdr_bool(xdrs, &objp->qq_single))
493 return (FALSE);
494 if (!xdr_bool(xdrs, &objp->qq_restart))
495 return (FALSE);
496 if (!xdr_uint32_t(xdrs, &objp->qq_max_quota))
497 return (FALSE);
498 if (!smb_list_xdr(xdrs, &objp->qq_sid_list,
499 offsetof(smb_quota_sid_t, qs_list_node),
500 sizeof (smb_quota_sid_t), (xdrproc_t)smb_quota_sid_xdr))
501 return (FALSE);
502
503 return (TRUE);
504 }
505
506 bool_t
smb_quota_response_xdr(XDR * xdrs,smb_quota_response_t * objp)507 smb_quota_response_xdr(XDR *xdrs, smb_quota_response_t *objp)
508 {
509 if (!xdr_uint32_t(xdrs, &objp->qr_status))
510 return (FALSE);
511 if (!smb_list_xdr(xdrs, &objp->qr_quota_list,
512 offsetof(smb_quota_t, q_list_node),
513 sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
514 return (FALSE);
515 return (TRUE);
516 }
517
518 bool_t
smb_quota_set_xdr(XDR * xdrs,smb_quota_set_t * objp)519 smb_quota_set_xdr(XDR *xdrs, smb_quota_set_t *objp)
520 {
521 if (!xdr_string(xdrs, &objp->qs_root_path, ~0))
522 return (FALSE);
523 if (!smb_list_xdr(xdrs, &objp->qs_quota_list,
524 offsetof(smb_quota_t, q_list_node),
525 sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
526 return (FALSE);
527 return (TRUE);
528 }
529
530 /*
531 * XDR a list_t list of elements
532 * offset - offset of list_node_t in list element
533 * elsize - size of list element
534 * elproc - XDR function for the list element
535 */
536 bool_t
smb_list_xdr(XDR * xdrs,list_t * list,const size_t offset,const size_t elsize,const xdrproc_t elproc)537 smb_list_xdr(XDR *xdrs, list_t *list, const size_t offset,
538 const size_t elsize, const xdrproc_t elproc)
539 {
540 void *node;
541 uint32_t count = 0;
542
543 switch (xdrs->x_op) {
544 case XDR_ENCODE:
545 node = list_head(list);
546 while (node) {
547 ++count;
548 node = list_next(list, node);
549 }
550 if (!xdr_uint32_t(xdrs, &count))
551 return (FALSE);
552
553 node = list_head(list);
554 while (node) {
555 if (!elproc(xdrs, node))
556 return (FALSE);
557 node = list_next(list, node);
558 }
559 return (TRUE);
560
561 case XDR_DECODE:
562 if (!xdr_uint32_t(xdrs, &count))
563 return (FALSE);
564 list_create(list, elsize, offset);
565 while (count) {
566 node = MEM_MALLOC("xdr", elsize);
567 if (node == NULL)
568 return (FALSE);
569 if (!elproc(xdrs, node))
570 return (FALSE);
571 list_insert_tail(list, node);
572 --count;
573 }
574 return (TRUE);
575
576 case XDR_FREE:
577 while ((node = list_head(list)) != NULL) {
578 list_remove(list, node);
579 (void) elproc(xdrs, node);
580 MEM_FREE("xdr", node);
581 }
582 list_destroy(list);
583 return (TRUE);
584 }
585
586 return (FALSE);
587 }
588
589 bool_t
dfs_target_pclass_xdr(XDR * xdrs,dfs_target_pclass_t * objp)590 dfs_target_pclass_xdr(XDR *xdrs, dfs_target_pclass_t *objp)
591 {
592 return (xdr_enum(xdrs, (enum_t *)objp));
593 }
594
595 bool_t
dfs_target_priority_xdr(XDR * xdrs,dfs_target_priority_t * objp)596 dfs_target_priority_xdr(XDR *xdrs, dfs_target_priority_t *objp)
597 {
598 if (!dfs_target_pclass_xdr(xdrs, &objp->p_class))
599 return (FALSE);
600
601 if (!xdr_uint16_t(xdrs, &objp->p_rank))
602 return (FALSE);
603
604 return (TRUE);
605 }
606
607 bool_t
dfs_target_xdr(XDR * xdrs,dfs_target_t * objp)608 dfs_target_xdr(XDR *xdrs, dfs_target_t *objp)
609 {
610 if (!xdr_vector(xdrs, (char *)objp->t_server, DFS_SRVNAME_MAX,
611 sizeof (char), (xdrproc_t)xdr_char))
612 return (FALSE);
613
614 if (!xdr_vector(xdrs, (char *)objp->t_share, DFS_NAME_MAX,
615 sizeof (char), (xdrproc_t)xdr_char))
616 return (FALSE);
617
618 if (!xdr_uint32_t(xdrs, &objp->t_state))
619 return (FALSE);
620
621 if (!dfs_target_priority_xdr(xdrs, &objp->t_priority))
622 return (FALSE);
623
624 return (TRUE);
625 }
626
627 bool_t
dfs_reftype_xdr(XDR * xdrs,dfs_reftype_t * objp)628 dfs_reftype_xdr(XDR *xdrs, dfs_reftype_t *objp)
629 {
630 return (xdr_enum(xdrs, (enum_t *)objp));
631 }
632
633 bool_t
dfs_info_xdr(XDR * xdrs,dfs_info_t * objp)634 dfs_info_xdr(XDR *xdrs, dfs_info_t *objp)
635 {
636 if (!xdr_vector(xdrs, (char *)objp->i_uncpath, DFS_PATH_MAX,
637 sizeof (char), (xdrproc_t)xdr_char))
638 return (FALSE);
639
640 if (!xdr_vector(xdrs, (char *)objp->i_comment, DFS_COMMENT_MAX,
641 sizeof (char), (xdrproc_t)xdr_char))
642 return (FALSE);
643
644 if (!xdr_vector(xdrs, (char *)objp->i_guid,
645 UUID_PRINTABLE_STRING_LENGTH, sizeof (char), (xdrproc_t)xdr_char))
646 return (FALSE);
647
648 if (!xdr_uint32_t(xdrs, &objp->i_state))
649 return (FALSE);
650
651 if (!xdr_uint32_t(xdrs, &objp->i_timeout))
652 return (FALSE);
653
654 if (!xdr_uint32_t(xdrs, &objp->i_propflags))
655 return (FALSE);
656
657 if (!xdr_uint32_t(xdrs, &objp->i_type))
658 return (FALSE);
659
660 if (!xdr_array(xdrs, (char **)&objp->i_targets,
661 (uint32_t *)&objp->i_ntargets, ~0, sizeof (dfs_target_t),
662 (xdrproc_t)dfs_target_xdr))
663 return (FALSE);
664
665 return (TRUE);
666 }
667
668 bool_t
dfs_referral_query_xdr(XDR * xdrs,dfs_referral_query_t * objp)669 dfs_referral_query_xdr(XDR *xdrs, dfs_referral_query_t *objp)
670 {
671 if (!dfs_reftype_xdr(xdrs, &objp->rq_type))
672 return (FALSE);
673
674 if (!xdr_string(xdrs, &objp->rq_path, ~0))
675 return (FALSE);
676
677 return (TRUE);
678 }
679
680 bool_t
dfs_referral_response_xdr(XDR * xdrs,dfs_referral_response_t * objp)681 dfs_referral_response_xdr(XDR *xdrs, dfs_referral_response_t *objp)
682 {
683 if (!dfs_info_xdr(xdrs, &objp->rp_referrals))
684 return (FALSE);
685
686 if (!xdr_uint32_t(xdrs, &objp->rp_status))
687 return (FALSE);
688
689 return (TRUE);
690 }
691
692 bool_t
smb_shr_hostaccess_query_xdr(XDR * xdrs,smb_shr_hostaccess_query_t * objp)693 smb_shr_hostaccess_query_xdr(XDR *xdrs, smb_shr_hostaccess_query_t *objp)
694 {
695 if (!xdr_string(xdrs, &objp->shq_none, ~0))
696 return (FALSE);
697
698 if (!xdr_string(xdrs, &objp->shq_ro, ~0))
699 return (FALSE);
700
701 if (!xdr_string(xdrs, &objp->shq_rw, ~0))
702 return (FALSE);
703
704 if (!xdr_uint32_t(xdrs, &objp->shq_flag))
705 return (FALSE);
706
707 if (!smb_inaddr_xdr(xdrs, &objp->shq_ipaddr))
708 return (FALSE);
709
710 return (TRUE);
711 }
712
713 bool_t
smb_shr_execinfo_xdr(XDR * xdrs,smb_shr_execinfo_t * objp)714 smb_shr_execinfo_xdr(XDR *xdrs, smb_shr_execinfo_t *objp)
715 {
716 if (!xdr_string(xdrs, &objp->e_sharename, ~0))
717 return (FALSE);
718
719 if (!xdr_string(xdrs, &objp->e_winname, ~0))
720 return (FALSE);
721
722 if (!xdr_string(xdrs, &objp->e_userdom, ~0))
723 return (FALSE);
724
725 if (!smb_inaddr_xdr(xdrs, &objp->e_srv_ipaddr))
726 return (FALSE);
727
728 if (!smb_inaddr_xdr(xdrs, &objp->e_cli_ipaddr))
729 return (FALSE);
730
731 if (!xdr_string(xdrs, &objp->e_cli_netbiosname, ~0))
732 return (FALSE);
733
734 if (!xdr_u_int(xdrs, &objp->e_uid))
735 return (FALSE);
736
737 if (!xdr_int(xdrs, &objp->e_type))
738 return (FALSE);
739
740 return (TRUE);
741 }
742
743 /*
744 * The smbsrv ioctl callers include a CRC of the XDR encoded data,
745 * and kmod ioctl handler checks it. Both use this function. This
746 * is not really XDR related, but this is as good a place as any.
747 */
748 #define SMB_CRC_POLYNOMIAL 0xD8B5D8B5
749 uint32_t
smb_crc_gen(uint8_t * buf,size_t len)750 smb_crc_gen(uint8_t *buf, size_t len)
751 {
752 uint32_t crc = SMB_CRC_POLYNOMIAL;
753 uint8_t *p;
754 int i;
755
756 for (p = buf, i = 0; i < len; ++i, ++p) {
757 crc = (crc ^ (uint32_t)*p) + (crc << 12);
758
759 if (crc == 0 || crc == 0xFFFFFFFF)
760 crc = SMB_CRC_POLYNOMIAL;
761 }
762
763 return (crc);
764 }
765