From c55fdd5f8c2a9ccef937387a57e02b2c28efb32d Mon Sep 17 00:00:00 2001 From: German Parente Date: Mon, 22 Sep 2014 20:09:20 +0200 Subject: [PATCH] Ticket #47906: passwordhistory is not updated if password changed by admin user Bug Description: This is a side effect of fix for https://fedorahosted.org/389/ticket/47522 Password administrators should be able to violate password policy Once password is succesfully modified, we have to update password history and passwordexpirationtime. First attribute is modified when: config is set (passwordHistory: on in cn=config) old password is not NULL. We set old password when checking password syntax but this control was skipped at fix for 47522. NOTE: Perhaps we consider a feature that when is admin that changes the password, the passwordhistory must not be updated. In this case, this ticket should be closed. Fix Description: don't exit function op_shared_allow_pw_change when checking if admin is doing the modify. Keep the flag and allow old password to be set at password syntax check. Another alternative would be to set the current password in a different function than the one doing password check syntax https://fedorahosted.org/389/ticket/47906 Reviewed by: ? --- ldap/servers/slapd/modify.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c index fb0fdde..6401414 100644 --- a/ldap/servers/slapd/modify.c +++ b/ldap/servers/slapd/modify.c @@ -1208,6 +1208,7 @@ static void remove_mod (Slapi_Mods *smods, const char *type, Slapi_Mods *smod_un static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_Mods *smods) { int isroot, internal_op, repl_op, pwresponse_req = 0; + int isadmin = 0,result_syntax = 0; int res = 0; char *dn; char *errtxt = NULL; @@ -1254,6 +1255,8 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old goto done; } + isadmin = pw_is_pwp_admin(pb, pwpolicy); + /* internal operation has root permissions for subtrees it is allowed to access */ if (!internal_op) { @@ -1279,7 +1282,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old slapi_pblock_set( pb, SLAPI_BACKEND, slapi_be_select( &sdn ) ); /* Check if ACIs allow password to be changed */ - if ( !pw_is_pwp_admin(pb, pwpolicy) && (res = slapi_acl_check_mods(pb, e, mods, &errtxt)) != LDAP_SUCCESS){ + if ( !isadmin && (res = slapi_acl_check_mods(pb, e, mods, &errtxt)) != LDAP_SUCCESS){ if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)){ if (proxydn){ proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); @@ -1299,17 +1302,8 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old goto done; } - /* - * If this mod is being performed by a password administrator/rootDN, - * just return success. - */ - if(pw_is_pwp_admin(pb, pwpolicy)){ - rc = 1; - goto done; - } - /* Check if password policy allows users to change their passwords.*/ - if (!pb->pb_op->o_isroot && slapi_sdn_compare(&sdn, &pb->pb_op->o_sdn)==0 && + if (!isadmin && !pb->pb_op->o_isroot && slapi_sdn_compare(&sdn, &pb->pb_op->o_sdn)==0 && !pb->pb_conn->c_needpw && !pwpolicy->pw_change) { if ( pwresponse_req == 1 ) { @@ -1340,7 +1334,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old /* check if password is within password minimum age; error result is sent directly from check_pw_minage */ if ((internal_op || !pb->pb_conn->c_needpw) && - check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1) + check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1 && !isadmin) { if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) { @@ -1377,9 +1371,13 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old /* check password syntax; remember the old password; error sent directly from check_pw_syntax function */ valuearray_init_bervalarray(mod->mod_bvalues, &values); - switch (check_pw_syntax_ext (pb, &sdn, values, old_pw, NULL, - mod->mod_op, smods)) - { + result_syntax = check_pw_syntax_ext (pb, &sdn, values, old_pw, NULL, mod->mod_op, smods); + + if (isadmin) { + rc=1; + } else { + switch (result_syntax) + { case 0: /* success */ rc = 1; break; @@ -1420,7 +1418,8 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old break; default: break; - } + } + } valuearray_free(&values); done: -- 1.9.3