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 }; 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 624 dfs_reftype_xdr(XDR *xdrs, dfs_reftype_t *objp) 625 { 626 return (xdr_enum(xdrs, (enum_t *)objp)); 627 } 628 629 bool_t 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 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 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 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 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 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