changeset 12567:f6b7e92780d6

6954931 kclient(1M) should use new profile APIs, at least AD domain joins
author Shawn Emery <Shawn.Emery@Sun.COM>
date Mon, 07 Jun 2010 01:47:20 -0600
parents 8c45f76d0972
children 0f6ea478c2c7
files usr/src/cmd/krb5/kadmin/kclient/Makefile usr/src/cmd/krb5/kadmin/kclient/kclient.sh usr/src/cmd/krb5/kadmin/kclient/kconf.c usr/src/pkg/manifests/system-security-kerberos-5.mf
diffstat 4 files changed, 247 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/krb5/kadmin/kclient/Makefile	Mon Jun 07 01:47:20 2010 -0600
+++ b/usr/src/cmd/krb5/kadmin/kclient/Makefile	Mon Jun 07 01:47:20 2010 -0600
@@ -18,17 +18,15 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# ident	"%Z%%M%	%I%	%E% SMI"
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 # Makefile for Kerberos client-install utility.
 #
 
 PROG=		ksetpw \
 		kdyndns \
-		ksmb
+		ksmb \
+		kconf
 
 SHFILES=	kclient
 SECFILES=	pam_krb5_first \
@@ -45,8 +43,9 @@
 KS_OBJS=	ksetpw.o
 KD_OBJS=	kdyndns.o
 KSMB_OBJS=	ksmb.o
+KC_OBJS=	kconf.o
 
-OBJS=		$(KS_OBJS) $(KD_OBJS) $(KSMB_OBJS)
+OBJS=		$(KS_OBJS) $(KD_OBJS) $(KSMB_OBJS) $(KC_OBJS)
 
 SSRCS=	kclient.sh
 SRCS=	$(OBJS:%.o=%.c)
@@ -64,10 +63,12 @@
 ksetpw:=	LDFLAGS += $(KRUNPATH)
 kdyndns:=	LDFLAGS += -R/usr/lib/smbsrv
 ksmb:=		LDFLAGS += -R/usr/lib/smbsrv
+kconf:=		LDFLAGS += $(KRUNPATH)
 
 KS_LDLIBS =	$(LDLIBS) $(KMECHLIB)
 KD_LDLIBS =	$(LDLIBS) -L$(ROOT)/usr/lib/smbsrv -lsmbns
 KSMB_LDLIBS =	$(LDLIBS) -L$(ROOT)/usr/lib/smbsrv -lsmb
+KC_LDLIBS =	$(LDLIBS) $(KMECHLIB)
 
 .KEEP_STATE:
 
@@ -87,6 +88,10 @@
 	$(LINK.c) $(KS_OBJS) -o $@ $(KS_LDLIBS)
 	$(POST_PROCESS)
 
+kconf:		$(KC_OBJS)
+	$(LINK.c) $(KC_OBJS) -o $@ $(KC_LDLIBS)
+	$(POST_PROCESS)
+
 $(KRB5SBIN):
 	$(INS.dir)
 
--- a/usr/src/cmd/krb5/kadmin/kclient/kclient.sh	Mon Jun 07 01:47:20 2010 -0600
+++ b/usr/src/cmd/krb5/kadmin/kclient/kclient.sh	Mon Jun 07 01:47:20 2010 -0600
@@ -19,8 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 # This script is used to setup the Kerberos client by
 # supplying information about the Kerberos realm and kdc.
@@ -861,36 +860,27 @@
 }
 
 function write_ads_krb5conf {
+	typeset kdcs
+
 	printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE
 
-	exec 3>$KRB5_CONFIG
-	if [[ $? -ne 0 ]]; then
-		printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG >&2
-		error_message
-	fi
-
-	printf "[libdefaults]\n" 1>&3
-	printf "\tdefault_realm = $realm\n" 1>&3
-	printf "\n[realms]\n" 1>&3
-	printf "\t$realm = {\n" 1>&3
 	for i in ${KDCs[@]}
 	do
 		[[ $i == +([0-9]) ]] && continue
-		printf "\t\tkdc = $i\n" 1>&3
+		if [[ -n $kdcs ]]
+		then
+			kdcs="$kdcs,$i"
+		else
+			kdcs=$i
+		fi
 	done
-	# Defining the same as admin_server.  This would cause auth failures
-	# if this was different.
-	printf "\n\t\tkpasswd_server = $KDC\n" 1>&3
-	printf "\n\t\tadmin_server = $KDC\n" 1>&3
-	printf "\t\tkpasswd_protocol = SET_CHANGE\n\t}\n" 1>&3
-	printf "\n[domain_realm]\n" 1>&3
-	printf "\t.$dom = $realm\n\n" 1>&3
-	printf "[logging]\n" 1>&3
-	printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3
-	printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3
-	printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3
-	printf "[appdefaults]\n" 1>&3
-	printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n\t}\n" 1>&3
+
+	$KCONF -f $KRB5_CONFIG -r $realm -k $kdcs -m $KDC -p SET_CHANGE -d .$dom
+
+	if [[ $? -ne 0 ]]; then
+		printf "\n$(gettext "Can not update %s, exiting").\n" $KRB5_CONFIG >&2
+		error_message
+	fi
 }
 
 function getForestName {
@@ -1576,6 +1566,7 @@
 KSETPW=/usr/lib/krb5/ksetpw;	check_bin $KSETPW
 KSMB=/usr/lib/krb5/ksmb;	check_bin $KSMB
 KDYNDNS=/usr/lib/krb5/kdyndns;	check_bin $KDYNDNS
+KCONF=/usr/lib/krb5/kconf;	check_bin $KCONF
 
 dns_lookup=no
 ask_fqdns=no
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/krb5/kadmin/kclient/kconf.c	Mon Jun 07 01:47:20 2010 -0600
@@ -0,0 +1,217 @@
+/*
+ * 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) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <locale.h>
+#include <errno.h>
+#include <krb5.h>
+#include <profile.h>
+#include <com_err.h>
+
+struct profile_string_list {
+	char	**list;
+	int	num;
+	int	max;
+};
+
+/*
+ * From prof_get.c as the following four functions are private in mech_krb5.
+ */
+/*
+ * Initialize the string list abstraction.
+ */
+static errcode_t
+init_list(struct profile_string_list *list)
+{
+	list->num = 0;
+	list->max = 10;
+	list->list = malloc(list->max * sizeof (char *));
+	if (list->list == NULL)
+		return (ENOMEM);
+	list->list[0] = NULL;
+	return (0);
+}
+
+/*
+ * If re_list is non-NULL then pass the list header to the caller else free
+ * the previously allocated list.
+ */
+static void
+end_list(struct profile_string_list *list, char ***ret_list)
+{
+
+	if (list == NULL)
+		return;
+
+	if (ret_list) {
+		*ret_list = list->list;
+		return;
+	} else
+		profile_free_list(list->list);
+	list->num = list->max = 0;
+	list->list = NULL;
+}
+
+/*
+ * Add a string to the list.
+ */
+static errcode_t
+add_to_list(struct profile_string_list *list, const char *str)
+{
+	char 	*newstr, **newlist;
+	int	newmax;
+
+	if (list->num + 1 >= list->max) {
+		newmax = list->max + 10;
+		newlist = realloc(list->list, newmax * sizeof (char *));
+		if (newlist == NULL)
+			return (ENOMEM);
+		list->max = newmax;
+		list->list = newlist;
+	}
+	newstr = strdup(str);
+	if (newstr == NULL)
+		return (ENOMEM);
+
+	list->list[list->num++] = newstr;
+	list->list[list->num] = NULL;
+	return (0);
+}
+
+static void
+usage()
+{
+	(void) fprintf(stderr, gettext("kconf -f <file> -r <realm> "
+	    "-k <kdc[,kdc]> -m <master_kdc>\n -p <kpasswd_protocol> "
+	    "-d <domain>\n"));
+
+	exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+	profile_t	profile;
+	errcode_t	code;
+	char		c, *realm, *kdcs, *master, *domain, *token, *lasts;
+	char		*file, **ret_values = NULL;
+	boolean_t	set_change = FALSE;
+	struct profile_string_list values;
+
+	(void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define	TEXT_DOMAIN "SYS_TEST"
+#endif /* TEXT_DOMAIN */
+
+	(void) textdomain(TEXT_DOMAIN);
+
+	/*
+	 * kconf -f <file> -r <realm> -k <kdc[,kdc]> -m <master_kdc>
+	 * -p <kpasswd_protocol> -d <domain>
+	 */
+	while ((c = getopt(argc, argv, "f:r:k:a:s:p:d:m:")) != -1) {
+		switch (c) {
+		case 'f':
+			file = optarg;
+			break;
+		case 'r':
+			realm = optarg;
+			break;
+		case 'k':
+			kdcs = optarg;
+			break;
+		case 'm':
+			master = optarg;
+			break;
+		case 'p':
+			if (strcmp(optarg, "SET_CHANGE") == 0)
+				set_change = TRUE;
+			break;
+		case 'd':
+			domain = optarg;
+			break;
+		default:
+			usage();
+			break;
+		}
+	}
+
+	code = __profile_init(file, &profile);
+	if (code != 0) {
+		fprintf(stderr, gettext("Wasn't able to initialize profile\n"));
+		exit(code);
+	}
+
+	if (code = init_list(&values)) {
+		fprintf(stderr, gettext("Can not initialize list %d\n"), code);
+		goto error;
+	}
+	token = strtok_r(kdcs, ",", &lasts);
+	do {
+		if (token != NULL) {
+			code = add_to_list(&values, token);
+			if (code != 0) {
+				fprintf(stderr, gettext("Can not add to list "
+				    "%d\n"), code);
+				goto error;
+			}
+		} else {
+			fprintf(stderr, gettext("Couldn't parse kdc list %d\n"),
+			    code);
+			goto error;
+		}
+	} while ((token = strtok_r(NULL, ",", &lasts)) != NULL);
+	end_list(&values, &ret_values);
+
+	code = __profile_add_realm(profile, realm, master, ret_values,
+	    set_change, TRUE);
+	if (code != 0) {
+		fprintf(stderr, gettext("Wasn't able to add realm "
+		    "information\n"));
+		goto error;
+	}
+
+	code = __profile_add_domain_mapping(profile, domain, realm);
+	if (code != 0) {
+		fprintf(stderr, gettext("Wasn't able to add domain mapping\n"));
+		goto error;
+	}
+
+error:
+	if (ret_values != NULL)
+		profile_free_list(ret_values);
+
+	/*
+	 * Release profile, which will subsequently flush new profile to file.
+	 * If this fails then at least free profile memory.
+	 */
+	if ((code =  __profile_release(profile)) != NULL)
+		__profile_abandon(profile);
+
+	return (code);
+}
--- a/usr/src/pkg/manifests/system-security-kerberos-5.mf	Mon Jun 07 01:47:20 2010 -0600
+++ b/usr/src/pkg/manifests/system-security-kerberos-5.mf	Mon Jun 07 01:47:20 2010 -0600
@@ -20,8 +20,7 @@
 #
 
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 set name=pkg.fmri value=pkg:/system/security/kerberos-5@$(PKGVERS)
@@ -62,6 +61,7 @@
 file path=usr/lib/krb5/db2.so.1
 file path=usr/lib/krb5/gkadmin.jar mode=0444
 file path=usr/lib/krb5/kadmind mode=0500
+file path=usr/lib/krb5/kconf mode=0555
 file path=usr/lib/krb5/kdyndns mode=0555
 file path=usr/lib/krb5/kldap.so.1
 file path=usr/lib/krb5/klookup mode=0555