components/krb5/patches/035-multi-master.patch
author Shawn Emery <shawn.emery@oracle.com>
Wed, 11 May 2016 20:33:52 -0700
changeset 5969 96bac9fbcfbd
parent 5490 9bf0bc57423a
child 5986 bab15c34f645
permissions -rw-r--r--
PSARC/2016/244 Sync MIT Kerberos to 1.14.2 22954706 Should synchronize with MIT Kerberos 1.14 23116276 Userland krb pkgs must have mediation removed

#
# 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 -pur new/src/kadmin/cli/kadmin.c old/src/kadmin/cli/kadmin.c
--- old/src/kadmin/cli/kadmin.c	2016-03-31 16:44:43.282366236 -0700
+++ patched/src/kadmin/cli/kadmin.c	2016-03-31 19:24:20.929551275 -0700
@@ -255,7 +255,7 @@ kadmin_startup(int argc, char *argv[], c
     char **db_args = NULL;
     int db_args_size = 0;
     char *db_name = NULL;
-    char *svcname, *realm;
+    char **svcnames = NULL, *realm;
 
     memset(&params, 0, sizeof(params));
 
@@ -370,11 +370,6 @@ kadmin_startup(int argc, char *argv[], c
     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.
@@ -503,13 +498,14 @@ kadmin_startup(int argc, char *argv[], c
     if (ccache_name) {
         info(_("Authenticating as principal %s with existing "
                "credentials.\n"), princstr);
-        retval = kadm5_init_with_creds(context, princstr, cc, svcname, &params,
+        retval = kadm5_init_with_creds_mm(context, princstr, cc, svcnames,
+                                       &params,
                                        KADM5_STRUCT_VERSION,
                                        KADM5_API_VERSION_4, db_args, &handle);
     } else if (use_anonymous) {
         info(_("Authenticating as principal %s with password; "
                "anonymous requested.\n"), princstr);
-        retval = kadm5_init_anonymous(context, princstr, svcname, &params,
+        retval = kadm5_init_anonymous_mm(context, princstr, svcnames, &params,
                                       KADM5_STRUCT_VERSION,
                                       KADM5_API_VERSION_4, db_args, &handle);
     } else if (use_keytab) {
@@ -520,17 +516,20 @@ kadmin_startup(int argc, char *argv[], c
             info(_("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,
                                       &params, KADM5_STRUCT_VERSION,
                                       KADM5_API_VERSION_4, db_args, &handle);
     } else {
         info(_("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,
                                           &params, 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);
/usr/gnu/bin/diff -pur old/src/lib/kadm5/clnt/client_init.c new/src/lib/kadm5/clnt/client_init.c
--- unpatched/src/lib/kadm5/clnt/client_init.c	2016-03-28 00:19:36.988270188 -0600
+++ patched/src/lib/kadm5/clnt/client_init.c	2016-03-28 13:12:43.769371355 -0600
@@ -55,7 +55,7 @@ enum init_type { INIT_PASS, INIT_SKEY, I
 
 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 @@ kadm5_init_with_creds(krb5_context conte
                       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 @@ kadm5_init_with_password(krb5_context co
                          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 @@ kadm5_init_anonymous(krb5_context contex
                      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 @@ kadm5_init(krb5_context context, char *c
            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 @@ kadm5_init_with_skey(krb5_context contex
                      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);
 }
 
@@ -339,7 +422,7 @@ _kadm5_initialize_rpcsec_gss_handle(kadm
 	}
 
 	/*
-	 * 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
@@ -512,9 +595,35 @@ cleanup:
 	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)
 {
@@ -532,6 +641,10 @@ init_any(krb5_context context, char *cli
 
     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(); */
@@ -599,34 +712,56 @@ init_any(krb5_context context, char *cli
     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;
@@ -659,6 +794,8 @@ cleanup:
     krb5_free_principal(handle->context, server);
     if (code)
         free(handle);
+    free_srv_names(kadmin_srv_names);
+    free(tmp_srv_names[0]);
 
     return code;
 }
@@ -671,46 +808,43 @@ get_init_creds(kadm5_server_handle_t han
 {
     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
@@ -747,7 +881,7 @@ get_init_creds(kadm5_server_handle_t han
     }
     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,
                                   &params,
                                   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);