diff options
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/libshare/smb/libshare_smb.c | 8 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/libsmb.h | 4 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_cfg.c | 97 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_info.c | 3 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_kmod.c | 3 |
5 files changed, 88 insertions, 27 deletions
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c index 7a731820e0..6a0ad97b7f 100644 --- a/usr/src/lib/libshare/smb/libshare_smb.c +++ b/usr/src/lib/libshare/smb/libshare_smb.c @@ -84,7 +84,7 @@ 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 protocol_validator(int, char *); static int require_validator(int, char *); static int smb_enable_resource(sa_resource_t); @@ -918,10 +918,12 @@ struct smb_proto_option_defs { 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_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_OPLOCK_ENABLE, 0, 0, true_false_validator, SMB_REFRESH_REFRESH }, }; @@ -2389,7 +2391,7 @@ disposition_validator(int index, char *value) /*ARGSUSED*/ static int -max_protocol_validator(int index, char *value) +protocol_validator(int index, char *value) { if (value == NULL) return (SA_BAD_VALUE); diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h index 3c60630327..56cab5ca8a 100644 --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBSMB_H @@ -158,6 +158,7 @@ typedef enum { SMB_CI_MAXIMUM_CREDITS, SMB_CI_MAX_PROTOCOL, SMB_CI_ENCRYPT, + SMB_CI_MIN_PROTOCOL, SMB_CI_MAX } smb_cfg_id_t; @@ -216,6 +217,7 @@ extern void smb_config_get_negtok(uchar_t *, uint32_t *); extern int smb_config_check_protocol(char *); extern uint32_t smb_config_get_max_protocol(void); +extern uint32_t smb_config_get_min_protocol(void); extern void smb_config_upgrade(void); extern smb_cfg_val_t smb_config_get_require(smb_cfg_id_t); diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c index 3a82584c03..cfecd0e944 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -147,6 +147,7 @@ static smb_cfg_param_t smb_cfg_table[] = {SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0}, {SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0}, {SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0}, + {SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0}, /* SMB_CI_MAX */ }; @@ -669,15 +670,42 @@ smb_config_setstr(smb_cfg_id_t id, char *value) * by requiring encryption to accidentally expose their data * by lowering the protocol, so prevent them from going below 3.0 * if encryption is required. + * Also, ensure that max_protocol >= min_protocol. */ - if (id == SMB_CI_MAX_PROTOCOL && - smb_config_get_require(SMB_CI_ENCRYPT) == SMB_CONFIG_REQUIRED && - smb_config_get_max_protocol() >= SMB_VERS_3_0 && - smb_convert_version_str(value) < SMB_VERS_3_0) { - syslog(LOG_ERR, "Cannot set smbd/max_protocol below 3.0" - " while smbd/encrypt == required."); - rc = SMBD_SMF_INVALID_ARG; - } else { + if (id == SMB_CI_MAX_PROTOCOL) { + smb_cfg_val_t encrypt; + uint32_t min; + uint32_t val; + + encrypt = smb_config_get_require(SMB_CI_ENCRYPT); + min = smb_config_get_min_protocol(); + val = smb_convert_version_str(value); + + if (encrypt == SMB_CONFIG_REQUIRED && + val < SMB_VERS_3_0) { + syslog(LOG_ERR, "Cannot set smbd/max_protocol below 3.0" + " while smbd/encrypt == required."); + rc = SMBD_SMF_INVALID_ARG; + } else if (val < min) { + syslog(LOG_ERR, "Cannot set smbd/max_protocol to less" + " than smbd/min_protocol."); + rc = SMBD_SMF_INVALID_ARG; + } + } else if (id == SMB_CI_MIN_PROTOCOL) { + uint32_t max; + uint32_t val; + + max = smb_config_get_max_protocol(); + val = smb_convert_version_str(value); + + if (val > max) { + syslog(LOG_ERR, "Cannot set smbd/min_protocol to more" + " than smbd/max_protocol."); + rc = SMBD_SMF_INVALID_ARG; + } + } + + if (rc == SMBD_SMF_OK) { rc = smb_smf_set_string_property(handle, cfg->sc_name, value); } @@ -1166,6 +1194,26 @@ smb_config_getent(smb_cfg_id_t id) return (NULL); } +static uint32_t +smb_config_get_protocol(smb_cfg_id_t id, char *name, uint32_t default_val) +{ + char str[SMB_VERSTR_LEN]; + int rc; + uint32_t val; + + rc = smb_config_getstr(id, str, sizeof (str)); + if (rc == SMBD_SMF_OK) { + val = smb_convert_version_str(str); + if (val != 0) + return (val); + if (str[0] != '\0') { + syslog(LOG_ERR, "smbd/%s value invalid: %s", name, str); + } + } + + return (default_val); +} + /* * The service manifest has empty values by default for min_protocol and * max_protocol. The expectation is that when those values are empty, we don't @@ -1178,21 +1226,28 @@ uint32_t max_protocol_default = SMB_VERS_3_0; uint32_t smb_config_get_max_protocol(void) { - char str[SMB_VERSTR_LEN]; - int rc; uint32_t max; - rc = smb_config_getstr(SMB_CI_MAX_PROTOCOL, str, sizeof (str)); - if (rc == SMBD_SMF_OK) { - max = smb_convert_version_str(str); - if (max != 0) - return (max); - if (str[0] != '\0') { - syslog(LOG_ERR, "smbd/max_protocol value invalid"); - } - } + max = smb_config_get_protocol(SMB_CI_MAX_PROTOCOL, "max_protocol", + max_protocol_default); + + return (max); +} + +/* + * This should eventually be SMB_VERS_2_BASE + */ +uint32_t min_protocol_default = SMB_VERS_1; + +uint32_t +smb_config_get_min_protocol(void) +{ + uint32_t min; + + min = smb_config_get_protocol(SMB_CI_MIN_PROTOCOL, "min_protocol", + min_protocol_default); - return (max_protocol_default); + return (min); } int diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_info.c b/usr/src/lib/smbsrv/libsmb/common/smb_info.c index 870a667444..4e6df7bb92 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <sys/types.h> @@ -157,6 +157,7 @@ smb_load_kconfig(smb_kmod_cfg_t *kcfg) kcfg->skc_sync_enable = smb_config_getbool(SMB_CI_SYNC_ENABLE); kcfg->skc_traverse_mounts = smb_config_getbool(SMB_CI_TRAVERSE_MOUNTS); kcfg->skc_max_protocol = smb_config_get_max_protocol(); + kcfg->skc_min_protocol = smb_config_get_min_protocol(); kcfg->skc_secmode = smb_config_get_secmode(); kcfg->skc_encrypt = smb_config_get_require(SMB_CI_ENCRYPT); diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c b/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c index 28638b538b..652cf15961 100644 --- a/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c +++ b/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. * Copyright 2017 Joyent, Inc. */ @@ -89,6 +89,7 @@ smb_kmod_setcfg(smb_kmod_cfg_t *cfg) ioc.print_enable = cfg->skc_print_enable; ioc.traverse_mounts = cfg->skc_traverse_mounts; ioc.max_protocol = cfg->skc_max_protocol; + ioc.min_protocol = cfg->skc_min_protocol; ioc.exec_flags = cfg->skc_execflags; ioc.negtok_len = cfg->skc_negtok_len; ioc.version = cfg->skc_version; |
