--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/035-multi-master.patch Wed Feb 24 10:43:57 2016 -0600
@@ -0,0 +1,692 @@
+#
+# This patch provides support in kadmin and kpropd to work in a
+# multi-master environment.
+#
+# Note that we have discussed support for this with MIT in the past but
+# they have been reticent to add such support. It is possible that
+# support for this may be introduced at a later time at which point we
+# should look at modifying/deleting this patch.
+# Patch source: in-house
+#
+diff -u -r old/src/kadmin/cli/kadmin.c new/src/kadmin/cli/kadmin.c
+--- old/src/kadmin/cli/kadmin.c 2015-05-28 15:10:45.129616302 -0500
++++ new/src/kadmin/cli/kadmin.c 2015-05-29 13:32:41.901105712 -0500
+@@ -268,7 +268,7 @@
+ char **db_args = NULL;
+ int db_args_size = 0;
+ char *db_name = NULL;
+- char *svcname, *realm;
++ char **svcnames = NULL, *realm;
+
+ memset(¶ms, 0, sizeof(params));
+
+@@ -380,11 +380,6 @@
+ params.mask |= KADM5_CONFIG_REALM;
+ params.realm = def_realm;
+
+- if (params.mask & KADM5_CONFIG_OLD_AUTH_GSSAPI)
+- svcname = KADM5_ADMIN_SERVICE;
+- else
+- svcname = NULL;
+-
+ /*
+ * Set cc to an open credentials cache, either specified by the -c
+ * argument or the default.
+@@ -515,13 +510,15 @@
+ if (ccache_name) {
+ printf(_("Authenticating as principal %s with existing "
+ "credentials.\n"), princstr);
+- retval = kadm5_init_with_creds(context, princstr, cc, svcname, ¶ms,
++ retval = kadm5_init_with_creds_mm(context, princstr, cc, svcnames,
++ ¶ms,
+ KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_4, db_args, &handle);
+ } else if (use_anonymous) {
+ printf(_("Authenticating as principal %s with password; "
+ "anonymous requested.\n"), princstr);
+- retval = kadm5_init_anonymous(context, princstr, svcname, ¶ms,
++ retval = kadm5_init_anonymous_mm(context, princstr, svcnames,
++ ¶ms,
+ KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_4, db_args, &handle);
+ } else if (use_keytab) {
+@@ -531,17 +528,20 @@
+ else
+ printf(_("Authenticating as principal %s with default keytab.\n"),
+ princstr);
+- retval = kadm5_init_with_skey(context, princstr, keytab_name, svcname,
++ retval = kadm5_init_with_skey_mm(context, princstr, keytab_name,
++ svcnames,
+ ¶ms, KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_4, db_args, &handle);
+ } else {
+ printf(_("Authenticating as principal %s with password.\n"),
+ princstr);
+- retval = kadm5_init_with_password(context, princstr, password, svcname,
++ retval = kadm5_init_with_password_mm(context, princstr, password,
++ svcnames,
+ ¶ms, KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_4, db_args,
+ &handle);
+ }
++ free_srv_names(svcnames);
+ if (retval) {
+ com_err(whoami, retval, _("while initializing %s interface"), whoami);
+ if (retval == KADM5_BAD_CLIENT_PARAMS ||
+diff -u -r old/src/lib/kadm5/admin.h new/src/lib/kadm5/admin.h
+--- old/src/lib/kadm5/admin.h 2015-05-28 15:10:45.095122403 -0500
++++ new/src/lib/kadm5/admin.h 2015-05-28 15:34:35.800877732 -0500
+@@ -345,6 +345,51 @@
+ krb5_ui_4 api_version,
+ char **db_args,
+ void **server_handle);
++kadm5_ret_t kadm5_init_with_creds_mm(krb5_context context,
++ char *client_name,
++ krb5_ccache ccache,
++ char **svcnames,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle);
++kadm5_ret_t kadm5_init_with_password_mm(krb5_context context,
++ char *client_name,
++ char *pass,
++ char **svcnames,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle);
++kadm5_ret_t kadm5_init_anonymous_mm(krb5_context context,
++ char *client_name,
++ char **svcnames,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle);
++kadm5_ret_t kadm5_init_mm(krb5_context context,
++ char *client_name,
++ char *pass,
++ char **svcnames,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle);
++kadm5_ret_t kadm5_init_with_skey_mm(krb5_context context,
++ char *client_name,
++ char *keytab,
++ char **svcnames,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle);
++
+ kadm5_ret_t kadm5_lock(void *server_handle);
+ kadm5_ret_t kadm5_unlock(void *server_handle);
+ kadm5_ret_t kadm5_flush(void *server_handle);
+diff -u -r old/src/lib/kadm5/clnt/client_init.c new/src/lib/kadm5/clnt/client_init.c
+--- old/src/lib/kadm5/clnt/client_init.c 2015-05-28 15:10:45.192975632 -0500
++++ new/src/lib/kadm5/clnt/client_init.c 2015-06-02 10:33:51.639341637 -0500
+@@ -55,7 +55,7 @@
+
+ static kadm5_ret_t
+ init_any(krb5_context context, char *client_name, enum init_type init_type,
+- char *pass, krb5_ccache ccache_in, char *service_name,
++ char *pass, krb5_ccache ccache_in, char **service_names,
+ kadm5_config_params *params, krb5_ui_4 struct_version,
+ krb5_ui_4 api_version, char **db_args, void **server_handle);
+
+@@ -87,8 +87,25 @@
+ krb5_ui_4 api_version, char **db_args,
+ void **server_handle)
+ {
++ char *svcnames[2];
++
++ svcnames[0] = service_name;
++ svcnames[1] = NULL;
++
++ return init_any(context, client_name, INIT_CREDS, NULL, ccache,
++ svcnames, params, struct_version, api_version, db_args,
++ server_handle);
++}
++
++kadm5_ret_t
++kadm5_init_with_creds_mm(krb5_context context, char *client_name,
++ krb5_ccache ccache, char **svcnames,
++ kadm5_config_params *params, krb5_ui_4 struct_version,
++ krb5_ui_4 api_version, char **db_args,
++ void **server_handle)
++{
+ return init_any(context, client_name, INIT_CREDS, NULL, ccache,
+- service_name, params, struct_version, api_version, db_args,
++ svcnames, params, struct_version, api_version, db_args,
+ server_handle);
+ }
+
+@@ -99,7 +116,24 @@
+ krb5_ui_4 api_version, char **db_args,
+ void **server_handle)
+ {
+- return init_any(context, client_name, INIT_PASS, pass, NULL, service_name,
++ char *svcnames[2];
++
++ svcnames[0] = service_name;
++ svcnames[1] = NULL;
++
++ return init_any(context, client_name, INIT_PASS, pass, NULL, svcnames,
++ params, struct_version, api_version, db_args,
++ server_handle);
++}
++
++kadm5_ret_t
++kadm5_init_with_password_mm(krb5_context context, char *client_name,
++ char *pass, char **svcnames,
++ kadm5_config_params *params, krb5_ui_4 struct_version,
++ krb5_ui_4 api_version, char **db_args,
++ void **server_handle)
++{
++ return init_any(context, client_name, INIT_PASS, pass, NULL, svcnames,
+ params, struct_version, api_version, db_args,
+ server_handle);
+ }
+@@ -110,8 +144,24 @@
+ krb5_ui_4 struct_version, krb5_ui_4 api_version,
+ char **db_args, void **server_handle)
+ {
++ char *svcnames[2];
++
++ svcnames[0] = service_name;
++ svcnames[1] = NULL;
++
++ return init_any(context, client_name, INIT_ANONYMOUS, NULL, NULL,
++ svcnames, params, struct_version, api_version,
++ db_args, server_handle);
++}
++
++kadm5_ret_t
++kadm5_init_anonymous_mm(krb5_context context, char *client_name,
++ char **svcnames, kadm5_config_params *params,
++ krb5_ui_4 struct_version, krb5_ui_4 api_version,
++ char **db_args, void **server_handle)
++{
+ return init_any(context, client_name, INIT_ANONYMOUS, NULL, NULL,
+- service_name, params, struct_version, api_version,
++ svcnames, params, struct_version, api_version,
+ db_args, server_handle);
+ }
+
+@@ -121,7 +171,23 @@
+ krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args,
+ void **server_handle)
+ {
+- return init_any(context, client_name, INIT_PASS, pass, NULL, service_name,
++ char *svcnames[2];
++
++ svcnames[0] = service_name;
++ svcnames[1] = NULL;
++
++ return init_any(context, client_name, INIT_PASS, pass, NULL, svcnames,
++ params, struct_version, api_version, db_args,
++ server_handle);
++}
++
++kadm5_ret_t
++kadm5_init_mm(krb5_context context, char *client_name, char *pass,
++ char **svcnames, kadm5_config_params *params,
++ krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args,
++ void **server_handle)
++{
++ return init_any(context, client_name, INIT_PASS, pass, NULL, svcnames,
+ params, struct_version, api_version, db_args,
+ server_handle);
+ }
+@@ -133,8 +199,25 @@
+ krb5_ui_4 api_version, char **db_args,
+ void **server_handle)
+ {
++ char *svcnames[2];
++
++ svcnames[0] = service_name;
++ svcnames[1] = NULL;
++
+ return init_any(context, client_name, INIT_SKEY, keytab, NULL,
+- service_name, params, struct_version, api_version, db_args,
++ svcnames, params, struct_version, api_version, db_args,
++ server_handle);
++}
++
++kadm5_ret_t
++kadm5_init_with_skey_mm(krb5_context context, char *client_name,
++ char *keytab, char **svcnames,
++ kadm5_config_params *params, krb5_ui_4 struct_version,
++ krb5_ui_4 api_version, char **db_args,
++ void **server_handle)
++{
++ return init_any(context, client_name, INIT_SKEY, keytab, NULL,
++ svcnames, params, struct_version, api_version, db_args,
+ server_handle);
+ }
+
+@@ -338,7 +421,7 @@
+ }
+
+ /*
+- * iprop fallback logic:
++ * iprop fallback logic:
+ * - if iprop_port is configured, connect to iprop_port
+ * - if not, query remote rpc/bind
+ * - if that fails, try consuming iprop service on kadmin port
+@@ -506,9 +589,35 @@
+ return (code);
+ }
+
++/* utility function used below */
++static void
++clean_up(kadm5_server_handle_t handle,
++ krb5_principal *server,
++ krb5_ccache *ccache)
++{
++ if (handle->destroy_cache && handle->cache_name) {
++ if (krb5_cc_resolve(handle->context,
++ handle->cache_name, &ccache) == 0)
++ (void) krb5_cc_destroy (handle->context, ccache);
++ }
++
++ free(handle->cache_name);
++ handle->cache_name = NULL;
++
++ if (handle->clnt && handle->clnt->cl_auth)
++ AUTH_DESTROY(handle->clnt->cl_auth);
++ if (handle->clnt) {
++ clnt_destroy(handle->clnt);
++ handle->clnt = NULL;
++ }
++
++ krb5_free_principal(handle->context, *server);
++ *server = NULL;
++}
++
+ static kadm5_ret_t
+ init_any(krb5_context context, char *client_name, enum init_type init_type,
+- char *pass, krb5_ccache ccache_in, char *svcname,
++ char *pass, krb5_ccache ccache_in, char **svcnames_in,
+ kadm5_config_params *params_in, krb5_ui_4 struct_version,
+ krb5_ui_4 api_version, char **db_args, void **server_handle)
+ {
+@@ -526,6 +635,10 @@
+
+ int code = 0;
+ generic_ret *r;
++ char **kadmin_srv_names = NULL;
++ char *tmp_srv_names[2] = {NULL, NULL};
++ char **svcname_ptr;
++ int i;
+
+ initialize_ovk_error_table();
+ /* initialize_adb_error_table(); */
+@@ -593,34 +706,56 @@
+ if (code)
+ goto error;
+
+- /* NULL svcname means use host-based. */
+- if (svcname == NULL) {
+- char **kadmin_srv_names;
++ if (svcnames_in == NULL || svcnames_in[0] == NULL) {
++ if (params_in && params_in->mask & KADM5_CONFIG_ADMIN_SERVER &&
++ params_in->admin_server != NULL) {
++ /* User passed in a admin server host name so use that */
++ if (asprintf(&tmp_srv_names[0], "%s@%s", KADM5_ADMIN_HOST_SERVICE,
++ params_in->admin_server) == -1) {
++ code = ENOMEM;
++ goto error;
++ }
++ svcname_ptr = tmp_srv_names;
++ } else {
++ /* Otherwise punt and get the admin server names. */
++ code = kadm5_get_adm_host_srv_names(context, handle->params.realm,
++ &kadmin_srv_names);
++ if (code)
++ goto error;
++ svcname_ptr = kadmin_srv_names;
++ }
++ } else {
++ svcname_ptr = svcnames_in;
++ }
+
+- code = kadm5_get_adm_host_srv_names(context, handle->params.realm,
+- &kadmin_srv_names);
+- if (code)
+- goto error;
+- svcname = strdup(kadmin_srv_names[0]);
+- free_srv_names(kadmin_srv_names);
+- if (svcname == NULL) {
+- code = ENOMEM;
+- goto error;
+- }
++ for (i = 0; svcname_ptr[i]; i++) {
++ /* Get credentials. */
++ code = get_init_creds(handle, client, init_type, pass, ccache_in,
++ svcname_ptr[i], handle->params.realm, &server);
++ if (code) {
++ if (code == KADM5_SECURE_PRINC_MISSING ||
++ code == KRB5_ERR_BAD_HOSTNAME) {
++ /* clean up for another go around */
++ clean_up(handle, &server, &ccache);
++ continue;
++ } else
++ goto error;
++ }
++
++ code = _kadm5_initialize_rpcsec_gss_handle(handle, client_name,
++ svcname_ptr[i]);
++ if (code) {
++ /* clean up for another go around */
++ clean_up(handle, &server, &ccache);
++ } else {
++ /* inited the rpcsec_gss handle, can stop looping now */
++ break;
++ }
+ }
+
+- /* Get credentials. */
+- code = get_init_creds(handle, client, init_type, pass, ccache_in,
+- svcname, handle->params.realm, &server);
+ if (code)
+ goto error;
+
+- code = _kadm5_initialize_rpcsec_gss_handle(handle, client_name,
+- svcname);
+- if (code != 0) {
+- goto error;
+- }
+-
+ *server_handle = (void *) handle;
+
+ goto cleanup;
+@@ -653,6 +788,8 @@
+ krb5_free_principal(handle->context, server);
+ if (code)
+ free(handle);
++ free_srv_names(kadmin_srv_names);
++ free(tmp_srv_names[0]);
+
+ return code;
+ }
+@@ -665,46 +802,43 @@
+ {
+ kadm5_ret_t code;
+ krb5_ccache ccache = NULL;
+- krb5_principal cprinc;
+ char svcbuf[BUFSIZ], *service, *host, *svcname, *save;
++ char strtok_buf[BUFSIZ];
+
+ *server_out = NULL;
+
+- /*
+- * Convert the RPCSEC_GSS version to the host based version as this
+- * is what gic expects.
+- */
+- if ((svcname = strdup(svcname_in)) == NULL) {
+- code = ENOMEM;
+- goto error;
+- }
+- if ((service = strtok_r(svcname, "@", &save)) != NULL) {
+- if ((host = strtok_r(NULL, "@", &save)) != NULL) {
+- char *str = NULL;
+- /*
+- * We want the canonical name here, via sname_to_principal.
+- */
+- code = krb5_sname_to_principal(handle->context, host, service,
+- KRB5_NT_SRV_HST, &cprinc);
+- if (code) {
+- free(svcname);
+- goto error;
+- }
+- code = krb5_unparse_name_flags(handle->context, cprinc,
+- KRB5_PRINCIPAL_UNPARSE_NO_REALM, &str);
+- krb5_free_principal(handle->context, cprinc);
+- if (code) {
+- free(svcname);
+- goto error;
+- }
+- (void) strncpy(svcbuf, str, sizeof(svcbuf));
+- krb5_free_unparsed_name(handle->context, str);
+- }
++ if (strpbrk(svcname_in, "@") == NULL) {
++ svcname = svcname_in;
+ } else {
+- strncpy(svcbuf, svcname, sizeof(svcbuf));
+- svcbuf[sizeof(svcname)-1] = '\0';
++ /*
++ * Convert the RPCSEC_GSS version to the host based version as this
++ * is what gic expects.
++ */
++ (void) strlcpy(strtok_buf, svcname_in, sizeof(strtok_buf));
++ service = strtok_r(strtok_buf, "@", &save);
++ if ((host = strtok_r(NULL, "@", &save)) != NULL) {
++ char *str = NULL;
++ krb5_principal cprinc;
++ /*
++ * We want the canonical name here, via sname_to_principal.
++ */
++ code = krb5_sname_to_principal(handle->context, host, service,
++ KRB5_NT_SRV_HST, &cprinc);
++ if (code)
++ goto error;
++
++ code = krb5_unparse_name_flags(handle->context, cprinc,
++ KRB5_PRINCIPAL_UNPARSE_NO_REALM,
++ &str);
++ krb5_free_principal(handle->context, cprinc);
++ if (code)
++ goto error;
++
++ (void) strlcpy(svcbuf, str, sizeof(svcbuf));
++ krb5_free_unparsed_name(handle->context, str);
++ svcname = svcbuf;
++ }
+ }
+- free(svcname);
+
+ /*
+ * Acquire a service ticket for svcname@realm for client, using password
+@@ -741,7 +875,7 @@
+ }
+ handle->lhandle->cache_name = handle->cache_name;
+
+- code = gic_iter(handle, init_type, ccache, client, pass, svcbuf, realm,
++ code = gic_iter(handle, init_type, ccache, client, pass, svcname, realm,
+ server_out);
+ /* Improved error messages */
+ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) code = KADM5_BAD_PASSWORD;
+diff -u -r old/src/lib/kadm5/clnt/libkadm5clnt_mit.exports new/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
+--- old/src/lib/kadm5/clnt/libkadm5clnt_mit.exports 2015-02-11 21:16:43.000000000 -0600
++++ new/src/lib/kadm5/clnt/libkadm5clnt_mit.exports 2015-05-28 15:34:35.828495806 -0500
+@@ -31,6 +31,11 @@
+ kadm5_init_with_creds
+ kadm5_init_with_password
+ kadm5_init_with_skey
++kadm5_init_mm
++kadm5_init_anonymous_mm
++kadm5_init_with_creds_mm
++kadm5_init_with_password_mm
++kadm5_init_with_skey_mm
+ kadm5_lock
+ kadm5_modify_policy
+ kadm5_modify_principal
+diff -u -r old/src/lib/kadm5/srv/server_init.c new/src/lib/kadm5/srv/server_init.c
+--- old/src/lib/kadm5/srv/server_init.c 2015-05-28 15:10:45.100182433 -0500
++++ new/src/lib/kadm5/srv/server_init.c 2015-05-29 12:40:47.354397224 -0500
+@@ -97,6 +97,29 @@
+ server_handle);
+ }
+
++/*
++ * The following *_mm() functions are also defined here because kadmin.local
++ * shares the same source as kadmin. One difference however is that
++ * kadmin.local links with libkadm5srv_mit.so instead of libkadm5clnt_mit.so so
++ * these functions must also be defined here. Given kadmin.local can only
++ * operate on one server, the *_mm() functions just pass in the first server in
++ * the list of service_names.
++ */
++kadm5_ret_t kadm5_init_with_password_mm(krb5_context context,
++ char *client_name,
++ char *pass, char **service_names,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle)
++{
++ return kadm5_init_with_password(context, client_name, pass,
++ service_names ? service_names[0] : NULL,
++ params, struct_version, api_version,
++ db_args, server_handle);
++}
++
+ kadm5_ret_t kadm5_init_anonymous(krb5_context context, char *client_name,
+ char *service_name,
+ kadm5_config_params *params,
+@@ -110,6 +133,20 @@
+ server_handle);
+ }
+
++kadm5_ret_t kadm5_init_anonymous_mm(krb5_context context, char *client_name,
++ char **service_names,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle)
++{
++ return kadm5_init_anonymous(context, client_name,
++ service_names ? service_names[0] : NULL,
++ params, struct_version, api_version,
++ db_args, server_handle);
++}
++
+ kadm5_ret_t kadm5_init_with_creds(krb5_context context,
+ char *client_name,
+ krb5_ccache ccache,
+@@ -133,6 +170,22 @@
+ server_handle);
+ }
+
++kadm5_ret_t kadm5_init_with_creds_mm(krb5_context context,
++ char *client_name,
++ krb5_ccache ccache,
++ char **service_names,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle)
++{
++ return kadm5_init_with_creds(context, client_name, ccache,
++ service_names ? service_names[0] : NULL,
++ params, struct_version, api_version,
++ db_args, server_handle);
++}
++
+
+ kadm5_ret_t kadm5_init_with_skey(krb5_context context, char *client_name,
+ char *keytab, char *service_name,
+@@ -155,6 +208,20 @@
+ server_handle);
+ }
+
++kadm5_ret_t kadm5_init_with_skey_mm(krb5_context context, char *client_name,
++ char *keytab, char **service_names,
++ kadm5_config_params *params,
++ krb5_ui_4 struct_version,
++ krb5_ui_4 api_version,
++ char **db_args,
++ void **server_handle)
++{
++ return kadm5_init_with_skey(context, client_name, keytab,
++ service_names ? service_names[0] : NULL,
++ params, struct_version, api_version, db_args,
++ server_handle);
++}
++
+ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
+ char *service_name,
+ kadm5_config_params *params_in,
+diff -u -r old/src/slave/kpropd.c new/src/slave/kpropd.c
+--- old/src/slave/kpropd.c 2015-05-28 15:10:45.194095824 -0500
++++ new/src/slave/kpropd.c 2015-05-29 12:17:56.397347156 -0500
+@@ -609,7 +609,7 @@
+ kadm5_ret_t retval;
+ krb5_principal iprop_svc_principal;
+ void *server_handle = NULL;
+- char *iprop_svc_princstr = NULL, *master_svc_princstr = NULL;
++ char *iprop_svc_princstr = NULL, **master_svc_princstrs = NULL;
+ unsigned int pollin, backoff_time;
+ int backoff_cnt = 0, reinit_cnt = 0;
+ struct timeval iprop_start, iprop_end;
+@@ -639,22 +639,9 @@
+ params.mask |= KADM5_CONFIG_REALM;
+ params.realm = def_realm;
+
+- if (master_svc_princstr == NULL) {
+-#if 0
+- retval = kadm5_get_kiprop_host_srv_name(kpropd_context, def_realm,
+- &master_svc_princstr);
+- if (retval) {
+- com_err(progname, retval,
+- _("%s: unable to get kiprop host based "
+- "service name for realm %s\n"),
+- progname, def_realm);
+- return retval;
+- }
+-#endif
+- char **kiprop_srv_names;
+-
++ if (master_svc_princstrs == NULL) {
+ retval = kadm5_get_kiprop_host_srv_names(kpropd_context, def_realm,
+- &kiprop_srv_names);
++ &master_svc_princstrs);
+ if (retval) {
+ com_err(progname, retval,
+ _("%s: unable to get kiprop host based "
+@@ -662,15 +649,6 @@
+ progname, def_realm);
+ return retval;
+ }
+- master_svc_princstr = strdup(kiprop_srv_names[0]);
+- free_srv_names(kiprop_srv_names);
+- if (master_svc_princstr == NULL) {
+- com_err(progname, retval,
+- _("%s: unable to allocate memory for kiprop host based "
+- "service name for realm %s\n"),
+- progname, def_realm);
+- return ENOMEM;
+- }
+ }
+
+ retval = krb5_sname_to_principal(kpropd_context, NULL, KIPROP_SVC_NAME,
+@@ -714,9 +692,9 @@
+ fprintf(stderr, _("Initializing kadm5 as client %s\n"),
+ iprop_svc_princstr);
+ }
+- retval = kadm5_init_with_skey(kpropd_context, iprop_svc_princstr,
++ retval = kadm5_init_with_skey_mm(kpropd_context, iprop_svc_princstr,
+ srvtab,
+- master_svc_princstr,
++ master_svc_princstrs,
+ ¶ms,
+ KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_4,
+@@ -1014,7 +992,7 @@
+ syslog(LOG_ERR, _("ERROR returned by master KDC, bailing.\n"));
+ done:
+ free(iprop_svc_princstr);
+- free(master_svc_princstr);
++ free_srv_names(master_svc_princstrs);
+ krb5_free_default_realm(kpropd_context, def_realm);
+ kadm5_destroy(server_handle);
+ krb5_free_context(kpropd_context);