From 4167ad01d73b0c7c0912bf537730da5c9b46b2c3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 17 Sep 2011 15:08:06 -0400 Subject: ipa-kdb: Properly set password expiration time. We do the policy check so we are the only one that can calculate the new pwd espiration time. Fixes: https://fedorahosted.org/freeipa/ticket/1793 --- daemons/ipa-kdb/ipa_kdb.h | 4 ++++ daemons/ipa-kdb/ipa_kdb_passwords.c | 46 ++++++++++++++++++++++++++++++++++++ daemons/ipa-kdb/ipa_kdb_principals.c | 28 ++++++++++++++++++---- 3 files changed, 74 insertions(+), 4 deletions(-) (limited to 'daemons/ipa-kdb') diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index 78746918a..cfcaca649 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -178,3 +178,7 @@ krb5_error_code ipadb_change_pwd(krb5_context context, int new_kvno, krb5_boolean keepold, krb5_db_entry *db_entry); +krb5_error_code ipadb_get_pwd_expiration(krb5_context context, + krb5_db_entry *entry, + struct ipadb_e_data *ied, + time_t *expire_time); diff --git a/daemons/ipa-kdb/ipa_kdb_passwords.c b/daemons/ipa-kdb/ipa_kdb_passwords.c index ab58057a1..18be9be01 100644 --- a/daemons/ipa-kdb/ipa_kdb_passwords.c +++ b/daemons/ipa-kdb/ipa_kdb_passwords.c @@ -269,3 +269,49 @@ krb5_error_code ipadb_change_pwd(krb5_context context, return 0; } +/* + * Check who actually changed the password, if it is not 'self' then + * we need to expire it if it is a user principal. + */ +krb5_error_code ipadb_get_pwd_expiration(krb5_context context, + krb5_db_entry *entry, + struct ipadb_e_data *ied, + time_t *expire_time) +{ + krb5_error_code kerr; + krb5_timestamp mod_time; + krb5_principal mod_princ = NULL; + krb5_boolean truexp = true; + + + /* Assume all principals with just one component as user principals */ + if (entry->princ->length == 1) { + kerr = krb5_dbe_lookup_mod_princ_data(context, entry, + &mod_time, &mod_princ); + if (kerr) { + goto done; + } + + /* If the mod principal is kadmind then we have to assume an actual + * password change for now. Apparently kadmind does not properly pass + * the actual user principal down when said user is performing a + * password change */ + if (mod_princ->length == 1 && + strcmp(mod_princ->data[0].data, "kadmind") != 0) { + truexp = krb5_principal_compare(context, mod_princ, entry->princ); + } + } + + if (truexp) { + *expire_time = mod_time + ied->pol.max_pwd_life; + } else { + /* not 'self', so reset */ + *expire_time = mod_time; + } + + kerr = 0; + +done: + krb5_free_principal(context, mod_princ); + return kerr; +} diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index 8e1d42185..ed5195fb9 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -1362,7 +1362,8 @@ done: return kerr; } -static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods, +static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, + struct ipadb_mods *imods, krb5_db_entry *entry, char *principal, int mod_op) @@ -1561,10 +1562,11 @@ static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods, /* KADM5_LOAD */ - /* Store saved password if any and password history */ + /* Handle password change related operations. */ if (entry->e_data) { struct ipadb_e_data *ied; time_t now = time(NULL); + time_t expire_time; char **new_history; int nh_len; int ret; @@ -1603,6 +1605,22 @@ static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods, goto done; } } + + /* Also set new password expiration time. + * Have to do it here because kadmin doesn't know policies and resets + * entry->mask after we have gone through the password change code. + */ + kerr = ipadb_get_pwd_expiration(kcontext, entry, ied, &expire_time); + if (kerr) { + goto done; + } + + kerr = ipadb_get_ldap_mod_time(imods, + "krbPasswordExpiration", + expire_time, mod_op); + if (kerr) { + goto done; + } } kerr = 0; @@ -1689,7 +1707,8 @@ static krb5_error_code ipadb_add_principal(krb5_context kcontext, goto done; } - kerr = ipadb_entry_to_mods(imods, entry, principal, LDAP_MOD_ADD); + kerr = ipadb_entry_to_mods(kcontext, imods, + entry, principal, LDAP_MOD_ADD); if (kerr != 0) { goto done; } @@ -1752,7 +1771,8 @@ static krb5_error_code ipadb_modify_principal(krb5_context kcontext, goto done; } - kerr = ipadb_entry_to_mods(imods, entry, principal, LDAP_MOD_REPLACE); + kerr = ipadb_entry_to_mods(kcontext, imods, + entry, principal, LDAP_MOD_REPLACE); if (kerr != 0) { goto done; } -- cgit