From f17fba0adc91f9ecacfdb4cd975dc20ce051b80f Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 16 Sep 2025 14:48:59 +0300 Subject: [PATCH] ipa-pwd-extop: add SysAcctManagersDNs support Add new attribute, SysAcctManagersDNs, to store list of DNs allowed to reset user passwords without forcing the users to change them afterwards. This list will differ from the use of PassSyncManagersDNs by the fact that password policy checks will still apply to those password changes. Fixes: https://pagure.io/freeipa/issue/9842 Signed-off-by: Alexander Bokovoy Reviewed-By: Rafael Guterres Jeffman Reviewed-By: Thomas Woerner Reviewed-By: Florence Blanc-Renaud --- .../ipa-slapi-plugins/ipa-pwd-extop/common.c | 15 ++++++++++---- .../ipa-pwd-extop/ipa_pwd_extop.c | 9 +++++---- .../ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h | 3 ++- .../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 20 +++++++++++-------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c index c85795c1e..114d20417 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/common.c @@ -225,7 +225,10 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void) goto free_and_error; } config->passsync_mgrs = - slapi_entry_attr_get_charray(config_entry, "passSyncManagersDNs"); + slapi_entry_attr_get_charray(config_entry, "passSyncManagersDNs"); + config->sysacct_mgrs = + slapi_entry_attr_get_charray(config_entry, "SysAcctManagersDNs"); + /* now add Directory Manager, it is always added by default */ tmpstr = slapi_ch_strdup("cn=Directory Manager"); slapi_ch_array_add(&config->passsync_mgrs, tmpstr); @@ -233,8 +236,6 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void) LOG_OOM(); goto free_and_error; } - for (i = 0; config->passsync_mgrs[i]; i++) /* count */ ; - config->num_passsync_mgrs = i; slapi_entry_free(config_entry); @@ -289,6 +290,7 @@ free_and_error: free(config->pref_encsalts); free(config->supp_encsalts); slapi_ch_array_free(config->passsync_mgrs); + slapi_ch_array_free(config->sysacct_mgrs); free(config); } slapi_entry_free(config_entry); @@ -614,6 +616,12 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data) switch(data->changetype) { case IPA_CHANGETYPE_NORMAL: + case IPA_CHANGETYPE_SYSACCT: + /* + * Treat a system account-initiated password change as the user's + * initiated one as well, to force password quality checks on them. + */ + /* Find the entry with the password policy */ ret = ipapwd_getPolicy(data->dn, data->target, &pol); if (ret) { @@ -1143,4 +1151,3 @@ int ipapwd_check_max_pwd_len(size_t len, char **errMesg) { } return 0; } - diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c index 43c31beca..ca48a12a6 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c @@ -583,10 +583,11 @@ parse_req_done: (strcasecmp(ipa_changepw_principal_dn, bindDN) != 0)) { pwdata.changetype = IPA_CHANGETYPE_ADMIN; - for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) { - if (strcasecmp(krbcfg->passsync_mgrs[i], bindDN) == 0) { - pwdata.changetype = IPA_CHANGETYPE_DSMGR; - break; + if (slapi_ch_array_utf8_inlist(krbcfg->passsync_mgrs, bindDN) == 1) { + pwdata.changetype = IPA_CHANGETYPE_DSMGR; + } else { + if (slapi_ch_array_utf8_inlist(krbcfg->sysacct_mgrs, bindDN) == 1) { + pwdata.changetype = IPA_CHANGETYPE_SYSACCT; } } } diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h index 976970006..c2682a7ba 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h @@ -75,6 +75,7 @@ #define IPA_CHANGETYPE_NORMAL 0 #define IPA_CHANGETYPE_ADMIN 1 #define IPA_CHANGETYPE_DSMGR 2 +#define IPA_CHANGETYPE_SYSACCT 3 struct ipapwd_data { Slapi_Entry *target; @@ -108,7 +109,7 @@ struct ipapwd_krbcfg { int num_pref_encsalts; krb5_key_salt_tuple *pref_encsalts; char **passsync_mgrs; - int num_passsync_mgrs; + char **sysacct_mgrs; bool allow_nt_hash; bool enforce_ldap_otp; }; diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c index 42e880fd0..0fdb7840b 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c @@ -368,10 +368,12 @@ static int ipapwd_pre_add(Slapi_PBlock *pb) slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn); /* if it is a passsync manager we also need to skip resets */ - for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) { - if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) { - pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR; - break; + if (slapi_ch_array_utf8_inlist(krbcfg->passsync_mgrs, binddn) == 1) { + pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR; + } else { + /* if it is a system account allowed to skip resets, mark it so */ + if (slapi_ch_array_utf8_inlist(krbcfg->sysacct_mgrs, binddn) == 1) { + pwdop->pwdata.changetype = IPA_CHANGETYPE_SYSACCT; } } } @@ -861,10 +863,12 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb) pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN; /* if it is a passsync manager we also need to skip resets */ - for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) { - if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) { - pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR; - break; + if (slapi_ch_array_utf8_inlist(krbcfg->passsync_mgrs, binddn) == 1) { + pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR; + } else { + /* if it is a system account allowed to skip resets, mark it so */ + if (slapi_ch_array_utf8_inlist(krbcfg->sysacct_mgrs, binddn) == 1) { + pwdop->pwdata.changetype = IPA_CHANGETYPE_SYSACCT; } } }