xref: /onnv-gate/usr/src/cmd/krb5/kadmin/kclient/kconf.c (revision 12567:f6b7e92780d6)
1*12567SShawn.Emery@Sun.COM /*
2*12567SShawn.Emery@Sun.COM  * CDDL HEADER START
3*12567SShawn.Emery@Sun.COM  *
4*12567SShawn.Emery@Sun.COM  * The contents of this file are subject to the terms of the
5*12567SShawn.Emery@Sun.COM  * Common Development and Distribution License (the "License").
6*12567SShawn.Emery@Sun.COM  * You may not use this file except in compliance with the License.
7*12567SShawn.Emery@Sun.COM  *
8*12567SShawn.Emery@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12567SShawn.Emery@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12567SShawn.Emery@Sun.COM  * See the License for the specific language governing permissions
11*12567SShawn.Emery@Sun.COM  * and limitations under the License.
12*12567SShawn.Emery@Sun.COM  *
13*12567SShawn.Emery@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12567SShawn.Emery@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12567SShawn.Emery@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12567SShawn.Emery@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12567SShawn.Emery@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12567SShawn.Emery@Sun.COM  *
19*12567SShawn.Emery@Sun.COM  * CDDL HEADER END
20*12567SShawn.Emery@Sun.COM  */
21*12567SShawn.Emery@Sun.COM 
22*12567SShawn.Emery@Sun.COM /*
23*12567SShawn.Emery@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12567SShawn.Emery@Sun.COM  */
25*12567SShawn.Emery@Sun.COM 
26*12567SShawn.Emery@Sun.COM #include <stdio.h>
27*12567SShawn.Emery@Sun.COM #include <stdlib.h>
28*12567SShawn.Emery@Sun.COM #include <strings.h>
29*12567SShawn.Emery@Sun.COM #include <locale.h>
30*12567SShawn.Emery@Sun.COM #include <errno.h>
31*12567SShawn.Emery@Sun.COM #include <krb5.h>
32*12567SShawn.Emery@Sun.COM #include <profile.h>
33*12567SShawn.Emery@Sun.COM #include <com_err.h>
34*12567SShawn.Emery@Sun.COM 
35*12567SShawn.Emery@Sun.COM struct profile_string_list {
36*12567SShawn.Emery@Sun.COM 	char	**list;
37*12567SShawn.Emery@Sun.COM 	int	num;
38*12567SShawn.Emery@Sun.COM 	int	max;
39*12567SShawn.Emery@Sun.COM };
40*12567SShawn.Emery@Sun.COM 
41*12567SShawn.Emery@Sun.COM /*
42*12567SShawn.Emery@Sun.COM  * From prof_get.c as the following four functions are private in mech_krb5.
43*12567SShawn.Emery@Sun.COM  */
44*12567SShawn.Emery@Sun.COM /*
45*12567SShawn.Emery@Sun.COM  * Initialize the string list abstraction.
46*12567SShawn.Emery@Sun.COM  */
47*12567SShawn.Emery@Sun.COM static errcode_t
init_list(struct profile_string_list * list)48*12567SShawn.Emery@Sun.COM init_list(struct profile_string_list *list)
49*12567SShawn.Emery@Sun.COM {
50*12567SShawn.Emery@Sun.COM 	list->num = 0;
51*12567SShawn.Emery@Sun.COM 	list->max = 10;
52*12567SShawn.Emery@Sun.COM 	list->list = malloc(list->max * sizeof (char *));
53*12567SShawn.Emery@Sun.COM 	if (list->list == NULL)
54*12567SShawn.Emery@Sun.COM 		return (ENOMEM);
55*12567SShawn.Emery@Sun.COM 	list->list[0] = NULL;
56*12567SShawn.Emery@Sun.COM 	return (0);
57*12567SShawn.Emery@Sun.COM }
58*12567SShawn.Emery@Sun.COM 
59*12567SShawn.Emery@Sun.COM /*
60*12567SShawn.Emery@Sun.COM  * If re_list is non-NULL then pass the list header to the caller else free
61*12567SShawn.Emery@Sun.COM  * the previously allocated list.
62*12567SShawn.Emery@Sun.COM  */
63*12567SShawn.Emery@Sun.COM static void
end_list(struct profile_string_list * list,char *** ret_list)64*12567SShawn.Emery@Sun.COM end_list(struct profile_string_list *list, char ***ret_list)
65*12567SShawn.Emery@Sun.COM {
66*12567SShawn.Emery@Sun.COM 
67*12567SShawn.Emery@Sun.COM 	if (list == NULL)
68*12567SShawn.Emery@Sun.COM 		return;
69*12567SShawn.Emery@Sun.COM 
70*12567SShawn.Emery@Sun.COM 	if (ret_list) {
71*12567SShawn.Emery@Sun.COM 		*ret_list = list->list;
72*12567SShawn.Emery@Sun.COM 		return;
73*12567SShawn.Emery@Sun.COM 	} else
74*12567SShawn.Emery@Sun.COM 		profile_free_list(list->list);
75*12567SShawn.Emery@Sun.COM 	list->num = list->max = 0;
76*12567SShawn.Emery@Sun.COM 	list->list = NULL;
77*12567SShawn.Emery@Sun.COM }
78*12567SShawn.Emery@Sun.COM 
79*12567SShawn.Emery@Sun.COM /*
80*12567SShawn.Emery@Sun.COM  * Add a string to the list.
81*12567SShawn.Emery@Sun.COM  */
82*12567SShawn.Emery@Sun.COM static errcode_t
add_to_list(struct profile_string_list * list,const char * str)83*12567SShawn.Emery@Sun.COM add_to_list(struct profile_string_list *list, const char *str)
84*12567SShawn.Emery@Sun.COM {
85*12567SShawn.Emery@Sun.COM 	char 	*newstr, **newlist;
86*12567SShawn.Emery@Sun.COM 	int	newmax;
87*12567SShawn.Emery@Sun.COM 
88*12567SShawn.Emery@Sun.COM 	if (list->num + 1 >= list->max) {
89*12567SShawn.Emery@Sun.COM 		newmax = list->max + 10;
90*12567SShawn.Emery@Sun.COM 		newlist = realloc(list->list, newmax * sizeof (char *));
91*12567SShawn.Emery@Sun.COM 		if (newlist == NULL)
92*12567SShawn.Emery@Sun.COM 			return (ENOMEM);
93*12567SShawn.Emery@Sun.COM 		list->max = newmax;
94*12567SShawn.Emery@Sun.COM 		list->list = newlist;
95*12567SShawn.Emery@Sun.COM 	}
96*12567SShawn.Emery@Sun.COM 	newstr = strdup(str);
97*12567SShawn.Emery@Sun.COM 	if (newstr == NULL)
98*12567SShawn.Emery@Sun.COM 		return (ENOMEM);
99*12567SShawn.Emery@Sun.COM 
100*12567SShawn.Emery@Sun.COM 	list->list[list->num++] = newstr;
101*12567SShawn.Emery@Sun.COM 	list->list[list->num] = NULL;
102*12567SShawn.Emery@Sun.COM 	return (0);
103*12567SShawn.Emery@Sun.COM }
104*12567SShawn.Emery@Sun.COM 
105*12567SShawn.Emery@Sun.COM static void
usage()106*12567SShawn.Emery@Sun.COM usage()
107*12567SShawn.Emery@Sun.COM {
108*12567SShawn.Emery@Sun.COM 	(void) fprintf(stderr, gettext("kconf -f <file> -r <realm> "
109*12567SShawn.Emery@Sun.COM 	    "-k <kdc[,kdc]> -m <master_kdc>\n -p <kpasswd_protocol> "
110*12567SShawn.Emery@Sun.COM 	    "-d <domain>\n"));
111*12567SShawn.Emery@Sun.COM 
112*12567SShawn.Emery@Sun.COM 	exit(1);
113*12567SShawn.Emery@Sun.COM }
114*12567SShawn.Emery@Sun.COM 
115*12567SShawn.Emery@Sun.COM int
main(int argc,char ** argv)116*12567SShawn.Emery@Sun.COM main(int argc, char **argv)
117*12567SShawn.Emery@Sun.COM {
118*12567SShawn.Emery@Sun.COM 	profile_t	profile;
119*12567SShawn.Emery@Sun.COM 	errcode_t	code;
120*12567SShawn.Emery@Sun.COM 	char		c, *realm, *kdcs, *master, *domain, *token, *lasts;
121*12567SShawn.Emery@Sun.COM 	char		*file, **ret_values = NULL;
122*12567SShawn.Emery@Sun.COM 	boolean_t	set_change = FALSE;
123*12567SShawn.Emery@Sun.COM 	struct profile_string_list values;
124*12567SShawn.Emery@Sun.COM 
125*12567SShawn.Emery@Sun.COM 	(void) setlocale(LC_ALL, "");
126*12567SShawn.Emery@Sun.COM 
127*12567SShawn.Emery@Sun.COM #if !defined(TEXT_DOMAIN)
128*12567SShawn.Emery@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
129*12567SShawn.Emery@Sun.COM #endif /* TEXT_DOMAIN */
130*12567SShawn.Emery@Sun.COM 
131*12567SShawn.Emery@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
132*12567SShawn.Emery@Sun.COM 
133*12567SShawn.Emery@Sun.COM 	/*
134*12567SShawn.Emery@Sun.COM 	 * kconf -f <file> -r <realm> -k <kdc[,kdc]> -m <master_kdc>
135*12567SShawn.Emery@Sun.COM 	 * -p <kpasswd_protocol> -d <domain>
136*12567SShawn.Emery@Sun.COM 	 */
137*12567SShawn.Emery@Sun.COM 	while ((c = getopt(argc, argv, "f:r:k:a:s:p:d:m:")) != -1) {
138*12567SShawn.Emery@Sun.COM 		switch (c) {
139*12567SShawn.Emery@Sun.COM 		case 'f':
140*12567SShawn.Emery@Sun.COM 			file = optarg;
141*12567SShawn.Emery@Sun.COM 			break;
142*12567SShawn.Emery@Sun.COM 		case 'r':
143*12567SShawn.Emery@Sun.COM 			realm = optarg;
144*12567SShawn.Emery@Sun.COM 			break;
145*12567SShawn.Emery@Sun.COM 		case 'k':
146*12567SShawn.Emery@Sun.COM 			kdcs = optarg;
147*12567SShawn.Emery@Sun.COM 			break;
148*12567SShawn.Emery@Sun.COM 		case 'm':
149*12567SShawn.Emery@Sun.COM 			master = optarg;
150*12567SShawn.Emery@Sun.COM 			break;
151*12567SShawn.Emery@Sun.COM 		case 'p':
152*12567SShawn.Emery@Sun.COM 			if (strcmp(optarg, "SET_CHANGE") == 0)
153*12567SShawn.Emery@Sun.COM 				set_change = TRUE;
154*12567SShawn.Emery@Sun.COM 			break;
155*12567SShawn.Emery@Sun.COM 		case 'd':
156*12567SShawn.Emery@Sun.COM 			domain = optarg;
157*12567SShawn.Emery@Sun.COM 			break;
158*12567SShawn.Emery@Sun.COM 		default:
159*12567SShawn.Emery@Sun.COM 			usage();
160*12567SShawn.Emery@Sun.COM 			break;
161*12567SShawn.Emery@Sun.COM 		}
162*12567SShawn.Emery@Sun.COM 	}
163*12567SShawn.Emery@Sun.COM 
164*12567SShawn.Emery@Sun.COM 	code = __profile_init(file, &profile);
165*12567SShawn.Emery@Sun.COM 	if (code != 0) {
166*12567SShawn.Emery@Sun.COM 		fprintf(stderr, gettext("Wasn't able to initialize profile\n"));
167*12567SShawn.Emery@Sun.COM 		exit(code);
168*12567SShawn.Emery@Sun.COM 	}
169*12567SShawn.Emery@Sun.COM 
170*12567SShawn.Emery@Sun.COM 	if (code = init_list(&values)) {
171*12567SShawn.Emery@Sun.COM 		fprintf(stderr, gettext("Can not initialize list %d\n"), code);
172*12567SShawn.Emery@Sun.COM 		goto error;
173*12567SShawn.Emery@Sun.COM 	}
174*12567SShawn.Emery@Sun.COM 	token = strtok_r(kdcs, ",", &lasts);
175*12567SShawn.Emery@Sun.COM 	do {
176*12567SShawn.Emery@Sun.COM 		if (token != NULL) {
177*12567SShawn.Emery@Sun.COM 			code = add_to_list(&values, token);
178*12567SShawn.Emery@Sun.COM 			if (code != 0) {
179*12567SShawn.Emery@Sun.COM 				fprintf(stderr, gettext("Can not add to list "
180*12567SShawn.Emery@Sun.COM 				    "%d\n"), code);
181*12567SShawn.Emery@Sun.COM 				goto error;
182*12567SShawn.Emery@Sun.COM 			}
183*12567SShawn.Emery@Sun.COM 		} else {
184*12567SShawn.Emery@Sun.COM 			fprintf(stderr, gettext("Couldn't parse kdc list %d\n"),
185*12567SShawn.Emery@Sun.COM 			    code);
186*12567SShawn.Emery@Sun.COM 			goto error;
187*12567SShawn.Emery@Sun.COM 		}
188*12567SShawn.Emery@Sun.COM 	} while ((token = strtok_r(NULL, ",", &lasts)) != NULL);
189*12567SShawn.Emery@Sun.COM 	end_list(&values, &ret_values);
190*12567SShawn.Emery@Sun.COM 
191*12567SShawn.Emery@Sun.COM 	code = __profile_add_realm(profile, realm, master, ret_values,
192*12567SShawn.Emery@Sun.COM 	    set_change, TRUE);
193*12567SShawn.Emery@Sun.COM 	if (code != 0) {
194*12567SShawn.Emery@Sun.COM 		fprintf(stderr, gettext("Wasn't able to add realm "
195*12567SShawn.Emery@Sun.COM 		    "information\n"));
196*12567SShawn.Emery@Sun.COM 		goto error;
197*12567SShawn.Emery@Sun.COM 	}
198*12567SShawn.Emery@Sun.COM 
199*12567SShawn.Emery@Sun.COM 	code = __profile_add_domain_mapping(profile, domain, realm);
200*12567SShawn.Emery@Sun.COM 	if (code != 0) {
201*12567SShawn.Emery@Sun.COM 		fprintf(stderr, gettext("Wasn't able to add domain mapping\n"));
202*12567SShawn.Emery@Sun.COM 		goto error;
203*12567SShawn.Emery@Sun.COM 	}
204*12567SShawn.Emery@Sun.COM 
205*12567SShawn.Emery@Sun.COM error:
206*12567SShawn.Emery@Sun.COM 	if (ret_values != NULL)
207*12567SShawn.Emery@Sun.COM 		profile_free_list(ret_values);
208*12567SShawn.Emery@Sun.COM 
209*12567SShawn.Emery@Sun.COM 	/*
210*12567SShawn.Emery@Sun.COM 	 * Release profile, which will subsequently flush new profile to file.
211*12567SShawn.Emery@Sun.COM 	 * If this fails then at least free profile memory.
212*12567SShawn.Emery@Sun.COM 	 */
213*12567SShawn.Emery@Sun.COM 	if ((code =  __profile_release(profile)) != NULL)
214*12567SShawn.Emery@Sun.COM 		__profile_abandon(profile);
215*12567SShawn.Emery@Sun.COM 
216*12567SShawn.Emery@Sun.COM 	return (code);
217*12567SShawn.Emery@Sun.COM }
218