summaryrefslogtreecommitdiff
path: root/src/lib/kadm5/srv/kadm5_hook.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kadm5/srv/kadm5_hook.c')
-rw-r--r--src/lib/kadm5/srv/kadm5_hook.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/lib/kadm5/srv/kadm5_hook.c b/src/lib/kadm5/srv/kadm5_hook.c
new file mode 100644
index 000000000000..df337bc32e0c
--- /dev/null
+++ b/src/lib/kadm5/srv/kadm5_hook.c
@@ -0,0 +1,186 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/kadm5/srv/kadm5_hook.c */
+/*
+ * 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.
+ */
+/* Consumer interface for kadm5_hook plugins. */
+
+#include "k5-int.h"
+#include "server_internal.h"
+#include <krb5/kadm5_hook_plugin.h>
+#include <adm_proto.h>
+#include <syslog.h>
+
+struct kadm5_hook_handle_st {
+ kadm5_hook_vftable_1 vt;
+ kadm5_hook_modinfo *data;
+};
+
+krb5_error_code
+k5_kadm5_hook_load(krb5_context context,
+ kadm5_hook_handle **handles_out)
+{
+ krb5_error_code ret;
+ krb5_plugin_initvt_fn *modules = NULL, *mod;
+ size_t count;
+ kadm5_hook_handle *list = NULL, handle = NULL;
+
+ *handles_out = NULL;
+
+ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KADM5_HOOK, &modules);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Allocate a large enough list of handles. */
+ for (count = 0; modules[count] != NULL; count++);
+ list = k5calloc(count + 1, sizeof(*list), &ret);
+ if (list == NULL)
+ goto cleanup;
+
+ /* For each module, allocate a handle, initialize its vtable, and
+ * initialize the module. */
+ count = 0;
+ for (mod = modules; *mod != NULL; mod++) {
+ handle = k5alloc(sizeof(*handle), &ret);
+ if (handle == NULL)
+ goto cleanup;
+ ret = (*mod)(context, 1, 2, (krb5_plugin_vtable)&handle->vt);
+ if (ret != 0) { /* Failed vtable init is non-fatal. */
+ free(handle);
+ handle = NULL;
+ continue;
+ }
+ handle->data = NULL;
+ if (handle->vt.init != NULL) {
+ ret = handle->vt.init(context, &handle->data);
+ if (ret != 0) /* Failed initialization is fatal. */
+ goto cleanup;
+ }
+ list[count++] = handle;
+ list[count] = NULL;
+ handle = NULL;
+ }
+ list[count] = NULL;
+
+ ret = 0;
+ *handles_out = list;
+ list = NULL;
+
+cleanup:
+ free(handle);
+ k5_plugin_free_modules(context, modules);
+ k5_kadm5_hook_free_handles(context, list);
+ return ret;
+}
+
+void
+k5_kadm5_hook_free_handles(krb5_context context, kadm5_hook_handle *handles)
+{
+ kadm5_hook_handle *hp, handle;
+
+ if (handles == NULL)
+ return;
+ for (hp = handles; *hp != NULL; hp++) {
+ handle = *hp;
+ if (handle->vt.fini != NULL)
+ handle->vt.fini(context, handle->data);
+ free(handle);
+ }
+ free(handles);
+}
+
+static void
+log_failure(krb5_context context,
+ const char *name,
+ const char *function,
+ krb5_error_code ret)
+{
+ const char *e = krb5_get_error_message(context, ret);
+
+ krb5_klog_syslog(LOG_ERR, _("kadm5_hook %s failed postcommit %s: %s"),
+ name, function, e);
+ krb5_free_error_message(context, e);
+}
+
+#define ITERATE(operation, params) \
+ for (; *handles; handles++) { \
+ kadm5_hook_handle h = *handles; \
+ krb5_error_code ret = 0; \
+ if (h->vt.operation) { \
+ ret = h->vt.operation params; \
+ } \
+ if (ret) { \
+ if (stage == KADM5_HOOK_STAGE_PRECOMMIT) \
+ return ret; \
+ else \
+ log_failure(context, h->vt.name, #operation, ret); \
+ } \
+ }
+
+
+kadm5_ret_t
+k5_kadm5_hook_chpass(krb5_context context, kadm5_hook_handle *handles,
+ int stage, krb5_principal princ, krb5_boolean keepold,
+ int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
+ const char *newpass)
+{
+ ITERATE(chpass, (context, h->data,
+ stage, princ, keepold,
+ n_ks_tuple, ks_tuple, newpass));
+ return 0;
+}
+
+kadm5_ret_t
+k5_kadm5_hook_create(krb5_context context, kadm5_hook_handle *handles,
+ int stage, kadm5_principal_ent_t princ, long mask,
+ int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
+ const char *newpass)
+{
+ ITERATE(create, (context, h->data,
+ stage, princ, mask, n_ks_tuple, ks_tuple, newpass));
+ return 0;
+}
+
+kadm5_ret_t
+k5_kadm5_hook_modify(krb5_context context, kadm5_hook_handle *handles,
+ int stage, kadm5_principal_ent_t princ, long mask)
+{
+ ITERATE(modify, (context, h->data, stage, princ, mask));
+ return 0;
+}
+
+kadm5_ret_t
+k5_kadm5_hook_rename(krb5_context context, kadm5_hook_handle *handles,
+ int stage, krb5_principal oprinc, krb5_principal nprinc)
+{
+ ITERATE(rename, (context, h->data, stage, oprinc, nprinc));
+ return 0;
+}
+
+kadm5_ret_t
+k5_kadm5_hook_remove(krb5_context context, kadm5_hook_handle *handles,
+ int stage, krb5_principal princ)
+{
+ ITERATE(remove, (context, h->data, stage, princ));
+ return 0;
+}