From ab6e5a77de769f55d55e70d7754ec732385e7067 Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Wed, 30 Sep 2009 09:33:29 -0700 Subject: Add minimum SSF setting This adds a new configuration setting to the cn=config entry named nsslapd-minssf. This can be set to a non-negative integer representing the minimum key strength required to process operations. The default setting will be 0. The SSF for a particular connection will be determined by the key strength cipher used to protect the connection. If the SSF used for a connection does not meet the minimum requirement, the operation will be rejected with an error code of LDAP_UNWILLING_TO_PERFORM (53) along with a message stating that the minimum SSF was not met. Notable exceptions to this are operations that attempt to protect a connection. These operations are: * SASL BIND * startTLS These operations will be allowed to occur on a connection with a SSF less than the minimum. If the results of these operations end up with a SSF smaller than the minimum, they will be rejected. Additionally, we allow UNBIND and ABANDON operations to go through. I also corrected a few issues with the anonymous access switch code that I noticed while testing. We need to allow the startTLS extended operation to go through when sent by an anonymous user since it is common to send startTLS prior to a BIND to protect the credentials. I also noticed that we were using the authtype from the operation struct to determine is a user was anonymous when we really should have been using the DN. This was causing anonymous operations to get through on SSL/TLS connections. --- ldap/servers/slapd/libglobs.c | 59 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'ldap/servers/slapd/libglobs.c') diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index 5eb1afd5..cd7bb5dc 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -613,7 +613,10 @@ static struct config_get_and_set { {CONFIG_ANON_ACCESS_ATTRIBUTE, config_set_anon_access_switch, NULL, 0, (void**)&global_slapdFrontendConfig.allow_anon_access, CONFIG_ON_OFF, - (ConfigGetFunc)config_get_anon_access_switch} + (ConfigGetFunc)config_get_anon_access_switch}, + {CONFIG_MINSSF_ATTRIBUTE, config_set_minssf, + NULL, 0, + (void**)&global_slapdFrontendConfig.minssf, CONFIG_INT, NULL} #ifdef MEMPOOL_EXPERIMENTAL ,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch, NULL, 0, @@ -875,6 +878,7 @@ FrontendConfig_init () { cfg->outbound_ldap_io_timeout = SLAPD_DEFAULT_OUTBOUND_LDAP_IO_TIMEOUT; cfg->max_filter_nest_level = SLAPD_DEFAULT_MAX_FILTER_NEST_LEVEL; cfg->maxsasliosize = SLAPD_DEFAULT_MAX_SASLIO_SIZE; + cfg->minssf = SLAPD_DEFAULT_MIN_SSF; #ifdef _WIN32 cfg->conntablesize = SLAPD_DEFAULT_CONNTABLESIZE; @@ -4665,6 +4669,59 @@ config_get_maxsasliosize() return maxsasliosize; } +int +config_set_minssf( const char *attrname, char *value, char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + int minssf; + char *endptr; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + if ( config_value_is_null( attrname, value, errorbuf, 0 )) { + return LDAP_OPERATIONS_ERROR; + } + + minssf = (int) strtol(value, &endptr, 10); + + /* Check for non-numeric garbage in the value */ + if (*endptr != '\0') { + retVal = LDAP_OPERATIONS_ERROR; + } + + /* Check for a value overflow */ + if (((minssf == INT_MAX) || (minssf == INT_MIN)) && (errno == ERANGE)){ + retVal = LDAP_OPERATIONS_ERROR; + } + + /* Don't allow negative values. */ + if (minssf < 0) { + retVal = LDAP_OPERATIONS_ERROR; + } + + if (retVal != LDAP_SUCCESS) { + PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, + "%s: \"%s\" is invalid. Value must range from 0 to %d", + attrname, value, INT_MAX ); + } else if (apply) { + CFG_LOCK_WRITE(slapdFrontendConfig); + slapdFrontendConfig->minssf = minssf; + CFG_UNLOCK_WRITE(slapdFrontendConfig); + } + + return retVal; +} + +int +config_get_minssf() +{ + int minssf; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + minssf = slapdFrontendConfig->minssf; + + return minssf; +} + int config_set_max_filter_nest_level( const char *attrname, char *value, char *errorbuf, int apply ) -- cgit