Projects/Local authorization pluggable interface
Contents
Description
This project adds a pluggable interface to affect the behavior of the krb5_kuserok() and krb5_aname_to_localname() functions.
Background
The krb5_aname_to_localname() function attempts to convert a krb5 principal name into a local account name according to policy. The default behavior maps single-component principals within the default realm to their values without realm (e.g. ghudson@ATHENA.MIT.EDU to ghudson, if ATHENA.MIT.EDU is the default realm). Its behavior can be modified through profile configuration as outlined below:
[realms] DEFREALMNAME = { auth_to_local_names = { princname = localname } auth_to_local = RULE:[selstring](regexp)s/pattern/replacement/ auth_to_local = DEFAULT }
The krb5_kuserok() function decides whether a principal name is authorized to control a particular local account name. The current implementation looks for a .k5login file in the local account's home directory and searches it for the principal name; if no .k5login file exists, authorization succeeds if krb5_aname_to_localname maps the principal name to the local account name.
Proposal
Since both operations are about the relationship of krb5 principals to local accounts, a single pluggable interface allows modules to affect either operation or both of them.
The pluggable interface will have three methods (plus initialization and finalization methods):
krb5_error_code (*userok)(krb5_context context, krb5_localauth_moddata data, krb5_const_principal aname, const char *lname); const char **an2ln_types; krb5_error_code (*an2ln)(krb5_context context, krb5_localauth_moddata data, const char *type, const char *residual, krb5_const_principal aname, char **lname_out); void (*free_string)(krb5_context context, krb5_localauth_moddata data, char *str);
The userok method is optional. If it is implemented, it will be invoked for krb5_kuserok operations. It should return 0 if authorization is allowed, EPERM if authorization is authoritatively denied, KRB5_PLUGIN_NO_HANDLE if the module cannot determine whether authorization is allowed, and any other error code on a serious failure. krb5_kuserok will return true if at least one module returns success and all other modules return success or KRB5_PLUGIN_NO_HANDLE. If any module returns EPERM or another error, remaining modules will be skipped and krb5_kuserok will return false.
an2ln_types is optional. If it is set, it contains a null-terminated array of uppercase string constants which act as type names. As krb5_aname_to_localname processes the auth_to_local values in the profile, any values with type strings matching a string in an2ln_types will result in calls to the an2ln method, with the residual string (or NULL if there is none) as an argument. The method should return 0 and set *lname_out if it can translate the principal, KRB5_LNAME_NOTRANS if it cannot, and any other error code on a serious failure. The an2ln method will be invoked multiple times if multiple auth_to_local values reference its types, if it returns KRB5_LNAME_NOTRANS on prior invocations.
If an2ln types is not set, but the an2ln method is implemented, the module's an2ln method will be consulted for all krb5_aname_to_localname operations, with type and residual set to NULL.
The free_string method will be used to return any local names returned by the an2ln methods. It is mandatory if an2ln is implemented.
Module registration will fail (with a trace log message, but without disabling all kuserok or an2ln library operations) if it tries to register an already-registered an2ln_types value.
Rationale
We expect two different kinds of aname-to-lname modules:
- A module which implements a parameterized operation for auth_to_local processing, such as database support or an augmented version of rule processing. An administrator might register multiple modules of this type, and might invoke a module multiple times with different parameters. A module of this type would set one or more an2ln_types values.
- A module which wants to delegate all aname-to-lname processing to another system facility such as sssd. Most likely it would be unnecessary to register more than one module of this type, but the interface leaves open the possibility for a module to override only a segment of the principal namespace and return KRB5_LNAME_NOTRANS for other principals. A module of this type would leave an2ln_types as NULL.
Testing
A test module will be added to plugins/localauth, to be built by default but not installed. A test harness and script will use the module to exercise the pluggable interface.
Documentation
A new page under doc/plugindev will document the pluggable interface. krb5_conf.rst will be amended to briefly describe the interface.
Mailing list discussions
- http://mailman.mit.edu/pipermail/krbdev/2013-January/011414.html
- http://mailman.mit.edu/pipermail/krbdev/2013-February/011421.html
Commits
4216fb5b0e0abb80a3ccd8251abddc18435d81f3 Add localauth pluggable interface b8696b1ed70ffebbeee7142f1e5e086d75ce4e30 Add tests for localauth interface 4aec0626fffea5d7e060979c2a4dc9555beae96a Document localauth interface ec217570e20d4702be2830235bad56184d47b1d2 Remove stray include in localauth_plugin.h
Release notes
Developer experience:
- Add a plugin interface to control krb5_aname_to_localname and krb5_kuserok behavior.