Contents

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).

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.