Commit d25926ce authored by Russ Allbery's avatar Russ Allbery

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.
parent 0ea873a8
......@@ -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
......
......@@ -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.
......
......@@ -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
......
......@@ -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);
......
......@@ -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(&params, 0, sizeof(params));
params.realm = (char *) realm;
params.mask = KADM5_CONFIG_REALM;
code = kadm5_init_with_skey_ctx(ctx, (char *) "kadmin/admin", NULL, NULL,
&params, KADM5_STRUCT_VERSION,
code = kadm5_init_with_skey_ctx(kadm_ctx, (char *) "kadmin/admin", NULL,
NULL, &params, 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;
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment