With the transition to ipa-kdb and krb5 1.10 policy cheks were missing
as they are implemented at the driver level.

This patch adds policy checks back.

Fixes https://fedorahosted.org/freeipa/ticket/2393

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 3a89f43f03f73d05ec6b69764807d67643296271 Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Fri, 17 Feb 2012 11:45:56 -0500
Subject: [PATCH] policy: add function to check lockout policy

Fixes: https://fedorahosted.org/freeipa/ticket/2393
---
 daemons/ipa-kdb/ipa_kdb.c           |    2 +-
 daemons/ipa-kdb/ipa_kdb.h           |    8 +++++
 daemons/ipa-kdb/ipa_kdb_pwdpolicy.c |   53 +++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
index 1dae4e6c1824c7936b0359d71dad809aed668d04..ed87d6fef246ca4566ba87af40d2e41fd20f757f 100644
--- a/daemons/ipa-kdb/ipa_kdb.c
+++ b/daemons/ipa-kdb/ipa_kdb.c
@@ -454,7 +454,7 @@ kdb_vftabl kdb_function_table = {
     NULL,                               /* encrypt_key_data */
     ipadb_sign_authdata,                /* sign_authdata */
     NULL,                               /* check_transited_realms */
-    NULL,                               /* check_policy_as */
+    ipadb_check_policy_as,              /* check_policy_as */
     NULL,                               /* check_policy_tgs */
     ipadb_audit_as_req,                 /* audit_as_req */
     NULL,                               /* refresh_config */
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 22e28223c2c9c178c0041512a9d8b5621f590441..996d8448b091f0c37c28eedad31c4f310ad9dccb 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -185,6 +185,14 @@ krb5_error_code ipadb_delete_pwd_policy(krb5_context kcontext,
                                         char *policy);
 void ipadb_free_pwd_policy(krb5_context kcontext, osa_policy_ent_t val);
 
+krb5_error_code ipadb_check_policy_as(krb5_context kcontext,
+                                      krb5_kdc_req *request,
+                                      krb5_db_entry *client,
+                                      krb5_db_entry *server,
+                                      krb5_timestamp kdc_time,
+                                      const char **status,
+                                      krb5_pa_data ***e_data);
+
 /* MASTER KEY FUNCTIONS */
 krb5_error_code ipadb_fetch_master_key(krb5_context kcontext,
                                        krb5_principal mname,
diff --git a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
index 03948029f1c69d9c554b6ca7a50f581f9ef374c7..91de0342bb0e7e57b188a40642c06127549c33fb 100644
--- a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
+++ b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
@@ -275,3 +275,56 @@ void ipadb_free_pwd_policy(krb5_context kcontext, osa_policy_ent_t val)
     }
 }
 
+krb5_error_code ipadb_check_policy_as(krb5_context kcontext,
+                                      krb5_kdc_req *request,
+                                      krb5_db_entry *client,
+                                      krb5_db_entry *server,
+                                      krb5_timestamp kdc_time,
+                                      const char **status,
+                                      krb5_pa_data ***e_data)
+{
+    struct ipadb_context *ipactx;
+    struct ipadb_e_data *ied;
+    krb5_error_code kerr;
+
+    if (!client) {
+        return ENOENT;
+    }
+
+    ipactx = ipadb_get_context(kcontext);
+    if (!ipactx) {
+        return EINVAL;
+    }
+
+    ied = (struct ipadb_e_data *)client->e_data;
+    if (!ied) {
+        return EINVAL;
+    }
+
+    if (!ied->pol) {
+        kerr = ipadb_get_ipapwd_policy(ipactx, ied->pw_policy_dn, &ied->pol);
+        if (kerr != 0) {
+            return kerr;
+        }
+    }
+
+    if (client->last_failed <= ied->last_admin_unlock) {
+        /* admin unlocked the account */
+        return 0;
+    }
+
+    if (ied->pol->max_fail == 0 ||
+        client->fail_auth_count < ied->pol->max_fail) {
+        /* still within allowed failures range */
+        return 0;
+    }
+
+    if (ied->pol->lockout_duration == 0 ||
+        client->last_failed + ied->pol->lockout_duration > kdc_time) {
+        /* ok client permanently locked, or within lockout period */
+        *status = "LOCKED_OUT";
+        return KRB5KDC_ERR_CLIENT_REVOKED;
+    }
+
+    return 0;
+}
-- 
1.7.7.6

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

Reply via email to