logo_kerberos.gif

Difference between revisions of "Projects/Policy refcount elimination"

From K5Wiki
Jump to: navigation, search
(Code changes)
m (Testing)
Line 69: Line 69:
   
 
* Creation of a principal with a nonexistent policy
 
* Creation of a principal with a nonexistent policy
* Modification of a principal to reflect a nonexistent policy
+
* Modification of a principal to refer to a nonexistent policy
 
* Deleting a policy referenced by a principal
 
* Deleting a policy referenced by a principal
 
* Fetching a principal (with getprinc) referencing a nonexistent policy
 
* Fetching a principal (with getprinc) referencing a nonexistent policy

Revision as of 19:34, 8 January 2013

This project is targeted at release 1.12.

An announcement has been sent to krbdev@mit.edu starting a review of this project. That review will conclude on 2012-01-14.

Comments can be sent to krbdev@mit.edu.


This project corresponds to [krbdev.mit.edu #7385], which proposes to eliminate the use of the policy reference count field.

Background

Policy objects in the Kerberos database contain a policy_refcnt field, which is intended to reflect the number of principals associated with that policy. libkadm5srv maintains the policy_refcnt field in its principal operations (so modifying a principal can also result in modifying its old or new policy reference), and refuses to delete a policy with a non-zero policy_refcnt value.

The policy reference count field creates a number of problems:

  • If the database is modified by any agent other than kadmin (e.g. through LDAP operations for an LDAP KDB, or through an application using libkdb5 for any type of KDB), the policy field may not be maintained.
  • The LDAP KDB schema does not contain a field for the policy reference count, presumably out of concern that it might become out of date. Instead, prior to [krbdev.mit.edu #6799], every policy fetch operation performed a search for all principals referencing the policy. This created a terrible performance problem--especially since fetching a principal currently requires fetching its associated policy object. After [krbdev.mit.edu #6799], LDAP populates the refcnt_policy field with 0 and checks for references from principals when deleting a policy, but this creates a layering inconsistency between the LDAP KDB and other KDB types.
  • Historically, there have been bugs such as [krbdev.mit.edu #7384] allowing policy reference counts to become out of sync on slaves, and there are probably still bugs of that nature. If a slave is promoted to a master with inconsistent reference counts, the new master could incorrectly forbid or allow a policy deletion operation.
  • [krbdev.mit.edu #7522] proposes to propagate policy changes over iprop (which currently has no way to marshal them) by forcing a full propagation whenever a policy changes. Frequent changes to policy reference counts would render this prohibitively expensive. Ignoring policy changes which only change the policy_refcnt field would allow reference count fields to become inconsistent on slaves.
  • Policy deletion is a rare operation. Fundamentally, it does not make sense to impose an extra burden on principal modifications for the sake of such a rare operation.

Alternatives for policy deletion

Here are four options for handling policy deletion without using the reference count:

1. Disallow policy deletion altogether. A typical KDB does not have many policy objects, so the total space occupied by policies is quite small, and there is no efficiency reason to delete them. However, administrators might find it annoying not to be able to delete a policy name which contains a typo.

2. At deletion time, iterate over all principals. If any principals reference the policy, disallow the deletion.

3. At deletion time, iterate over all principals. If any principals reference the policy, null out their policy references.

4. Delete the policy even though it might be referenced by principals. If a principals references a nonexistent policy, treat it as if the principal had no policy reference. If a policy with the same name is recreated, principals referencing that policy name will become associated with the new policy. Put another way, principals could be thought of as referencing policy names (which might or might not exist as policy objects), rather than directly referencing policy objects.

This project proposes to implement option #4.

Code changes

The following units of code are affected by this project:

  • kadm5_policy_ent_rec, osa_policy_ent_rec: add comments indicating that policy_refcnt is no longer maintained or used.
  • kadm5_create_principal_3, kadm5_modify_principal, kadm5_delete_principal: stop maintaining policy_refcnt fields of policies referenced by the old or new principal entries. Stop returning an error if the new principal entry references a nonexistent policy (also in apply_keysalt_policy).
  • kadm5_chpass_principal_3, kadm5_randkey_principal_3, kadm5_setv4key_principal, kadm5_setkey_principal_3: Stop erroring out if the entry references a nonexistent policy.
  • kadm5_create_policy_internal, kadm5_modify_policy_internal: stop checking mask & KADM5_REF_COUNT and setting pent.policy_refcnt. These functions can be folded into their callers (kadm5_create_policy and kadm5_modify_policy respectively).
  • kadm5_delete_policy: stop checking policy_refcnt.
  • kadm5_get_policy: set entry->policy_refcnt to 0 instead of propagating it from the KDB entry.
  • dump_k5beta7_policy, dump_r1_8_policy, dump_r1_11_policy: dump 0 instead of the policy_refcnt value from entry.
  • process_k5beta7_policy, process_r1_8_policy, process_r1_11_policy: ignore the policy_refcnt values read from the dump instead of storing them into the entry.
  • kadmin_addprinc, kadmin_modprinc: If the principal's policy reference is being set, check if the policy exists and warn if it does not.
  • kadmin_getpol: Don't output policy_refcnt in long-form output. In terse output, always output 0.
  • populate_krb5_db_entry (in LDAP KDB module): don't return an error if the entry's policy cannot be found.
  • krb5_ldap_delete_password_policy: stop checking the reference count.

Testing

The kadm5 dejagnu test suite will need to be modified to allow the new semantics. t_kdb.py may need adjusting as well.

The two Python scripts t_lockout.py and t_pwhist.py will be consolidated into a new script t_policy.py. In addition to the current lockout and password history tests, this new script will test:

  • Creation of a principal with a nonexistent policy
  • Modification of a principal to refer to a nonexistent policy
  • Deleting a policy referenced by a principal
  • Fetching a principal (with getprinc) referencing a nonexistent policy
  • Authenticating (with preauth) against a principal referencing a nonexistent policy
  • Creating the policy (formerly nonexistent) referenced by a principal, and checking that it is now enforced

Release notes

Administrator experience:

  • Principal entries may now refer to the names of policies which do not exist as policy objects in the database. Policy objects may now be deleted whether or not principals reference their names. A principal which references a nonexistent policy name will behave as if it does not reference a policy.