Performance issue in LDAP policy fetch
authorGreg Hudson <ghudson@mit.edu>
Thu, 7 Oct 2010 17:49:44 +0000 (17:49 +0000)
committerGreg Hudson <ghudson@mit.edu>
Thu, 7 Oct 2010 17:49:44 +0000 (17:49 +0000)
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
src/lib/krb5/error_tables/kdb5_err.et
src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c

index 65f5db1644720d0e1812b5a8e54e3968418db4f4..046a07725da781ac1857f3d49e3d556a2074d19c 100644 (file)
@@ -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
index f6b97dc9d8e5fb75e2c436addba2dad514d383dd..6fb19d031d77779da5cd6dd301359b0bbc4f5230 100644 (file)
@@ -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
index d58fbe965761b815ae22762311d7c58af2d5998d..0d76453839e28c1765d52bcc539bf600ce1b9b79 100644 (file)
@@ -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;