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