From 5a28daefe46c1592936115a7b6c9c9b97957b148 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Thu, 7 Oct 2010 17:49:44 +0000 Subject: [PATCH] Performance issue in LDAP policy fetch Instead of performing a tree search to fill in the refcnt field of a policy object whenever a policy is fetched, set the refcnt to 0 and perform a check when policies are deleted. ticket: 6799 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24440 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/kadm5/srv/svr_policy.c | 8 ++++---- src/lib/krb5/error_tables/kdb5_err.et | 1 + .../kdb/ldap/libkdb_ldap/ldap_pwd_policy.c | 20 +++++++++++++------ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/lib/kadm5/srv/svr_policy.c b/src/lib/kadm5/srv/svr_policy.c index 65f5db164..046a07725 100644 --- a/src/lib/kadm5/srv/svr_policy.c +++ b/src/lib/kadm5/srv/svr_policy.c @@ -193,10 +193,10 @@ kadm5_delete_policy(void *server_handle, kadm5_policy_t name) return KADM5_POLICY_REF; } krb5_db_free_policy(handle->context, entry); - if ((ret = krb5_db_delete_policy(handle->context, name))) - return ret; - else - return KADM5_OK; + ret = krb5_db_delete_policy(handle->context, name); + if (ret == KRB5_KDB_POLICY_REF) + ret = KADM5_POLICY_REF; + return (ret == 0) ? KADM5_OK : ret; } kadm5_ret_t diff --git a/src/lib/krb5/error_tables/kdb5_err.et b/src/lib/krb5/error_tables/kdb5_err.et index f6b97dc9d..6fb19d031 100644 --- a/src/lib/krb5/error_tables/kdb5_err.et +++ b/src/lib/krb5/error_tables/kdb5_err.et @@ -83,5 +83,6 @@ ec KRB5_LOG_UNSTABLE, "Update log is unstable" ec KRB5_LOG_CORRUPT, "Update log is corrupt" ec KRB5_LOG_ERROR, "Generic update log error" ec KRB5_KDB_DBTYPE_MISMATCH, "Database module does not match KDC version" +ec KRB5_KDB_POLICY_REF, "Policy is in use" end diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c index d58fbe965..0d7645383 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c @@ -214,11 +214,12 @@ populate_policy(krb5_context context, krb5_ldap_get_value(ld, ent, "krbpwdfailurecountinterval", &(pol_entry->pw_failcnt_interval)); krb5_ldap_get_value(ld, ent, "krbpwdlockoutduration", &(pol_entry->pw_lockout_duration)); - /* Get the reference count */ - pol_dn = ldap_get_dn(ld, ent); - st = krb5_ldap_get_reference_count (context, pol_dn, "krbPwdPolicyReference", - &(pol_entry->policy_refcnt), ld); - ldap_memfree(pol_dn); + /* + * We don't store the policy refcnt, because principals might be maintained + * outside of kadmin. Instead, we will check for principal references when + * policies are deleted. + */ + pol_entry->policy_refcnt = 0; cleanup: return st; @@ -329,7 +330,7 @@ cleanup: krb5_error_code krb5_ldap_delete_password_policy(krb5_context context, char *policy) { - int mask = 0; + int mask = 0, refcount; char *policy_dn = NULL, *class[] = {"krbpwdpolicy", NULL}; krb5_error_code st=0; LDAP *ld=NULL; @@ -351,6 +352,13 @@ krb5_ldap_delete_password_policy(krb5_context context, char *policy) if (st != 0) goto cleanup; + st = krb5_ldap_get_reference_count(context, policy_dn, + "krbPwdPolicyReference", &refcount, ld); + if (st == 0 && refcount != 0) + st = KRB5_KDB_POLICY_REF; + if (st != 0) + goto cleanup; + /* Ensure that the object is a password policy */ if ((st=checkattributevalue(ld, policy_dn, "objectclass", class, &mask)) != 0) goto cleanup; -- 2.26.2