summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2013-12-09 22:51:27 -0800
committerRuss Allbery <eagle@eyrie.org>2013-12-09 22:51:27 -0800
commitd25926ce187353b6a0df67e0fa49e416d715ca25 (patch)
tree53b391e94db53784070bcb8abe9bf1f99fe2735b
parent0ea873a8dea1f2d0258e781a7a7538bf34cb474f (diff)
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.
-rw-r--r--NEWS5
-rw-r--r--README3
-rw-r--r--configure.ac15
-rw-r--r--plugin/general.c14
-rw-r--r--plugin/instance.c18
-rw-r--r--portable/kadmin.h8
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(&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;
diff --git a/portable/kadmin.h b/portable/kadmin.h
index f410481..95f6d4b 100644
--- a/portable/kadmin.h
+++ b/portable/kadmin.h
@@ -56,6 +56,14 @@
#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
* the below will fix it up if built against MIT.