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)
{