Print this page
NEX-16502 libshare needs to support SMB in a zone
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@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-9497 SMB should bypass ACL traverse checking
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-10019 SMB server min_protocol setting
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@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-4598 SMB2 credit shortage with Mac client
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
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-3629 CLONE NEX-3624 SMB server max_workers cannot be increased above 1024
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Alek Pinchuk <alek@nexenta.com>
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
4295 libshare sa_get_proto_status sometimes returns unallocated strings
Reviewed by: Marcel Telka <marcel@telka.sk>
Approved by: Garrett D'Amore <garrett@damore.org>
NEX-1050 enable_smb2 should be smb2_enable
NEX-1022 SMB2 should be enabled by default
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).
re #13470 rb4432 Sync some SMB differences from illumos
re #7930 rb3848 failover error: cannot share pool/folder - smb add share failed

*** 19,29 **** * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* * SMB specific functions */ --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * SMB specific functions */
*** 82,92 **** static int ipv4_validator(int, char *); static int hostname_validator(int, char *); static int path_validator(int, char *); static int cmd_validator(int, char *); static int disposition_validator(int, char *); ! static int max_protocol_validator(int, char *); static int smb_enable_resource(sa_resource_t); static int smb_disable_resource(sa_resource_t); static uint64_t smb_share_features(void); static int smb_list_transient(sa_handle_t); --- 82,93 ---- static int ipv4_validator(int, char *); static int hostname_validator(int, char *); static int path_validator(int, char *); static int cmd_validator(int, char *); static int disposition_validator(int, char *); ! static int protocol_validator(int, char *); ! static int require_validator(int, char *); static int smb_enable_resource(sa_resource_t); static int smb_disable_resource(sa_resource_t); static uint64_t smb_share_features(void); static int smb_list_transient(sa_handle_t);
*** 96,106 **** static char *smb_csc_name(const smb_share_t *); static sa_group_t smb_get_defaultgrp(sa_handle_t); static int interface_validator(int, char *); static int smb_update_optionset_props(sa_handle_t, sa_resource_t, nvlist_t *); ! static boolean_t smb_saprop_getbool(sa_optionset_t, char *); static boolean_t smb_saprop_getstr(sa_optionset_t, char *, char *, size_t); static struct { char *value; uint32_t flag; --- 97,107 ---- static char *smb_csc_name(const smb_share_t *); static sa_group_t smb_get_defaultgrp(sa_handle_t); static int interface_validator(int, char *); static int smb_update_optionset_props(sa_handle_t, sa_resource_t, nvlist_t *); ! static boolean_t smb_saprop_getbool(sa_optionset_t, char *, boolean_t); static boolean_t smb_saprop_getstr(sa_optionset_t, char *, char *, size_t); static struct { char *value; uint32_t flag;
*** 176,185 **** --- 177,190 ---- { SHOPT_CATIA, OPT_TYPE_BOOLEAN }, { SHOPT_CSC, OPT_TYPE_CSC }, { SHOPT_GUEST, OPT_TYPE_BOOLEAN }, { SHOPT_DFSROOT, OPT_TYPE_BOOLEAN }, { SHOPT_DESCRIPTION, OPT_TYPE_STRING }, + { SHOPT_CA, OPT_TYPE_BOOLEAN }, + { SHOPT_FSO, OPT_TYPE_BOOLEAN }, + { SHOPT_QUOTAS, OPT_TYPE_BOOLEAN }, + { SHOPT_ENCRYPT, OPT_TYPE_STRING }, { NULL, NULL } }; /* * findopt(name)
*** 384,396 **** { char *path; smb_share_t si; sa_resource_t resource; boolean_t iszfs; - boolean_t privileged; int err = SA_OK; - priv_set_t *priv_effective; boolean_t online; /* * Don't support Trusted Extensions. */ --- 389,399 ----
*** 398,412 **** (void) printf(dgettext(TEXT_DOMAIN, "SMB: service not supported with Trusted Extensions\n")); return (SA_NOT_SUPPORTED); } - priv_effective = priv_allocset(); - (void) getppriv(PRIV_EFFECTIVE, priv_effective); - privileged = (priv_isfullset(priv_effective) == B_TRUE); - priv_freeset(priv_effective); - /* get the path since it is important in several places */ path = sa_get_share_attr(share, "path"); if (path == NULL) return (SA_NO_SUCH_PATH); --- 401,410 ----
*** 417,449 **** if (!online && !smb_isautoenable() && smb_isdisabled()) goto done; iszfs = sa_path_is_zfs(path); - if (iszfs) { - - if (privileged == B_FALSE && !online) { - if (!online) { - (void) printf(dgettext(TEXT_DOMAIN, - "SMB: Cannot share remove " - "file system: %s\n"), path); - (void) printf(dgettext(TEXT_DOMAIN, - "SMB: Service needs to be enabled " - "by a privileged user\n")); - err = SA_NO_PERMISSION; - errno = EPERM; - } - if (err) { - sa_free_attr_string(path); - return (err); - } - - } - } - - if (privileged == B_TRUE && !online) { err = smb_enable_service(); if (err != SA_OK) { (void) printf(dgettext(TEXT_DOMAIN, "SMB: Unable to enable service\n")); } else { --- 415,425 ----
*** 912,928 **** { SMB_CI_MAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH }, { SMB_CI_UNMAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH }, { SMB_CI_DISPOSITION, 0, MAX_VALUE_BUFLEN, disposition_validator, SMB_REFRESH_REFRESH }, ! { SMB_CI_MAX_PROTOCOL, 0, MAX_VALUE_BUFLEN, max_protocol_validator, SMB_REFRESH_REFRESH }, }; #define SMB_OPT_NUM \ (sizeof (smb_proto_options) / sizeof (smb_proto_options[0])) /* * Check the range of value as int range. */ static int range_check_validator(int index, char *value) --- 888,930 ---- { SMB_CI_MAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH }, { SMB_CI_UNMAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH }, { SMB_CI_DISPOSITION, 0, MAX_VALUE_BUFLEN, disposition_validator, SMB_REFRESH_REFRESH }, ! { SMB_CI_MAX_PROTOCOL, 0, MAX_VALUE_BUFLEN, protocol_validator, SMB_REFRESH_REFRESH }, + { SMB_CI_ENCRYPT, 0, MAX_VALUE_BUFLEN, require_validator, + SMB_REFRESH_REFRESH }, + { SMB_CI_MIN_PROTOCOL, 0, MAX_VALUE_BUFLEN, protocol_validator, + SMB_REFRESH_REFRESH }, + { SMB_CI_BYPASS_TRAVERSE_CHECKING, 0, 0, true_false_validator, + SMB_REFRESH_REFRESH }, + { SMB_CI_OPLOCK_ENABLE, 0, 0, true_false_validator, + SMB_REFRESH_REFRESH }, }; #define SMB_OPT_NUM \ (sizeof (smb_proto_options) / sizeof (smb_proto_options[0])) + static int + require_validator(int index, char *value) + { + if (string_length_check_validator(index, value) != SA_OK) + return (SA_BAD_VALUE); + + if (strcmp(value, "required") == 0) + return (SA_OK); + + if (strcmp(value, "disabled") == 0) + return (SA_OK); + + if (strcmp(value, "enabled") == 0) + return (SA_OK); + + return (SA_BAD_VALUE); + } + /* * Check the range of value as int range. */ static int range_check_validator(int index, char *value)
*** 1532,1542 **** ret = smb_validate_proto_prop(index, name, value); if (ret == SA_OK) { opt = &smb_proto_options[index]; /* Save to SMF */ ! (void) smb_config_set(opt->smb_index, value); /* * Specialized refresh mechanisms can * be flagged in the proto_options and * processed here. */ --- 1534,1548 ---- ret = smb_validate_proto_prop(index, name, value); if (ret == SA_OK) { opt = &smb_proto_options[index]; /* Save to SMF */ ! if (smb_config_set(opt->smb_index, ! value) != 0) { ! ret = SA_BAD_VALUE; ! goto out; ! } /* * Specialized refresh mechanisms can * be flagged in the proto_options and * processed here. */
*** 1548,1557 **** --- 1554,1564 ---- SMBD_DEFAULT_INSTANCE_FMRI); } } } + out: if (name != NULL) sa_free_attr_string(name); if (value != NULL) sa_free_attr_string(value);
*** 2113,2122 **** --- 2120,2130 ---- sa_optionset_t opts; char *path; char *rname; char *val = NULL; char csc_value[SMB_CSC_BUFSZ]; + char strbuf[sizeof ("required")]; bzero(si, sizeof (smb_share_t)); if ((path = sa_get_share_attr(share, "path")) == NULL) return (SA_NO_SUCH_PATH);
*** 2145,2166 **** opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1); if (opts == NULL) return (SA_OK); ! if (smb_saprop_getbool(opts, SHOPT_CATIA)) si->shr_flags |= SMB_SHRF_CATIA; ! if (smb_saprop_getbool(opts, SHOPT_ABE)) si->shr_flags |= SMB_SHRF_ABE; ! if (smb_saprop_getbool(opts, SHOPT_GUEST)) si->shr_flags |= SMB_SHRF_GUEST_OK; ! if (smb_saprop_getbool(opts, SHOPT_DFSROOT)) si->shr_flags |= SMB_SHRF_DFSROOT; (void) smb_saprop_getstr(opts, SHOPT_AD_CONTAINER, si->shr_container, sizeof (si->shr_container)); if (smb_saprop_getstr(opts, SHOPT_CSC, csc_value, sizeof (csc_value))) smb_csc_option(csc_value, si); --- 2153,2187 ---- opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1); if (opts == NULL) return (SA_OK); ! if (smb_saprop_getbool(opts, SHOPT_CATIA, B_FALSE)) si->shr_flags |= SMB_SHRF_CATIA; ! if (smb_saprop_getbool(opts, SHOPT_ABE, B_FALSE)) si->shr_flags |= SMB_SHRF_ABE; ! if (smb_saprop_getbool(opts, SHOPT_GUEST, B_FALSE)) si->shr_flags |= SMB_SHRF_GUEST_OK; ! if (smb_saprop_getbool(opts, SHOPT_DFSROOT, B_FALSE)) si->shr_flags |= SMB_SHRF_DFSROOT; + if (smb_saprop_getbool(opts, SHOPT_CA, B_FALSE)) + si->shr_flags |= SMB_SHRF_CA; + + if (smb_saprop_getbool(opts, SHOPT_FSO, B_FALSE)) + si->shr_flags |= SMB_SHRF_FSO; + + /* Quotas are enabled by default. */ + if (smb_saprop_getbool(opts, SHOPT_QUOTAS, B_TRUE)) + si->shr_flags |= SMB_SHRF_QUOTAS; + + if (smb_saprop_getstr(opts, SHOPT_ENCRYPT, strbuf, sizeof (strbuf))) + smb_cfg_set_require(strbuf, &si->shr_encrypt); + (void) smb_saprop_getstr(opts, SHOPT_AD_CONTAINER, si->shr_container, sizeof (si->shr_container)); if (smb_saprop_getstr(opts, SHOPT_CSC, csc_value, sizeof (csc_value))) smb_csc_option(csc_value, si);
*** 2345,2355 **** return (SA_BAD_VALUE); } /*ARGSUSED*/ static int ! max_protocol_validator(int index, char *value) { if (value == NULL) return (SA_BAD_VALUE); if (*value == '\0') --- 2366,2376 ---- return (SA_BAD_VALUE); } /*ARGSUSED*/ static int ! protocol_validator(int index, char *value) { if (value == NULL) return (SA_BAD_VALUE); if (*value == '\0')
*** 2421,2444 **** return (err); } static boolean_t ! smb_saprop_getbool(sa_optionset_t opts, char *propname) { sa_property_t prop; char *val; ! boolean_t propval = B_FALSE; prop = sa_get_property(opts, propname); if ((val = sa_get_property_attr(prop, "value")) != NULL) { ! if ((strcasecmp(val, "true") == 0) || (strcmp(val, "1") == 0)) ! propval = B_TRUE; free(val); } ! return (propval); } static boolean_t smb_saprop_getstr(sa_optionset_t opts, char *propname, char *buf, size_t bufsz) { --- 2442,2474 ---- return (err); } static boolean_t ! smb_saprop_getbool(sa_optionset_t opts, char *propname, boolean_t def) { sa_property_t prop; char *val; ! boolean_t ret = def; prop = sa_get_property(opts, propname); if ((val = sa_get_property_attr(prop, "value")) != NULL) { ! if (def) { ! /* Default is true, ret false if... */ ! if ((strcasecmp(val, "false") == 0) || ! (strcmp(val, "0") == 0)) ! ret = B_FALSE; ! } else { ! /* Default is false, ret true if... */ ! if ((strcasecmp(val, "true") == 0) || ! (strcmp(val, "1") == 0)) ! ret = B_TRUE; ! } free(val); } ! return (ret); } static boolean_t smb_saprop_getstr(sa_optionset_t opts, char *propname, char *buf, size_t bufsz) {