components/krb5/Solaris/kadm_host_srv_names.c
changeset 5490 9bf0bc57423a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/Solaris/kadm_host_srv_names.c	Wed Feb 24 10:43:57 2016 -0600
@@ -0,0 +1,245 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * lib/kad5/kadm_host_srv_names.c
+ */
+
+#include <k5-int.h>
+#include "admin.h"
+#include <stdio.h>
+#include "fake-addrinfo.h"
+/* HACK!!! need struct serverlist*/
+#include "../krb5/os/os-proto.h"
+
+/* HACK!!! */
+#define	KADM5_ADMIN_HOST_SERVICE	"kadmin"
+#define	KADM5_CHANGEPW_HOST_SERVICE	"changepw"
+
+extern krb5_error_code
+k5_locate_kadmin(krb5_context context, const krb5_data *realm,
+		                 struct serverlist *serverlist);
+
+extern krb5_error_code
+locate_kpasswd(krb5_context context, const krb5_data *realm,
+	       struct serverlist *serverlist, krb5_boolean no_udp);
+
+/*
+ * Find the admin server for the given realm. If the realm is null or
+ * the empty string, find the admin server for the default realm.
+ * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
+ * free the storage allocated to the admin server, master.
+ */
+kadm5_ret_t
+kadm5_get_master(krb5_context context, const char *realm, char **master)
+{
+    kadm5_ret_t		ret = KADM5_OK;
+    char		*def_realm = NULL;
+    krb5_error_code	code;
+    struct serverlist	serverlist = SERVERLIST_INIT;
+    struct server_entry	*entry;
+    krb5_data		krealm;
+
+    if (realm == 0 || *realm == '\0')
+	krb5_get_default_realm(context, &def_realm);
+
+    krealm = string2data(def_realm ? def_realm : (char *) realm);
+
+    code = k5_locate_server(context, &krealm, &serverlist,
+				locate_service_kadmin, TRUE);
+    if (code == 0) {
+	entry = &serverlist.servers[0];
+	*master = strdup(entry->hostname);
+	if (*master == NULL)
+	    ret = ENOMEM;
+    } else
+	ret = KADM5_NO_SRV;
+			
+    if (def_realm != NULL)
+	krb5_free_default_realm(context, def_realm);
+
+    k5_free_serverlist(&serverlist);
+
+    return (ret);
+}
+
+void
+free_srv_names(char **srv_names)
+{
+    int i;
+
+    if (srv_names == NULL)
+        return;
+    
+    for (i = 0; srv_names[i] != NULL; i++) {
+        free(srv_names[i]);
+    }
+
+    free(srv_names);
+}
+
+/*
+ * Get the host base service name for the admin principal. Returns
+ * KADM5_OK on success. Caller must call free_srv_names() on
+ * host_service_names.
+ */
+kadm5_ret_t
+kadm5_get_adm_host_srv_names(krb5_context context,
+			    const char *realm, char ***host_service_names)
+{
+    kadm5_ret_t ret;
+    char **tmp_srv_names;
+    struct serverlist sl = SERVERLIST_INIT;
+    int i;
+    krb5_data realm_data;
+
+    /* get list of admin servers */
+    if (realm == NULL)
+        return (EINVAL);
+    realm_data.magic = KV5M_DATA;
+    realm_data.data = (char *) realm;
+    realm_data.length = strlen(realm);
+    if (ret = k5_locate_kadmin(context, (const krb5_data *) &realm_data, &sl))
+        return (ret);
+
+    /* + 1 for array terminator */
+    tmp_srv_names = calloc(sl.nservers + 1, sizeof (char *));
+    if (tmp_srv_names == NULL) {
+        k5_free_serverlist(&sl);
+        return (ENOMEM);
+    }
+
+    for (i = 0; i < sl.nservers; i++) {
+        tmp_srv_names[i] = malloc(strlen(KADM5_ADMIN_HOST_SERVICE) +
+                                  strlen(sl.servers[i].hostname) + 2);
+        if (tmp_srv_names[i] == NULL) {
+            free_srv_names(tmp_srv_names);
+            k5_free_serverlist(&sl);
+            return (ENOMEM);
+        }
+        sprintf(tmp_srv_names[i], "%s@%s", KADM5_ADMIN_HOST_SERVICE,
+                sl.servers[i].hostname);
+    }
+
+    k5_free_serverlist(&sl);
+    *host_service_names = tmp_srv_names;
+    return (KADM5_OK);
+}
+
+/*
+ * Get the host base service name for the changepw principal. Returns
+ * KADM5_OK on success. Caller must call free_srv_names() on
+ * host_service_names.
+ */
+kadm5_ret_t
+kadm5_get_cpw_host_srv_names(krb5_context context,
+			    const char *realm, char ***host_service_names)
+{
+    kadm5_ret_t ret;
+    char **tmp_srv_names;
+    struct serverlist sl = SERVERLIST_INIT;
+    int i;
+    krb5_data realm_data;
+
+    /* get list of admin servers */
+    if (realm == NULL)
+        return (EINVAL);
+    realm_data.magic = KV5M_DATA;
+    realm_data.data = (char *) realm;
+    realm_data.length = strlen(realm);
+    if (ret = locate_kpasswd(context, (const krb5_data *) &realm_data, &sl, 0))
+        return (ret);
+
+    /* + 1 for array terminator */
+    tmp_srv_names = calloc(sl.nservers + 1, sizeof (char *));
+    if (tmp_srv_names == NULL) {
+        k5_free_serverlist(&sl);
+        return (ENOMEM);
+    }
+
+    for (i = 0; i < sl.nservers; i++) {
+        tmp_srv_names[i] = malloc(strlen(KADM5_CHANGEPW_HOST_SERVICE) +
+                                  strlen(sl.servers[i].hostname) + 2);
+        if (tmp_srv_names[i] == NULL) {
+            free_srv_names(tmp_srv_names);
+            k5_free_serverlist(&sl);
+            return (ENOMEM);
+        }
+        sprintf(tmp_srv_names[i], "%s@%s", KADM5_CHANGEPW_HOST_SERVICE,
+                sl.servers[i].hostname);
+    }
+
+    k5_free_serverlist(&sl);
+    *host_service_names = tmp_srv_names;
+    return (KADM5_OK);
+}
+
+/*
+ * Get the host base service name for the kiprop principal. Returns
+ * KADM5_OK on success. Caller must free the storage allocated
+ * for host_service_name.
+ */
+kadm5_ret_t
+kadm5_get_kiprop_host_srv_names(krb5_context context,
+                               const char *realm,
+                               char ***host_service_names)
+{
+    kadm5_ret_t ret;
+    char **tmp_srv_names;
+    struct serverlist sl = SERVERLIST_INIT;
+    int i;
+    krb5_data realm_data;
+
+    /* get list of admin servers */
+    if (realm == NULL)
+        return (EINVAL);
+    realm_data.magic = KV5M_DATA;
+    realm_data.data = (char *) realm;
+    realm_data.length = strlen(realm);
+    if (ret = k5_locate_kadmin(context, (const krb5_data *) &realm_data, &sl))
+        return (ret);
+
+    /* + 1 for array terminator */
+    tmp_srv_names = calloc(sl.nservers + 1, sizeof (char *));
+    if (tmp_srv_names == NULL) {
+        k5_free_serverlist(&sl);
+        return (ENOMEM);
+    }
+
+    for (i = 0; i < sl.nservers; i++) {
+        tmp_srv_names[i] = malloc(strlen(KADM5_KIPROP_HOST_SERVICE) +
+                                  strlen(sl.servers[i].hostname) + 2);
+        if (tmp_srv_names[i] == NULL) {
+            free_srv_names(tmp_srv_names);
+            k5_free_serverlist(&sl);
+            return (ENOMEM);
+        }
+        sprintf(tmp_srv_names[i], "%s@%s", KADM5_KIPROP_HOST_SERVICE,
+                sl.servers[i].hostname);
+    }
+
+    k5_free_serverlist(&sl);
+    *host_service_names = tmp_srv_names;
+    return (KADM5_OK);
+}