Files
Jeffrey Altman 387684aa93 WIN32: fix calling conventions for 32-bit builds
On 32-bit Windows Intel builds the __cdecl and __stdcall calling
conventions are different so labeling the functions that are
exported or assigned to function pointers matters.

Change-Id: I03b6f34baeb9ffb2e683fd979f12f27a5078a4da
2019-01-14 06:12:36 -05:00

287 lines
7.6 KiB
C

/*
* Copyright (c) 2018-2019, AuriStor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <assert.h>
#include <krb5.h>
#include <stdio.h>
#include <string.h>
#include "admin.h"
#include "kadm5-hook.h"
/*
* Sample kadm5 hook plugin that just logs when it is called. Install it
* somewhere and configure the path in the [kadmin] section of krb5.conf.
* e.g.
*
* [kadmin]
* plugin_dir = /usr/local/heimdal/lib/plugin/kadm5
*
*/
static char sample_data_1, sample_data_2;
static krb5_error_code
sample_log(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
const char *tag,
krb5_error_code code,
krb5_const_principal princ)
{
char *p = NULL;
int which = 0;
/* verify we get called with the right contex tpointer */
if (data == &sample_data_1)
which = 1;
else if (data == &sample_data_2)
which = 2;
assert(which != 0);
/* code should always be zero on pre-commit */
assert(code == 0 || stage == KADM5_HOOK_STAGE_POSTCOMMIT);
if (princ)
(void) krb5_unparse_name(context, princ, &p);
krb5_warn(context, code, "sample_hook_%d: %s %s hook princ '%s'", which, tag,
stage == KADM5_HOOK_STAGE_PRECOMMIT ? "pre-commit" : "post-commit",
p != NULL ? p : "<unknown>");
krb5_xfree(p);
/* returning zero and KRB5_PLUGIN_NO_HANDLE are the same for hook plugins */
return 0;
}
static krb5_error_code KRB5_CALLCONV
sample_init_1(krb5_context context, void **data)
{
*data = &sample_data_1;
krb5_warn(context, 0, "sample_hook_1: initializing");
return 0;
}
static krb5_error_code KRB5_CALLCONV
sample_init_2(krb5_context context, void **data)
{
*data = &sample_data_2;
krb5_warn(context, 0, "sample_hook_2: initializing");
return 0;
}
static void KRB5_CALLCONV
sample_fini(void *data)
{
krb5_warn(NULL, 0, "sample_fini: finalizing");
}
static krb5_error_code KRB5_CALLCONV
sample_chpass_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ,
uint32_t flags,
size_t n_ks_tuple,
krb5_key_salt_tuple *ks_tuple,
const char *password)
{
return sample_log(context, data, stage, "chpass", code, princ);
}
static krb5_error_code KRB5_CALLCONV
sample_chpass_with_key_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ,
uint32_t flags,
size_t n_key_data,
krb5_key_data *key_data)
{
return sample_log(context, data, stage, "chpass_with_key", code, princ);
}
static krb5_error_code KRB5_CALLCONV
sample_create_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
kadm5_principal_ent_t ent,
uint32_t mask,
const char *password)
{
return sample_log(context, data, stage, "create", code, ent->principal);
}
static krb5_error_code KRB5_CALLCONV
sample_modify_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
kadm5_principal_ent_t ent,
uint32_t mask)
{
return sample_log(context, data, stage, "modify", code, ent->principal);
}
static krb5_error_code KRB5_CALLCONV
sample_delete_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ)
{
return sample_log(context, data, stage, "delete", code, princ);
}
static krb5_error_code KRB5_CALLCONV
sample_randkey_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ)
{
return sample_log(context, data, stage, "randkey", code, princ);
}
static krb5_error_code KRB5_CALLCONV
sample_rename_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal source,
krb5_const_principal target)
{
return sample_log(context, data, stage, "rename", code, source);
}
static krb5_error_code KRB5_CALLCONV
sample_set_keys_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ,
uint32_t flags,
size_t n_ks_tuple,
krb5_key_salt_tuple *ks_tuple,
size_t n_keys,
krb5_keyblock *keyblocks)
{
return sample_log(context, data, stage, "set_keys", code, princ);
}
static krb5_error_code KRB5_CALLCONV
sample_prune_hook(krb5_context context,
void *data,
enum kadm5_hook_stage stage,
krb5_error_code code,
krb5_const_principal princ,
int kvno)
{
return sample_log(context, data, stage, "prune", code, princ);
}
static const kadm5_hook_ftable sample_hook_1 = {
KADM5_HOOK_VERSION_V1,
sample_init_1,
sample_fini,
"sample_hook_1",
"Heimdal",
sample_chpass_hook,
sample_chpass_with_key_hook,
sample_create_hook,
sample_modify_hook,
sample_delete_hook,
sample_randkey_hook,
sample_rename_hook,
sample_set_keys_hook,
sample_prune_hook,
};
static const kadm5_hook_ftable sample_hook_2 = {
KADM5_HOOK_VERSION_V1,
sample_init_2,
sample_fini,
"sample_hook_2",
"Heimdal",
sample_chpass_hook,
sample_chpass_with_key_hook,
sample_create_hook,
sample_modify_hook,
sample_delete_hook,
sample_randkey_hook,
sample_rename_hook,
sample_set_keys_hook,
sample_prune_hook,
};
/* Arrays of pointers, because hooks may be different versions/sizes */
static const kadm5_hook_ftable *const sample_hooks[] = {
&sample_hook_1,
&sample_hook_2,
};
krb5_error_code
kadm5_hook_plugin_load(krb5_context context,
krb5_get_instance_func_t *get_instance,
size_t *num_hooks,
const kadm5_hook_ftable *const **hooks);
static uintptr_t KRB5_LIB_CALL
sample_hook_get_instance(const char *libname)
{
if (strcmp(libname, "kadm5") == 0)
return kadm5_get_instance(libname);
else if (strcmp(libname, "krb5") == 0)
return krb5_get_instance(libname);
return 0;
}
krb5_error_code
kadm5_hook_plugin_load(krb5_context context,
krb5_get_instance_func_t *get_instance,
size_t *num_hooks,
const kadm5_hook_ftable *const **hooks)
{
*get_instance = sample_hook_get_instance;
*num_hooks = sizeof(sample_hooks) / sizeof(sample_hooks[0]);
*hooks = sample_hooks;
return 0;
}