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
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 };
102 int i;
103
104 for (i = 0; i < (sizeof (ops) / sizeof (ops[0])); ++i) {
105 if (ops[i].op == op)
106 return (ops[i].name);
107 }
108
109 return ("unknown");
110 }
111
112 /*
113 * Encode a door header structure into an XDR buffer.
114 */
115 int
smb_doorhdr_encode(smb_doorhdr_t * hdr,uint8_t * buf,uint32_t buflen)116 smb_doorhdr_encode(smb_doorhdr_t *hdr, uint8_t *buf, uint32_t buflen)
117 {
118 XDR xdrs;
119 int rc = 0;
120
121 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
122
123 if (!smb_doorhdr_xdr(&xdrs, hdr))
124 rc = -1;
125
126 xdr_destroy(&xdrs);
127 return (rc);
128 }
129
130 /*
131 * Decode an XDR buffer into a door header structure.
132 */
133 int
smb_doorhdr_decode(smb_doorhdr_t * hdr,uint8_t * buf,uint32_t buflen)134 smb_doorhdr_decode(smb_doorhdr_t *hdr, uint8_t *buf, uint32_t buflen)
135 {
136 XDR xdrs;
137 int rc = 0;
138
139 bzero(hdr, sizeof (smb_doorhdr_t));
140 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
141
142 if (!smb_doorhdr_xdr(&xdrs, hdr))
143 rc = -1;
144
145 xdr_destroy(&xdrs);
146 return (rc);
147 }
148
149 bool_t
smb_doorhdr_xdr(XDR * xdrs,smb_doorhdr_t * objp)150 smb_doorhdr_xdr(XDR *xdrs, smb_doorhdr_t *objp)
151 {
152 if (!xdr_uint32_t(xdrs, &objp->dh_magic))
153 return (FALSE);
154 if (!xdr_uint32_t(xdrs, &objp->dh_flags))
155 return (FALSE);
156 if (!xdr_uint32_t(xdrs, &objp->dh_fid))
157 return (FALSE);
158 if (!xdr_uint32_t(xdrs, &objp->dh_op))
159 return (FALSE);
160 if (!xdr_uint32_t(xdrs, &objp->dh_txid))
161 return (FALSE);
162 if (!xdr_uint32_t(xdrs, &objp->dh_datalen))
163 return (FALSE);
164 if (!xdr_uint32_t(xdrs, &objp->dh_resid))
165 return (FALSE);
166 if (!xdr_uint32_t(xdrs, &objp->dh_door_rc))
167 return (FALSE);
168 if (!xdr_uint32_t(xdrs, &objp->dh_status))
169 return (FALSE);
170 return (TRUE);
171 }
172
173 /*
174 * Encode an smb_netuserinfo_t into a buffer.
175 */
176 int
smb_netuserinfo_encode(smb_netuserinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)177 smb_netuserinfo_encode(smb_netuserinfo_t *info, uint8_t *buf,
178 uint32_t buflen, uint_t *nbytes)
179 {
180 XDR xdrs;
181 int rc = 0;
182
183 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
184
185 if (!smb_netuserinfo_xdr(&xdrs, info))
186 rc = -1;
187
188 if (nbytes != NULL)
189 *nbytes = xdr_getpos(&xdrs);
190 xdr_destroy(&xdrs);
191 return (rc);
192 }
193
194 /*
195 * Decode an XDR buffer into an smb_netuserinfo_t.
196 */
197 int
smb_netuserinfo_decode(smb_netuserinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)198 smb_netuserinfo_decode(smb_netuserinfo_t *info, uint8_t *buf,
199 uint32_t buflen, uint_t *nbytes)
200 {
201 XDR xdrs;
202 int rc = 0;
203
204 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
205
206 bzero(info, sizeof (smb_netuserinfo_t));
207 if (!smb_netuserinfo_xdr(&xdrs, info))
208 rc = -1;
209
210 if (nbytes != NULL)
211 *nbytes = xdr_getpos(&xdrs);
212 xdr_destroy(&xdrs);
213 return (rc);
214 }
215
216 bool_t
smb_inaddr_xdr(XDR * xdrs,smb_inaddr_t * objp)217 smb_inaddr_xdr(XDR *xdrs, smb_inaddr_t *objp)
218 {
219 if (!xdr_int32_t(xdrs, &objp->a_family))
220 return (FALSE);
221 if (objp->a_family == AF_INET) {
222 if (!xdr_uint32_t(xdrs, (in_addr_t *)&objp->a_ipv4))
223 return (FALSE);
224 } else {
225 if (!xdr_vector(xdrs, (char *)&objp->a_ipv6,
226 sizeof (objp->a_ipv6), sizeof (char), (xdrproc_t)xdr_char))
227 return (FALSE);
228 }
229 return (TRUE);
230 }
231
232 /*
233 * XDR encode/decode for smb_netuserinfo_t.
234 */
235 bool_t
smb_netuserinfo_xdr(XDR * xdrs,smb_netuserinfo_t * objp)236 smb_netuserinfo_xdr(XDR *xdrs, smb_netuserinfo_t *objp)
237 {
238 if (!xdr_uint64_t(xdrs, &objp->ui_session_id))
239 return (FALSE);
240 if (!xdr_uint16_t(xdrs, &objp->ui_smb_uid))
241 return (FALSE);
242 if (!xdr_uint16_t(xdrs, &objp->ui_domain_len))
243 return (FALSE);
244 if (!xdr_string(xdrs, &objp->ui_domain, ~0))
245 return (FALSE);
246 if (!xdr_uint16_t(xdrs, &objp->ui_account_len))
247 return (FALSE);
248 if (!xdr_string(xdrs, &objp->ui_account, ~0))
249 return (FALSE);
250 if (!xdr_uint32_t(xdrs, &objp->ui_posix_uid))
251 return (FALSE);
252 if (!xdr_uint16_t(xdrs, &objp->ui_workstation_len))
253 return (FALSE);
254 if (!xdr_string(xdrs, &objp->ui_workstation, ~0))
255 return (FALSE);
256 if (!smb_inaddr_xdr(xdrs, &objp->ui_ipaddr))
257 return (FALSE);
258 if (!xdr_int32_t(xdrs, &objp->ui_native_os))
259 return (FALSE);
260 if (!xdr_int64_t(xdrs, &objp->ui_logon_time))
261 return (FALSE);
262 if (!xdr_uint32_t(xdrs, &objp->ui_numopens))
263 return (FALSE);
264 if (!xdr_uint32_t(xdrs, &objp->ui_flags))
265 return (FALSE);
266 return (TRUE);
267 }
268
269 /*
270 * Encode an smb_netconnectinfo_t into a buffer.
271 */
272 int
smb_netconnectinfo_encode(smb_netconnectinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)273 smb_netconnectinfo_encode(smb_netconnectinfo_t *info, uint8_t *buf,
274 uint32_t buflen, uint_t *nbytes)
275 {
276 XDR xdrs;
277 int rc = 0;
278
279 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
280
281 if (!smb_netconnectinfo_xdr(&xdrs, info))
282 rc = -1;
283
284 if (nbytes != NULL)
285 *nbytes = xdr_getpos(&xdrs);
286 xdr_destroy(&xdrs);
287 return (rc);
288 }
289
290 /*
291 * Decode an XDR buffer into an smb_netconnectinfo_t.
292 */
293 int
smb_netconnectinfo_decode(smb_netconnectinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)294 smb_netconnectinfo_decode(smb_netconnectinfo_t *info, uint8_t *buf,
295 uint32_t buflen, uint_t *nbytes)
296 {
297 XDR xdrs;
298 int rc = 0;
299
300 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
301
302 bzero(info, sizeof (smb_netconnectinfo_t));
303 if (!smb_netconnectinfo_xdr(&xdrs, info))
304 rc = -1;
305
306 if (nbytes != NULL)
307 *nbytes = xdr_getpos(&xdrs);
308 xdr_destroy(&xdrs);
309 return (rc);
310 }
311
312 /*
313 * XDR encode/decode for smb_netconnectinfo_t.
314 */
315 bool_t
smb_netconnectinfo_xdr(XDR * xdrs,smb_netconnectinfo_t * objp)316 smb_netconnectinfo_xdr(XDR *xdrs, smb_netconnectinfo_t *objp)
317 {
318 if (!xdr_uint32_t(xdrs, &objp->ci_id))
319 return (FALSE);
320 if (!xdr_uint32_t(xdrs, &objp->ci_type))
321 return (FALSE);
322 if (!xdr_uint32_t(xdrs, &objp->ci_numopens))
323 return (FALSE);
324 if (!xdr_uint32_t(xdrs, &objp->ci_numusers))
325 return (FALSE);
326 if (!xdr_uint32_t(xdrs, &objp->ci_time))
327 return (FALSE);
328 if (!xdr_uint32_t(xdrs, &objp->ci_namelen))
329 return (FALSE);
330 if (!xdr_uint32_t(xdrs, &objp->ci_sharelen))
331 return (FALSE);
332 if (!xdr_string(xdrs, &objp->ci_username, MAXNAMELEN))
333 return (FALSE);
334 if (!xdr_string(xdrs, &objp->ci_share, MAXNAMELEN))
335 return (FALSE);
336 return (TRUE);
337 }
338
339 /*
340 * Encode an smb_netfileinfo_t into a buffer.
341 */
342 int
smb_netfileinfo_encode(smb_netfileinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)343 smb_netfileinfo_encode(smb_netfileinfo_t *info, uint8_t *buf,
344 uint32_t buflen, uint_t *nbytes)
345 {
346 XDR xdrs;
347 int rc = 0;
348
349 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
350
351 if (!smb_netfileinfo_xdr(&xdrs, info))
352 rc = -1;
353
354 if (nbytes != NULL)
355 *nbytes = xdr_getpos(&xdrs);
356 xdr_destroy(&xdrs);
357 return (rc);
358 }
359
360 /*
361 * Decode an XDR buffer into an smb_netfileinfo_t.
362 */
363 int
smb_netfileinfo_decode(smb_netfileinfo_t * info,uint8_t * buf,uint32_t buflen,uint_t * nbytes)364 smb_netfileinfo_decode(smb_netfileinfo_t *info, uint8_t *buf,
365 uint32_t buflen, uint_t *nbytes)
366 {
367 XDR xdrs;
368 int rc = 0;
369
370 xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
371
372 bzero(info, sizeof (smb_netfileinfo_t));
373 if (!smb_netfileinfo_xdr(&xdrs, info))
374 rc = -1;
375
376 if (nbytes != NULL)
377 *nbytes = xdr_getpos(&xdrs);
378 xdr_destroy(&xdrs);
379 return (rc);
380 }
381
382 /*
383 * XDR encode/decode for smb_netfileinfo_t.
384 */
385 bool_t
smb_netfileinfo_xdr(XDR * xdrs,smb_netfileinfo_t * objp)386 smb_netfileinfo_xdr(XDR *xdrs, smb_netfileinfo_t *objp)
387 {
388 if (!xdr_uint16_t(xdrs, &objp->fi_fid))
389 return (FALSE);
390 if (!xdr_uint32_t(xdrs, &objp->fi_uniqid))
391 return (FALSE);
392 if (!xdr_uint32_t(xdrs, &objp->fi_permissions))
393 return (FALSE);
394 if (!xdr_uint32_t(xdrs, &objp->fi_numlocks))
395 return (FALSE);
396 if (!xdr_uint32_t(xdrs, &objp->fi_pathlen))
397 return (FALSE);
398 if (!xdr_uint32_t(xdrs, &objp->fi_namelen))
399 return (FALSE);
400 if (!xdr_string(xdrs, &objp->fi_path, MAXPATHLEN))
401 return (FALSE);
402 if (!xdr_string(xdrs, &objp->fi_username, MAXNAMELEN))
403 return (FALSE);
404 return (TRUE);
405 }
406
407 bool_t
smb_gmttoken_query_xdr(XDR * xdrs,smb_gmttoken_query_t * objp)408 smb_gmttoken_query_xdr(XDR *xdrs, smb_gmttoken_query_t *objp)
409 {
410 if (!xdr_uint32_t(xdrs, &objp->gtq_count)) {
411 return (FALSE);
412 }
413 if (!xdr_string(xdrs, &objp->gtq_path, ~0)) {
414 return (FALSE);
415 }
416 return (TRUE);
417 }
418
419 static bool_t
smb_gmttoken_xdr(XDR * xdrs,smb_gmttoken_t * objp)420 smb_gmttoken_xdr(XDR *xdrs, smb_gmttoken_t *objp)
421 {
422 if (!xdr_string(xdrs, objp, SMB_VSS_GMT_SIZE)) {
423 return (FALSE);
424 }
425 return (TRUE);
426 }
427
428 bool_t
smb_gmttoken_response_xdr(XDR * xdrs,smb_gmttoken_response_t * objp)429 smb_gmttoken_response_xdr(XDR *xdrs, smb_gmttoken_response_t *objp)
430 {
431 if (!xdr_uint32_t(xdrs, &objp->gtr_count)) {
432 return (FALSE);
433 }
434 if (!xdr_array(xdrs, (char **)&objp->gtr_gmttokens.gtr_gmttokens_val,
435 (uint_t *)&objp->gtr_gmttokens.gtr_gmttokens_len, ~0,
436 sizeof (smb_gmttoken_t), (xdrproc_t)smb_gmttoken_xdr)) {
437 return (FALSE);
438 }
439 return (TRUE);
440 }
441
442 bool_t
smb_gmttoken_snapname_xdr(XDR * xdrs,smb_gmttoken_snapname_t * objp)443 smb_gmttoken_snapname_xdr(XDR *xdrs, smb_gmttoken_snapname_t *objp)
444 {
445 if (!xdr_string(xdrs, &objp->gts_path, MAXPATHLEN)) {
446 return (FALSE);
447 }
448 if (!xdr_string(xdrs, &objp->gts_gmttoken, SMB_VSS_GMT_SIZE)) {
449 return (FALSE);
450 }
451 return (TRUE);
452 }
453
454 bool_t
smb_quota_xdr(XDR * xdrs,smb_quota_t * objp)455 smb_quota_xdr(XDR *xdrs, smb_quota_t *objp)
456 {
457 if (!xdr_vector(xdrs, (char *)objp->q_sidstr, SMB_SID_STRSZ,
458 sizeof (char), (xdrproc_t)xdr_char))
459 return (FALSE);
460 if (!xdr_uint32_t(xdrs, &objp->q_sidtype))
461 return (FALSE);
462 if (!xdr_uint64_t(xdrs, &objp->q_used))
463 return (FALSE);
464 if (!xdr_uint64_t(xdrs, &objp->q_thresh))
465 return (FALSE);
466 if (!xdr_uint64_t(xdrs, &objp->q_limit))
467 return (FALSE);
468
469 return (TRUE);
470 }
471
472 bool_t
smb_quota_sid_xdr(XDR * xdrs,smb_quota_sid_t * objp)473 smb_quota_sid_xdr(XDR *xdrs, smb_quota_sid_t *objp)
474 {
475 if (!xdr_vector(xdrs, (char *)objp->qs_sidstr, SMB_SID_STRSZ,
476 sizeof (char), (xdrproc_t)xdr_char))
477 return (FALSE);
478 return (TRUE);
479 }
480
481 bool_t
smb_quota_query_xdr(XDR * xdrs,smb_quota_query_t * objp)482 smb_quota_query_xdr(XDR *xdrs, smb_quota_query_t *objp)
483 {
484 if (!xdr_string(xdrs, &objp->qq_root_path, ~0))
485 return (FALSE);
486 if (!xdr_uint32_t(xdrs, &objp->qq_query_op))
487 return (FALSE);
488 if (!xdr_bool(xdrs, &objp->qq_single))
489 return (FALSE);
490 if (!xdr_bool(xdrs, &objp->qq_restart))
491 return (FALSE);
492 if (!xdr_uint32_t(xdrs, &objp->qq_max_quota))
493 return (FALSE);
494 if (!smb_list_xdr(xdrs, &objp->qq_sid_list,
495 offsetof(smb_quota_sid_t, qs_list_node),
496 sizeof (smb_quota_sid_t), (xdrproc_t)smb_quota_sid_xdr))
497 return (FALSE);
498
499 return (TRUE);
500 }
501
502 bool_t
smb_quota_response_xdr(XDR * xdrs,smb_quota_response_t * objp)503 smb_quota_response_xdr(XDR *xdrs, smb_quota_response_t *objp)
504 {
505 if (!xdr_uint32_t(xdrs, &objp->qr_status))
506 return (FALSE);
507 if (!smb_list_xdr(xdrs, &objp->qr_quota_list,
508 offsetof(smb_quota_t, q_list_node),
509 sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
510 return (FALSE);
511 return (TRUE);
512 }
513
514 bool_t
smb_quota_set_xdr(XDR * xdrs,smb_quota_set_t * objp)515 smb_quota_set_xdr(XDR *xdrs, smb_quota_set_t *objp)
516 {
517 if (!xdr_string(xdrs, &objp->qs_root_path, ~0))
518 return (FALSE);
519 if (!smb_list_xdr(xdrs, &objp->qs_quota_list,
520 offsetof(smb_quota_t, q_list_node),
521 sizeof (smb_quota_t), (xdrproc_t)smb_quota_xdr))
522 return (FALSE);
523 return (TRUE);
524 }
525
526 /*
527 * XDR a list_t list of elements
528 * offset - offset of list_node_t in list element
529 * elsize - size of list element
530 * elproc - XDR function for the list element
531 */
532 bool_t
smb_list_xdr(XDR * xdrs,list_t * list,const size_t offset,const size_t elsize,const xdrproc_t elproc)533 smb_list_xdr(XDR *xdrs, list_t *list, const size_t offset,
534 const size_t elsize, const xdrproc_t elproc)
535 {
536 void *node;
537 uint32_t count = 0;
538
539 switch (xdrs->x_op) {
540 case XDR_ENCODE:
541 node = list_head(list);
542 while (node) {
543 ++count;
544 node = list_next(list, node);
545 }
546 if (!xdr_uint32_t(xdrs, &count))
547 return (FALSE);
548
549 node = list_head(list);
550 while (node) {
551 if (!elproc(xdrs, node))
552 return (FALSE);
553 node = list_next(list, node);
554 }
555 return (TRUE);
556
557 case XDR_DECODE:
558 if (!xdr_uint32_t(xdrs, &count))
559 return (FALSE);
560 list_create(list, elsize, offset);
561 while (count) {
562 node = MEM_MALLOC("xdr", elsize);
563 if (node == NULL)
564 return (FALSE);
565 if (!elproc(xdrs, node))
566 return (FALSE);
567 list_insert_tail(list, node);
568 --count;
569 }
570 return (TRUE);
571
572 case XDR_FREE:
573 while ((node = list_head(list)) != NULL) {
574 list_remove(list, node);
575 (void) elproc(xdrs, node);
576 MEM_FREE("xdr", node);
577 }
578 list_destroy(list);
579 return (TRUE);
580 }
581
582 return (FALSE);
583 }
584
585 bool_t
dfs_target_pclass_xdr(XDR * xdrs,dfs_target_pclass_t * objp)586 dfs_target_pclass_xdr(XDR *xdrs, dfs_target_pclass_t *objp)
587 {
588 return (xdr_enum(xdrs, (enum_t *)objp));
589 }
590
591 bool_t
dfs_target_priority_xdr(XDR * xdrs,dfs_target_priority_t * objp)592 dfs_target_priority_xdr(XDR *xdrs, dfs_target_priority_t *objp)
593 {
594 if (!dfs_target_pclass_xdr(xdrs, &objp->p_class))
595 return (FALSE);
596
597 if (!xdr_uint16_t(xdrs, &objp->p_rank))
598 return (FALSE);
599
600 return (TRUE);
601 }
602
603 bool_t
dfs_target_xdr(XDR * xdrs,dfs_target_t * objp)604 dfs_target_xdr(XDR *xdrs, dfs_target_t *objp)
605 {
606 if (!xdr_vector(xdrs, (char *)objp->t_server, DFS_SRVNAME_MAX,
607 sizeof (char), (xdrproc_t)xdr_char))
608 return (FALSE);
609
610 if (!xdr_vector(xdrs, (char *)objp->t_share, DFS_NAME_MAX,
611 sizeof (char), (xdrproc_t)xdr_char))
612 return (FALSE);
613
614 if (!xdr_uint32_t(xdrs, &objp->t_state))
615 return (FALSE);
616
617 if (!dfs_target_priority_xdr(xdrs, &objp->t_priority))
618 return (FALSE);
619
620 return (TRUE);
621 }
622
623 bool_t
dfs_reftype_xdr(XDR * xdrs,dfs_reftype_t * objp)624 dfs_reftype_xdr(XDR *xdrs, dfs_reftype_t *objp)
625 {
626 return (xdr_enum(xdrs, (enum_t *)objp));
627 }
628
629 bool_t
dfs_info_xdr(XDR * xdrs,dfs_info_t * objp)630 dfs_info_xdr(XDR *xdrs, dfs_info_t *objp)
631 {
632 if (!xdr_vector(xdrs, (char *)objp->i_uncpath, DFS_PATH_MAX,
633 sizeof (char), (xdrproc_t)xdr_char))
634 return (FALSE);
635
636 if (!xdr_vector(xdrs, (char *)objp->i_comment, DFS_COMMENT_MAX,
637 sizeof (char), (xdrproc_t)xdr_char))
638 return (FALSE);
639
640 if (!xdr_vector(xdrs, (char *)objp->i_guid,
641 UUID_PRINTABLE_STRING_LENGTH, sizeof (char), (xdrproc_t)xdr_char))
642 return (FALSE);
643
644 if (!xdr_uint32_t(xdrs, &objp->i_state))
645 return (FALSE);
646
647 if (!xdr_uint32_t(xdrs, &objp->i_timeout))
648 return (FALSE);
649
650 if (!xdr_uint32_t(xdrs, &objp->i_propflags))
651 return (FALSE);
652
653 if (!xdr_uint32_t(xdrs, &objp->i_type))
654 return (FALSE);
655
656 if (!xdr_array(xdrs, (char **)&objp->i_targets,
657 (uint32_t *)&objp->i_ntargets, ~0, sizeof (dfs_target_t),
658 (xdrproc_t)dfs_target_xdr))
659 return (FALSE);
660
661 return (TRUE);
662 }
663
664 bool_t
dfs_referral_query_xdr(XDR * xdrs,dfs_referral_query_t * objp)665 dfs_referral_query_xdr(XDR *xdrs, dfs_referral_query_t *objp)
666 {
667 if (!dfs_reftype_xdr(xdrs, &objp->rq_type))
668 return (FALSE);
669
670 if (!xdr_string(xdrs, &objp->rq_path, ~0))
671 return (FALSE);
672
673 return (TRUE);
674 }
675
676 bool_t
dfs_referral_response_xdr(XDR * xdrs,dfs_referral_response_t * objp)677 dfs_referral_response_xdr(XDR *xdrs, dfs_referral_response_t *objp)
678 {
679 if (!dfs_info_xdr(xdrs, &objp->rp_referrals))
680 return (FALSE);
681
682 if (!xdr_uint32_t(xdrs, &objp->rp_status))
683 return (FALSE);
684
685 return (TRUE);
686 }
687
688 bool_t
smb_shr_hostaccess_query_xdr(XDR * xdrs,smb_shr_hostaccess_query_t * objp)689 smb_shr_hostaccess_query_xdr(XDR *xdrs, smb_shr_hostaccess_query_t *objp)
690 {
691 if (!xdr_string(xdrs, &objp->shq_none, ~0))
692 return (FALSE);
693
694 if (!xdr_string(xdrs, &objp->shq_ro, ~0))
695 return (FALSE);
696
697 if (!xdr_string(xdrs, &objp->shq_rw, ~0))
698 return (FALSE);
699
700 if (!xdr_uint32_t(xdrs, &objp->shq_flag))
701 return (FALSE);
702
703 if (!smb_inaddr_xdr(xdrs, &objp->shq_ipaddr))
704 return (FALSE);
705
706 return (TRUE);
707 }
708
709 bool_t
smb_shr_execinfo_xdr(XDR * xdrs,smb_shr_execinfo_t * objp)710 smb_shr_execinfo_xdr(XDR *xdrs, smb_shr_execinfo_t *objp)
711 {
712 if (!xdr_string(xdrs, &objp->e_sharename, ~0))
713 return (FALSE);
714
715 if (!xdr_string(xdrs, &objp->e_winname, ~0))
716 return (FALSE);
717
718 if (!xdr_string(xdrs, &objp->e_userdom, ~0))
719 return (FALSE);
720
721 if (!smb_inaddr_xdr(xdrs, &objp->e_srv_ipaddr))
722 return (FALSE);
723
724 if (!smb_inaddr_xdr(xdrs, &objp->e_cli_ipaddr))
725 return (FALSE);
726
727 if (!xdr_string(xdrs, &objp->e_cli_netbiosname, ~0))
728 return (FALSE);
729
730 if (!xdr_u_int(xdrs, &objp->e_uid))
731 return (FALSE);
732
733 if (!xdr_int(xdrs, &objp->e_type))
734 return (FALSE);
735
736 return (TRUE);
737 }
738
739 /*
740 * The smbsrv ioctl callers include a CRC of the XDR encoded data,
741 * and kmod ioctl handler checks it. Both use this function. This
742 * is not really XDR related, but this is as good a place as any.
743 */
744 #define SMB_CRC_POLYNOMIAL 0xD8B5D8B5
745 uint32_t
smb_crc_gen(uint8_t * buf,size_t len)746 smb_crc_gen(uint8_t *buf, size_t len)
747 {
748 uint32_t crc = SMB_CRC_POLYNOMIAL;
749 uint8_t *p;
750 int i;
751
752 for (p = buf, i = 0; i < len; ++i, ++p) {
753 crc = (crc ^ (uint32_t)*p) + (crc << 12);
754
755 if (crc == 0 || crc == 0xFFFFFFFF)
756 crc = SMB_CRC_POLYNOMIAL;
757 }
758
759 return (crc);
760 }
761