Skip to content

Commit

Permalink
Trac Ticket 168 - minssf should not apply to rootdse
Browse files Browse the repository at this point in the history
https://fedorahosted.org/389/ticket/168

Fix description: This patch is for supporting a request to
allow accessing rootdse with lower ssf than minssf configuration
setting.
. introduced a on/off type config parameter:
      nsslapd-minssf-exclude-rootdse.
. by default, the value is off.
. when it is off, the server's behavior remains intact.
. when it is on, the server allows to access rootdse even if
  the ssf value is less than nsslapd-minssf value.
  • Loading branch information
nhosoi committed Jan 18, 2012
1 parent ed87077 commit 48e99c1
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 4 deletions.
13 changes: 11 additions & 2 deletions ldap/servers/slapd/bind.c
Expand Up @@ -138,6 +138,7 @@ do_bind( Slapi_PBlock *pb )
Slapi_Entry *bind_target_entry = NULL;
int auto_bind = 0;
int minssf = 0;
int minssf_exclude_rootdse = 0;

LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );

Expand Down Expand Up @@ -493,7 +494,15 @@ do_bind( Slapi_PBlock *pb )

/* Check if the minimum SSF requirement has been met. */
minssf = config_get_minssf();
if ((pb->pb_conn->c_sasl_ssf < minssf) && (pb->pb_conn->c_ssl_ssf < minssf) &&
/*
* If nsslapd-minssf-exclude-rootdse is on, we have to go to the
* next step and check if the operation is against rootdse or not.
* Once found it's not on rootdse, return LDAP_UNWILLING_TO_PERFORM
* there.
*/
minssf_exclude_rootdse = config_get_minssf_exclude_rootdse();
if (!minssf_exclude_rootdse && (pb->pb_conn->c_sasl_ssf < minssf) &&
(pb->pb_conn->c_ssl_ssf < minssf) &&
(pb->pb_conn->c_local_ssf < minssf)) {
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"Minimum SSF not met.", 0, NULL);
Expand Down Expand Up @@ -560,7 +569,7 @@ do_bind( Slapi_PBlock *pb )
goto free_and_return;
}
/* Check if simple binds are allowed over an insecure channel. We only check
* this for authenticated binds. */
* this for authenticated binds. */
} else if (config_get_require_secure_binds() == 1) {
Connection *conn = NULL;
int sasl_ssf = 0;
Expand Down
10 changes: 9 additions & 1 deletion ldap/servers/slapd/connection.c
Expand Up @@ -496,6 +496,7 @@ static void
connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb)
{
int minssf = config_get_minssf();
int minssf_exclude_rootdse = 0;

/* Get the effective key length now since the first SSL handshake should be complete */
connection_set_ssl_ssf( conn );
Expand All @@ -508,7 +509,14 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb)
* code will ensure that only SASL binds and startTLS are
* allowed, which gives the connection a chance to meet the
* SSF requirements. We also allow UNBIND and ABANDON.*/
if ((conn->c_sasl_ssf < minssf) && (conn->c_ssl_ssf < minssf) &&
/*
* If nsslapd-minssf-exclude-rootdse is on, we have to go to the
* next step and check if the operation is against rootdse or not.
* Once found it's not on rootdse, return LDAP_UNWILLING_TO_PERFORM there.
*/
minssf_exclude_rootdse = config_get_minssf_exclude_rootdse();
if (!minssf_exclude_rootdse &&
(conn->c_sasl_ssf < minssf) && (conn->c_ssl_ssf < minssf) &&
(conn->c_local_ssf < minssf) &&(op->o_tag != LDAP_REQ_BIND) &&
(op->o_tag != LDAP_REQ_EXTENDED) && (op->o_tag != LDAP_REQ_UNBIND) &&
(op->o_tag != LDAP_REQ_ABANDON)) {
Expand Down
35 changes: 35 additions & 0 deletions ldap/servers/slapd/libglobs.c
Expand Up @@ -626,6 +626,11 @@ static struct config_get_and_set {
{CONFIG_MINSSF_ATTRIBUTE, config_set_minssf,
NULL, 0,
(void**)&global_slapdFrontendConfig.minssf, CONFIG_INT, NULL},
{CONFIG_MINSSF_EXCLUDE_ROOTDSE, config_set_minssf_exclude_rootdse,
NULL, 0,
(void**)&global_slapdFrontendConfig.minssf_exclude_rootdse,
CONFIG_ON_OFF,
(ConfigGetFunc)config_get_minssf_exclude_rootdse},
{CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE, config_set_force_sasl_external,
NULL, 0,
(void**)&global_slapdFrontendConfig.force_sasl_external, CONFIG_ON_OFF,
Expand Down Expand Up @@ -918,6 +923,8 @@ FrontendConfig_init () {
cfg->maxsasliosize = SLAPD_DEFAULT_MAX_SASLIO_SIZE;
cfg->localssf = SLAPD_DEFAULT_LOCAL_SSF;
cfg->minssf = SLAPD_DEFAULT_MIN_SSF;
cfg->minssf_exclude_rootdse = LDAP_OFF; /* minssf is applied to rootdse,
by default */
cfg->validate_cert = SLAPD_VALIDATE_CERT_WARN;

#ifdef _WIN32
Expand Down Expand Up @@ -4880,6 +4887,22 @@ config_set_minssf( const char *attrname, char *value, char *errorbuf, int apply
return retVal;
}

int
config_set_minssf_exclude_rootdse( const char *attrname, char *value,
char *errorbuf, int apply )
{
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();

retVal = config_set_onoff ( attrname,
value,
&(slapdFrontendConfig->minssf_exclude_rootdse),
errorbuf,
apply );

return retVal;
}

int
config_get_localssf()
{
Expand All @@ -4902,6 +4925,18 @@ config_get_minssf()
return minssf;
}

int
config_get_minssf_exclude_rootdse()
{
int retVal;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
CFG_LOCK_READ(slapdFrontendConfig);
retVal = slapdFrontendConfig->minssf_exclude_rootdse;
CFG_UNLOCK_READ(slapdFrontendConfig);

return retVal;
}

int
config_set_max_filter_nest_level( const char *attrname, char *value,
char *errorbuf, int apply )
Expand Down
22 changes: 22 additions & 0 deletions ldap/servers/slapd/modify.c
Expand Up @@ -141,6 +141,7 @@ do_modify( Slapi_PBlock *pb )
int has_password_mod = 0; /* number of password mods */
char *old_pw = NULL; /* remember the old password */
char *rawdn = NULL;
int minssf_exclude_rootdse = 0;

LDAPDebug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 );

Expand Down Expand Up @@ -197,6 +198,27 @@ do_modify( Slapi_PBlock *pb )

LDAPDebug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", rawdn, 0, 0 );

/*
* If nsslapd-minssf-exclude-rootdse is on, the minssf check has been
* postponed until here. We should do it now.
*/
minssf_exclude_rootdse = config_get_minssf_exclude_rootdse();
if (minssf_exclude_rootdse) {
int minssf = 0;
/* Check if the minimum SSF requirement has been met. */
minssf = config_get_minssf();
if ((pb->pb_conn->c_sasl_ssf < minssf) &&
(pb->pb_conn->c_ssl_ssf < minssf) &&
(pb->pb_conn->c_local_ssf < minssf)) {
op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
"Minimum SSF not met");
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"Minimum SSF not met.", 0, NULL);
slapi_ch_free((void **) &rawdn);
return;
}
}

slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot);
slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, rawdn );

Expand Down
2 changes: 2 additions & 0 deletions ldap/servers/slapd/proto-slap.h
Expand Up @@ -370,6 +370,7 @@ int config_set_require_secure_binds(const char *attrname, char *value, char *err
int config_set_anon_access_switch(const char *attrname, char *value, char *errorbuf, int apply );
int config_set_localssf(const char *attrname, char *value, char *errorbuf, int apply );
int config_set_minssf(const char *attrname, char *value, char *errorbuf, int apply );
int config_set_minssf_exclude_rootdse( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_validate_cert_switch(const char *attrname, char *value, char *errorbuf, int apply );
int config_set_accesslogbuffering(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_csnlogging(const char *attrname, char *value, char *errorbuf, int apply);
Expand Down Expand Up @@ -510,6 +511,7 @@ int config_get_require_secure_binds(void);
int config_get_anon_access_switch(void);
int config_get_localssf(void);
int config_get_minssf(void);
int config_get_minssf_exclude_rootdse(void);
int config_get_validate_cert_switch(void);
int config_get_csnlogging();
#ifdef MEMPOOL_EXPERIMENTAL
Expand Down
29 changes: 28 additions & 1 deletion ldap/servers/slapd/search.c
Expand Up @@ -80,6 +80,7 @@ do_search( Slapi_PBlock *pb )
int changesonly = 0;
int rc = -1;
int strict = 0;
int minssf_exclude_rootdse = 0;

LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );

Expand Down Expand Up @@ -141,14 +142,40 @@ do_search( Slapi_PBlock *pb )
if ((slapi_sdn_get_dn(&(operation->o_sdn)) == NULL) &&
(scope != LDAP_SCOPE_BASE) &&
(config_get_anon_access_switch() == SLAPD_ANON_ACCESS_ROOTDSE)) {
op_shared_log_error_access(pb, "SRCH", base?base:"", "anonymous search not allowed");
op_shared_log_error_access(pb, "SRCH", rawbase?rawbase:"",
"anonymous search not allowed");

send_ldap_result( pb, LDAP_INAPPROPRIATE_AUTH, NULL,
"Anonymous access is not allowed.", 0, NULL );

goto free_and_return;
}

/*
* If nsslapd-minssf-exclude-rootdse is on, the minssf check has been
* postponed till this moment since we need to know whether the basedn
* is rootdse or not.
*
* If (minssf_exclude_rootdse && (basedn is rootdse),
* then we allow accessing rootdse.
* Otherwise, return Minimum SSF not met.
*/
minssf_exclude_rootdse = config_get_minssf_exclude_rootdse();
if (!minssf_exclude_rootdse || (rawbase && strlen(rawbase) > 0)) {
int minssf = 0;
/* Check if the minimum SSF requirement has been met. */
minssf = config_get_minssf();
if ((pb->pb_conn->c_sasl_ssf < minssf) &&
(pb->pb_conn->c_ssl_ssf < minssf) &&
(pb->pb_conn->c_local_ssf < minssf)) {
op_shared_log_error_access(pb, "SRCH", rawbase?rawbase:"",
"Minimum SSF not met");
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"Minimum SSF not met.", 0, NULL);
goto free_and_return;
}
}

/*
* ignore negative time and size limits since they make no sense
*/
Expand Down
2 changes: 2 additions & 0 deletions ldap/servers/slapd/slap.h
Expand Up @@ -1869,6 +1869,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_ANON_ACCESS_ATTRIBUTE "nsslapd-allow-anonymous-access"
#define CONFIG_LOCALSSF_ATTRIBUTE "nsslapd-localssf"
#define CONFIG_MINSSF_ATTRIBUTE "nsslapd-minssf"
#define CONFIG_MINSSF_EXCLUDE_ROOTDSE "nsslapd-minssf-exclude-rootdse"
#define CONFIG_VALIDATE_CERT_ATTRIBUTE "nsslapd-validate-cert"
#ifndef _WIN32
#define CONFIG_LOCALUSER_ATTRIBUTE "nsslapd-localuser"
Expand Down Expand Up @@ -2176,6 +2177,7 @@ typedef struct _slapdFrontendConfig {
int allow_anon_access; /* switch to enable/disable anonymous access */
int localssf; /* the security strength factor to assign to local conns (ldapi) */
int minssf; /* minimum security strength factor (for SASL and SSL/TLS) */
int minssf_exclude_rootdse; /* ON: minssf is ignored when searching rootdse */
size_t maxsasliosize; /* limit incoming SASL IO packet size */
char *anon_limits_dn; /* template entry for anonymous resource limits */
#ifndef _WIN32
Expand Down

0 comments on commit 48e99c1

Please sign in to comment.