Projects/Kadmin hook interface

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

Comments can be sent to krbdev@mit.edu.

The Kadm5 hook interface provides a plugin interface for plugins to be aware of administrative operations for kadm5 principals.
Plugins track the following administrative operations:

Principal creation

Change password

Principal modification

The plugins are called twice: once in a precommit phase before the operation takes place and if no plugins fail and the database is updated, once in a postcommit operation.
This interface is based on a proposed patch to Heimdal by Russ Allbery for the krb5-sync plugin. Russ indicated that Heimdal is likely to adopt an approach based on stackable database plugins rather than his approach. That's probably undesirable for MIT because the kadm5 API is more stable than the KDB API and because this interface is easier for plugin authors than writing a KDB module. This interface has the following changes from Russ's interface:

Opaque struct rather than void * for the module context

Include key-salt tuples for create/chpass

Add a remove entry point

Remove name and vendor entries to be consistent with other plugin framework uses

Plugin header

/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* include/krb5/kadm5_hook_plugin.h
*/
/*
* Copyright (C) 2010 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
#ifndef H_KRB5_KADM5_HOOK_PLUGIN
#define H_KRB5_KADM5_HOOK_PLUGIN
/**
* @file krb5/krb5_kadm5_hook_plugin.h
* Provide a plugin interface for kadm5 operations. This interface
* permits a plugin to intercept principal modification, creation and
* change password operations. Operations run at two stages: a
* precommit stage that runs before the operation is committed to the
* database and a postcommit operation that runs after the database
* is updated.
*
* This interface is based on a proposed extension to Heimdal by Russ
* Allbery; it is likely that Heimdal will adopt an approach based on
* stacked kdb modules rather than this interface. For MIT, writing a
* plugin to this interface is significantly easier than stacking kdb
* modules. Also, the kadm5 interface is significantly more stable
* than the kdb interface, so this approach is more desirable than
* stacked kdb modules.
*
* This interface depends on kadm5/admin.h. As such, the interface
* does not provide strong guarantees of ABI stability.
*/
#include <krb5/krb5.h>
#include <krb5/plugin.h>
#include <kadm5/admin.h>
/**
* Whether the operation is being run before or after the database
* update
*/
enum kadm5_hook_stage {
KADM5_HOOK_STAGE_PRECOMMIT,
KADM5_HOOK_STAGE_POSTCOMMIT
};
/** Opaque module data pointer*/
typedef struct kadm5_hook_modinfo_st kadm5_hook_modinfo;
/**
* Interface for the v1 virtual table for the kadm5_hook plugin
*/
typedef struct kadm5_hook_vtable_1_st {
/** Initialize a plugin module
* @param modinfo returns newly allocated module info for future
* calls. Cleaned up by the fini() function.
*/
kadm5_ret_t (*init)(krb5_context, kadm5_hook_modinfo **modinfo);
/** Clean up a module and free @a modinfo*/
void (*fini)(krb5_context, kadm5_hook_modinfo *modinfo);
/** Indicates that the password is being changed.
* @param stage is an integer from #kadm5_hook_stage enumeration
* */
kadm5_ret_t (*chpass)(krb5_context,
kadm5_hook_modinfo *modinfo,
int stage,
krb5_principal,
int n_ks_tuple,
krb5_key_salt_tuple *ks_tuple,
const char *newpass);
/** Indicate a principal is created*/
kadm5_ret_t (*create)(krb5_context,
kadm5_hook_modinfo *,
int stage,
kadm5_principal_ent_t, long mask,
int n_ks_tuple,
krb5_key_salt_tuple *ks_tuple,
const char *password);
/** Modify a principal*/
kadm5_ret_t (*modify)(krb5_context,
kadm5_hook_modinfo *,
int stage,
kadm5_principal_ent_t, long mask);
/** Indicate a principal is deleted*/
kadm5_ret_t (* remove) (krb5_context,
kadm5_hook_modinfo *modinfo,
int stage, krb5_principal
);
/*End of minor version 1*/
}kadm5_hook_vftable_1;
#endif /*H_KRB5_KADM5_HOOK_PLUGIN*/