svn rev #24003: trunk/ doc/ src/include/ src/plugins/kdb/db2/ src/plugins/kdb/ldap/libkdb_ldap/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon May 10 18:42:04 EDT 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=24003
Commit By: ghudson
Log Message:
ticket: 6719
subject: Add lockout-related performance tuning variables

The account lockout feature of krb5 1.8 came at a cost in database
accesses for principals requiring preauth, even if lockout is not
used.  Add dbmodules variables disable_last_success and
disable_lockout for the DB2 and LDAP back ends, allowing the admin to
recover the lost performance at the cost of new functionality.

(Unrelated documentation fix: document database_name as a DB2-specific
dbmodules variable instead of the realm variable it used to be.)



Changed Files:
U   trunk/doc/admin.texinfo
U   trunk/src/include/k5-int.h
U   trunk/src/plugins/kdb/db2/kdb_db2.c
U   trunk/src/plugins/kdb/db2/kdb_db2.h
U   trunk/src/plugins/kdb/db2/lockout.c
U   trunk/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
U   trunk/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
U   trunk/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
Modified: trunk/doc/admin.texinfo
===================================================================
--- trunk/doc/admin.texinfo	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/doc/admin.texinfo	2010-05-10 22:42:04 UTC (rev 24003)
@@ -1051,6 +1051,23 @@
 @itemx db_library
 This tag indicates the name of the loadable database library. The value should be @samp{db2} for DB2 database and @samp{kldap} for LDAP database.
 
+ at itemx database_name
+This DB2-specific tag indicates the location of the database.  The
+default is @* @code{@value{DefaultDatabaseName}}.
+
+ at itemx disable_last_success
+If set to @code{true}, suppresses KDC updates to the ``Last successful
+authentication'' field of principal entries requiring preauthentication.
+Setting this flag may improve performance.  (Principal entries which do
+not require preauthentication never update the ``Last successful
+authentication'' field.)
+
+ at itemx disable_lockout
+If set to @code{true}, suppresses KDC updates to the ``Last failed
+authentication'' and ``Failed password attempts'' fields of principal
+entries requiring preauthentication.  Setting this flag may improve
+performance, but also disables account lockout.
+
 @itemx ldap_kerberos_container_dn 
 This LDAP specific tag indicates the DN of the container object where the realm objects will be located.
 
@@ -1481,10 +1498,6 @@
 daemons @code{kadmind4} and @code{v5passwdd} use to authenticate to
 the database.  The default is @code{@value{DefaultAdminKeytab}}.
 
- at itemx database_name
-(String.)  Location of the Kerberos database for this realm.  The
-default is @* @code{@value{DefaultDatabaseName}}.
-
 @itemx default_principal_expiration
 (Absolute time string.)  Specifies the default expiration date of
 principals created in this realm.  The default value for this tag is

Modified: trunk/src/include/k5-int.h
===================================================================
--- trunk/src/include/k5-int.h	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/include/k5-int.h	2010-05-10 22:42:04 UTC (rev 24003)
@@ -203,6 +203,8 @@
 #define KRB5_CONF_DEFAULT_PRINCIPAL_EXPIRATION   "default_principal_expiration"
 #define KRB5_CONF_DEFAULT_PRINCIPAL_FLAGS        "default_principal_flags"
 #define KRB5_CONF_DICT_FILE                   "dict_file"
+#define KRB5_CONF_DISABLE_LAST_SUCCESS        "disable_last_success"
+#define KRB5_CONF_DISABLE_LOCKOUT             "disable_lockout"
 #define KRB5_CONF_DNS_LOOKUP_KDC              "dns_lookup_kdc"
 #define KRB5_CONF_DNS_LOOKUP_REALM            "dns_lookup_realm"
 #define KRB5_CONF_DNS_FALLBACK                "dns_fallback"

Modified: trunk/src/plugins/kdb/db2/kdb_db2.c
===================================================================
--- trunk/src/plugins/kdb/db2/kdb_db2.c	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/db2/kdb_db2.c	2010-05-10 22:42:04 UTC (rev 24003)
@@ -204,6 +204,7 @@
     krb5_db2_context *db_ctx;
     char **t_ptr, *opt = NULL, *val = NULL, *pval = NULL;
     profile_t profile = KRB5_DB_GET_PROFILE(context);
+    int bval;
 
     status = k5db2_init_context(context);
     if (status != 0)
@@ -252,6 +253,18 @@
         db_ctx->db_name = strdup(pval);
     }
 
+    status = profile_get_boolean(profile, KDB_MODULE_SECTION, conf_section,
+                                 KRB5_CONF_DISABLE_LAST_SUCCESS, FALSE, &bval);
+    if (status != 0)
+        goto cleanup;
+    db_ctx->disable_last_success = bval;
+
+    status = profile_get_boolean(profile, KDB_MODULE_SECTION, conf_section,
+                                 KRB5_CONF_DISABLE_LOCKOUT, FALSE, &bval);
+    if (status != 0)
+        goto cleanup;
+    db_ctx->disable_lockout = bval;
+
 cleanup:
     free(opt);
     free(val);

Modified: trunk/src/plugins/kdb/db2/kdb_db2.h
===================================================================
--- trunk/src/plugins/kdb/db2/kdb_db2.h	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/db2/kdb_db2.h	2010-05-10 22:42:04 UTC (rev 24003)
@@ -46,7 +46,9 @@
     krb5_keyblock      *db_master_key; /* Master key of database */
     krb5_keylist_node *db_master_key_list;  /* Master key list of database */
     osa_adb_policy_t    policy_db;
-    krb5_boolean tempdb;
+    krb5_boolean        tempdb;
+    krb5_boolean        disable_last_success;
+    krb5_boolean        disable_lockout;
 } krb5_db2_context;
 
 #define KRB5_DB2_MAX_RETRY 5

Modified: trunk/src/plugins/kdb/db2/lockout.c
===================================================================
--- trunk/src/plugins/kdb/db2/lockout.c	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/db2/lockout.c	2010-05-10 22:42:04 UTC (rev 24003)
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <kadm5/server_internal.h>
+#include "kdb5.h"
 #include "kdb_db2.h"
 
 /*
@@ -120,7 +121,11 @@
     krb5_kvno max_fail = 0;
     krb5_deltat failcnt_interval = 0;
     krb5_deltat lockout_duration = 0;
+    krb5_db2_context *db_ctx = context->dal_handle->db_context;
 
+    if (db_ctx->disable_lockout)
+        return 0;
+
     code = lookup_lockout_policy(context, entry, &max_fail,
                                  &failcnt_interval,
                                  &lockout_duration);
@@ -144,6 +149,8 @@
     krb5_deltat failcnt_interval = 0;
     krb5_deltat lockout_duration = 0;
     int nentries = 1;
+    krb5_db2_context *db_ctx = context->dal_handle->db_context;
+    krb5_boolean need_update = FALSE;
 
     switch (status) {
     case 0:
@@ -158,38 +165,43 @@
         return 0;
     }
 
-    code = lookup_lockout_policy(context, entry, &max_fail,
-                                 &failcnt_interval,
-                                 &lockout_duration);
-    if (code != 0)
-        return code;
+    if (!db_ctx->disable_lockout) {
+        code = lookup_lockout_policy(context, entry, &max_fail,
+                                     &failcnt_interval, &lockout_duration);
+        if (code != 0)
+            return code;
+    }
 
-    assert (!locked_check_p(context, stamp, max_fail, lockout_duration, entry));
-
+    /* Only mark the authentication as successful if the entry
+     * required preauthentication, otherwise we have no idea. */
     if (status == 0 && (entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH)) {
-        /*
-         * Only mark the authentication as successful if the entry
-         * required preauthentication, otherwise we have no idea.
-         */
-        entry->fail_auth_count = 0;
-        entry->last_success = stamp;
-    } else if (status == KRB5KDC_ERR_PREAUTH_FAILED ||
-               status == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+        if (!db_ctx->disable_lockout && entry->fail_auth_count != 0) {
+            entry->fail_auth_count = 0;
+            need_update = TRUE;
+        }
+        if (!db_ctx->disable_last_success) {
+            entry->last_success = stamp;
+            need_update = TRUE;
+        }
+    } else if (!db_ctx->disable_lockout &&
+               (status == KRB5KDC_ERR_PREAUTH_FAILED ||
+                status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
         if (failcnt_interval != 0 &&
             stamp > entry->last_failed + failcnt_interval) {
-            /* Reset fail_auth_count after failcnt_interval */
+            /* Reset fail_auth_count after failcnt_interval. */
             entry->fail_auth_count = 0;
         }
 
         entry->last_failed = stamp;
         entry->fail_auth_count++;
-    } else
-        return 0; /* nothing to do */
+        need_update = TRUE;
+    }
 
-    code = krb5_db2_db_put_principal(context, entry,
-                                     &nentries, NULL);
-    if (code != 0)
-        return code;
+    if (need_update) {
+        code = krb5_db2_db_put_principal(context, entry, &nentries, NULL);
+        if (code != 0)
+            return code;
+    }
 
     return 0;
 }

Modified: trunk/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
===================================================================
--- trunk/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h	2010-05-10 22:42:04 UTC (rev 24003)
@@ -223,6 +223,8 @@
     k5_mutex_t                    hndl_lock;
     krb5_ldap_krbcontainer_params *krbcontainer;
     krb5_ldap_realm_params        *lrparams;
+    krb5_boolean                  disable_last_success;
+    krb5_boolean                  disable_lockout;
     krb5_context                  kcontext;   /* to set the error code and message */
 } krb5_ldap_context;
 

Modified: trunk/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
===================================================================
--- trunk/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-05-10 22:42:04 UTC (rev 24003)
@@ -105,6 +105,37 @@
     return 0;
 }
 
+/* Get integer or string values from the config section, falling back
+   to the default section, then to hard-coded values.  */
+static errcode_t
+prof_get_boolean_def(krb5_context ctx, const char *conf_section,
+                     const char *name, krb5_boolean dfl, krb5_boolean *out)
+{
+    errcode_t err;
+    int out_temp = 0;
+
+    err = profile_get_boolean(ctx->profile, KDB_MODULE_SECTION, conf_section,
+                              name, -1, &out_temp);
+    if (err) {
+        krb5_set_error_message(ctx, err, "Error reading '%s' attribute: %s",
+                               name, error_message(err));
+        return err;
+    }
+    if (out_temp != -1) {
+        *out = out_temp;
+        return 0;
+    }
+    err = profile_get_boolean(ctx->profile, KDB_MODULE_DEF_SECTION, name, 0,
+                              dfl, &out_temp);
+    if (err) {
+        krb5_set_error_message(ctx, err, "Error reading '%s' attribute: %s",
+                               name, error_message(err));
+        return err;
+    }
+    *out = out_temp;
+    return 0;
+}
+
 /* We don't have non-null defaults in any of our calls, so don't
    bother with the extra argument.  */
 static errcode_t
@@ -309,6 +340,16 @@
         }
     }
 
+    if ((st = prof_get_boolean_def(context, conf_section,
+                                   KRB5_CONF_DISABLE_LAST_SUCCESS, FALSE,
+                                   &ldap_context->disable_last_success)))
+        goto cleanup;
+
+    if ((st = prof_get_boolean_def(context, conf_section,
+                                   KRB5_CONF_DISABLE_LOCKOUT, FALSE,
+                                   &ldap_context->disable_lockout)))
+        goto cleanup;
+
 cleanup:
     return(st);
 }

Modified: trunk/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
===================================================================
--- trunk/src/plugins/kdb/ldap/libkdb_ldap/lockout.c	2010-05-10 22:23:57 UTC (rev 24002)
+++ trunk/src/plugins/kdb/ldap/libkdb_ldap/lockout.c	2010-05-10 22:42:04 UTC (rev 24003)
@@ -113,10 +113,16 @@
                                krb5_timestamp stamp)
 {
     krb5_error_code code;
+    kdb5_dal_handle *dal_handle;
+    krb5_ldap_context *ldap_context;
     krb5_kvno max_fail = 0;
     krb5_deltat failcnt_interval = 0;
     krb5_deltat lockout_duration = 0;
 
+    SETUP_CONTEXT();
+    if (ldap_context->disable_lockout)
+        return 0;
+
     code = lookup_lockout_policy(context, entry, &max_fail,
                                  &failcnt_interval,
                                  &lockout_duration);
@@ -136,11 +142,15 @@
                         krb5_error_code status)
 {
     krb5_error_code code;
+    kdb5_dal_handle *dal_handle;
+    krb5_ldap_context *ldap_context;
     krb5_kvno max_fail = 0;
     krb5_deltat failcnt_interval = 0;
     krb5_deltat lockout_duration = 0;
     int nentries = 1;
 
+    SETUP_CONTEXT();
+
     switch (status) {
     case 0:
     case KRB5KDC_ERR_PREAUTH_FAILED:
@@ -150,26 +160,32 @@
         return 0;
     }
 
-    code = lookup_lockout_policy(context, entry, &max_fail,
-                                 &failcnt_interval,
-                                 &lockout_duration);
-    if (code != 0)
-        return code;
+    if (!ldap_context->disable_lockout) {
+        code = lookup_lockout_policy(context, entry, &max_fail,
+                                     &failcnt_interval,
+                                     &lockout_duration);
+        if (code != 0)
+            return code;
+    }
 
     entry->mask = 0;
 
     assert (!locked_check_p(context, stamp, max_fail, lockout_duration, entry));
 
+    /* Only mark the authentication as successful if the entry
+     * required preauthentication, otherwise we have no idea. */
     if (status == 0 && (entry->attributes & KRB5_KDB_REQUIRES_PRE_AUTH)) {
-        /*
-         * Only mark the authentication as successful if the entry
-         * required preauthentication, otherwise we have no idea.
-         */
-        entry->fail_auth_count = 0;
-        entry->last_success = stamp;
-        entry->mask |= KADM5_FAIL_AUTH_COUNT | KADM5_LAST_SUCCESS;
-    } else if (status == KRB5KDC_ERR_PREAUTH_FAILED ||
-               status == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+        if (!ldap_context->disable_lockout && entry->fail_auth_count != 0) {
+            entry->fail_auth_count = 0;
+            entry->mask |= KADM5_FAIL_AUTH_COUNT;
+        }
+        if (!ldap_context->disable_last_success) {
+            entry->last_success = stamp;
+            entry->mask |= KADM5_LAST_SUCCESS;
+        }
+    } else if (!ldap_context->disable_lockout &&
+               (status == KRB5KDC_ERR_PREAUTH_FAILED ||
+                status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
         if (failcnt_interval != 0 &&
             stamp > entry->last_failed + failcnt_interval) {
             /* Reset fail_auth_count after failcnt_interval */
@@ -182,8 +198,7 @@
     }
 
     if (entry->mask) {
-        code = krb5_ldap_put_principal(context, entry,
-                                       &nentries, NULL);
+        code = krb5_ldap_put_principal(context, entry, &nentries, NULL);
         if (code != 0)
             return code;
     }




More information about the cvs-krb5 mailing list