From 749897299831fd5efeea7d299f9ab9c449017f23 Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Jul 22 2014 00:47:20 +0000 Subject: Ticket 47753 - Add switch to disable pre-hashed password checking By default, 389 DS doesn't allow pre-hashed passwords to be set by anyone other than Directory Manager. This privilege can be delegated to other users by adding them to the Password Administrators group. This works fine for most cases, but there are cases where one might want to allow anyone to set pre-hashed passwords. An example is the FreeIPA project, who has their own SLAPI plug-in that controls pre-hashed password checking. We should add a switch to completely disable pre-hashed password checking to support this case. https://fedorahosted.org/389/ticket/47753 Reviewed by mreynolds@redhat.com (cherry picked from commit ab6438901fd1481ceceb40d6dff8935ac656dc04) --- diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in index 9a52bc5..17555a3 100644 --- a/ldap/ldif/template-dse.ldif.in +++ b/ldap/ldif/template-dse.ldif.in @@ -58,6 +58,7 @@ nsslapd-maxdescriptors: 1024 nsslapd-max-filter-nest-level: 40 nsslapd-ndn-cache-enabled: off nsslapd-sasl-mapping-fallback: off +nsslapd-allow-hashed-passwords: off dn: cn=features,cn=config objectclass: top diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif index 41cdd8b..07a673b 100644 --- a/ldap/schema/01core389.ldif +++ b/ldap/schema/01core389.ldif @@ -158,6 +158,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2165 NAME 'schemaUpdateObjectclassAccept attributeTypes: ( 2.16.840.1.113730.3.1.2166 NAME 'schemaUpdateObjectclassReject' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2167 NAME 'schemaUpdateAttributeAccept' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2168 NAME 'schemaUpdateAttributeReject' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) +attributeTypes: ( 2.16.840.1.113730.3.1.2307 NAME 'nsslapd-allow-hashed-passwords' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) # # objectclasses # diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index 2a8e05d..94144c8 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -228,6 +228,7 @@ slapi_onoff_t init_pw_is_legacy; slapi_onoff_t init_pw_track_update_time; slapi_onoff_t init_pw_change; slapi_onoff_t init_pw_exp; +slapi_onoff_t init_allow_hashed_pw; slapi_onoff_t init_pw_syntax; slapi_onoff_t init_schemacheck; slapi_onoff_t init_schemamod; @@ -742,6 +743,10 @@ static struct config_get_and_set { log_set_expirationtimeunit, SLAPD_AUDIT_LOG, (void**)&global_slapdFrontendConfig.auditlog_exptimeunit, CONFIG_STRING_OR_UNKNOWN, NULL, INIT_AUDITLOG_EXPTIMEUNIT}, + {CONFIG_ALLOW_HASHED_PW_ATTRIBUTE, config_set_allow_hashed_pw, + NULL, 0, + (void**)&global_slapdFrontendConfig.allow_hashed_pw, + CONFIG_ON_OFF, NULL, &init_allow_hashed_pw}, {CONFIG_PW_SYNTAX_ATTRIBUTE, config_set_pw_syntax, NULL, 0, (void**)&global_slapdFrontendConfig.pw_policy.pw_syntax, @@ -1446,6 +1451,7 @@ FrontendConfig_init () { init_pwpolicy_local = cfg->pwpolicy_local = LDAP_OFF; init_pw_change = cfg->pw_policy.pw_change = LDAP_ON; init_pw_must_change = cfg->pw_policy.pw_must_change = LDAP_OFF; + init_allow_hashed_pw = cfg->allow_hashed_pw = LDAP_OFF; init_pw_syntax = cfg->pw_policy.pw_syntax = LDAP_OFF; init_pw_exp = cfg->pw_policy.pw_exp = LDAP_OFF; cfg->pw_policy.pw_minlength = 8; @@ -2514,6 +2520,20 @@ config_set_pwpolicy_local( const char *attrname, char *value, char *errorbuf, in } int +config_set_allow_hashed_pw( const char *attrname, char *value, char *errorbuf, int apply ) { + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff ( attrname, + value, + &(slapdFrontendConfig->allow_hashed_pw), + errorbuf, + apply); + + return retVal; +} + +int config_set_pw_syntax( const char *attrname, char *value, char *errorbuf, int apply ) { int retVal = LDAP_SUCCESS; slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); @@ -4767,6 +4787,18 @@ config_get_pw_must_change() { return retVal; } +int +config_get_allow_hashed_pw() +{ + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + int retVal; + + CFG_ONOFF_LOCK_READ(slapdFrontendConfig); + retVal = (int)slapdFrontendConfig->allow_hashed_pw; + CFG_ONOFF_UNLOCK_READ(slapdFrontendConfig); + + return retVal; +} int config_get_pw_syntax() { diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index a0b9b12..b8d563d 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -322,6 +322,7 @@ int config_set_errorlog(const char *attrname, char *value, char *errorbuf, int a int config_set_pw_change(const char *attrname, char *value, char *errorbuf, int apply ); int config_set_pw_must_change(const char *attrname, char *value, char *errorbuf, int apply ); int config_set_pwpolicy_local(const char *attrname, char *value, char *errorbuf, int apply ); +int config_set_allow_hashed_pw( const char *attrname, char *value, char *errorbuf, int apply ); int config_set_pw_syntax(const char *attrname, char *value, char *errorbuf, int apply ); int config_set_pw_minlength(const char *attrname, char *value, char *errorbuf, int apply ); int config_set_pw_mindigits(const char *attrname, char *value, char *errorbuf, int apply ); @@ -446,6 +447,7 @@ char *config_get_pw_storagescheme(); int config_get_pw_change(); int config_get_pw_history(); int config_get_pw_must_change(); +int config_get_allow_hashed_pw(); int config_get_pw_syntax(); int config_get_pw_minlength(); int config_get_pw_mindigits(); diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c index b4a3295..a4d2dc6 100644 --- a/ldap/servers/slapd/pw.c +++ b/ldap/servers/slapd/pw.c @@ -820,8 +820,9 @@ check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, */ for ( i = 0; vals[ i ] != NULL; ++i ){ if (slapi_is_encoded((char *)slapi_value_get_string(vals[i]))) { - if ((!is_replication && ((internal_op && pb->pb_conn && !slapi_dn_isroot(pb->pb_conn->c_dn)) || - (!internal_op && !pw_is_pwp_admin(pb, pwpolicy))))) { + if (!is_replication && !config_get_allow_hashed_pw() && + ((internal_op && pb->pb_conn && !slapi_dn_isroot(pb->pb_conn->c_dn)) || + (!internal_op && !pw_is_pwp_admin(pb, pwpolicy)))) { PR_snprintf( errormsg, BUFSIZ, "invalid password syntax - passwords with storage scheme are not allowed"); if ( pwresponse_req == 1 ) { diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 5a53113..45635d5 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -2056,6 +2056,7 @@ typedef struct _slapdEntryPoints { #define CONFIG_GROUPEVALNESTLEVEL_ATTRIBUTE "nsslapd-groupevalnestlevel" #define CONFIG_NAGLE_ATTRIBUTE "nsslapd-nagle" #define CONFIG_PWPOLICY_LOCAL_ATTRIBUTE "nsslapd-pwpolicy-local" +#define CONFIG_ALLOW_HASHED_PW_ATTRIBUTE "nsslapd-allow-hashed-passwords" #define CONFIG_PW_CHANGE_ATTRIBUTE "passwordChange" #define CONFIG_PW_MUSTCHANGE_ATTRIBUTE "passwordMustChange" #define CONFIG_PW_SYNTAX_ATTRIBUTE "passwordCheckSyntax" @@ -2264,6 +2265,7 @@ typedef struct _slapdFrontendConfig { slapi_onoff_t pwpolicy_local; slapi_onoff_t pw_is_global_policy; + slapi_onoff_t allow_hashed_pw; passwdPolicy pw_policy; /* ACCESS LOG */