xref: /illumos-gate/usr/src/common/smbsrv/smb_xdr.c (revision b3700b07)
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 2012 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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 	return (TRUE);
453 }
454 
455 bool_t
456 smb_quota_xdr(XDR *xdrs, smb_quota_t *objp)
457 {
458 	if (!xdr_vector(xdrs, (char *)objp->q_sidstr, SMB_SID_STRSZ,
459 	    sizeof (char), (xdrproc_t)xdr_char))
460 		return (FALSE);
461 	if (!xdr_uint32_t(xdrs, &objp->q_sidtype))
462 		return (FALSE);
463 	if (!xdr_uint64_t(xdrs, &objp->q_used))
464 		return (FALSE);
465 	if (!xdr_uint64_t(xdrs, &objp->q_thresh))
466 		return (FALSE);
467 	if (!xdr_uint64_t(xdrs, &objp->q_limit))
468 		return (FALSE);
469 
470 	return (TRUE);
471 }
472 
473 bool_t
474 smb_quota_sid_xdr(XDR *xdrs, smb_quota_sid_t *objp)
475 {
476 	if (!xdr_vector(xdrs, (char *)objp->qs_sidstr, SMB_SID_STRSZ,
477 	    sizeof (char), (xdrproc_t)xdr_char))
478 		return (FALSE);
479 	return (TRUE);
480 }
481 
482 bool_t
483 smb_quota_query_xdr(XDR *xdrs, smb_quota_query_t *objp)
484 {
485 	if (!xdr_string(xdrs, &objp->qq_root_path, ~0))
486 		return (FALSE);
487 	if (!xdr_uint32_t(xdrs, &objp->qq_query_op))
488 		return (FALSE);
489 	if (!xdr_bool(xdrs, &objp->qq_single))
490 		return (FALSE);
491 	if (!xdr_bool(xdrs, &objp->qq_restart))
492 		return (FALSE);
493 	if (!xdr_uint32_t(xdrs, &objp->qq_max_quota))
494 		return (FALSE);
495 	if (!smb_list_xdr(xdrs, &objp->qq_sid_list,
496 	    offsetof(smb_quota_sid_t, qs_list_node),
497 	    sizeof (smb_quota_sid_t), (xdrproc_t)smb_quota_sid_xdr))
498 		return (FALSE);
499 
500 	return (TRUE);
501 }
502 
503 bool_t
504 smb_quota_response_xdr(XDR *xdrs, smb_quota_response_t *objp)
505 {
506 	if (!xdr_uint32_t(xdrs, &objp->qr_status))
507 		return (FALSE);
508 	if (!smb_list_xdr(xdrs, &objp->qr_quota_list,
509 	    offsetof(smb_quota_t, q_list_node),
510 	    sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
511 		return (FALSE);
512 	return (TRUE);
513 }
514 
515 bool_t
516 smb_quota_set_xdr(XDR *xdrs, smb_quota_set_t *objp)
517 {
518 	if (!xdr_string(xdrs, &objp->qs_root_path, ~0))
519 		return (FALSE);
520 	if (!smb_list_xdr(xdrs, &objp->qs_quota_list,
521 	    offsetof(smb_quota_t, q_list_node),
522 	    sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
523 		return (FALSE);
524 	return (TRUE);
525 }
526 
527 /*
528  * XDR a list_t list of elements
529  * offset - offset of list_node_t in list element
530  * elsize - size of list element
531  * elproc - XDR function for the list element
532  */
533 bool_t
534 smb_list_xdr(XDR *xdrs, list_t *list,  const size_t offset,
535     const size_t elsize, const xdrproc_t elproc)
536 {
537 	void *node;
538 	uint32_t count = 0;
539 
540 	switch (xdrs->x_op) {
541 	case XDR_ENCODE:
542 		node = list_head(list);
543 		while (node) {
544 			++count;
545 			node = list_next(list, node);
546 		}
547 		if (!xdr_uint32_t(xdrs, &count))
548 			return (FALSE);
549 
550 		node = list_head(list);
551 		while (node) {
552 			if (!elproc(xdrs, node))
553 				return (FALSE);
554 			node = list_next(list, node);
555 		}
556 		return (TRUE);
557 
558 	case XDR_DECODE:
559 		if (!xdr_uint32_t(xdrs, &count))
560 			return (FALSE);
561 		list_create(list, elsize, offset);
562 		while (count) {
563 			node = MEM_MALLOC("xdr", elsize);
564 			if (node == NULL)
565 				return (FALSE);
566 			if (!elproc(xdrs, node))
567 				return (FALSE);
568 			list_insert_tail(list, node);
569 			--count;
570 		}
571 		return (TRUE);
572 
573 	case XDR_FREE:
574 		while ((node = list_head(list)) != NULL) {
575 			list_remove(list, node);
576 			(void) elproc(xdrs, node);
577 			MEM_FREE("xdr", node);
578 		}
579 		list_destroy(list);
580 		return (TRUE);
581 	}
582 
583 	return (FALSE);
584 }
585 
586 bool_t
587 dfs_target_pclass_xdr(XDR *xdrs, dfs_target_pclass_t *objp)
588 {
589 	return (xdr_enum(xdrs, (enum_t *)objp));
590 }
591 
592 bool_t
593 dfs_target_priority_xdr(XDR *xdrs, dfs_target_priority_t *objp)
594 {
595 	if (!dfs_target_pclass_xdr(xdrs, &objp->p_class))
596 		return (FALSE);
597 
598 	if (!xdr_uint16_t(xdrs, &objp->p_rank))
599 		return (FALSE);
600 
601 	return (TRUE);
602 }
603 
604 bool_t
605 dfs_target_xdr(XDR *xdrs, dfs_target_t *objp)
606 {
607 	if (!xdr_vector(xdrs, (char *)objp->t_server, DFS_SRVNAME_MAX,
608 	    sizeof (char), (xdrproc_t)xdr_char))
609 		return (FALSE);
610 
611 	if (!xdr_vector(xdrs, (char *)objp->t_share, DFS_NAME_MAX,
612 	    sizeof (char), (xdrproc_t)xdr_char))
613 		return (FALSE);
614 
615 	if (!xdr_uint32_t(xdrs, &objp->t_state))
616 		return (FALSE);
617 
618 	if (!dfs_target_priority_xdr(xdrs, &objp->t_priority))
619 		return (FALSE);
620 
621 	return (TRUE);
622 }
623 
624 bool_t
625 dfs_reftype_xdr(XDR *xdrs, dfs_reftype_t *objp)
626 {
627 	return (xdr_enum(xdrs, (enum_t *)objp));
628 }
629 
630 bool_t
631 dfs_info_xdr(XDR *xdrs, dfs_info_t *objp)
632 {
633 	if (!xdr_vector(xdrs, (char *)objp->i_uncpath, DFS_PATH_MAX,
634 	    sizeof (char), (xdrproc_t)xdr_char))
635 		return (FALSE);
636 
637 	if (!xdr_vector(xdrs, (char *)objp->i_comment, DFS_COMMENT_MAX,
638 	    sizeof (char), (xdrproc_t)xdr_char))
639 		return (FALSE);
640 
641 	if (!xdr_vector(xdrs, (char *)objp->i_guid,
642 	    UUID_PRINTABLE_STRING_LENGTH, sizeof (char), (xdrproc_t)xdr_char))
643 		return (FALSE);
644 
645 	if (!xdr_uint32_t(xdrs, &objp->i_state))
646 		return (FALSE);
647 
648 	if (!xdr_uint32_t(xdrs, &objp->i_timeout))
649 		return (FALSE);
650 
651 	if (!xdr_uint32_t(xdrs, &objp->i_propflags))
652 		return (FALSE);
653 
654 	if (!xdr_uint32_t(xdrs, &objp->i_type))
655 		return (FALSE);
656 
657 	if (!xdr_array(xdrs, (char **)&objp->i_targets,
658 	    (uint32_t *)&objp->i_ntargets, ~0, sizeof (dfs_target_t),
659 	    (xdrproc_t)dfs_target_xdr))
660 		return (FALSE);
661 
662 	return (TRUE);
663 }
664 
665 bool_t
666 dfs_referral_query_xdr(XDR *xdrs, dfs_referral_query_t *objp)
667 {
668 	if (!dfs_reftype_xdr(xdrs, &objp->rq_type))
669 		return (FALSE);
670 
671 	if (!xdr_string(xdrs, &objp->rq_path, ~0))
672 		return (FALSE);
673 
674 	return (TRUE);
675 }
676 
677 bool_t
678 dfs_referral_response_xdr(XDR *xdrs, dfs_referral_response_t *objp)
679 {
680 	if (!dfs_info_xdr(xdrs, &objp->rp_referrals))
681 		return (FALSE);
682 
683 	if (!xdr_uint32_t(xdrs, &objp->rp_status))
684 		return (FALSE);
685 
686 	return (TRUE);
687 }
688 
689 bool_t
690 smb_shr_hostaccess_query_xdr(XDR *xdrs, smb_shr_hostaccess_query_t *objp)
691 {
692 	if (!xdr_string(xdrs, &objp->shq_none, ~0))
693 		return (FALSE);
694 
695 	if (!xdr_string(xdrs, &objp->shq_ro, ~0))
696 		return (FALSE);
697 
698 	if (!xdr_string(xdrs, &objp->shq_rw, ~0))
699 		return (FALSE);
700 
701 	if (!xdr_uint32_t(xdrs, &objp->shq_flag))
702 		return (FALSE);
703 
704 	if (!smb_inaddr_xdr(xdrs, &objp->shq_ipaddr))
705 		return (FALSE);
706 
707 	return (TRUE);
708 }
709 
710 bool_t
711 smb_shr_execinfo_xdr(XDR *xdrs, smb_shr_execinfo_t *objp)
712 {
713 	if (!xdr_string(xdrs, &objp->e_sharename, ~0))
714 		return (FALSE);
715 
716 	if (!xdr_string(xdrs, &objp->e_winname, ~0))
717 		return (FALSE);
718 
719 	if (!xdr_string(xdrs, &objp->e_userdom, ~0))
720 		return (FALSE);
721 
722 	if (!smb_inaddr_xdr(xdrs, &objp->e_srv_ipaddr))
723 		return (FALSE);
724 
725 	if (!smb_inaddr_xdr(xdrs, &objp->e_cli_ipaddr))
726 		return (FALSE);
727 
728 	if (!xdr_string(xdrs, &objp->e_cli_netbiosname, ~0))
729 		return (FALSE);
730 
731 	if (!xdr_u_int(xdrs, &objp->e_uid))
732 		return (FALSE);
733 
734 	if (!xdr_int(xdrs, &objp->e_type))
735 		return (FALSE);
736 
737 	return (TRUE);
738 }
739 
740 /*
741  * The smbsrv ioctl callers include a CRC of the XDR encoded data,
742  * and kmod ioctl handler checks it.  Both use this function.  This
743  * is not really XDR related, but this is as good a place as any.
744  */
745 #define	SMB_CRC_POLYNOMIAL	0xD8B5D8B5
746 uint32_t
747 smb_crc_gen(uint8_t *buf, size_t len)
748 {
749 	uint32_t crc = SMB_CRC_POLYNOMIAL;
750 	uint8_t *p;
751 	int i;
752 
753 	for (p = buf, i = 0; i < len; ++i, ++p) {
754 		crc = (crc ^ (uint32_t)*p) + (crc << 12);
755 
756 		if (crc == 0 || crc == 0xFFFFFFFF)
757 			crc = SMB_CRC_POLYNOMIAL;
758 	}
759 
760 	return (crc);
761 }
762