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