Print this page
NEX-17457 kernel share list fails to be updated after fs import
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
NEX-16159 Time spent sharing SMB filesystems could be reduced by optimizing smb_getdataset for default mount points
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Reviewed by: Matt Barden <matt.barden@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-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-10098 Disabling SMB server service does not change the sharestate of a smb share to “offline”.(cstyle)
NEX-10098 Disabling SMB server service does not change the sharestate of a smb share to “offline”.
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@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-6949 SMB shares with no permission for root fail after restart
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexent.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6135 Pool cannot get exported while deletes is running
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexent.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-4865 Still creating .$EXTEND directory with quotas disabled
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@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>
NEX-3673 CLONE NEX-2525 Customer cannot set Share Properties using MMC in Windows Server 2008 R2
Reviewed by: Alek Pinchuk <alek@nexenta.com>
NEX-1473 share unavailable after failover (copyright update)
NEX-1473 share unavailable after failover

*** 17,27 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* * SMB/CIFS share cache implementation. */ --- 17,27 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* * SMB/CIFS share cache implementation. */
*** 387,396 **** --- 387,397 ---- smb_shr_add(smb_share_t *si) { struct stat st; smb_share_t *cached_si; nvlist_t *shrlist; + boolean_t created_zfs = B_FALSE; uint32_t status; int rc; assert(si != NULL);
*** 414,432 **** --- 415,460 ---- if (STYPE_ISDSK(si->shr_type)) { /* * If share type is STYPE_DISKTREE then the path to the * share should exist so that we can add the share to cache. + * If path is ZFS, add the .zfs/shares/<share> entry. + * + * Both actions may require privileges that main dropped, + * so we need to temporarily make those effective. */ + if (smb_proc_takesem() == 0) { + + (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + rc = stat(si->shr_path, &st); + if (rc == 0) { + smb_shr_zfs_add(si); + created_zfs = B_TRUE; + } + + (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + smb_proc_givesem(); + } else { + rc = NERR_InternalError; + } if (rc != 0) { smb_shr_cache_unlock(); return (NERR_ItemNotFound); } } if ((status = smb_shr_cache_addent(si)) != NERR_Success) { + /* This error should be impossible after findent above. */ smb_shr_cache_unlock(); return (status); } /* don't hold the lock across door call */
*** 438,462 **** nvlist_free(shrlist); if (rc == 0) { smb_shr_publish(si->shr_name, si->shr_container); - /* If path is ZFS, add the .zfs/shares/<share> entry. */ - smb_shr_zfs_add(si); - if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) dfs_namespace_load(si->shr_name); return (NERR_Success); } } if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) { smb_shr_cache_delent(si->shr_name); smb_shr_cache_unlock(); } /* * rc == ENOENT means the shared directory doesn't exist */ return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError); } --- 466,510 ---- nvlist_free(shrlist); if (rc == 0) { smb_shr_publish(si->shr_name, si->shr_container); if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) dfs_namespace_load(si->shr_name); return (NERR_Success); } } + /* + * Error code path, i.e. when the kernel could not accept + * the new share for some reason. + */ if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) { smb_shr_cache_delent(si->shr_name); smb_shr_cache_unlock(); } + if (created_zfs && smb_proc_takesem() == 0) { + + (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_shr_zfs_remove(si); + + (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_proc_givesem(); + } + /* * rc == ENOENT means the shared directory doesn't exist */ return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError); }
*** 503,515 **** } } /* * If path is ZFS, remove the .zfs/shares/<share> entry. Need ! * to remove before cleanup of cache occurs. */ smb_shr_zfs_remove(si); (void) smb_shr_encode(si, &shrlist); (void) strlcpy(container, si->shr_container, sizeof (container)); dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0); smb_shr_cache_delent(sharename); --- 551,582 ---- } } /* * If path is ZFS, remove the .zfs/shares/<share> entry. Need ! * to remove before cleanup of cache occurs. These actions ! * require temporary elevation of privileges. */ + if (smb_proc_takesem() == 0) { + + (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + smb_shr_zfs_remove(si); + + (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_proc_givesem(); + } + (void) smb_shr_encode(si, &shrlist); (void) strlcpy(container, si->shr_container, sizeof (container)); dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0); smb_shr_cache_delent(sharename);
*** 568,581 **** } bcopy(from_si, &to_si, sizeof (smb_share_t)); (void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name)); - /* If path is ZFS, rename the .zfs/shares/<share> entry. */ smb_shr_zfs_rename(from_si, &to_si); if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) { smb_shr_cache_unlock(); return (status); } --- 635,664 ---- } bcopy(from_si, &to_si, sizeof (smb_share_t)); (void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name)); /* If path is ZFS, rename the .zfs/shares/<share> entry. */ + if (smb_proc_takesem() == 0) { + + (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + smb_shr_zfs_rename(from_si, &to_si); + (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_proc_givesem(); + } + if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) { smb_shr_cache_unlock(); return (status); }
*** 626,643 **** * Modifies an existing share. Properties that can be modified are: * * o comment * o AD container * o host access ! * o abe */ uint32_t smb_shr_modify(smb_share_t *new_si) { smb_share_t *si; boolean_t adc_changed = B_FALSE; ! char old_container[MAXPATHLEN]; uint32_t access, flag; nvlist_t *shrlist; assert(new_si != NULL); --- 709,727 ---- * Modifies an existing share. Properties that can be modified are: * * o comment * o AD container * o host access ! * o flags */ uint32_t smb_shr_modify(smb_share_t *new_si) { + smb_share_t old_si; smb_share_t *si; boolean_t adc_changed = B_FALSE; ! boolean_t quota_flag_changed = B_FALSE; uint32_t access, flag; nvlist_t *shrlist; assert(new_si != NULL);
*** 653,672 **** /* IPC$ share cannot be modified */ smb_shr_cache_unlock(); return (ERROR_ACCESS_DENIED); } (void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt)); ! adc_changed = (strcmp(new_si->shr_container, si->shr_container) != 0); ! if (adc_changed) { ! /* save current container - needed for unpublishing */ ! (void) strlcpy(old_container, si->shr_container, ! sizeof (old_container)); (void) strlcpy(si->shr_container, new_si->shr_container, sizeof (si->shr_container)); ! } flag = (new_si->shr_flags & SMB_SHRF_ABE); si->shr_flags &= ~SMB_SHRF_ABE; si->shr_flags |= flag; --- 737,760 ---- /* IPC$ share cannot be modified */ smb_shr_cache_unlock(); return (ERROR_ACCESS_DENIED); } + /* + * Keep a copy of what the share entry looks like before we + * modify it. We need this for things like unpublishing + * from the old share container, removing the quota dir. + */ + bcopy(si, &old_si, sizeof (old_si)); + + /* Share comment */ (void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt)); ! /* Container */ (void) strlcpy(si->shr_container, new_si->shr_container, sizeof (si->shr_container)); ! adc_changed = (strcmp(old_si.shr_container, si->shr_container) != 0); flag = (new_si->shr_flags & SMB_SHRF_ABE); si->shr_flags &= ~SMB_SHRF_ABE; si->shr_flags |= flag;
*** 680,697 **** --- 768,801 ---- flag = (new_si->shr_flags & SMB_SHRF_DFSROOT); si->shr_flags &= ~SMB_SHRF_DFSROOT; si->shr_flags |= flag; + flag = (new_si->shr_flags & SMB_SHRF_CA); + si->shr_flags &= ~SMB_SHRF_CA; + si->shr_flags |= flag; + + flag = (new_si->shr_flags & SMB_SHRF_FSO); + si->shr_flags &= ~SMB_SHRF_FSO; + si->shr_flags |= flag; + + flag = (new_si->shr_flags & SMB_SHRF_QUOTAS); + si->shr_flags &= ~SMB_SHRF_QUOTAS; + si->shr_flags |= flag; + if ((old_si.shr_flags ^ si->shr_flags) & SMB_SHRF_QUOTAS) + quota_flag_changed = B_TRUE; + flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK); si->shr_flags &= ~SMB_SHRF_CSC_MASK; si->shr_flags |= flag; access = (new_si->shr_flags & SMB_SHRF_ACC_ALL); si->shr_flags &= ~SMB_SHRF_ACC_ALL; si->shr_flags |= access; + si->shr_encrypt = new_si->shr_encrypt; + if (access & SMB_SHRF_ACC_NONE) (void) strlcpy(si->shr_access_none, new_si->shr_access_none, sizeof (si->shr_access_none)); if (access & SMB_SHRF_ACC_RO)
*** 713,726 **** nvlist_free(shrlist); } } if (adc_changed) { ! smb_shr_unpublish(new_si->shr_name, old_container); smb_shr_publish(new_si->shr_name, new_si->shr_container); } return (NERR_Success); } /* * smb_shr_exists --- 817,851 ---- nvlist_free(shrlist); } } if (adc_changed) { ! smb_shr_unpublish(old_si.shr_name, old_si.shr_container); smb_shr_publish(new_si->shr_name, new_si->shr_container); } + /* The following required privileges we dropped. */ + if (quota_flag_changed && smb_proc_takesem() == 0) { + + (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_shr_zfs_remove(&old_si); + smb_shr_zfs_add(si); + + (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, + PRIV_FILE_DAC_SEARCH, + PRIV_FILE_DAC_WRITE, + NULL); + + smb_proc_givesem(); + } + return (NERR_Success); } /* * smb_shr_exists
*** 1434,1444 **** * All functions in this section are private * ============================================ */ /* ! * Load shares from sharemgr */ /*ARGSUSED*/ void * smb_shr_load(void *args) { --- 1559,1574 ---- * All functions in this section are private * ============================================ */ /* ! * Loads the SMB shares, from sharemgr, then: ! * - calls smb_shr_add which: ! * - adds the share into the share cache ! * - adds the share into in-kernel kshare table ! * - publishes the share in ADS ! * - updates the share list in sharefs/sharetab */ /*ARGSUSED*/ void * smb_shr_load(void *args) {
*** 1445,1458 **** sa_handle_t handle; sa_group_t group, subgroup; char *gstate; boolean_t gdisabled; ! (void) mutex_lock(&smb_shr_exec_mtx); ! (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap, ! MAXPATHLEN); ! (void) mutex_unlock(&smb_shr_exec_mtx); if ((handle = smb_shr_sa_enter()) == NULL) { syslog(LOG_ERR, "smb_shr_load: load failed"); return (NULL); } --- 1575,1585 ---- sa_handle_t handle; sa_group_t group, subgroup; char *gstate; boolean_t gdisabled; ! smb_shr_load_execinfo(); if ((handle = smb_shr_sa_enter()) == NULL) { syslog(LOG_ERR, "smb_shr_load: load failed"); return (NULL); }
*** 1479,1489 **** --- 1606,1660 ---- } smb_shr_sa_exit(); return (NULL); } + void + smb_shr_load_execinfo() + { + (void) mutex_lock(&smb_shr_exec_mtx); + (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap, + MAXPATHLEN); + (void) mutex_unlock(&smb_shr_exec_mtx); + } + /* + * Handles disabling shares in sharefs when stoping smbd + */ + void + smb_shr_unload() + { + smb_shriter_t iterator; + smb_share_t *si; + sa_handle_t handle; + int rc; + + if ((handle = smb_shr_sa_enter()) == NULL) { + syslog(LOG_ERR, "smb_shr_unload: failed"); + return; + } + + smb_shr_iterinit(&iterator); + + while ((si = smb_shr_iterate(&iterator)) != NULL) { + + /* Skip transient shares, IPC$, ... */ + if ((si->shr_flags & SMB_SHRF_TRANS) || + STYPE_ISIPC(si->shr_type)) + continue; + + rc = sa_delete_sharetab(handle, si->shr_path, "smb"); + if (rc) { + syslog(LOG_ERR, + "sharefs remove %s failed, rc=%d, err=%d", + si->shr_path, rc, errno); + } + } + smb_shr_sa_exit(); + } + + /* * Load the shares contained in the specified group. * * Don't process groups on which the smb protocol is disabled. * The top level ZFS group won't have the smb protocol enabled * but sub-groups will.
*** 1533,1542 **** --- 1704,1714 ---- { smb_share_t si; char *sharename; uint32_t status; boolean_t loaded; + int rc; if ((sharename = sa_get_resource_attr(resource, "name")) == NULL) return (NERR_InternalError); loaded = smb_shr_exists(sharename);
*** 1556,1565 **** --- 1728,1743 ---- syslog(LOG_DEBUG, "share: failed to cache %s (%d)", si.shr_name, status); return (status); } + rc = sa_update_sharetab(share, "smb"); + if (rc) { + syslog(LOG_ERR, "sharefs add %s failed, rc=%d, err=%d", + sharename, rc, errno); + } + return (NERR_Success); } static char * smb_shr_sa_getprop(sa_optionset_t opts, char *propname)
*** 1646,1655 **** --- 1824,1861 ---- if (val != NULL) { smb_shr_sa_setflag(val, si, SMB_SHRF_DFSROOT); free(val); } + val = smb_shr_sa_getprop(opts, SHOPT_CA); + if (val != NULL) { + smb_shr_sa_setflag(val, si, SMB_SHRF_CA); + free(val); + } + + val = smb_shr_sa_getprop(opts, SHOPT_FSO); + if (val != NULL) { + smb_shr_sa_setflag(val, si, SMB_SHRF_FSO); + free(val); + } + + val = smb_shr_sa_getprop(opts, SHOPT_QUOTAS); + if (val != NULL) { + /* Turn the flag on or off */ + smb_shr_sa_setflag(val, si, SMB_SHRF_QUOTAS); + free(val); + } else { + /* Default for this is enabled. */ + si->shr_flags |= SMB_SHRF_QUOTAS; + } + + val = smb_shr_sa_getprop(opts, SHOPT_ENCRYPT); + if (val != NULL) { + smb_cfg_set_require(val, &si->shr_encrypt); + free(val); + } + val = smb_shr_sa_getprop(opts, SHOPT_CSC); if (val != NULL) { smb_shr_sa_csc_option(val, si); free(val); }
*** 2021,2046 **** } } /* * If the share path refers to a ZFS file system, add the ! * .zfs/shares/<share> object and call smb_quota_add_fs() ! * to initialize quota support for the share. */ static void smb_shr_zfs_add(smb_share_t *si) { libzfs_handle_t *libhd; zfs_handle_t *zfshd; int ret; char buf[MAXPATHLEN]; /* dataset or mountpoint */ ! if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0) return; ! if ((libhd = libzfs_init()) == NULL) return; if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) { libzfs_fini(libhd); return; } --- 2227,2254 ---- } } /* * If the share path refers to a ZFS file system, add the ! * .zfs/shares/<share> object and add or remove the special ! * directory and file telling clients about quota support. */ static void smb_shr_zfs_add(smb_share_t *si) { libzfs_handle_t *libhd; zfs_handle_t *zfshd; int ret; char buf[MAXPATHLEN]; /* dataset or mountpoint */ ! if ((libhd = libzfs_init()) == NULL) return; ! if (smb_getdataset(libhd, si->shr_path, buf, MAXPATHLEN) != 0) { ! libzfs_fini(libhd); return; + } if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) { libzfs_fini(libhd); return; }
*** 2049,2088 **** ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name); if (ret != 0 && errno != EAGAIN && errno != EEXIST) syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n", si->shr_name, strerror(errno)); ! if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN, ! NULL, NULL, 0, B_FALSE) == 0) { smb_quota_add_fs(buf); } - zfs_close(zfshd); libzfs_fini(libhd); } /* * If the share path refers to a ZFS file system, remove the ! * .zfs/shares/<share> object, and call smb_quota_remove_fs() ! * to end quota support for the share. */ static void smb_shr_zfs_remove(smb_share_t *si) { libzfs_handle_t *libhd; - zfs_handle_t *zfshd; int ret; char buf[MAXPATHLEN]; /* dataset or mountpoint */ - if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0) - return; - if ((libhd = libzfs_init()) == NULL) return; ! if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) { libzfs_fini(libhd); return; } errno = 0; --- 2257,2298 ---- ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name); if (ret != 0 && errno != EAGAIN && errno != EEXIST) syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n", si->shr_name, strerror(errno)); ! ret = zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, ! buf, MAXPATHLEN, NULL, NULL, 0, B_FALSE); ! if (ret != 0) { ! syslog(LOG_INFO, "share: failed to get mountpoint: " ! "%s\n", si->shr_name); ! } else { ! if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) { smb_quota_add_fs(buf); + } else { + smb_quota_remove_fs(buf); } + } zfs_close(zfshd); libzfs_fini(libhd); } /* * If the share path refers to a ZFS file system, remove the ! * .zfs/shares/<share> object. */ static void smb_shr_zfs_remove(smb_share_t *si) { libzfs_handle_t *libhd; int ret; char buf[MAXPATHLEN]; /* dataset or mountpoint */ if ((libhd = libzfs_init()) == NULL) return; ! if (smb_getdataset(libhd, si->shr_path, buf, MAXPATHLEN) != 0) { libzfs_fini(libhd); return; } errno = 0;
*** 2089,2104 **** ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name); if (ret != 0 && errno != EAGAIN) syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n", si->shr_name, strerror(errno)); ! if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN, ! NULL, NULL, 0, B_FALSE) == 0) { ! smb_quota_remove_fs(buf); ! } - zfs_close(zfshd); libzfs_fini(libhd); } /* * If the share path refers to a ZFS file system, rename the --- 2299,2314 ---- ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name); if (ret != 0 && errno != EAGAIN) syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n", si->shr_name, strerror(errno)); ! /* ! * We could remove the quotas directory here, but that adds ! * significantly to the time required for a zpool export, ! * so just leave it here and fixup when we share next. ! */ libzfs_fini(libhd); } /* * If the share path refers to a ZFS file system, rename the
*** 2110,2124 **** libzfs_handle_t *libhd; zfs_handle_t *zfshd; int ret; char dataset[MAXPATHLEN]; ! if (smb_getdataset(from->shr_path, dataset, MAXPATHLEN) != 0) return; ! if ((libhd = libzfs_init()) == NULL) return; if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) { libzfs_fini(libhd); return; } --- 2320,2336 ---- libzfs_handle_t *libhd; zfs_handle_t *zfshd; int ret; char dataset[MAXPATHLEN]; ! if ((libhd = libzfs_init()) == NULL) return; ! if (smb_getdataset(libhd, from->shr_path, dataset, MAXPATHLEN) != 0) { ! libzfs_fini(libhd); return; + } if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) { libzfs_fini(libhd); return; }
*** 2413,2425 **** rc |= nvlist_add_string(smb, SHOPT_CATIA, "true"); if ((si->shr_flags & SMB_SHRF_GUEST_OK) != 0) rc |= nvlist_add_string(smb, SHOPT_GUEST, "true"); if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true"); if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) { ! rc |= nvlist_add_string(smb, "Autohome", "true"); rc |= nvlist_add_uint32(smb, "uid", si->shr_uid); rc |= nvlist_add_uint32(smb, "gid", si->shr_gid); } if ((csc = smb_shr_sa_csc_name(si)) != NULL) --- 2625,2650 ---- rc |= nvlist_add_string(smb, SHOPT_CATIA, "true"); if ((si->shr_flags & SMB_SHRF_GUEST_OK) != 0) rc |= nvlist_add_string(smb, SHOPT_GUEST, "true"); if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0) rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true"); + if ((si->shr_flags & SMB_SHRF_CA) != 0) + rc |= nvlist_add_string(smb, SHOPT_CA, "true"); + if ((si->shr_flags & SMB_SHRF_FSO) != 0) + rc |= nvlist_add_string(smb, SHOPT_FSO, "true"); + if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) + rc |= nvlist_add_string(smb, SHOPT_QUOTAS, "true"); + if (si->shr_encrypt == SMB_CONFIG_REQUIRED) + rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "required"); + else if (si->shr_encrypt == SMB_CONFIG_ENABLED) + rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "enabled"); + else + rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "disabled"); + if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) { ! rc |= nvlist_add_string(smb, SHOPT_AUTOHOME, "true"); rc |= nvlist_add_uint32(smb, "uid", si->shr_uid); rc |= nvlist_add_uint32(smb, "gid", si->shr_gid); } if ((csc = smb_shr_sa_csc_name(si)) != NULL)