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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 629 dfs_reftype_xdr(XDR *xdrs, dfs_reftype_t *objp) 630 { 631 return (xdr_enum(xdrs, (enum_t *)objp)); 632 } 633 634 bool_t 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 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 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 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 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 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