From 5d78cdf80951748f5f954a69c41a2a2cb1b84812 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Tue, 1 Apr 2014 12:41:16 +0200 Subject: ipa-pwd-extop: Deny LDAP binds for accounts with expired principals Adds a check for krbprincipalexpiration attribute to pre_bind operation in ipa-pwd-extop dirsrv plugin. If the principal is expired, auth is denied and LDAP_UNWILLING_TO_PERFORM along with the error message is sent back to the client. Since krbprincipalexpiration attribute is not mandatory, if there is no value set, the check is passed. https://fedorahosted.org/freeipa/ticket/3305 Reviewed-By: Simo Sorce Reviewed-By: Alexander Bokovoy --- daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'daemons') diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c index def312ca8..23c7cb18c 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c @@ -1381,7 +1381,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) static const char *attrs_list[] = { SLAPI_USERPWD_ATTR, "ipaUserAuthType", "krbprincipalkey", "uid", "krbprincipalname", "objectclass", "passwordexpirationtime", - "passwordhistory", + "passwordhistory", "krbprincipalexpiration", NULL }; struct berval *credentials = NULL; @@ -1390,6 +1390,10 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) int method = 0; bool syncreq; int ret = 0; + time_t current_time; + time_t expire_time; + char *principal_expire = NULL; + struct tm expire_tm; /* get BIND parameters */ ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET, &dn); @@ -1411,6 +1415,35 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) return 0; } + /* Check if the principal is not expired */ + principal_expire = slapi_entry_attr_get_charptr(entry, "krbPrincipalExpiration"); + + if (principal_expire) { + /* if it is set, check whether the principal has not expired */ + memset(&expire_tm, 0, sizeof (expire_tm)); + + if (strptime(principal_expire, "%Y%m%d%H%M%SZ", &expire_tm)) { + expire_time = mktime(&expire_tm); + current_time = time(NULL); + + /* mktime returns -1 if the tm struct cannot be represented as + * as calendar time (seconds since the Epoch). This might + * happen with tm structs that are ill-formated or on 32-bit + * platforms with dates that would cause overflow + * (year 2038 and later). + * In such cases, skip the expiration check. */ + + if (current_time > expire_time && expire_time > 0) { + LOG_FATAL("kerberos principal in %s is expired\n", dn); + slapi_entry_free(entry); + slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, + "Account (Kerberos principal) is expired", + 0, NULL); + return -1; + } + } + } + /* Try to do OTP first. */ syncreq = sync_request_present(pb); if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials)) { -- cgit