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