Print this page
NEX-17095 illumos 8935 SMB ioctl fixes incomplete
8935 SMB ioctl fixes incomplete
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Rui Loura <rui.loura@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dominik Hassler <hasslerd@gmx.li>
Approved by: Garrett D'Amore <garrett@damore.org>
NEX-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-7490 read_kstat_data panic in smb_named_kstat_update
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexent.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6308 namespace collision for per-share kstats when changing sharesmb property
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6266 SMB kstats namespace collision for share names longer than 28 characters (follow-up)
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-6266 SMB kstats namespace collision for share names longer than 28 characters
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-5175 want SMB statistics separately for reads, writes, other
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4844 assertion failed: kshare->shr_magic == SMB_SHARE_MAGIC
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4313 want iops, bandwidth, and latency kstats for smb
Portions contributed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-3863 Would like an SMB share property to enable/disable quotas
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SMB-74 Process oplock breaks as session requests
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
SMB-65 SMB server in non-global zones (kmem_caches)
common kmem_cache instances across zones
separate GZ-only init from NGZ init
SMB-64 smbsrv workers run at excessively high priority
re #9812 rb3153 System panic'd with assertion failed: sl->sl_count == 0 in smb_slist_destructor after hostname change, smbd restart and attempts to rejoin active directory domain


   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 /*
  23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2017 Joyent, Inc.
  26  */
  27 
  28 #include <smbsrv/smb_door.h>
  29 #include <smbsrv/smb_kproto.h>
  30 #include <smbsrv/smb_ktypes.h>


  31 
  32 typedef struct smb_unshare {
  33         list_node_t     us_lnd;
  34         char            us_sharename[MAXNAMELEN];
  35 } smb_unshare_t;
  36 
  37 static kmem_cache_t     *smb_kshare_cache_share;
  38 static kmem_cache_t     *smb_kshare_cache_unexport;
  39 kmem_cache_t    *smb_kshare_cache_vfs;
  40 
  41 static int smb_kshare_cmp(const void *, const void *);
  42 static void smb_kshare_hold(const void *);
  43 static boolean_t smb_kshare_rele(const void *);
  44 static void smb_kshare_destroy(void *);
  45 static char *smb_kshare_oemname(const char *);
  46 static int smb_kshare_is_special(const char *);
  47 static boolean_t smb_kshare_is_admin(const char *);
  48 static smb_kshare_t *smb_kshare_decode(nvlist_t *);
  49 static uint32_t smb_kshare_decode_bool(nvlist_t *, const char *, uint32_t);
  50 static void smb_kshare_unexport_thread(smb_thread_t *, void *);
  51 static int smb_kshare_export(smb_server_t *, smb_kshare_t *);
  52 static int smb_kshare_unexport(smb_server_t *, const char *);
  53 static int smb_kshare_export_trans(smb_server_t *, char *, char *, char *);
  54 static void smb_kshare_csc_flags(smb_kshare_t *, const char *);




  55 
  56 static boolean_t smb_export_isready(smb_server_t *);
  57 
  58 #ifdef  _KERNEL
  59 static int smb_kshare_chk_dsrv_status(int, smb_dr_ctx_t *);
  60 #endif  /* _KERNEL */
  61 
  62 static const smb_avl_nops_t smb_kshare_avlops = {
  63         smb_kshare_cmp,
  64         smb_kshare_hold,
  65         smb_kshare_rele,
  66         smb_kshare_destroy
  67 };
  68 
  69 #ifdef  _KERNEL
  70 /*
  71  * This function is not MultiThread safe. The caller has to make sure only one
  72  * thread calls this function.
  73  */
  74 door_handle_t


 277         (void) smb_kshare_export_trans(sv, "vss$", SMB_VSS, "VSS");
 278 }
 279 
 280 /*
 281  * This function is called when smb_server_t goes
 282  * away which means SMB shares should not be made
 283  * available to clients
 284  */
 285 void
 286 smb_export_stop(smb_server_t *sv)
 287 {
 288         mutex_enter(&sv->sv_export.e_mutex);
 289         if (!sv->sv_export.e_ready) {
 290                 mutex_exit(&sv->sv_export.e_mutex);
 291                 return;
 292         }
 293         sv->sv_export.e_ready = B_FALSE;
 294         mutex_exit(&sv->sv_export.e_mutex);
 295 
 296         smb_avl_destroy(&sv->sv_export.e_share_avl);
 297         smb_vfs_rele_all(&sv->sv_export);
 298 }
 299 
 300 void
 301 smb_kshare_g_init(void)
 302 {
 303         smb_kshare_cache_share = kmem_cache_create("smb_share_cache",
 304             sizeof (smb_kshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 305 
 306         smb_kshare_cache_unexport = kmem_cache_create("smb_unexport_cache",
 307             sizeof (smb_unshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 308 
 309         smb_kshare_cache_vfs = kmem_cache_create("smb_vfs_cache",
 310             sizeof (smb_vfs_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 311 }
 312 
 313 void
 314 smb_kshare_init(smb_server_t *sv)
 315 {
 316 
 317         smb_llist_constructor(&sv->sv_export.e_vfs_list, sizeof (smb_vfs_t),
 318             offsetof(smb_vfs_t, sv_lnd));
 319 
 320         smb_slist_constructor(&sv->sv_export.e_unexport_list,
 321             sizeof (smb_unshare_t), offsetof(smb_unshare_t, us_lnd));
 322 }
 323 
 324 int
 325 smb_kshare_start(smb_server_t *sv)
 326 {
 327         smb_thread_init(&sv->sv_export.e_unexport_thread, "smb_kshare_unexport",
 328             smb_kshare_unexport_thread, sv, smbsrv_base_pri);
 329 
 330         return (smb_thread_start(&sv->sv_export.e_unexport_thread));
 331 }
 332 
 333 void
 334 smb_kshare_stop(smb_server_t *sv)
 335 {
 336         smb_thread_stop(&sv->sv_export.e_unexport_thread);
 337         smb_thread_destroy(&sv->sv_export.e_unexport_thread);
 338 }
 339 
 340 void
 341 smb_kshare_fini(smb_server_t *sv)
 342 {
 343         smb_unshare_t *ux;
 344 
 345         while ((ux = list_head(&sv->sv_export.e_unexport_list.sl_list))
 346             != NULL) {
 347                 smb_slist_remove(&sv->sv_export.e_unexport_list, ux);
 348                 kmem_cache_free(smb_kshare_cache_unexport, ux);
 349         }
 350         smb_slist_destructor(&sv->sv_export.e_unexport_list);
 351 
 352         smb_vfs_rele_all(&sv->sv_export);
 353 
 354         smb_llist_destructor(&sv->sv_export.e_vfs_list);
 355 }
 356 
 357 void
 358 smb_kshare_g_fini(void)
 359 {
 360         kmem_cache_destroy(smb_kshare_cache_unexport);
 361         kmem_cache_destroy(smb_kshare_cache_share);
 362         kmem_cache_destroy(smb_kshare_cache_vfs);
 363 }
 364 
 365 /*
 366  * A list of shares in nvlist format can be sent down
 367  * from userspace thourgh the IOCTL interface. The nvlist
 368  * is unpacked here and all the shares in the list will
 369  * be exported.
 370  */
 371 int
 372 smb_kshare_export_list(smb_ioc_share_t *ioc)
 373 {
 374         smb_server_t    *sv = NULL;
 375         nvlist_t        *shrlist = NULL;
 376         nvlist_t         *share;
 377         nvpair_t         *nvp;
 378         smb_kshare_t     *shr;
 379         char            *shrname;
 380         int             rc;
 381 
 382         if ((rc = smb_server_lookup(&sv)) != 0)


 666 
 667         key.shr_name = (char *)shrname;
 668         shr = smb_avl_lookup(&sv->sv_export.e_share_avl, &key);
 669         return (shr);
 670 }
 671 
 672 /*
 673  * Releases the hold taken on the specified share object
 674  */
 675 void
 676 smb_kshare_release(smb_server_t *sv, smb_kshare_t *shr)
 677 {
 678         ASSERT(shr);
 679         ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
 680 
 681         smb_avl_release(&sv->sv_export.e_share_avl, shr);
 682 }
 683 
 684 /*
 685  * Add the given share in the specified server.
 686  * If the share is a disk share, smb_vfs_hold() is
 687  * invoked to ensure that there is a hold on the
 688  * corresponding file system before the share is
 689  * added to shares AVL.
 690  *
 691  * If the share is an Autohome share and it is
 692  * already in the AVL only a reference count for
 693  * that share is incremented.
 694  */
 695 static int
 696 smb_kshare_export(smb_server_t *sv, smb_kshare_t *shr)
 697 {
 698         smb_avl_t       *share_avl;
 699         smb_kshare_t    *auto_shr;
 700         vnode_t         *vp;
 701         int             rc = 0;
 702 
 703         share_avl = &sv->sv_export.e_share_avl;
 704 
 705         if (!STYPE_ISDSK(shr->shr_type)) {
 706                 if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 707                         cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 708                             shr->shr_name, rc);
 709                 }
 710 
 711                 return (rc);
 712         }
 713 
 714         if ((auto_shr = smb_avl_lookup(share_avl, shr)) != NULL) {
 715                 if ((auto_shr->shr_flags & SMB_SHRF_AUTOHOME) == 0) {
 716                         smb_avl_release(share_avl, auto_shr);
 717                         return (EEXIST);
 718                 }
 719 
 720                 mutex_enter(&auto_shr->shr_mutex);
 721                 auto_shr->shr_autocnt++;
 722                 mutex_exit(&auto_shr->shr_mutex);


 723                 smb_avl_release(share_avl, auto_shr);
 724                 return (0);
 725         }
 726 
 727         if ((rc = smb_server_sharevp(sv, shr->shr_path, &vp)) != 0) {
 728                 cmn_err(CE_WARN, "export[%s(%s)]: failed obtaining vnode (%d)",






 729                     shr->shr_name, shr->shr_path, rc);
 730                 return (rc);
 731         }
 732 
 733         if ((rc = smb_vfs_hold(&sv->sv_export, vp->v_vfsp)) == 0) {
 734                 if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 735                         cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 736                             shr->shr_name, rc);
 737                         smb_vfs_rele(&sv->sv_export, vp->v_vfsp);


 738                 }
 739         } else {
 740                 cmn_err(CE_WARN, "export[%s(%s)]: failed holding VFS (%d)",
 741                     shr->shr_name, shr->shr_path, rc);












 742         }

 743 
 744         VN_RELE(vp);
 745         return (rc);
 746 }
 747 

 748 /*











































































































































































 749  * Removes the share specified by 'shrname' from the AVL
 750  * tree of the given server if it's there.
 751  *
 752  * If the share is an Autohome share, the autohome count
 753  * is decremented and the share is only removed if the
 754  * count goes to zero.
 755  *
 756  * If the share is a disk share, the hold on the corresponding
 757  * file system is released before removing the share from
 758  * the AVL tree.
 759  */
 760 static int
 761 smb_kshare_unexport(smb_server_t *sv, const char *shrname)
 762 {
 763         smb_avl_t       *share_avl;
 764         smb_kshare_t    key;
 765         smb_kshare_t    *shr;
 766         vnode_t         *vp;
 767         int             rc;
 768         boolean_t       auto_unexport;
 769 
 770         share_avl = &sv->sv_export.e_share_avl;
 771 
 772         key.shr_name = (char *)shrname;
 773         if ((shr = smb_avl_lookup(share_avl, &key)) == NULL)
 774                 return (ENOENT);
 775 
 776         if ((shr->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
 777                 mutex_enter(&shr->shr_mutex);
 778                 shr->shr_autocnt--;
 779                 auto_unexport = (shr->shr_autocnt == 0);
 780                 mutex_exit(&shr->shr_mutex);
 781                 if (!auto_unexport) {
 782                         smb_avl_release(share_avl, shr);
 783                         return (0);
 784                 }
 785         }
 786 
 787         if (STYPE_ISDSK(shr->shr_type)) {
 788                 if ((rc = smb_server_sharevp(sv, shr->shr_path, &vp)) != 0) {
 789                         smb_avl_release(share_avl, shr);
 790                         cmn_err(CE_WARN, "unexport[%s]: failed obtaining vnode"
 791                             " (%d)", shrname, rc);
 792                         return (rc);
 793                 }
 794 
 795                 smb_vfs_rele(&sv->sv_export, vp->v_vfsp);
 796                 VN_RELE(vp);
 797         }
 798 
 799         smb_avl_remove(share_avl, shr);
 800         smb_avl_release(share_avl, shr);
 801 
 802         return (0);
 803 }
 804 
 805 /*
 806  * Exports IPC$ or Admin shares
 807  */
 808 static int
 809 smb_kshare_export_trans(smb_server_t *sv, char *name, char *path, char *cmnt)
 810 {
 811         smb_kshare_t *shr;
 812 
 813         ASSERT(name);
 814         ASSERT(path);
 815 
 816         shr = kmem_cache_alloc(smb_kshare_cache_share, KM_SLEEP);
 817         bzero(shr, sizeof (smb_kshare_t));
 818 
 819         shr->shr_magic = SMB_SHARE_MAGIC;


 832         if (cmnt)
 833                 shr->shr_cmnt = smb_mem_strdup(cmnt);
 834         shr->shr_oemname = smb_kshare_oemname(name);
 835 
 836         return (smb_kshare_export(sv, shr));
 837 }
 838 
 839 /*
 840  * Decodes share information in an nvlist format into a smb_kshare_t
 841  * structure.
 842  *
 843  * This is a temporary function and will be replaced by functions
 844  * provided by libsharev2 code after it's available.
 845  */
 846 static smb_kshare_t *
 847 smb_kshare_decode(nvlist_t *share)
 848 {
 849         smb_kshare_t tmp;
 850         smb_kshare_t *shr;
 851         nvlist_t *smb;
 852         char *csc_name = NULL;
 853         int rc;
 854 
 855         ASSERT(share);
 856 
 857         bzero(&tmp, sizeof (smb_kshare_t));
 858 
 859         rc = nvlist_lookup_string(share, "name", &tmp.shr_name);
 860         rc |= nvlist_lookup_string(share, "path", &tmp.shr_path);
 861         (void) nvlist_lookup_string(share, "desc", &tmp.shr_cmnt);
 862 
 863         ASSERT(tmp.shr_name && tmp.shr_path);
 864 
 865         rc |= nvlist_lookup_nvlist(share, "smb", &smb);
 866         if (rc != 0) {
 867                 cmn_err(CE_WARN, "kshare: failed looking up SMB properties"
 868                     " (%d)", rc);
 869                 return (NULL);
 870         }
 871 
 872         rc = nvlist_lookup_uint32(smb, "type", &tmp.shr_type);
 873         if (rc != 0) {
 874                 cmn_err(CE_WARN, "kshare[%s]: failed getting the share type"
 875                     " (%d)", tmp.shr_name, rc);
 876                 return (NULL);
 877         }
 878 
 879         (void) nvlist_lookup_string(smb, SHOPT_AD_CONTAINER,
 880             &tmp.shr_container);
 881         (void) nvlist_lookup_string(smb, SHOPT_NONE, &tmp.shr_access_none);
 882         (void) nvlist_lookup_string(smb, SHOPT_RO, &tmp.shr_access_ro);
 883         (void) nvlist_lookup_string(smb, SHOPT_RW, &tmp.shr_access_rw);
 884 
 885         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_ABE, SMB_SHRF_ABE);
 886         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_CATIA,
 887             SMB_SHRF_CATIA);
 888         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_GUEST,
 889             SMB_SHRF_GUEST_OK);
 890         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_DFSROOT,
 891             SMB_SHRF_DFSROOT);
 892         tmp.shr_flags |= smb_kshare_decode_bool(smb, "Autohome",




 893             SMB_SHRF_AUTOHOME);
 894 
 895         if ((tmp.shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME) {
 896                 rc = nvlist_lookup_uint32(smb, "uid", &tmp.shr_uid);
 897                 rc |= nvlist_lookup_uint32(smb, "gid", &tmp.shr_gid);
 898                 if (rc != 0) {
 899                         cmn_err(CE_WARN, "kshare: failed looking up uid/gid"
 900                             " (%d)", rc);
 901                         return (NULL);
 902                 }
 903         }
 904 



 905         (void) nvlist_lookup_string(smb, SHOPT_CSC, &csc_name);
 906         smb_kshare_csc_flags(&tmp, csc_name);
 907 
 908         shr = kmem_cache_alloc(smb_kshare_cache_share, KM_SLEEP);
 909         bzero(shr, sizeof (smb_kshare_t));
 910 
 911         shr->shr_magic = SMB_SHARE_MAGIC;
 912         shr->shr_refcnt = 1;
 913 
 914         shr->shr_name = smb_mem_strdup(tmp.shr_name);
 915         shr->shr_path = smb_mem_strdup(tmp.shr_path);
 916         if (tmp.shr_cmnt)
 917                 shr->shr_cmnt = smb_mem_strdup(tmp.shr_cmnt);
 918         if (tmp.shr_container)
 919                 shr->shr_container = smb_mem_strdup(tmp.shr_container);
 920         if (tmp.shr_access_none)
 921                 shr->shr_access_none = smb_mem_strdup(tmp.shr_access_none);
 922         if (tmp.shr_access_ro)
 923                 shr->shr_access_ro = smb_mem_strdup(tmp.shr_access_ro);
 924         if (tmp.shr_access_rw)
 925                 shr->shr_access_rw = smb_mem_strdup(tmp.shr_access_rw);
 926 
 927         shr->shr_oemname = smb_kshare_oemname(shr->shr_name);
 928         shr->shr_flags = tmp.shr_flags | smb_kshare_is_admin(shr->shr_name);
 929         shr->shr_type = tmp.shr_type | smb_kshare_is_special(shr->shr_name);

 930 
 931         shr->shr_uid = tmp.shr_uid;
 932         shr->shr_gid = tmp.shr_gid;
 933 
 934         if ((shr->shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME)
 935                 shr->shr_autocnt = 1;
 936 
 937         return (shr);
 938 }
 939 
 940 #if 0
 941 static void
 942 smb_kshare_log(smb_kshare_t *shr)
 943 {
 944         cmn_err(CE_NOTE, "Share info:");
 945         cmn_err(CE_NOTE, "\tname: %s", (shr->shr_name) ? shr->shr_name : "");
 946         cmn_err(CE_NOTE, "\tpath: %s", (shr->shr_path) ? shr->shr_path : "");
 947         cmn_err(CE_NOTE, "\tcmnt: (%s)",
 948             (shr->shr_cmnt) ? shr->shr_cmnt : "NULL");
 949         cmn_err(CE_NOTE, "\toemname: (%s)",
 950             (shr->shr_oemname) ? shr->shr_oemname : "NULL");
 951         cmn_err(CE_NOTE, "\tflags: %X", shr->shr_flags);
 952         cmn_err(CE_NOTE, "\ttype: %d", shr->shr_type);
 953 }
 954 #endif
 955 
 956 /*


1016         shr->shr_refcnt--;
1017         destroy = (shr->shr_refcnt == 0);
1018         mutex_exit(&shr->shr_mutex);
1019 
1020         return (destroy);
1021 }
1022 
1023 /*
1024  * Frees all the memory allocated for the given
1025  * share structure. It also removes the structure
1026  * from the share cache.
1027  */
1028 static void
1029 smb_kshare_destroy(void *p)
1030 {
1031         smb_kshare_t *shr = (smb_kshare_t *)p;
1032 
1033         ASSERT(shr);
1034         ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
1035 















1036         smb_mem_free(shr->shr_name);
1037         smb_mem_free(shr->shr_path);
1038         smb_mem_free(shr->shr_cmnt);
1039         smb_mem_free(shr->shr_container);
1040         smb_mem_free(shr->shr_oemname);
1041         smb_mem_free(shr->shr_access_none);
1042         smb_mem_free(shr->shr_access_ro);
1043         smb_mem_free(shr->shr_access_rw);
1044 
1045         kmem_cache_free(smb_kshare_cache_share, shr);
1046 }
1047 
1048 
1049 /*
1050  * Generate an OEM name for the given share name.  If the name is
1051  * shorter than 13 bytes the oemname will be returned; otherwise NULL
1052  * is returned.
1053  */
1054 static char *
1055 smb_kshare_oemname(const char *shrname)




   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 /*
  23  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2017 Joyent, Inc.
  26  */
  27 
  28 #include <smbsrv/smb_door.h>

  29 #include <smbsrv/smb_ktypes.h>
  30 #include <smbsrv/smb2_kproto.h>
  31 #include <smbsrv/smb_kstat.h>
  32 
  33 typedef struct smb_unshare {
  34         list_node_t     us_lnd;
  35         char            us_sharename[MAXNAMELEN];
  36 } smb_unshare_t;
  37 
  38 static kmem_cache_t     *smb_kshare_cache_share;
  39 static kmem_cache_t     *smb_kshare_cache_unexport;

  40 
  41 static int smb_kshare_cmp(const void *, const void *);
  42 static void smb_kshare_hold(const void *);
  43 static boolean_t smb_kshare_rele(const void *);
  44 static void smb_kshare_destroy(void *);
  45 static char *smb_kshare_oemname(const char *);
  46 static int smb_kshare_is_special(const char *);
  47 static boolean_t smb_kshare_is_admin(const char *);
  48 static smb_kshare_t *smb_kshare_decode(nvlist_t *);
  49 static uint32_t smb_kshare_decode_bool(nvlist_t *, const char *, uint32_t);
  50 static void smb_kshare_unexport_thread(smb_thread_t *, void *);
  51 static int smb_kshare_export(smb_server_t *, smb_kshare_t *);
  52 static int smb_kshare_unexport(smb_server_t *, const char *);
  53 static int smb_kshare_export_trans(smb_server_t *, char *, char *, char *);
  54 static void smb_kshare_csc_flags(smb_kshare_t *, const char *);
  55 static int smb_named_kstat_update(kstat_t *ks, int rw);
  56 static int smb_kshare_kstat_update(kstat_t *, int);
  57 void kshare_stats_init(smb_server_t *, smb_kshare_t *);
  58 void kshare_stats_fini(smb_kshare_t *);
  59 
  60 static boolean_t smb_export_isready(smb_server_t *);
  61 
  62 #ifdef  _KERNEL
  63 static int smb_kshare_chk_dsrv_status(int, smb_dr_ctx_t *);
  64 #endif  /* _KERNEL */
  65 
  66 static const smb_avl_nops_t smb_kshare_avlops = {
  67         smb_kshare_cmp,
  68         smb_kshare_hold,
  69         smb_kshare_rele,
  70         smb_kshare_destroy
  71 };
  72 
  73 #ifdef  _KERNEL
  74 /*
  75  * This function is not MultiThread safe. The caller has to make sure only one
  76  * thread calls this function.
  77  */
  78 door_handle_t


 281         (void) smb_kshare_export_trans(sv, "vss$", SMB_VSS, "VSS");
 282 }
 283 
 284 /*
 285  * This function is called when smb_server_t goes
 286  * away which means SMB shares should not be made
 287  * available to clients
 288  */
 289 void
 290 smb_export_stop(smb_server_t *sv)
 291 {
 292         mutex_enter(&sv->sv_export.e_mutex);
 293         if (!sv->sv_export.e_ready) {
 294                 mutex_exit(&sv->sv_export.e_mutex);
 295                 return;
 296         }
 297         sv->sv_export.e_ready = B_FALSE;
 298         mutex_exit(&sv->sv_export.e_mutex);
 299 
 300         smb_avl_destroy(&sv->sv_export.e_share_avl);

 301 }
 302 
 303 void
 304 smb_kshare_g_init(void)
 305 {
 306         smb_kshare_cache_share = kmem_cache_create("smb_share_cache",
 307             sizeof (smb_kshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 308 
 309         smb_kshare_cache_unexport = kmem_cache_create("smb_unexport_cache",
 310             sizeof (smb_unshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);



 311 }
 312 
 313 void
 314 smb_kshare_init(smb_server_t *sv)
 315 {
 316 



 317         smb_slist_constructor(&sv->sv_export.e_unexport_list,
 318             sizeof (smb_unshare_t), offsetof(smb_unshare_t, us_lnd));
 319 }
 320 
 321 int
 322 smb_kshare_start(smb_server_t *sv)
 323 {
 324         smb_thread_init(&sv->sv_export.e_unexport_thread, "smb_kshare_unexport",
 325             smb_kshare_unexport_thread, sv, smbsrv_base_pri);
 326 
 327         return (smb_thread_start(&sv->sv_export.e_unexport_thread));
 328 }
 329 
 330 void
 331 smb_kshare_stop(smb_server_t *sv)
 332 {
 333         smb_thread_stop(&sv->sv_export.e_unexport_thread);
 334         smb_thread_destroy(&sv->sv_export.e_unexport_thread);
 335 }
 336 
 337 void
 338 smb_kshare_fini(smb_server_t *sv)
 339 {
 340         smb_unshare_t *ux;
 341 
 342         while ((ux = list_head(&sv->sv_export.e_unexport_list.sl_list))
 343             != NULL) {
 344                 smb_slist_remove(&sv->sv_export.e_unexport_list, ux);
 345                 kmem_cache_free(smb_kshare_cache_unexport, ux);
 346         }
 347         smb_slist_destructor(&sv->sv_export.e_unexport_list);




 348 }
 349 
 350 void
 351 smb_kshare_g_fini(void)
 352 {
 353         kmem_cache_destroy(smb_kshare_cache_unexport);
 354         kmem_cache_destroy(smb_kshare_cache_share);

 355 }
 356 
 357 /*
 358  * A list of shares in nvlist format can be sent down
 359  * from userspace thourgh the IOCTL interface. The nvlist
 360  * is unpacked here and all the shares in the list will
 361  * be exported.
 362  */
 363 int
 364 smb_kshare_export_list(smb_ioc_share_t *ioc)
 365 {
 366         smb_server_t    *sv = NULL;
 367         nvlist_t        *shrlist = NULL;
 368         nvlist_t         *share;
 369         nvpair_t         *nvp;
 370         smb_kshare_t     *shr;
 371         char            *shrname;
 372         int             rc;
 373 
 374         if ((rc = smb_server_lookup(&sv)) != 0)


 658 
 659         key.shr_name = (char *)shrname;
 660         shr = smb_avl_lookup(&sv->sv_export.e_share_avl, &key);
 661         return (shr);
 662 }
 663 
 664 /*
 665  * Releases the hold taken on the specified share object
 666  */
 667 void
 668 smb_kshare_release(smb_server_t *sv, smb_kshare_t *shr)
 669 {
 670         ASSERT(shr);
 671         ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
 672 
 673         smb_avl_release(&sv->sv_export.e_share_avl, shr);
 674 }
 675 
 676 /*
 677  * Add the given share in the specified server.
 678  * If the share is a disk share, lookup the share path
 679  * and hold the smb_node_t for the share root.


 680  *
 681  * If the share is an Autohome share and it is
 682  * already in the AVL only a reference count for
 683  * that share is incremented.
 684  */
 685 static int
 686 smb_kshare_export(smb_server_t *sv, smb_kshare_t *shr)
 687 {
 688         smb_avl_t       *share_avl;
 689         smb_kshare_t    *auto_shr;
 690         smb_node_t      *snode = NULL;
 691         int             rc = 0;
 692 
 693         share_avl = &sv->sv_export.e_share_avl;
 694 
 695         if (!STYPE_ISDSK(shr->shr_type)) {
 696                 if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 697                         cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 698                             shr->shr_name, rc);
 699                 }
 700 
 701                 return (rc);
 702         }
 703 
 704         if ((auto_shr = smb_avl_lookup(share_avl, shr)) != NULL) {
 705                 rc = EEXIST;
 706                 if ((auto_shr->shr_flags & SMB_SHRF_AUTOHOME) != 0) {



 707                         mutex_enter(&auto_shr->shr_mutex);
 708                         auto_shr->shr_autocnt++;
 709                         mutex_exit(&auto_shr->shr_mutex);
 710                         rc = 0;
 711                 }
 712                 smb_avl_release(share_avl, auto_shr);
 713                 return (rc);
 714         }
 715 
 716         /*
 717          * Get the root smb_node_t for this share, held.
 718          * This hold is normally released during AVL destroy,
 719          * via the element destructor:  smb_kshare_destroy
 720          */
 721         rc = smb_server_share_lookup(sv, shr->shr_path, &snode);
 722         if (rc != 0) {
 723                 cmn_err(CE_WARN, "export[%s(%s)]: lookup failed (%d)",
 724                     shr->shr_name, shr->shr_path, rc);
 725                 return (rc);
 726         }
 727 
 728         shr->shr_root_node = snode;
 729         if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 730                 cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 731                     shr->shr_name, rc);
 732                 shr->shr_root_node = NULL;
 733                 smb_node_release(snode);
 734                 return (rc);
 735         }
 736 
 737         kshare_stats_init(sv, shr);
 738 
 739         /*
 740          * For CA shares, find or create the CA handle dir,
 741          * and (if restarted) import persistent handles.
 742          */
 743         if ((shr->shr_flags & SMB_SHRF_CA) != 0) {
 744                 rc = smb2_dh_new_ca_share(sv, shr);
 745                 if (rc != 0) {
 746                         /* Just make it a non-CA share. */
 747                         mutex_enter(&shr->shr_mutex);
 748                         shr->shr_flags &= ~SMB_SHRF_CA;
 749                         mutex_exit(&shr->shr_mutex);
 750                         rc = 0;
 751                 }
 752         }
 753 

 754         return (rc);
 755 }
 756 
 757 
 758 /*
 759  * Following a pattern somewhat similar to smb_server_kstat_init,
 760  * but organized a little differently.
 761  */
 762 void
 763 kshare_stats_init(smb_server_t *sv, smb_kshare_t *ks)
 764 {
 765         static const char       *kr_names[] = SMBSRV_CLSH__NAMES;
 766         char                    ks_name[KSTAT_STRLEN];
 767         smbsrv_clsh_kstats_t    *ksr;
 768         int                     idx;
 769         smb_named_stats_t       *smbnsp;
 770         kstat_t                 *kstat = NULL;
 771         int                     namelen;
 772 
 773         /*
 774          * Most share names are short, and we'd like to allow consumers like
 775          * the smbstat command to compose the kstat names for short share names
 776          * directly.  In the (rare) case where we have longer share names, we
 777          * need an indirection scheme to get around the limited (31 chars) size
 778          * of kstat names. So for share names 24 chars or shorter, we compose
 779          * the kstat name directly as "smbsrv:0:sh/sharename" and when the share
 780          * name is longer, compose the kstat name using an arbitrary
 781          * (but unique) identifier like: "smbsrv:0:sh/:ffffff0009560a98".  To
 782          * find the unique identifier given a (long) share name, the consumer
 783          * has to enumerate the (fake) "smbsrvshr" kstat module, looking for the
 784          * kstat with the sharename element matching the one they want.  Both
 785          * direct and indirect names are instantiated under the "smbsrvshr"
 786          * module, so a consumer that wants all the share kstats could always
 787          * lookup the kstat names using the indirection scheme if that's easier.
 788          * (Nothing forces the consumer to directly compose kstat names when the
 789          * share name happens to be short -- they can always enumerate to find
 790          * it.)
 791          *
 792          * SMB share names are not allowed to contain a colon.  The naming
 793          * scheme here uses a colon at the beginning of what would otherwise be
 794          * the share name part of the kstat name to indicate that this name uses
 795          * the "indirection" scheme.  With indirection, the part after the colon
 796          * is an arbitrary (but unique per share) identifier of some other
 797          * kstat, and a consumer needs to fetch that kstat to get the real share
 798          * name.
 799          */
 800         namelen = strlen(ks->shr_name);
 801         if (namelen <= 24) {
 802                 (void) snprintf(ks_name, sizeof (ks_name), "sh/%s",
 803                     ks->shr_name);
 804 
 805                 kstat = kstat_hold_byname("smbsrvshr", 0, ks_name, sv->sv_zid);
 806         }
 807 
 808         if (namelen > 24 || kstat != NULL) {
 809                 (void) snprintf(ks_name, sizeof (ks_name), "sh/:%p",
 810                     (void *)ks);
 811 
 812                 if (kstat != NULL)
 813                         kstat_rele(kstat);
 814         }
 815 
 816         ks->shr_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
 817             ks_name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
 818             sizeof (smbsrv_clsh_kstats_t), 0, sv->sv_zid);
 819 
 820         if (ks->shr_ksp == NULL)
 821                 return;
 822 
 823         ks->stats.ksns = kstat_create_zone("smbsrvshr", 0,
 824             ks_name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
 825             0, KSTAT_FLAG_VIRTUAL, sv->sv_zid);
 826 
 827         if (ks->stats.ksns == NULL) {
 828                 kstat_delete(ks->shr_ksp);
 829                 ks->shr_ksp = NULL;
 830                 return;
 831         }
 832 
 833         ks->shr_ksp->ks_update = smb_kshare_kstat_update;
 834         ks->shr_ksp->ks_private = ks;
 835 
 836         /*
 837          * In-line equivalent of smb_dispatch_stats_init
 838          */
 839         ksr = (smbsrv_clsh_kstats_t *)ks->shr_ksp->ks_data;
 840         for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++) {
 841                 smb_latency_init(&ks->shr_stats[idx].sdt_lat);
 842                 (void) strlcpy(ksr->ks_clsh[idx].kr_name, kr_names[idx],
 843                     KSTAT_STRLEN);
 844         }
 845 
 846         /*
 847          * SMB named kstats setup for > KSTAT_STRLEN name to short name mapping.
 848          */
 849         smbnsp = &ks->stats.ks_data;
 850         ks->stats.ksns->ks_data = &ks->stats.ks_data;
 851         ks->stats.ksns->ks_data_size = sizeof (ks->stats.ks_data);
 852         ks->stats.ksns->ks_ndata = 1;
 853         kstat_named_init(smbnsp->kn, "share name",
 854             KSTAT_DATA_STRING);
 855         ks->stats.ksns->ks_update = smb_named_kstat_update;
 856         ks->stats.ksns->ks_private = (void *)ks;
 857 
 858         kstat_install(ks->shr_ksp);
 859         kstat_install(ks->stats.ksns);
 860 }
 861 
 862 void
 863 kshare_stats_fini(smb_kshare_t *ks)
 864 {
 865         int idx;
 866 
 867         for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++)
 868                 smb_latency_destroy(&ks->shr_stats[idx].sdt_lat);
 869 }
 870 
 871 static int
 872 smb_named_kstat_update(kstat_t *ks, int rw)
 873 {
 874         smb_kshare_t            *smbksp = (smb_kshare_t *)ks->ks_private;
 875         smb_named_stats_t       *smbnsp = &smbksp->stats.ks_data;
 876 
 877         if (rw == KSTAT_READ) {
 878                 (void) strlcpy(smbnsp->name, smbksp->shr_name,
 879                     sizeof (smbnsp->name));
 880 
 881                 kstat_named_setstr(&smbnsp->kn[0],
 882                     (const char *)smbksp->shr_name);
 883         }
 884         return (0);
 885 }
 886 
 887 /*
 888  * Update the kstat data from our private stats.
 889  */
 890 static int
 891 smb_kshare_kstat_update(kstat_t *ksp, int rw)
 892 {
 893         smb_kshare_t *kshare;
 894         smb_disp_stats_t *sds;
 895         smbsrv_clsh_kstats_t    *clsh;
 896         smb_kstat_req_t *ksr;
 897         int i;
 898 
 899         if (rw == KSTAT_WRITE)
 900                 return (EACCES);
 901 
 902         kshare = ksp->ks_private;
 903         ASSERT(kshare->shr_magic == SMB_SHARE_MAGIC);
 904         sds = kshare->shr_stats;
 905 
 906         clsh = (smbsrv_clsh_kstats_t *)ksp->ks_data;
 907         ksr = clsh->ks_clsh;
 908 
 909         for (i = 0; i < SMBSRV_CLSH__NREQ; i++, ksr++, sds++) {
 910                 ksr->kr_rxb = sds->sdt_rxb;
 911                 ksr->kr_txb = sds->sdt_txb;
 912                 mutex_enter(&sds->sdt_lat.ly_mutex);
 913                 ksr->kr_nreq = sds->sdt_lat.ly_a_nreq;
 914                 ksr->kr_sum = sds->sdt_lat.ly_a_sum;
 915                 ksr->kr_a_mean = sds->sdt_lat.ly_a_mean;
 916                 ksr->kr_a_stddev = sds->sdt_lat.ly_a_stddev;
 917                 ksr->kr_d_mean = sds->sdt_lat.ly_d_mean;
 918                 ksr->kr_d_stddev = sds->sdt_lat.ly_d_stddev;
 919                 sds->sdt_lat.ly_d_mean = 0;
 920                 sds->sdt_lat.ly_d_nreq = 0;
 921                 sds->sdt_lat.ly_d_stddev = 0;
 922                 sds->sdt_lat.ly_d_sum = 0;
 923                 mutex_exit(&sds->sdt_lat.ly_mutex);
 924         }
 925 
 926         return (0);
 927 }
 928 
 929 /*
 930  * Removes the share specified by 'shrname' from the AVL
 931  * tree of the given server if it's there.
 932  *
 933  * If the share is an Autohome share, the autohome count
 934  * is decremented and the share is only removed if the
 935  * count goes to zero.
 936  *
 937  * If the share is a disk share, the hold on the corresponding
 938  * file system is released before removing the share from
 939  * the AVL tree.
 940  */
 941 static int
 942 smb_kshare_unexport(smb_server_t *sv, const char *shrname)
 943 {
 944         smb_avl_t       *share_avl;
 945         smb_kshare_t    key;
 946         smb_kshare_t    *shr;


 947         boolean_t       auto_unexport;
 948 
 949         share_avl = &sv->sv_export.e_share_avl;
 950 
 951         key.shr_name = (char *)shrname;
 952         if ((shr = smb_avl_lookup(share_avl, &key)) == NULL)
 953                 return (ENOENT);
 954 
 955         if ((shr->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
 956                 mutex_enter(&shr->shr_mutex);
 957                 shr->shr_autocnt--;
 958                 auto_unexport = (shr->shr_autocnt == 0);
 959                 mutex_exit(&shr->shr_mutex);
 960                 if (!auto_unexport) {
 961                         smb_avl_release(share_avl, shr);
 962                         return (0);
 963                 }
 964         }
 965 
 966         smb_avl_remove(share_avl, shr);






 967 
 968         mutex_enter(&shr->shr_mutex);
 969         shr->shr_flags |= SMB_SHRF_REMOVED;
 970         mutex_exit(&shr->shr_mutex);
 971 

 972         smb_avl_release(share_avl, shr);
 973 
 974         return (0);
 975 }
 976 
 977 /*
 978  * Exports IPC$ or Admin shares
 979  */
 980 static int
 981 smb_kshare_export_trans(smb_server_t *sv, char *name, char *path, char *cmnt)
 982 {
 983         smb_kshare_t *shr;
 984 
 985         ASSERT(name);
 986         ASSERT(path);
 987 
 988         shr = kmem_cache_alloc(smb_kshare_cache_share, KM_SLEEP);
 989         bzero(shr, sizeof (smb_kshare_t));
 990 
 991         shr->shr_magic = SMB_SHARE_MAGIC;


1004         if (cmnt)
1005                 shr->shr_cmnt = smb_mem_strdup(cmnt);
1006         shr->shr_oemname = smb_kshare_oemname(name);
1007 
1008         return (smb_kshare_export(sv, shr));
1009 }
1010 
1011 /*
1012  * Decodes share information in an nvlist format into a smb_kshare_t
1013  * structure.
1014  *
1015  * This is a temporary function and will be replaced by functions
1016  * provided by libsharev2 code after it's available.
1017  */
1018 static smb_kshare_t *
1019 smb_kshare_decode(nvlist_t *share)
1020 {
1021         smb_kshare_t tmp;
1022         smb_kshare_t *shr;
1023         nvlist_t *smb;
1024         char *csc_name = NULL, *strbuf = NULL;
1025         int rc;
1026 
1027         ASSERT(share);
1028 
1029         bzero(&tmp, sizeof (smb_kshare_t));
1030 
1031         rc = nvlist_lookup_string(share, "name", &tmp.shr_name);
1032         rc |= nvlist_lookup_string(share, "path", &tmp.shr_path);
1033         (void) nvlist_lookup_string(share, "desc", &tmp.shr_cmnt);
1034 
1035         ASSERT(tmp.shr_name && tmp.shr_path);
1036 
1037         rc |= nvlist_lookup_nvlist(share, "smb", &smb);
1038         if (rc != 0) {
1039                 cmn_err(CE_WARN, "kshare: failed looking up SMB properties"
1040                     " (%d)", rc);
1041                 return (NULL);
1042         }
1043 
1044         rc = nvlist_lookup_uint32(smb, "type", &tmp.shr_type);
1045         if (rc != 0) {
1046                 cmn_err(CE_WARN, "kshare[%s]: failed getting the share type"
1047                     " (%d)", tmp.shr_name, rc);
1048                 return (NULL);
1049         }
1050 
1051         (void) nvlist_lookup_string(smb, SHOPT_AD_CONTAINER,
1052             &tmp.shr_container);
1053         (void) nvlist_lookup_string(smb, SHOPT_NONE, &tmp.shr_access_none);
1054         (void) nvlist_lookup_string(smb, SHOPT_RO, &tmp.shr_access_ro);
1055         (void) nvlist_lookup_string(smb, SHOPT_RW, &tmp.shr_access_rw);
1056 
1057         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_ABE, SMB_SHRF_ABE);
1058         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_CATIA,
1059             SMB_SHRF_CATIA);
1060         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_GUEST,
1061             SMB_SHRF_GUEST_OK);
1062         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_DFSROOT,
1063             SMB_SHRF_DFSROOT);
1064         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_QUOTAS,
1065             SMB_SHRF_QUOTAS);
1066         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_CA, SMB_SHRF_CA);
1067         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_FSO, SMB_SHRF_FSO);
1068         tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_AUTOHOME,
1069             SMB_SHRF_AUTOHOME);
1070 
1071         if ((tmp.shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME) {
1072                 rc = nvlist_lookup_uint32(smb, "uid", &tmp.shr_uid);
1073                 rc |= nvlist_lookup_uint32(smb, "gid", &tmp.shr_gid);
1074                 if (rc != 0) {
1075                         cmn_err(CE_WARN, "kshare: failed looking up uid/gid"
1076                             " (%d)", rc);
1077                         return (NULL);
1078                 }
1079         }
1080 
1081         (void) nvlist_lookup_string(smb, SHOPT_ENCRYPT, &strbuf);
1082         smb_cfg_set_require(strbuf, &tmp.shr_encrypt);
1083 
1084         (void) nvlist_lookup_string(smb, SHOPT_CSC, &csc_name);
1085         smb_kshare_csc_flags(&tmp, csc_name);
1086 
1087         shr = kmem_cache_alloc(smb_kshare_cache_share, KM_SLEEP);
1088         bzero(shr, sizeof (smb_kshare_t));
1089 
1090         shr->shr_magic = SMB_SHARE_MAGIC;
1091         shr->shr_refcnt = 1;
1092 
1093         shr->shr_name = smb_mem_strdup(tmp.shr_name);
1094         shr->shr_path = smb_mem_strdup(tmp.shr_path);
1095         if (tmp.shr_cmnt)
1096                 shr->shr_cmnt = smb_mem_strdup(tmp.shr_cmnt);
1097         if (tmp.shr_container)
1098                 shr->shr_container = smb_mem_strdup(tmp.shr_container);
1099         if (tmp.shr_access_none)
1100                 shr->shr_access_none = smb_mem_strdup(tmp.shr_access_none);
1101         if (tmp.shr_access_ro)
1102                 shr->shr_access_ro = smb_mem_strdup(tmp.shr_access_ro);
1103         if (tmp.shr_access_rw)
1104                 shr->shr_access_rw = smb_mem_strdup(tmp.shr_access_rw);
1105 
1106         shr->shr_oemname = smb_kshare_oemname(shr->shr_name);
1107         shr->shr_flags = tmp.shr_flags | smb_kshare_is_admin(shr->shr_name);
1108         shr->shr_type = tmp.shr_type | smb_kshare_is_special(shr->shr_name);
1109         shr->shr_encrypt = tmp.shr_encrypt;
1110 
1111         shr->shr_uid = tmp.shr_uid;
1112         shr->shr_gid = tmp.shr_gid;
1113 
1114         if ((shr->shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME)
1115                 shr->shr_autocnt = 1;

1116         return (shr);
1117 }
1118 
1119 #if 0
1120 static void
1121 smb_kshare_log(smb_kshare_t *shr)
1122 {
1123         cmn_err(CE_NOTE, "Share info:");
1124         cmn_err(CE_NOTE, "\tname: %s", (shr->shr_name) ? shr->shr_name : "");
1125         cmn_err(CE_NOTE, "\tpath: %s", (shr->shr_path) ? shr->shr_path : "");
1126         cmn_err(CE_NOTE, "\tcmnt: (%s)",
1127             (shr->shr_cmnt) ? shr->shr_cmnt : "NULL");
1128         cmn_err(CE_NOTE, "\toemname: (%s)",
1129             (shr->shr_oemname) ? shr->shr_oemname : "NULL");
1130         cmn_err(CE_NOTE, "\tflags: %X", shr->shr_flags);
1131         cmn_err(CE_NOTE, "\ttype: %d", shr->shr_type);
1132 }
1133 #endif
1134 
1135 /*


1195         shr->shr_refcnt--;
1196         destroy = (shr->shr_refcnt == 0);
1197         mutex_exit(&shr->shr_mutex);
1198 
1199         return (destroy);
1200 }
1201 
1202 /*
1203  * Frees all the memory allocated for the given
1204  * share structure. It also removes the structure
1205  * from the share cache.
1206  */
1207 static void
1208 smb_kshare_destroy(void *p)
1209 {
1210         smb_kshare_t *shr = (smb_kshare_t *)p;
1211 
1212         ASSERT(shr);
1213         ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
1214 
1215         if (shr->shr_ksp != NULL) {
1216                 kstat_delete(shr->shr_ksp);
1217                 shr->shr_ksp = NULL;
1218                 kshare_stats_fini(shr);
1219         }
1220 
1221         if (shr->stats.ksns != NULL) {
1222                 kstat_delete(shr->stats.ksns);
1223         }
1224 
1225         if (shr->shr_ca_dir != NULL)
1226                 smb_node_release(shr->shr_ca_dir);
1227         if (shr->shr_root_node)
1228                 smb_node_release(shr->shr_root_node);
1229 
1230         smb_mem_free(shr->shr_name);
1231         smb_mem_free(shr->shr_path);
1232         smb_mem_free(shr->shr_cmnt);
1233         smb_mem_free(shr->shr_container);
1234         smb_mem_free(shr->shr_oemname);
1235         smb_mem_free(shr->shr_access_none);
1236         smb_mem_free(shr->shr_access_ro);
1237         smb_mem_free(shr->shr_access_rw);
1238 
1239         kmem_cache_free(smb_kshare_cache_share, shr);
1240 }
1241 
1242 
1243 /*
1244  * Generate an OEM name for the given share name.  If the name is
1245  * shorter than 13 bytes the oemname will be returned; otherwise NULL
1246  * is returned.
1247  */
1248 static char *
1249 smb_kshare_oemname(const char *shrname)