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