summaryrefslogtreecommitdiffstats
path: root/src/plugins/kdb
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-05-10 22:42:04 +0000
committerGreg Hudson <ghudson@mit.edu>2010-05-10 22:42:04 +0000
commit6eacb6d5f29da306ea605a5efb00c0d01c3182b1 (patch)
tree8b37e7da4e702e962560823515da5a744c5edf7c /src/plugins/kdb
parentf795c92a96a2a559fe01fc5906d488167ab6b4b9 (diff)
downloadkrb5-6eacb6d5f29da306ea605a5efb00c0d01c3182b1.tar.gz
krb5-6eacb6d5f29da306ea605a5efb00c0d01c3182b1.tar.xz
krb5-6eacb6d5f29da306ea605a5efb00c0d01c3182b1.zip
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.) ticket: 6719 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24003 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/plugins/kdb')
-rw-r--r--src/plugins/kdb/db2/kdb_db2.c13
-rw-r--r--src/plugins/kdb/db2/kdb_db2.h4
-rw-r--r--src/plugins/kdb/db2/lockout.c56
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h2
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c41
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/lockout.c47
6 files changed, 124 insertions, 39 deletions
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
index 713ed7aac8..9c73c12dbc 100644
--- a/src/plugins/kdb/db2/kdb_db2.c
+++ b/src/plugins/kdb/db2/kdb_db2.c
@@ -204,6 +204,7 @@ configure_context(krb5_context context, char *conf_section, char **db_args)
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 @@ configure_context(krb5_context context, char *conf_section, char **db_args)
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);
diff --git a/src/plugins/kdb/db2/kdb_db2.h b/src/plugins/kdb/db2/kdb_db2.h
index 45958ee02c..7b4fcf405b 100644
--- a/src/plugins/kdb/db2/kdb_db2.h
+++ b/src/plugins/kdb/db2/kdb_db2.h
@@ -46,7 +46,9 @@ typedef struct _krb5_db2_context {
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
diff --git a/src/plugins/kdb/db2/lockout.c b/src/plugins/kdb/db2/lockout.c
index 498c0dea62..ec22dce738 100644
--- a/src/plugins/kdb/db2/lockout.c
+++ b/src/plugins/kdb/db2/lockout.c
@@ -33,6 +33,7 @@
#include <stdio.h>
#include <errno.h>
#include <kadm5/server_internal.h>
+#include "kdb5.h"
#include "kdb_db2.h"
/*
@@ -120,6 +121,10 @@ krb5_db2_lockout_check_policy(krb5_context context,
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,
@@ -144,6 +149,8 @@ krb5_db2_lockout_audit(krb5_context context,
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 @@ krb5_db2_lockout_audit(krb5_context context,
return 0;
}
- 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));
+ if (!db_ctx->disable_lockout) {
+ code = lookup_lockout_policy(context, entry, &max_fail,
+ &failcnt_interval, &lockout_duration);
+ if (code != 0)
+ return code;
+ }
+ /* 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;
}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
index 2130f8bc0a..95909f6beb 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
+++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
@@ -223,6 +223,8 @@ typedef struct _krb5_ldap_context {
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;
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index 65ae887345..c3cb185d0e 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -105,6 +105,37 @@ prof_get_integer_def(krb5_context ctx, const char *conf_section,
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 @@ krb5_ldap_read_server_params(krb5_context context, char *conf_section,
}
}
+ 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);
}
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
index 020c77a945..323963e8dd 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
@@ -113,10 +113,16 @@ krb5_ldap_lockout_check_policy(krb5_context context,
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_ldap_lockout_audit(krb5_context context,
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 @@ krb5_ldap_lockout_audit(krb5_context context,
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 @@ krb5_ldap_lockout_audit(krb5_context context,
}
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;
}