From a00b03831b6a7ccb87d58c92c1072c586889508e Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 28 Jun 2011 13:09:18 -0400 Subject: Don't set krbLastPwdChange when setting a host OTP password. We have no visibility into whether an entry has a keytab or not so krbLastPwdChange is used as a rough guide. If this value exists during enrollment then it fails because the host is considered already joined. This was getting set when a OTP was added to a host that had already been enrolled (e.g. you enroll a host, unenroll it, set a OTP, then try to re-enroll). The second enrollment was failing because the enrollment plugin thought it was still enrolled becaused krbLastPwdChange was set. https://fedorahosted.org/freeipa/ticket/1357 --- .../ipa-pwd-extop/ipa_pwd_extop.c | 9 ++++ .../ipa-pwd-extop/ipapwd_common.c | 48 +++++++++++++-------- .../ipa-pwd-extop/ipapwd_prepost.c | 50 +++++++++++++--------- 3 files changed, 70 insertions(+), 37 deletions(-) (limited to 'daemons') 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 f1da29321..cb9af98e4 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 @@ -141,6 +141,7 @@ static int ipapwd_chpwop(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg) struct berval *extop_value = NULL; BerElement *ber = NULL; Slapi_Entry *targetEntry=NULL; + Slapi_Value *objectclass=NULL; char *attrlist[] = {"*", "passwordHistory", NULL }; struct ipapwd_data pwdata; int is_krb, is_smb; @@ -288,6 +289,14 @@ parse_req_done: goto free_and_return; } + /* When setting the password for host principals do not set kerberos + * keys */ + objectclass = slapi_value_new_string("ipaHost"); + if ((slapi_entry_attr_has_syntax_value(targetEntry, SLAPI_ATTR_OBJECTCLASS, objectclass)) == 1) { + is_krb = 0; + } + slapi_value_free(&objectclass); + /* First thing to do is to ask access control if the bound identity has * rights to modify the userpassword attribute on this entry. If not, * then we fail immediately with insufficient access. This means that diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c index 25557aa94..fc9ccb05c 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c @@ -1120,7 +1120,9 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, char *lm = NULL; char *nt = NULL; int is_smb = 0; + int is_host = 0; Slapi_Value *sambaSamAccount; + Slapi_Value *ipaHost; char *errMesg = NULL; char *modtime = NULL; @@ -1133,6 +1135,13 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, } slapi_value_free(&sambaSamAccount); + ipaHost = slapi_value_new_string("ipaHost"); + if (slapi_entry_attr_has_syntax_value(data->target, + "objectClass", ipaHost)) { + is_host = 1; + } + slapi_value_free(&ipaHost); + ret = ipapwd_gen_hashes(krbcfg, data, data->password, is_krb, is_smb, @@ -1147,28 +1156,33 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "krbPrincipalKey", svals); - /* change Last Password Change field with the current date */ - if (!gmtime_r(&(data->timeNow), &utctime)) { - LOG_FATAL("failed to retrieve current date (buggy gmtime_r ?)\n"); - ret = LDAP_OPERATIONS_ERROR; - goto free_and_return; - } - strftime(timestr, GENERALIZED_TIME_LENGTH + 1, + /* krbLastPwdChange is used to tell whether a host entry has a + * keytab so don't set it on hosts. + */ + if (!is_host) { + /* change Last Password Change field with the current date */ + if (!gmtime_r(&(data->timeNow), &utctime)) { + LOG_FATAL("failed to retrieve current date (buggy gmtime_r ?)\n"); + ret = LDAP_OPERATIONS_ERROR; + goto free_and_return; + } + strftime(timestr, GENERALIZED_TIME_LENGTH + 1, "%Y%m%d%H%M%SZ", &utctime); - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, + slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "krbLastPwdChange", timestr); - /* set Password Expiration date */ - if (!gmtime_r(&(data->expireTime), &utctime)) { - LOG_FATAL("failed to convert expiration date\n"); - ret = LDAP_OPERATIONS_ERROR; - goto free_and_return; - } - strftime(timestr, GENERALIZED_TIME_LENGTH + 1, + /* set Password Expiration date */ + if (!gmtime_r(&(data->expireTime), &utctime)) { + LOG_FATAL("failed to convert expiration date\n"); + ret = LDAP_OPERATIONS_ERROR; + goto free_and_return; + } + strftime(timestr, GENERALIZED_TIME_LENGTH + 1, "%Y%m%d%H%M%SZ", &utctime); - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, + slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "krbPasswordExpiration", timestr); - } + } + } if (lm) { slapi_mods_add_string(smods, LDAP_MOD_REPLACE, diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c index 2b1c7d1e3..caca0fc70 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c @@ -793,6 +793,7 @@ static int ipapwd_post_op(Slapi_PBlock *pb) char *errMsg = "Internal operations error\n"; struct ipapwd_krbcfg *krbcfg = NULL; char *principal = NULL; + Slapi_Value *ipahost; LOG_TRACE("=>\n"); @@ -828,26 +829,6 @@ static int ipapwd_post_op(Slapi_PBlock *pb) /* prepare changes that can be made only as root */ smods = slapi_mods_new(); - /* change Last Password Change field with the current date */ - if (!gmtime_r(&(pwdop->pwdata.timeNow), &utctime)) { - LOG_FATAL("failed to parse current date (buggy gmtime_r ?)\n"); - goto done; - } - strftime(timestr, GENERALIZED_TIME_LENGTH+1, - "%Y%m%d%H%M%SZ", &utctime); - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, - "krbLastPwdChange", timestr); - - /* set Password Expiration date */ - if (!gmtime_r(&(pwdop->pwdata.expireTime), &utctime)) { - LOG_FATAL("failed to parse expiration date (buggy gmtime_r ?)\n"); - goto done; - } - strftime(timestr, GENERALIZED_TIME_LENGTH+1, - "%Y%m%d%H%M%SZ", &utctime); - slapi_mods_add_string(smods, LDAP_MOD_REPLACE, - "krbPasswordExpiration", timestr); - /* This was a mod operation on an existing entry, make sure we also update * the password history based on the entry we saved from the pre-op */ if (IPAPWD_OP_MOD == pwdop->pwd_op) { @@ -869,6 +850,35 @@ static int ipapwd_post_op(Slapi_PBlock *pb) } } + /* set Password Expiration date */ + if (!gmtime_r(&(pwdop->pwdata.expireTime), &utctime)) { + LOG_FATAL("failed to parse expiration date (buggy gmtime_r ?)\n"); + goto done; + } + strftime(timestr, GENERALIZED_TIME_LENGTH+1, + "%Y%m%d%H%M%SZ", &utctime); + slapi_mods_add_string(smods, LDAP_MOD_REPLACE, + "krbPasswordExpiration", timestr); + + /* Don't set a last password change password on host passwords. This + * attribute is used to tell whether we have a valid keytab. If we + * set it on userPassword it confuses enrollment. + */ + ipahost = slapi_value_new_string("ipaHost"); + if (!pwdop->pwdata.target || (slapi_entry_attr_has_syntax_value(pwdop->pwdata.target, SLAPI_ATTR_OBJECTCLASS, ipahost)) == 0) { + /* change Last Password Change field with the current date */ + if (!gmtime_r(&(pwdop->pwdata.timeNow), &utctime)) { + LOG_FATAL("failed to parse current date (buggy gmtime_r ?)\n"); + slapi_value_free(&ipahost); + goto done; + } + strftime(timestr, GENERALIZED_TIME_LENGTH+1, + "%Y%m%d%H%M%SZ", &utctime); + slapi_mods_add_string(smods, LDAP_MOD_REPLACE, + "krbLastPwdChange", timestr); + } + slapi_value_free(&ipahost); + ret = ipapwd_apply_mods(pwdop->pwdata.dn, smods); if (ret) LOG("Failed to set additional password attributes in the post-op!\n"); -- cgit