diff options
| author | Matt Barden <matt.barden@nexenta.com> | 2016-06-24 16:29:37 -0400 |
|---|---|---|
| committer | Gordon Ross <gwr@nexenta.com> | 2019-06-10 10:21:40 -0400 |
| commit | 1160dcf7283d2485f2b9c32da573db0275558d9b (patch) | |
| tree | 030eeb92246c6ebb11c12ae449eb16c4886c4406 /usr/src/lib/smbsrv/libsmb/common/smb_cfg.c | |
| parent | 0ab6f5190f1236c6d1d0e14df5129e0694b77426 (diff) | |
| download | illumos-gate-1160dcf7283d2485f2b9c32da573db0275558d9b.tar.gz | |
11018 SMB3 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>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/lib/smbsrv/libsmb/common/smb_cfg.c')
| -rw-r--r-- | usr/src/lib/smbsrv/libsmb/common/smb_cfg.c | 107 |
1 files changed, 75 insertions, 32 deletions
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c index 0bc13e4a3c..22c0257628 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 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ /* @@ -146,10 +146,29 @@ static smb_cfg_param_t smb_cfg_table[] = {SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0}, {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_MAX */ }; +/* + * We store the max SMB protocol version in SMF as a string, + * (for convenience of svccfg etc) but the programmatic get/set + * interfaces use the numeric form. + * + * The numeric values are as defined in the [MS-SMB2] spec. + * except for how we represent "1" (for SMB1) which is an + * arbitrary value below SMB2_VERS_BASE. + */ +static struct str_val +smb_versions[] = { + { "3.0", SMB_VERS_3_0 }, + { "2.1", SMB_VERS_2_1 }, + { "2.002", SMB_VERS_2_002 }, + { "1", SMB_VERS_1 }, + { NULL, 0 } +}; + static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t); static boolean_t smb_is_base64(unsigned char c); @@ -160,6 +179,20 @@ static int smb_config_set_idmap_preferred_dc(char *); static int smb_config_get_idmap_site_name(char *, int); static int smb_config_set_idmap_site_name(char *); +static uint32_t +smb_convert_version_str(const char *version) +{ + uint32_t dialect = 0; + int i; + + for (i = 0; smb_versions[i].str != NULL; i++) { + if (strcmp(version, smb_versions[i].str) == 0) + dialect = smb_versions[i].val; + } + + return (dialect); +} + char * smb_config_getname(smb_cfg_id_t id) { @@ -631,7 +664,22 @@ smb_config_setstr(smb_cfg_id_t id, char *value) value = tmp; } - rc = smb_smf_set_string_property(handle, cfg->sc_name, value); + /* + * We don't want people who care enough about protecting their data + * by requiring encryption to accidentally expose their data + * by lowering the protocol, so prevent them from going below 3.0 + * if encryption is required. + */ + 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 { + rc = smb_smf_set_string_property(handle, cfg->sc_name, value); + } free(tmp); (void) smb_smf_end_transaction(handle); @@ -1118,25 +1166,6 @@ smb_config_getent(smb_cfg_id_t id) return (NULL); } - -/* - * We store the max SMB protocol version in SMF as a string, - * (for convenience of svccfg etc) but the programmatic get/set - * interfaces use the numeric form. - * - * The numeric values are as defined in the [MS-SMB2] spec. - * except for how we represent "1" (for SMB1) which is an - * arbitrary value below SMB2_VERS_BASE. - */ -static struct str_val -smb_versions[] = { - { "3.0", SMB_VERS_3_0 }, - { "2.1", SMB_VERS_2_1 }, - { "2.002", SMB_VERS_2_002 }, - { "1", SMB_VERS_1 }, - { NULL, 0 } -}; - /* * This really should be the latest (SMB_VERS_3_0) * but we're being cautious with SMB3 for a while. @@ -1147,14 +1176,14 @@ uint32_t smb_config_get_max_protocol(void) { char str[SMB_VERSTR_LEN]; - int i, rc; + int rc; + uint32_t max; rc = smb_config_getstr(SMB_CI_MAX_PROTOCOL, str, sizeof (str)); if (rc == SMBD_SMF_OK) { - for (i = 0; smb_versions[i].str != NULL; i++) { - if (strcmp(str, smb_versions[i].str) == 0) - return (smb_versions[i].val); - } + max = smb_convert_version_str(str); + if (max != 0) + return (max); if (str[0] != '\0') { syslog(LOG_ERR, "smbd/max_protocol value invalid"); } @@ -1166,12 +1195,8 @@ smb_config_get_max_protocol(void) int smb_config_check_protocol(char *value) { - int i; - - for (i = 0; smb_versions[i].str != NULL; i++) { - if (strcmp(value, smb_versions[i].str) == 0) - return (0); - } + if (smb_convert_version_str(value) != 0) + return (0); return (-1); } @@ -1279,3 +1304,21 @@ smb_config_upgrade(void) { upgrade_smb2_enable(); } + +smb_cfg_val_t +smb_config_get_require(smb_cfg_id_t id) +{ + int rc; + char str[sizeof ("required")]; + + rc = smb_config_getstr(id, str, sizeof (str)); + if (rc != SMBD_SMF_OK) + return (SMB_CONFIG_DISABLED); + + if (strncmp(str, "required", sizeof (str)) == 0) + return (SMB_CONFIG_REQUIRED); + if (strncmp(str, "enabled", sizeof (str)) == 0) + return (SMB_CONFIG_ENABLED); + + return (SMB_CONFIG_DISABLED); +} |
