From d25926ce187353b6a0df67e0fa49e416d715ca25 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 9 Dec 2013 22:51:27 -0800 Subject: Add back ad_base_instance support for MIT Kerberos This works properly provided that the instance lookup uses a separate Kerberos context. Thanks to Greg Hudson for the fix. --- NEWS | 5 ++--- README | 3 --- configure.ac | 15 +++++---------- plugin/general.c | 14 +------------- plugin/instance.c | 18 +++++++++++++++--- portable/kadmin.h | 8 ++++++++ 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/NEWS b/NEWS index 040e548..31ecb87 100644 --- a/NEWS +++ b/NEWS @@ -24,9 +24,8 @@ krb5-sync 3.0 (2013-12-09) still provided. Add a new string krb5.conf option, ad_base_instance, which, if set, - changes the way that password synchronization is handled. This option - is only available for Heimdal, not for MIT Kerberos. When this option - is set, the password for the principal formed by appending that + changes the way that password synchronization is handled. When this + option is set, the password for the principal formed by appending that instance to a base principal is propagated to Active Directory as the password for the base principal. For example, if this is set to the string "windows", the password of the principal "user/windows" is diff --git a/README b/README index 3a6ec2d..1d2456c 100644 --- a/README +++ b/README @@ -255,9 +255,6 @@ CONFIGURATION ad_base_instance - This option is only available if built with Heimdal. It will result - in an initialization error if set when using MIT Kerberos. - If ad_base_instance is set, then any password change for a single-component principal (such as user@EXAMPLE.COM) will be handled somewhat specially. diff --git a/configure.ac b/configure.ac index f8432d3..b2c2d45 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,8 @@ LT_INIT dnl Only check for krb5/kadm5_hook_plugin.h if building with MIT, since we may dnl find a system MIT header file that can't be included when building with -dnl Heimdal. +dnl Heimdal. We use the probe for the krb5_realm data type as a proxy for +dnl whether we're building with Heimdal. RRA_LIB_KRB5 RRA_LIB_KRB5_SWITCH AC_CHECK_HEADERS([kadm5/kadm5_err.h]) @@ -39,14 +40,8 @@ AC_CHECK_FUNCS([krb5_free_default_realm \ krb5_principal_get_realm \ krb5_principal_set_realm \ krb5_xfree]) -AC_CHECK_TYPES([krb5_realm]) -AC_CHECK_MEMBER([krb5_creds.session], - [AC_DEFINE([HAVE_KRB5_HEIMDAL], [1], - [Define if your Kerberos implementation is Heimdal.])], - [AC_DEFINE([HAVE_KRB5_MIT], [1], - [Define if your Kerberos implementation is MIT.]) - AC_CHECK_HEADERS([krb5/kadm5_hook_plugin.h])], - [RRA_INCLUDES_KRB5]) +AC_CHECK_TYPES([krb5_realm], [], + [AC_CHECK_HEADERS([krb5/kadm5_hook_plugin.h])], [RRA_INCLUDES_KRB5]) AC_CHECK_FUNCS([krb5_get_init_creds_opt_free], [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS]) AC_CHECK_FUNCS([krb5_appdefault_string], [], @@ -57,7 +52,7 @@ RRA_LIB_KRB5_RESTORE RRA_LIB_KADM5SRV RRA_LIB_KADM5SRV_SWITCH -AC_CHECK_FUNCS([kadm5_init_with_skey_ctx]) +AC_CHECK_FUNCS([kadm5_init_krb5_context kadm5_init_with_skey_ctx]) RRA_LIB_KADM5SRV_RESTORE RRA_LIB_LDAP diff --git a/plugin/general.c b/plugin/general.c index b6bb6a1..1639ddc 100644 --- a/plugin/general.c +++ b/plugin/general.c @@ -55,20 +55,8 @@ sync_init(krb5_context ctx, kadm5_hook_modinfo **result) /* Get allowed instances from krb5.conf. */ sync_config_list(ctx, "ad_instances", &config->ad_instances); - /* - * See if we're propagating an instance to the base account in AD. This - * option is not supported on MIT Kerberos and results in an error there, - * since calling libkadm5srv functions from inside a plugin appears to - * result in corruption with MIT Kerberos (at least in 1.10.1). - */ + /* See if we're propagating an instance to the base account in AD. */ sync_config_string(ctx, "ad_base_instance", &config->ad_base_instance); -#if HAVE_KRB5_MIT - if (config->ad_base_instance != NULL) { - sync_close(ctx, config); - return sync_error_config(ctx, "ad_base_instance not supported on MIT" - " Kerberos"); - } -#endif /* See if we're forcing queuing of all changes. */ sync_config_boolean(ctx, "ad_queue_only", &config->ad_queue_only); diff --git a/plugin/instance.c b/plugin/instance.c index 87e1cbd..dce3072 100644 --- a/plugin/instance.c +++ b/plugin/instance.c @@ -34,6 +34,7 @@ sync_instance_exists(krb5_context ctx, krb5_principal base, krb5_principal princ = NULL; krb5_error_code code; const char *realm; + krb5_context kadm_ctx = NULL; kadm5_config_params params; void *handle = NULL; int mask; @@ -59,12 +60,20 @@ sync_instance_exists(krb5_context ctx, krb5_principal base, if (code != 0) goto fail; - /* Open the local KDB and look up this new principal. */ + /* + * Open the local KDB and look up this new principal. We need to use a + * separate Kerberos context from the one passed in by our caller. + * Otherwise, on MIT Kerberos, we tromp on kadmind's copy of the KDB, + * with bad results. + */ + code = kadm5_init_krb5_context(&kadm_ctx); + if (code != 0) + goto fail; memset(¶ms, 0, sizeof(params)); params.realm = (char *) realm; params.mask = KADM5_CONFIG_REALM; - code = kadm5_init_with_skey_ctx(ctx, (char *) "kadmin/admin", NULL, NULL, - ¶ms, KADM5_STRUCT_VERSION, + code = kadm5_init_with_skey_ctx(kadm_ctx, (char *) "kadmin/admin", NULL, + NULL, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &handle); if (code != 0) goto fail; @@ -77,10 +86,13 @@ sync_instance_exists(krb5_context ctx, krb5_principal base, kadm5_free_principal_ent(handle, &ent); } kadm5_destroy(handle); + krb5_free_context(kadm_ctx); krb5_free_principal(ctx, princ); return 0; fail: + if (kadm_ctx != NULL) + krb5_free_context(kadm_ctx); if (princ != NULL) krb5_free_principal(ctx, princ); return code; diff --git a/portable/kadmin.h b/portable/kadmin.h index f410481..95f6d4b 100644 --- a/portable/kadmin.h +++ b/portable/kadmin.h @@ -55,6 +55,14 @@ # define KADM5_MISSING_KRB5_CONF_PARAMS KADM5_MISSING_CONF_PARAMS #endif +/* + * MIT Kerberos provides this function for pure kadmin clients to get a + * Kerberos context. With Heimdal, just use krb5_init_context. + */ +#ifndef HAVE_KADM5_INIT_KRB5_CONTEXT +# define kadm5_init_krb5_context(c) krb5_init_context(c) +#endif + /* * Heimdal provides _ctx functions that take an existing context. MIT always * requires the context be passed in. Code should use the _ctx variant, and -- cgit v1.2.3