On 02/12/2013 05:50 PM, Tomas Babej wrote:
Hi,

This patch 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_INVALID_CREDENTIALS 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

Tomas


_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

I just self-reviewed the patch and noticed a memory leak. It's fixed now.

Updated patch attached.

Tomas
>From 8aa0184ba27d1725c03ed841c4a2b632dc2a74e1 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Mon, 11 Feb 2013 15:33:12 +0100
Subject: [PATCH] Deny LDAP binds for user accounts with expired principal

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_INVALID_CREDENTIALS 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
---
 .../ipa-pwd-extop/ipapwd_prepost.c                 | 38 +++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

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 3b512a4744d3edddc52e224c11aaa93388d06b75..1aea308758d3ba8a175b4c29321fc88580877d7c 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
@@ -1123,16 +1123,23 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
     Slapi_Value *value = NULL;
     Slapi_Attr *attr = NULL;
     struct tm expire_tm;
+    time_t current_time;
+    time_t expire_time;
     char *errMesg = "Internal operations error\n"; /* error message */
     char *expire = NULL; /* passwordExpirationTime attribute value */
+    char *principal_expire = NULL; /* krbPrincipalExpiration attribute value */
     char *dn = NULL; /* bind DN */
     Slapi_Value *objectclass;
     int method; /* authentication method */
     int ret = 0;
     char *principal = NULL;
+    bool auth_failed = false;
 
     LOG_TRACE("=>\n");
 
+    /* get current time*/
+    current_time = time(NULL);
+
     /* get BIND parameters */
     ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET, &dn);
     ret |= slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method);
@@ -1150,7 +1157,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
     const char *attrs_list[] = {SLAPI_USERPWD_ATTR, "krbprincipalkey", "uid",
                                 "krbprincipalname", "objectclass",
                                 "passwordexpirationtime",  "passwordhistory",
-                                NULL};
+                                "krbprincipalexpiration", NULL};
 
     /* retrieve user entry */
     ret = ipapwd_getEntry(dn, &entry, (char **) attrs_list);
@@ -1166,6 +1173,29 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
         goto done;
     }
 
+    /* check the krbPrincipalExpiration attribute is present */
+    ret = slapi_entry_attr_find(entry, "krbPrincipalExpiration", &attr);
+    if (!ret) {
+        /* if it is, check whether the principal has not expired */
+
+        principal_expire = slapi_entry_attr_get_charptr(entry,
+                               "krbprincipalexpiration");
+        memset(&expire_tm, 0, sizeof (expire_tm));
+
+        if (strptime(principal_expire, "%Y%m%d%H%M%SZ", &expire_tm)){
+            expire_time = mktime(&expire_tm);
+            /* this might have overflown on 32-bit system */
+
+            if (current_time > expire_time && expire_time > 0){
+                LOG_FATAL("kerberos principal has expired in user entry: %s\n",
+                          dn);
+                errMesg = "Kerberos principal has expired.";
+                auth_failed = true;
+                goto done;
+                }
+            }
+    }
+
     /* we aren't interested in host principals */
     objectclass = slapi_value_new_string("ipaHost");
     if ((slapi_entry_attr_has_syntax_value(entry, SLAPI_ATTR_OBJECTCLASS, objectclass)) == 1) {
@@ -1284,10 +1314,16 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
 done:
     slapi_ch_free_string(&principal);
     slapi_ch_free_string(&expire);
+    slapi_ch_free_string(&principal_expire);
     if (entry)
         slapi_entry_free(entry);
     free_ipapwd_krbcfg(&krbcfg);
 
+    if (auth_failed){
+        slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, errMesg,
+                               0, NULL);
+    }
+
     return 0;
 }
 
-- 
1.8.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to