kadm5: improve kadm5 hook logging (#397)

Centralize logging for kadm5 hook failure, log successful hook loading, better
logging on hook load failures and on platforms that do not support dlopen().
This commit is contained in:
Luke Howard
2018-12-27 11:58:26 +11:00
parent efb111e450
commit f62b00e33c
8 changed files with 57 additions and 63 deletions

View File

@@ -56,11 +56,8 @@ chpass_principal_hook(kadm5_server_context *context,
stage, code, princ, flags, stage, code, princ, flags,
n_ks_tuple, ks_tuple, password); n_ks_tuple, ks_tuple, password);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "chpass",
"chpass hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -120,11 +120,8 @@ create_principal_hook(kadm5_server_context *context,
ret = hook->hook->create(context->context, hook->data, ret = hook->hook->create(context->context, hook->data,
stage, code, princ, mask, password); stage, code, princ, mask, password);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "create",
"create hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -51,11 +51,8 @@ delete_principal_hook(kadm5_server_context *context,
ret = hook->hook->delete(context->context, hook->data, ret = hook->hook->delete(context->context, hook->data,
stage, code, princ); stage, code, princ);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "delete",
"delete hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -52,11 +52,8 @@ modify_principal_hook(kadm5_server_context *context,
ret = hook->hook->modify(context->context, hook->data, ret = hook->hook->modify(context->context, hook->data,
stage, code, princ, mask); stage, code, princ, mask);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "modify",
"modify hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -51,11 +51,8 @@ randkey_principal_hook(kadm5_server_context *context,
ret = hook->hook->randkey(context->context, hook->data, ret = hook->hook->randkey(context->context, hook->data,
stage, code, princ); stage, code, princ);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "randkey",
"randkey hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -52,11 +52,8 @@ rename_principal_hook(kadm5_server_context *context,
ret = hook->hook->rename(context->context, hook->data, ret = hook->hook->rename(context->context, hook->data,
stage, code, source, target); stage, code, source, target);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "rename",
"rename hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }

View File

@@ -31,6 +31,8 @@
*/ */
#include "kadm5_locl.h" #include "kadm5_locl.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h> #include <dlfcn.h>
#ifndef RTLD_NOW #ifndef RTLD_NOW
@@ -44,21 +46,37 @@
#ifndef RTLD_GROUP #ifndef RTLD_GROUP
#define RTLD_GROUP 0 #define RTLD_GROUP 0
#endif #endif
#endif /* HAVE_DLFCN_H */
void
_kadm5_s_set_hook_error_message(kadm5_server_context *context,
krb5_error_code ret,
const char *op,
const struct kadm5_hook *hook,
enum kadm5_hook_stage stage)
{
assert(ret != 0);
krb5_set_error_message(context->context, ret,
"%s hook `%s' failed %s-commit",
op, hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT ? "pre" : "post");
}
/* /*
* Load kadmin server hooks. * Load kadmin server hooks.
*/ */
#ifdef HAVE_DLOPEN
kadm5_ret_t kadm5_ret_t
_kadm5_s_init_hooks(kadm5_server_context *ctx) _kadm5_s_init_hooks(kadm5_server_context *ctx)
{ {
krb5_context context = ctx->context; krb5_context context = ctx->context;
char **hooks; char **hooks;
size_t i;
void *handle = NULL; void *handle = NULL;
struct kadm5_hook_context *hook_context = NULL; struct kadm5_hook_context *hook_context = NULL;
#ifdef HAVE_DLOPEN
struct kadm5_hook_context **tmp; struct kadm5_hook_context **tmp;
size_t i;
#endif
kadm5_ret_t ret = KADM5_BAD_SERVER_HOOK; kadm5_ret_t ret = KADM5_BAD_SERVER_HOOK;
hooks = krb5_config_get_strings(context, NULL, hooks = krb5_config_get_strings(context, NULL,
@@ -66,6 +84,7 @@ _kadm5_s_init_hooks(kadm5_server_context *ctx)
if (hooks == NULL) if (hooks == NULL)
return 0; return 0;
#ifdef HAVE_DLOPEN
for (i = 0; hooks[i] != NULL; i++) { for (i = 0; hooks[i] != NULL; i++) {
const char *hookpath = hooks[i]; const char *hookpath = hooks[i];
kadm5_hook_init_t hook_init; kadm5_hook_init_t hook_init;
@@ -81,8 +100,8 @@ _kadm5_s_init_hooks(kadm5_server_context *ctx)
hook_init = dlsym(handle, "kadm5_hook_init"); hook_init = dlsym(handle, "kadm5_hook_init");
if (hook_init == NULL) { if (hook_init == NULL) {
krb5_warnx(context, "didn't find `kadm5_hook_init' symbol in `%s':" krb5_warnx(context, "didn't find kadm5_hook_init symbol in `%s': %s",
" %s", hookpath, dlerror()); hookpath, dlerror());
ret = KADM5_BAD_SERVER_HOOK; ret = KADM5_BAD_SERVER_HOOK;
goto fail; goto fail;
} }
@@ -91,7 +110,7 @@ _kadm5_s_init_hooks(kadm5_server_context *ctx)
if (ret == 0 && hook == NULL) if (ret == 0 && hook == NULL)
ret = KADM5_BAD_SERVER_HOOK; ret = KADM5_BAD_SERVER_HOOK;
if (ret) { if (ret) {
krb5_warn(context, ret, "initialize of hook `%s' failed", hookpath); krb5_warn(context, ret, "initialization of hook `%s' failed", hookpath);
goto fail; goto fail;
} }
@@ -100,16 +119,18 @@ _kadm5_s_init_hooks(kadm5_server_context *ctx)
else if (hook->version > KADM5_HOOK_VERSION_V1) else if (hook->version > KADM5_HOOK_VERSION_V1)
ret = KADM5_NEW_SERVER_HOOK_VERSION; ret = KADM5_NEW_SERVER_HOOK_VERSION;
if (ret) { if (ret) {
krb5_warnx(context, "version of loaded hook `%s' is %u" krb5_warnx(context, "%s: version of loaded hook `%s' by vendor `%s' is %u"
" (supported versions %u to %u)", hookpath, hook->version, " (supported versions are %u to %u)",
hookpath, hook->name, hook->vendor, hook->version,
KADM5_HOOK_VERSION_V1, KADM5_HOOK_VERSION_V1); KADM5_HOOK_VERSION_V1, KADM5_HOOK_VERSION_V1);
hook->fini(context, data); hook->fini(context, data);
goto fail; goto fail;
} }
if (hook->init_context != krb5_init_context) { if (hook->init_context != krb5_init_context) {
krb5_warnx(context, "loaded hook `%s' is not linked against " krb5_warnx(context, "%s: loaded hook `%s' by vendor `%s' (API version %u)"
"this version of Heimdal", hookpath); "is not linked against this version of Heimdal",
hookpath, hook->name, hook->vendor, hook->version);
hook->fini(context, data); hook->fini(context, data);
goto fail; goto fail;
} }
@@ -135,9 +156,17 @@ _kadm5_s_init_hooks(kadm5_server_context *ctx)
ctx->hooks[ctx->num_hooks] = hook_context; ctx->hooks[ctx->num_hooks] = hook_context;
hook_context = NULL; hook_context = NULL;
ctx->num_hooks++; ctx->num_hooks++;
}
krb5_warnx(context, "Loaded kadm5 hook `%s' by vendor `%s' (API version %u)",
hook->name, hook->vendor, hook->version);
}
return 0; return 0;
#else
krb5_warnx(context, "kadm5 hooks configured, but platform "
"does not support dynamic loading");
ret = KADM5_BAD_SERVER_HOOK;
goto fail;
#endif /* HAVE_DLOPEN */
fail: fail:
_kadm5_s_free_hooks(ctx); _kadm5_s_free_hooks(ctx);
@@ -153,7 +182,8 @@ fail:
void void
_kadm5_s_free_hooks(kadm5_server_context *ctx) _kadm5_s_free_hooks(kadm5_server_context *ctx)
{ {
int i; #ifdef HAVE_DLOPEN
size_t i;
for (i = 0; i < ctx->num_hooks; i++) { for (i = 0; i < ctx->num_hooks; i++) {
if (ctx->hooks[i]->hook->fini != NULL) if (ctx->hooks[i]->hook->fini != NULL)
@@ -164,20 +194,5 @@ _kadm5_s_free_hooks(kadm5_server_context *ctx)
free(ctx->hooks); free(ctx->hooks);
ctx->hooks = NULL; ctx->hooks = NULL;
ctx->num_hooks = 0; ctx->num_hooks = 0;
#endif /* HAVE_DLOPEN */
} }
# else /* !HAVE_DLOPEN */
kadm5_ret_t
_kadm5_s_init_hooks(kadm5_server_context *ctx)
{
return 0;
}
void
_kadm5_s_free_hooks(kadm5_server_context *ctx)
{
return 0;
}
#endif /* !HAVE_DLOPEN */

View File

@@ -56,11 +56,8 @@ setkey_principal_hook(kadm5_server_context *context,
flags, n_ks_tuple, ks_tuple, flags, n_ks_tuple, ks_tuple,
n_keys, keyblocks); n_keys, keyblocks);
if (ret != 0) { if (ret != 0) {
krb5_prepend_error_message(context->context, ret, _kadm5_s_set_hook_error_message(context, ret, "setkey",
"setkey hook `%s' failed %scommit", hook->hook, stage);
hook->hook->name,
stage == KADM5_HOOK_STAGE_PRECOMMIT
? "pre" : "post");
if (stage == KADM5_HOOK_STAGE_PRECOMMIT) if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
break; break;
} }