mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-13 08:52:01 -05:00
Make the list of users that can skip passwrod policies configurable.
Addresses bz#471130 Also fix bugs in ipapwd_start. Also remove mutex, it is not necessary with the current code, we needed it when we used to change reload the configuration and keep it referenced in a static pointer. ipapwd_start runs only once and the global variables it sets are fixed in stone until DS is restarted.
This commit is contained in:
1 parent
47863ac169
commit
8929075150
1 file changed
+105
-48
@@ -140,9 +140,9 @@ struct ipapwd_encsalt {
|
||||
krb5_int32 salt_type;
|
||||
};
|
||||
|
||||
static const char *ipa_realm_dn = NULL;
|
||||
|
||||
Slapi_Mutex *ipa_globals = NULL;
|
||||
static const char *ipa_realm_dn;
|
||||
static const char *ipa_pwd_config_dn;
|
||||
static const char *ipa_changepw_principal_dn;
|
||||
|
||||
#define IPAPWD_PLUGIN_NAME "ipa-pwd-extop"
|
||||
#define IPAPWD_FEATURE_DESC "IPA Password Manager"
|
||||
@@ -169,6 +169,8 @@ struct ipapwd_krbcfg {
|
||||
struct ipapwd_encsalt *supp_encsalts;
|
||||
int num_pref_encsalts;
|
||||
struct ipapwd_encsalt *pref_encsalts;
|
||||
char **passsync_mgrs;
|
||||
int num_passsync_mgrs;
|
||||
};
|
||||
|
||||
static void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg)
|
||||
@@ -1982,26 +1984,26 @@ parse_req_done:
|
||||
pwdata.timeNow = time(NULL);
|
||||
pwdata.changetype = IPA_CHANGETYPE_NORMAL;
|
||||
|
||||
/*
|
||||
* (technically strcasecmp to compare DNs is not absolutely correct,
|
||||
* but it should work for the cases we care about here)
|
||||
*/
|
||||
|
||||
/* determine type of password change */
|
||||
if (strcasecmp(dn, bindDN) != 0) {
|
||||
char **bindexp;
|
||||
/* special cases */
|
||||
if ((strcasecmp(dn, bindDN) != 0) &&
|
||||
(strcasecmp(ipa_changepw_principal_dn, bindDN) != 0)) {
|
||||
int i;
|
||||
|
||||
pwdata.changetype = IPA_CHANGETYPE_ADMIN;
|
||||
pwdata.changetype = IPA_CHANGETYPE_ADMIN;
|
||||
|
||||
bindexp = ldap_explode_dn(bindDN, 0);
|
||||
if (bindexp) {
|
||||
/* special case kpasswd and Directory Manager */
|
||||
if ((strncasecmp(bindexp[0], "krbprincipalname=kadmin/changepw@", 33) == 0) &&
|
||||
(strcasecmp(&(bindexp[0][33]), krbcfg->realm) == 0)) {
|
||||
pwdata.changetype = IPA_CHANGETYPE_NORMAL;
|
||||
}
|
||||
if ((strcasecmp(bindexp[0], "cn=Directory Manager") == 0) &&
|
||||
bindexp[1] == NULL) {
|
||||
pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
}
|
||||
ldap_value_free(bindexp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
|
||||
if (strcasecmp(krbcfg->passsync_mgrs[i], bindDN) == 0) {
|
||||
pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check the policy */
|
||||
ret = ipapwd_CheckPolicy(&pwdata);
|
||||
@@ -2655,12 +2657,13 @@ static int new_ipapwd_encsalt(krb5_context krbctx, const char * const *encsalts,
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static struct ipapwd_krbcfg *ipapwd_getConfig(const char *realm_dn)
|
||||
static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
{
|
||||
krb5_error_code krberr;
|
||||
struct ipapwd_krbcfg *config = NULL;
|
||||
krb5_keyblock *kmkey = NULL;
|
||||
Slapi_Entry *realm_entry = NULL;
|
||||
Slapi_Entry *config_entry = NULL;
|
||||
Slapi_Attr *a;
|
||||
Slapi_Value *v;
|
||||
BerElement *be = NULL;
|
||||
@@ -2669,7 +2672,8 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(const char *realm_dn)
|
||||
const struct berval *bval;
|
||||
struct berval *mkey = NULL;
|
||||
char **encsalts;
|
||||
int ret;
|
||||
char *tmpstr;
|
||||
int i, ret;
|
||||
|
||||
config = calloc(1, sizeof(struct ipapwd_krbcfg));
|
||||
if (!config) {
|
||||
@@ -2700,7 +2704,7 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(const char *realm_dn)
|
||||
}
|
||||
|
||||
/* get the Realm Container entry */
|
||||
ret = ipapwd_getEntry(realm_dn, &realm_entry, NULL);
|
||||
ret = ipapwd_getEntry(ipa_realm_dn, &realm_entry, NULL);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
slapi_log_error(SLAPI_LOG_FATAL, "ipapwd_getConfig",
|
||||
"No realm Entry?\n");
|
||||
@@ -2808,6 +2812,25 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(const char *realm_dn)
|
||||
|
||||
slapi_entry_free(realm_entry);
|
||||
|
||||
/* get the Realm Container entry */
|
||||
ret = ipapwd_getEntry(ipa_pwd_config_dn, &config_entry, NULL);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
slapi_log_error(SLAPI_LOG_FATAL, "ipapwd_getConfig",
|
||||
"No config Entry? Impossible!\n");
|
||||
goto free_and_error;
|
||||
}
|
||||
config->passsync_mgrs = slapi_entry_attr_get_charray(config_entry, "passSyncManagersDNs");
|
||||
/* 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);
|
||||
if (config->passsync_mgrs == NULL) {
|
||||
slapi_log_error(SLAPI_LOG_FATAL, "ipapwd_getConfig",
|
||||
"Out of memory!\n");
|
||||
goto free_and_error;
|
||||
}
|
||||
for (i = 0; config->passsync_mgrs[i]; i++) /* count */ ;
|
||||
config->num_passsync_mgrs = i;
|
||||
|
||||
return config;
|
||||
|
||||
free_and_error:
|
||||
@@ -2821,6 +2844,7 @@ free_and_error:
|
||||
if (config->krbctx) krb5_free_context(config->krbctx);
|
||||
free(config->pref_encsalts);
|
||||
free(config->supp_encsalts);
|
||||
free(config->passsync_mgrs);
|
||||
free(config);
|
||||
}
|
||||
if (realm_entry) slapi_entry_free(realm_entry);
|
||||
@@ -2865,7 +2889,7 @@ static int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
|
||||
#endif
|
||||
|
||||
/* get the kerberos context and master key */
|
||||
*config = ipapwd_getConfig(ipa_realm_dn);
|
||||
*config = ipapwd_getConfig();
|
||||
if (NULL == *config) {
|
||||
slapi_log_error(SLAPI_LOG_PLUGIN, "ipa_pwd_extop",
|
||||
"Error Retrieving Master Key");
|
||||
@@ -3192,7 +3216,21 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
if (is_root) {
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
} else {
|
||||
char *binddn;
|
||||
int i;
|
||||
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
|
||||
|
||||
/* Check Bind DN */
|
||||
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
|
||||
|
||||
/* if it is a passsync manager we also need to skip resets */
|
||||
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
|
||||
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(dn);
|
||||
@@ -3559,6 +3597,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
} else {
|
||||
char *binddn;
|
||||
Slapi_DN *bdn, *tdn;
|
||||
int i;
|
||||
|
||||
/* Check Bind DN */
|
||||
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
|
||||
@@ -3570,10 +3609,20 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
* password change immediately as per our IPA policy */
|
||||
if (slapi_sdn_compare(bdn, tdn)) {
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
|
||||
|
||||
/* if it is a passsync manager we also need to skip resets */
|
||||
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
|
||||
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
slapi_sdn_free(&bdn);
|
||||
slapi_sdn_free(&tdn);
|
||||
|
||||
}
|
||||
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(dn);
|
||||
@@ -3773,63 +3822,71 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
||||
krb5_context krbctx;
|
||||
krb5_error_code krberr;
|
||||
char *realm;
|
||||
char *realm_dn;
|
||||
char *config_dn;
|
||||
char *partition_dn;
|
||||
Slapi_Entry *config_entry;
|
||||
Slapi_Entry *config_entry = NULL;
|
||||
int ret;
|
||||
|
||||
ipa_globals = slapi_new_mutex();
|
||||
|
||||
krberr = krb5_init_context(&krbctx);
|
||||
if (krberr) {
|
||||
slapi_log_error(SLAPI_LOG_FATAL, "ipapwd_start", "krb5_init_context failed\n");
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
/*retrieve the master key from the stash file */
|
||||
if (slapi_pblock_get(pb, SLAPI_TARGET_DN, &config_dn) != 0) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "No config DN?\n");
|
||||
krb5_free_context(krbctx);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ipapwd_getEntry(config_dn, &config_entry, NULL) != LDAP_SUCCESS) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "No config Entry?\n");
|
||||
krb5_free_context(krbctx);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
partition_dn = slapi_entry_attr_get_charptr(config_entry, "nsslapd-realmtree");
|
||||
if (!partition_dn) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Missing partition configuration entry (nsslapd-targetSubtree)!\n");
|
||||
krb5_free_context(krbctx);
|
||||
slapi_entry_free(config_entry);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Missing partition configuration entry (nsslapd-realmTree)!\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = krb5_get_default_realm(krbctx, &realm);
|
||||
if (ret) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Failed to get default realm?!\n");
|
||||
krb5_free_context(krbctx);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
realm_dn = slapi_ch_smprintf("cn=%s,cn=kerberos,%s", realm, partition_dn);
|
||||
if (!realm_dn) {
|
||||
ipa_realm_dn = slapi_ch_smprintf("cn=%s,cn=kerberos,%s", realm, partition_dn);
|
||||
if (!ipa_realm_dn) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Out of memory ?\n");
|
||||
free(realm);
|
||||
krb5_free_context(krbctx);
|
||||
slapi_entry_free(config_entry);
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
free(realm);
|
||||
|
||||
slapi_lock_mutex(ipa_globals);
|
||||
ipa_realm_dn = realm_dn;
|
||||
slapi_unlock_mutex(ipa_globals);
|
||||
ipa_pwd_config_dn = slapi_ch_strdup(config_dn);
|
||||
if (!ipa_pwd_config_dn) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Out of memory ?\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
ipa_changepw_principal_dn =
|
||||
slapi_ch_smprintf("krbprincipalname=kadmin/changepw@%s,%s",
|
||||
realm, ipa_realm_dn);
|
||||
if (!ipa_changepw_principal_dn) {
|
||||
slapi_log_error( SLAPI_LOG_FATAL, "ipapwd_start", "Out of memory ?\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = LDAP_SUCCESS;
|
||||
|
||||
done:
|
||||
krb5_free_context(krbctx);
|
||||
slapi_entry_free(config_entry);
|
||||
if (config_entry) slapi_entry_free(config_entry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user