From 0bddab1fbd772f05738b0715566bd3346df01c84 Mon Sep 17 00:00:00 2001
From: Nathan Kinder nkinder@redhat.com Date: Wed, 13 May 2009 19:45:12 -0700 Subject: [PATCH] Add require secure binds switch.
This adds a new configuration attribute named nsslapd-require-secure-binds. When enabled, a simple bind will only be allowed over a secure transport (SSL/TLS or a SASL privacy layer). An attempt to do a simple bind over an insecure transport will return a LDAP result of LDAP_CONFIDENTIALITY_REQUIRED.
The default setting is to have this option disabled. --- ldap/ldif/template-dse.ldif.in | 1 + ldap/servers/slapd/bind.c | 24 ++++++++++++++++++++++++ ldap/servers/slapd/libglobs.c | 36 +++++++++++++++++++++++++++++++++++- ldap/servers/slapd/proto-slap.h | 2 ++ ldap/servers/slapd/slap.h | 2 ++ 5 files changed, 64 insertions(+), 1 deletions(-)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in index 54a9c4f..82326d5 100644 --- a/ldap/ldif/template-dse.ldif.in +++ b/ldap/ldif/template-dse.ldif.in @@ -30,6 +30,7 @@ nsslapd-rewrite-rfc1274: off nsslapd-return-exact-case: on nsslapd-ssl-check-hostname: on nsslapd-allow-unauthenticated-binds: off +nsslapd-require-secure-binds: off nsslapd-port: %ds_port% nsslapd-localuser: %ds_user% nsslapd-errorlog-logging-enabled: on diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index fbf9a19..69844af 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -420,6 +420,30 @@ do_bind( Slapi_PBlock *pb ) } break; case LDAP_AUTH_SIMPLE: + /* Check if simple binds are allowed over an insecure channel. */ + if (config_get_require_secure_binds() == 1) { + Connection *conn = NULL; + int sasl_ssf = 0; + + /* Allow simple binds only for SSL/TLS established connections + * or connections using SASL privacy layers */ + conn = pb->pb_conn; + if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) { + slapi_log_error( SLAPI_LOG_PLUGIN, "passwd_modify_extop", + "Could not get SASL SSF from connection\n" ); + sasl_ssf = 0; + } + + if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) && + (sasl_ssf <= 1) ) { + send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL, + "Operation requires a secure connection", + 0, NULL); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + goto free_and_return; + } + } + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsSimpleAuthBinds); /* accept null binds */ if (dn == NULL || *dn == '\0') { diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index 8c13a9b..acd8615 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -612,7 +612,11 @@ static struct config_get_and_set { {CONFIG_UNAUTH_BINDS_ATTRIBUTE, config_set_unauth_binds_switch, NULL, 0, (void**)&global_slapdFrontendConfig.allow_unauth_binds, CONFIG_ON_OFF, - (ConfigGetFunc)config_get_unauth_binds_switch} + (ConfigGetFunc)config_get_unauth_binds_switch}, + {CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE, config_set_require_secure_binds, + NULL, 0, + (void**)&global_slapdFrontendConfig.require_secure_binds, CONFIG_ON_OFF, + (ConfigGetFunc)config_get_require_secure_binds} #ifdef MEMPOOL_EXPERIMENTAL ,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch, NULL, 0, @@ -863,6 +867,7 @@ FrontendConfig_init () { cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth"); #endif cfg->allow_unauth_binds = LDAP_OFF; + cfg->require_secure_binds = LDAP_OFF; cfg->slapi_counters = LDAP_ON; cfg->threadnumber = SLAPD_DEFAULT_MAX_THREADS; cfg->maxthreadsperconn = SLAPD_DEFAULT_MAX_THREADS_PER_CONN; @@ -4550,6 +4555,19 @@ config_get_unauth_binds_switch(void) }
+int +config_get_require_secure_binds(void) +{ + int retVal; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + CFG_LOCK_READ(slapdFrontendConfig); + retVal = slapdFrontendConfig->require_secure_binds; + CFG_UNLOCK_READ(slapdFrontendConfig); + +return retVal; +} + + int config_is_slapd_lite () { @@ -5316,6 +5334,22 @@ config_set_unauth_binds_switch( const char *attrname, char *value, return retVal; }
+int +config_set_require_secure_binds( const char *attrname, char *value, + char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff(attrname, + value, + &(slapdFrontendConfig->require_secure_binds), + errorbuf, + apply); + + return retVal; +} +
/* * This function is intended to be used from the dse code modify callback. It diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 2041a99..08279a0 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -343,6 +343,7 @@ int config_set_rewrite_rfc1274( const char *attrname, char *value, char *errorbu int config_set_outbound_ldap_io_timeout( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_unauth_binds_switch(const char *attrname, char *value, char *errorbuf, int apply ); +int config_set_require_secure_binds(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);
@@ -471,6 +472,7 @@ int config_get_hash_filters(); int config_get_rewrite_rfc1274(); int config_get_outbound_ldap_io_timeout(void); int config_get_unauth_binds_switch(void); +int config_get_require_secure_binds(void); int config_get_csnlogging(); #ifdef MEMPOOL_EXPERIMENTAL int config_get_mempool_switch(); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 724bef9..df752f0 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -1695,6 +1695,7 @@ typedef struct _slapdEntryPoints { #define CONFIG_USERAT_ATTRIBUTE "nsslapd-userat" #define CONFIG_SVRTAB_ATTRIBUTE "nsslapd-svrtab" #define CONFIG_UNAUTH_BINDS_ATTRIBUTE "nsslapd-allow-unauthenticated-binds" +#define CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE "nsslapd-require-secure-binds" #ifndef _WIN32 #define CONFIG_LOCALUSER_ATTRIBUTE "nsslapd-localuser" #endif /* !_WIN32 */ @@ -1988,6 +1989,7 @@ typedef struct _slapdFrontendConfig { char *ldapi_auto_dn_suffix; /* suffix to be appended to auto gen DNs */ int slapi_counters; /* switch to turn slapi_counters on/off */ int allow_unauth_binds; /* switch to enable/disable unauthenticated binds */ + int require_secure_binds; /* switch to require simple binds to use a secure channel */ size_t maxsasliosize; /* limit incoming SASL IO packet size */ #ifndef _WIN32 struct passwd *localuserinfo; /* userinfo of localuser */
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Looks good.
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
2009/5/15 Rich Megginson rmeggins@redhat.com
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Looks good.
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote: ------------------------------------------------------------------------ -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Nathan Kinder wrote:
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
A new patch with the above change is attached.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
From 33baa9314341b6b0bd5fd559886ba8e899a255e1 Mon Sep 17 00:00:00 2001
From: Nathan Kinder nkinder@redhat.com Date: Tue, 26 May 2009 14:26:50 -0700 Subject: [PATCH] Add require secure binds switch.
This adds a new configuration attribute named nsslapd-require-secure-binds. When enabled, a simple bind will only be allowed over a secure transport (SSL/TLS or a SASL privacy layer). An attempt to do a simple bind over an insecure transport will return a LDAP result of LDAP_CONFIDENTIALITY_REQUIRED. This new setting will not affect anonymous binds.
The default setting is to have this option disabled. --- ldap/ldif/template-dse.ldif.in | 1 + ldap/servers/slapd/bind.c | 53 +++++++++++++++++++++++++++++--------- ldap/servers/slapd/libglobs.c | 36 +++++++++++++++++++++++++- ldap/servers/slapd/proto-slap.h | 2 + ldap/servers/slapd/slap.h | 2 + 5 files changed, 80 insertions(+), 14 deletions(-)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in index 54a9c4f..82326d5 100644 --- a/ldap/ldif/template-dse.ldif.in +++ b/ldap/ldif/template-dse.ldif.in @@ -30,6 +30,7 @@ nsslapd-rewrite-rfc1274: off nsslapd-return-exact-case: on nsslapd-ssl-check-hostname: on nsslapd-allow-unauthenticated-binds: off +nsslapd-require-secure-binds: off nsslapd-port: %ds_port% nsslapd-localuser: %ds_user% nsslapd-errorlog-logging-enabled: on diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index fbf9a19..639522f 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -439,20 +439,47 @@ do_bind( Slapi_PBlock *pb ) plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN ); } goto free_and_return; - } else if ( cred.bv_len == 0 ) { - /* Increment unauthenticated bind counter */ - slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + } else { + /* Check if simple binds are allowed over an insecure channel. */ + if (config_get_require_secure_binds() == 1) { + Connection *conn = NULL; + int sasl_ssf = 0; + + /* Allow simple binds only for SSL/TLS established connections + * or connections using SASL privacy layers */ + conn = pb->pb_conn; + if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) { + slapi_log_error( SLAPI_LOG_PLUGIN, "passwd_modify_extop", + "Could not get SASL SSF from connection\n" ); + sasl_ssf = 0; + }
- /* Refuse the operation if unauthenticated binds are disabled. */ - if (!config_get_unauth_binds_switch()) { - /* As stated in RFC 4513, a server SHOULD by default fail - * Unauthenticated Bind requests with a resultCode of - * unwillingToPerform. */ - send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, - "Unauthenticated binds are not allowed", 0, NULL); - /* increment BindSecurityErrorcount */ - slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); - goto free_and_return; + if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) && + (sasl_ssf <= 1) ) { + send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL, + "Operation requires a secure connection", + 0, NULL); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + goto free_and_return; + } + } + + /* Check if unauthenticated binds are allowed. */ + if ( cred.bv_len == 0 ) { + /* Increment unauthenticated bind counter */ + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); + + /* Refuse the operation if unauthenticated binds are disabled. */ + if (!config_get_unauth_binds_switch()) { + /* As stated in RFC 4513, a server SHOULD by default fail + * Unauthenticated Bind requests with a resultCode of + * unwillingToPerform. */ + send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, + "Unauthenticated binds are not allowed", 0, NULL); + /* increment BindSecurityErrorcount */ + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + goto free_and_return; + } } } break; diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index 1155c8c..358a745 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -606,7 +606,11 @@ static struct config_get_and_set { {CONFIG_UNAUTH_BINDS_ATTRIBUTE, config_set_unauth_binds_switch, NULL, 0, (void**)&global_slapdFrontendConfig.allow_unauth_binds, CONFIG_ON_OFF, - (ConfigGetFunc)config_get_unauth_binds_switch} + (ConfigGetFunc)config_get_unauth_binds_switch}, + {CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE, config_set_require_secure_binds, + NULL, 0, + (void**)&global_slapdFrontendConfig.require_secure_binds, CONFIG_ON_OFF, + (ConfigGetFunc)config_get_require_secure_binds} #ifdef MEMPOOL_EXPERIMENTAL ,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch, NULL, 0, @@ -857,6 +861,7 @@ FrontendConfig_init () { cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth"); #endif cfg->allow_unauth_binds = LDAP_OFF; + cfg->require_secure_binds = LDAP_OFF; cfg->slapi_counters = LDAP_ON; cfg->threadnumber = SLAPD_DEFAULT_MAX_THREADS; cfg->maxthreadsperconn = SLAPD_DEFAULT_MAX_THREADS_PER_CONN; @@ -4544,6 +4549,19 @@ config_get_unauth_binds_switch(void) }
+int +config_get_require_secure_binds(void) +{ + int retVal; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + CFG_LOCK_READ(slapdFrontendConfig); + retVal = slapdFrontendConfig->require_secure_binds; + CFG_UNLOCK_READ(slapdFrontendConfig); + +return retVal; +} + + int config_is_slapd_lite () { @@ -5310,6 +5328,22 @@ config_set_unauth_binds_switch( const char *attrname, char *value, return retVal; }
+int +config_set_require_secure_binds( const char *attrname, char *value, + char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff(attrname, + value, + &(slapdFrontendConfig->require_secure_binds), + errorbuf, + apply); + + return retVal; +} +
/* * This function is intended to be used from the dse code modify callback. It diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index ba18a29..f81884c 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -343,6 +343,7 @@ int config_set_rewrite_rfc1274( const char *attrname, char *value, char *errorbu int config_set_outbound_ldap_io_timeout( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_unauth_binds_switch(const char *attrname, char *value, char *errorbuf, int apply ); +int config_set_require_secure_binds(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);
@@ -471,6 +472,7 @@ int config_get_hash_filters(); int config_get_rewrite_rfc1274(); int config_get_outbound_ldap_io_timeout(void); int config_get_unauth_binds_switch(void); +int config_get_require_secure_binds(void); int config_get_csnlogging(); #ifdef MEMPOOL_EXPERIMENTAL int config_get_mempool_switch(); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 3bcadde..7ae3fb4 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -1714,6 +1714,7 @@ typedef struct _slapdEntryPoints { #define CONFIG_USERAT_ATTRIBUTE "nsslapd-userat" #define CONFIG_SVRTAB_ATTRIBUTE "nsslapd-svrtab" #define CONFIG_UNAUTH_BINDS_ATTRIBUTE "nsslapd-allow-unauthenticated-binds" +#define CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE "nsslapd-require-secure-binds" #ifndef _WIN32 #define CONFIG_LOCALUSER_ATTRIBUTE "nsslapd-localuser" #endif /* !_WIN32 */ @@ -2007,6 +2008,7 @@ typedef struct _slapdFrontendConfig { char *ldapi_auto_dn_suffix; /* suffix to be appended to auto gen DNs */ int slapi_counters; /* switch to turn slapi_counters on/off */ int allow_unauth_binds; /* switch to enable/disable unauthenticated binds */ + int require_secure_binds; /* switch to require simple binds to use a secure channel */ size_t maxsasliosize; /* limit incoming SASL IO packet size */ #ifndef _WIN32 struct passwd *localuserinfo; /* userinfo of localuser */
Nathan Kinder wrote:
Nathan Kinder wrote:
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
A new patch with the above change is attached.
After some discussion with Rich, we determined that a change to the patch was necessary with regards to the way unauthenticated binds are treated. The attached patch treats unauthenticated binds the same as anonymous binds (assuming that they are allowed in the config). This means that the new setting to require secure binds will not affect unauthenticated binds or anonymous binds.
The patch also fixed a typo in one of the new log messages.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
From 4d32ce1809dfead6697404edaff066608c4bad9d Mon Sep 17 00:00:00 2001
From: Nathan Kinder nkinder@redhat.com Date: Fri, 29 May 2009 08:38:35 -0700 Subject: [PATCH] Add require secure binds switch.
This adds a new configuration attribute named nsslapd-require-secure-binds. When enabled, a simple bind will only be allowed over a secure transport (SSL/TLS or a SASL privacy layer). An attempt to do a simple bind over an insecure transport will return a LDAP result of LDAP_CONFIDENTIALITY_REQUIRED. This new setting will not affect anonymous or unauthenticated binds.
The default setting is to have this option disabled. --- ldap/ldif/template-dse.ldif.in | 1 + ldap/servers/slapd/bind.c | 24 ++++++++++++++++++++++++ ldap/servers/slapd/libglobs.c | 36 +++++++++++++++++++++++++++++++++++- ldap/servers/slapd/proto-slap.h | 2 ++ ldap/servers/slapd/slap.h | 2 ++ 5 files changed, 64 insertions(+), 1 deletions(-)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in index 54a9c4f..82326d5 100644 --- a/ldap/ldif/template-dse.ldif.in +++ b/ldap/ldif/template-dse.ldif.in @@ -30,6 +30,7 @@ nsslapd-rewrite-rfc1274: off nsslapd-return-exact-case: on nsslapd-ssl-check-hostname: on nsslapd-allow-unauthenticated-binds: off +nsslapd-require-secure-binds: off nsslapd-port: %ds_port% nsslapd-localuser: %ds_user% nsslapd-errorlog-logging-enabled: on diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index fbf9a19..359252f 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -439,6 +439,7 @@ do_bind( Slapi_PBlock *pb ) plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN ); } goto free_and_return; + /* Check if unauthenticated binds are allowed. */ } else if ( cred.bv_len == 0 ) { /* Increment unauthenticated bind counter */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds); @@ -454,6 +455,29 @@ do_bind( Slapi_PBlock *pb ) slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); goto free_and_return; } + /* Check if simple binds are allowed over an insecure channel. We only check + * this for authenticated binds. */ + } else if (config_get_require_secure_binds() == 1) { + Connection *conn = NULL; + int sasl_ssf = 0; + + /* Allow simple binds only for SSL/TLS established connections + * or connections using SASL privacy layers */ + conn = pb->pb_conn; + if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) { + slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind", + "Could not get SASL SSF from connection\n" ); + sasl_ssf = 0; + } + + if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) && + (sasl_ssf <= 1) ) { + send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL, + "Operation requires a secure connection", + 0, NULL); + slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors); + goto free_and_return; + } } break; default: diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index 1155c8c..358a745 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -606,7 +606,11 @@ static struct config_get_and_set { {CONFIG_UNAUTH_BINDS_ATTRIBUTE, config_set_unauth_binds_switch, NULL, 0, (void**)&global_slapdFrontendConfig.allow_unauth_binds, CONFIG_ON_OFF, - (ConfigGetFunc)config_get_unauth_binds_switch} + (ConfigGetFunc)config_get_unauth_binds_switch}, + {CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE, config_set_require_secure_binds, + NULL, 0, + (void**)&global_slapdFrontendConfig.require_secure_binds, CONFIG_ON_OFF, + (ConfigGetFunc)config_get_require_secure_binds} #ifdef MEMPOOL_EXPERIMENTAL ,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch, NULL, 0, @@ -857,6 +861,7 @@ FrontendConfig_init () { cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth"); #endif cfg->allow_unauth_binds = LDAP_OFF; + cfg->require_secure_binds = LDAP_OFF; cfg->slapi_counters = LDAP_ON; cfg->threadnumber = SLAPD_DEFAULT_MAX_THREADS; cfg->maxthreadsperconn = SLAPD_DEFAULT_MAX_THREADS_PER_CONN; @@ -4544,6 +4549,19 @@ config_get_unauth_binds_switch(void) }
+int +config_get_require_secure_binds(void) +{ + int retVal; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + CFG_LOCK_READ(slapdFrontendConfig); + retVal = slapdFrontendConfig->require_secure_binds; + CFG_UNLOCK_READ(slapdFrontendConfig); + +return retVal; +} + + int config_is_slapd_lite () { @@ -5310,6 +5328,22 @@ config_set_unauth_binds_switch( const char *attrname, char *value, return retVal; }
+int +config_set_require_secure_binds( const char *attrname, char *value, + char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff(attrname, + value, + &(slapdFrontendConfig->require_secure_binds), + errorbuf, + apply); + + return retVal; +} +
/* * This function is intended to be used from the dse code modify callback. It diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 41c80b5..6c7426e 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -343,6 +343,7 @@ int config_set_rewrite_rfc1274( const char *attrname, char *value, char *errorbu int config_set_outbound_ldap_io_timeout( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_unauth_binds_switch(const char *attrname, char *value, char *errorbuf, int apply ); +int config_set_require_secure_binds(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);
@@ -471,6 +472,7 @@ int config_get_hash_filters(); int config_get_rewrite_rfc1274(); int config_get_outbound_ldap_io_timeout(void); int config_get_unauth_binds_switch(void); +int config_get_require_secure_binds(void); int config_get_csnlogging(); #ifdef MEMPOOL_EXPERIMENTAL int config_get_mempool_switch(); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index f0d2191..ffcba46 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -1715,6 +1715,7 @@ typedef struct _slapdEntryPoints { #define CONFIG_USERAT_ATTRIBUTE "nsslapd-userat" #define CONFIG_SVRTAB_ATTRIBUTE "nsslapd-svrtab" #define CONFIG_UNAUTH_BINDS_ATTRIBUTE "nsslapd-allow-unauthenticated-binds" +#define CONFIG_REQUIRE_SECURE_BINDS_ATTRIBUTE "nsslapd-require-secure-binds" #ifndef _WIN32 #define CONFIG_LOCALUSER_ATTRIBUTE "nsslapd-localuser" #endif /* !_WIN32 */ @@ -2008,6 +2009,7 @@ typedef struct _slapdFrontendConfig { char *ldapi_auto_dn_suffix; /* suffix to be appended to auto gen DNs */ int slapi_counters; /* switch to turn slapi_counters on/off */ int allow_unauth_binds; /* switch to enable/disable unauthenticated binds */ + int require_secure_binds; /* switch to require simple binds to use a secure channel */ size_t maxsasliosize; /* limit incoming SASL IO packet size */ #ifndef _WIN32 struct passwd *localuserinfo; /* userinfo of localuser */
Your fixes look good to me. --noriko
Nathan Kinder wrote:
Nathan Kinder wrote:
Nathan Kinder wrote:
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
A new patch with the above change is attached.
After some discussion with Rich, we determined that a change to the patch was necessary with regards to the way unauthenticated binds are treated. The attached patch treats unauthenticated binds the same as anonymous binds (assuming that they are allowed in the config). This means that the new setting to require secure binds will not affect unauthenticated binds or anonymous binds.
The patch also fixed a typo in one of the new log messages.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Nathan Kinder wrote:
Nathan Kinder wrote:
Nathan Kinder wrote:
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
A new patch with the above change is attached.
After some discussion with Rich, we determined that a change to the patch was necessary with regards to the way unauthenticated binds are treated. The attached patch treats unauthenticated binds the same as anonymous binds (assuming that they are allowed in the config). This means that the new setting to require secure binds will not affect unauthenticated binds or anonymous binds.
The patch also fixed a typo in one of the new log messages.
Ok.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Rich Megginson wrote:
Nathan Kinder wrote:
Nathan Kinder wrote:
Nathan Kinder wrote:
Andrey Ivanov wrote:
Does it mean that when "nsslapd-require-secure-binds" is "on" then even the anonymous binds should be made by SSL? Maybe there is some sense in leaving a possibility to have anonymous binds non-SSL and frocing non-anonymous ones to be secure?
Sorry for the late response, but I was on vacation the last week.
The current patch does force all simple binds, including anonymous, to use a secure connection. I can see value in allowing anonymous simple binds over an unencrypted connection, as the main reason for this new setting is to prevent clear text transmission of passwords. I will revise the patch to ignore anonymous binds when nsslapd-require-secure-binds is on unless anyone else has arguments otherwise.
A new patch with the above change is attached.
After some discussion with Rich, we determined that a change to the patch was necessary with regards to the way unauthenticated binds are treated. The attached patch treats unauthenticated binds the same as anonymous binds (assuming that they are allowed in the config). This means that the new setting to require secure binds will not affect unauthenticated binds or anonymous binds.
The patch also fixed a typo in one of the new log messages.
Ok.
Pushed to master.
There are a number of other security related configuration settings that I plan to add soon, which will provide other ways of dealing with restricting anonymous operations. One of these features are a switch to disable any anonymous operations completely. Another is to have a minimum SSF setting on the server. The only operation we would allow after first connecting over plain LDAP would be startTLS. If the SSF then meets the minimum requirement, other operations would be allowed.
2009/5/15 Rich Megginson <rmeggins@redhat.com mailto:rmeggins@redhat.com>
Nathan Kinder wrote:
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com>https://www.redhat.com/mailman/listinfo/fedora-directory-devel
Looks good. -- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com <mailto:Fedora-directory-devel@redhat.com> https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
-- Fedora-directory-devel mailing list Fedora-directory-devel@redhat.com https://www.redhat.com/mailman/listinfo/fedora-directory-devel
389-devel@lists.fedoraproject.org