1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* lib/kadm5/alt_prof.c */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright 1995,2001,2008,2009 by the Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All Rights Reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Export of this software from the United States of America may
8*7f2fe78bSCy Schubert * require a specific license from the United States Government.
9*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
10*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
14*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
15*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
16*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
17*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
18*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
19*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
20*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
21*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
22*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
23*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
24*7f2fe78bSCy Schubert * or implied warranty.
25*7f2fe78bSCy Schubert */
26*7f2fe78bSCy Schubert /*
27*7f2fe78bSCy Schubert * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28*7f2fe78bSCy Schubert * Use is subject to license terms.
29*7f2fe78bSCy Schubert */
30*7f2fe78bSCy Schubert
31*7f2fe78bSCy Schubert /* Implement alternate profile file handling. */
32*7f2fe78bSCy Schubert #include "k5-int.h"
33*7f2fe78bSCy Schubert #include "fake-addrinfo.h"
34*7f2fe78bSCy Schubert #include <kadm5/admin.h>
35*7f2fe78bSCy Schubert #include "adm_proto.h"
36*7f2fe78bSCy Schubert #include <stdio.h>
37*7f2fe78bSCy Schubert #include <ctype.h>
38*7f2fe78bSCy Schubert #include <kdb_log.h>
39*7f2fe78bSCy Schubert
40*7f2fe78bSCy Schubert static krb5_key_salt_tuple *
copy_key_salt_tuple(krb5_key_salt_tuple * ksalt,krb5_int32 len)41*7f2fe78bSCy Schubert copy_key_salt_tuple(krb5_key_salt_tuple *ksalt, krb5_int32 len)
42*7f2fe78bSCy Schubert {
43*7f2fe78bSCy Schubert krb5_key_salt_tuple *knew;
44*7f2fe78bSCy Schubert
45*7f2fe78bSCy Schubert knew = calloc(len, sizeof(krb5_key_salt_tuple));
46*7f2fe78bSCy Schubert if (knew == NULL)
47*7f2fe78bSCy Schubert return NULL;
48*7f2fe78bSCy Schubert memcpy(knew, ksalt, len * sizeof(krb5_key_salt_tuple));
49*7f2fe78bSCy Schubert return knew;
50*7f2fe78bSCy Schubert }
51*7f2fe78bSCy Schubert
52*7f2fe78bSCy Schubert /*
53*7f2fe78bSCy Schubert * krb5_aprof_getvals() - Get values from alternate profile.
54*7f2fe78bSCy Schubert *
55*7f2fe78bSCy Schubert * Parameters:
56*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile.
57*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve.
58*7f2fe78bSCy Schubert * retdata - Returned data values.
59*7f2fe78bSCy Schubert *
60*7f2fe78bSCy Schubert * Returns:
61*7f2fe78bSCy Schubert * error codes from profile_get_values()
62*7f2fe78bSCy Schubert */
63*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_getvals(krb5_pointer acontext,const char ** hierarchy,char *** retdata)64*7f2fe78bSCy Schubert krb5_aprof_getvals(krb5_pointer acontext, const char **hierarchy,
65*7f2fe78bSCy Schubert char ***retdata)
66*7f2fe78bSCy Schubert {
67*7f2fe78bSCy Schubert return profile_get_values(acontext, hierarchy, retdata);
68*7f2fe78bSCy Schubert }
69*7f2fe78bSCy Schubert
70*7f2fe78bSCy Schubert /*
71*7f2fe78bSCy Schubert * krb5_aprof_get_boolean()
72*7f2fe78bSCy Schubert *
73*7f2fe78bSCy Schubert * Parameters:
74*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile
75*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve
76*7f2fe78bSCy Schubert * retdata - Returned data value
77*7f2fe78bSCy Schubert * Returns:
78*7f2fe78bSCy Schubert * error codes
79*7f2fe78bSCy Schubert */
80*7f2fe78bSCy Schubert
81*7f2fe78bSCy Schubert static krb5_error_code
string_to_boolean(const char * string,krb5_boolean * out)82*7f2fe78bSCy Schubert string_to_boolean(const char *string, krb5_boolean *out)
83*7f2fe78bSCy Schubert {
84*7f2fe78bSCy Schubert static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" };
85*7f2fe78bSCy Schubert static const char *const no[] = { "n", "no", "false", "f", "nil", "0",
86*7f2fe78bSCy Schubert "off" };
87*7f2fe78bSCy Schubert unsigned int i;
88*7f2fe78bSCy Schubert
89*7f2fe78bSCy Schubert for (i = 0; i < sizeof(yes) / sizeof(yes[0]); i++) {
90*7f2fe78bSCy Schubert if (!strcasecmp(string, yes[i])) {
91*7f2fe78bSCy Schubert *out = TRUE;
92*7f2fe78bSCy Schubert return 0;
93*7f2fe78bSCy Schubert }
94*7f2fe78bSCy Schubert }
95*7f2fe78bSCy Schubert for (i = 0; i < sizeof(no) / sizeof(no[0]); i++) {
96*7f2fe78bSCy Schubert if (!strcasecmp(string, no[i])) {
97*7f2fe78bSCy Schubert *out = FALSE;
98*7f2fe78bSCy Schubert return 0;
99*7f2fe78bSCy Schubert }
100*7f2fe78bSCy Schubert }
101*7f2fe78bSCy Schubert return PROF_BAD_BOOLEAN;
102*7f2fe78bSCy Schubert }
103*7f2fe78bSCy Schubert
104*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_get_boolean(krb5_pointer acontext,const char ** hierarchy,int uselast,krb5_boolean * retdata)105*7f2fe78bSCy Schubert krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy,
106*7f2fe78bSCy Schubert int uselast, krb5_boolean *retdata)
107*7f2fe78bSCy Schubert {
108*7f2fe78bSCy Schubert krb5_error_code ret;
109*7f2fe78bSCy Schubert char **values, *valp;
110*7f2fe78bSCy Schubert int idx;
111*7f2fe78bSCy Schubert krb5_boolean val;
112*7f2fe78bSCy Schubert
113*7f2fe78bSCy Schubert ret = krb5_aprof_getvals(acontext, hierarchy, &values);
114*7f2fe78bSCy Schubert if (ret)
115*7f2fe78bSCy Schubert return ret;
116*7f2fe78bSCy Schubert idx = 0;
117*7f2fe78bSCy Schubert if (uselast) {
118*7f2fe78bSCy Schubert while (values[idx] != NULL)
119*7f2fe78bSCy Schubert idx++;
120*7f2fe78bSCy Schubert idx--;
121*7f2fe78bSCy Schubert }
122*7f2fe78bSCy Schubert valp = values[idx];
123*7f2fe78bSCy Schubert ret = string_to_boolean(valp, &val);
124*7f2fe78bSCy Schubert profile_free_list(values);
125*7f2fe78bSCy Schubert if (ret)
126*7f2fe78bSCy Schubert return ret;
127*7f2fe78bSCy Schubert *retdata = val;
128*7f2fe78bSCy Schubert return 0;
129*7f2fe78bSCy Schubert }
130*7f2fe78bSCy Schubert
131*7f2fe78bSCy Schubert /*
132*7f2fe78bSCy Schubert * krb5_aprof_get_deltat() - Get a delta time value from the alternate
133*7f2fe78bSCy Schubert * profile.
134*7f2fe78bSCy Schubert *
135*7f2fe78bSCy Schubert * Parameters:
136*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile.
137*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve.
138*7f2fe78bSCy Schubert * uselast - if true, use last value, otherwise use first
139*7f2fe78bSCy Schubert * value found.
140*7f2fe78bSCy Schubert * deltatp - returned delta time value.
141*7f2fe78bSCy Schubert *
142*7f2fe78bSCy Schubert * Returns:
143*7f2fe78bSCy Schubert * error codes from profile_get_values()
144*7f2fe78bSCy Schubert * error codes from krb5_string_to_deltat()
145*7f2fe78bSCy Schubert */
146*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_get_deltat(krb5_pointer acontext,const char ** hierarchy,krb5_boolean uselast,krb5_deltat * deltatp)147*7f2fe78bSCy Schubert krb5_aprof_get_deltat(krb5_pointer acontext, const char **hierarchy,
148*7f2fe78bSCy Schubert krb5_boolean uselast, krb5_deltat *deltatp)
149*7f2fe78bSCy Schubert {
150*7f2fe78bSCy Schubert krb5_error_code ret;
151*7f2fe78bSCy Schubert char **values, *valp;
152*7f2fe78bSCy Schubert int idx;
153*7f2fe78bSCy Schubert
154*7f2fe78bSCy Schubert ret = krb5_aprof_getvals(acontext, hierarchy, &values);
155*7f2fe78bSCy Schubert if (ret)
156*7f2fe78bSCy Schubert return ret;
157*7f2fe78bSCy Schubert
158*7f2fe78bSCy Schubert idx = 0;
159*7f2fe78bSCy Schubert if (uselast) {
160*7f2fe78bSCy Schubert for (idx = 0; values[idx] != NULL; idx++);
161*7f2fe78bSCy Schubert idx--;
162*7f2fe78bSCy Schubert }
163*7f2fe78bSCy Schubert valp = values[idx];
164*7f2fe78bSCy Schubert
165*7f2fe78bSCy Schubert ret = krb5_string_to_deltat(valp, deltatp);
166*7f2fe78bSCy Schubert profile_free_list(values);
167*7f2fe78bSCy Schubert return ret;
168*7f2fe78bSCy Schubert }
169*7f2fe78bSCy Schubert
170*7f2fe78bSCy Schubert /*
171*7f2fe78bSCy Schubert * krb5_aprof_get_string() - Get a string value from the alternate profile.
172*7f2fe78bSCy Schubert *
173*7f2fe78bSCy Schubert * Parameters:
174*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile.
175*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve.
176*7f2fe78bSCy Schubert * uselast - if true, use last value, otherwise use first
177*7f2fe78bSCy Schubert * value found.
178*7f2fe78bSCy Schubert * stringp - returned string value.
179*7f2fe78bSCy Schubert *
180*7f2fe78bSCy Schubert * Returns:
181*7f2fe78bSCy Schubert * error codes from profile_get_values()
182*7f2fe78bSCy Schubert */
183*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_get_string(krb5_pointer acontext,const char ** hierarchy,krb5_boolean uselast,char ** stringp)184*7f2fe78bSCy Schubert krb5_aprof_get_string(krb5_pointer acontext, const char **hierarchy,
185*7f2fe78bSCy Schubert krb5_boolean uselast, char **stringp)
186*7f2fe78bSCy Schubert {
187*7f2fe78bSCy Schubert krb5_error_code ret;
188*7f2fe78bSCy Schubert char **values;
189*7f2fe78bSCy Schubert int lastidx;
190*7f2fe78bSCy Schubert
191*7f2fe78bSCy Schubert ret = krb5_aprof_getvals(acontext, hierarchy, &values);
192*7f2fe78bSCy Schubert if (ret)
193*7f2fe78bSCy Schubert return ret;
194*7f2fe78bSCy Schubert
195*7f2fe78bSCy Schubert for (lastidx = 0; values[lastidx] != NULL; lastidx++);
196*7f2fe78bSCy Schubert lastidx--;
197*7f2fe78bSCy Schubert
198*7f2fe78bSCy Schubert /* Excise the entry we want from the null-terminated list,
199*7f2fe78bSCy Schubert * and free up the rest. */
200*7f2fe78bSCy Schubert if (uselast) {
201*7f2fe78bSCy Schubert *stringp = values[lastidx];
202*7f2fe78bSCy Schubert values[lastidx] = NULL;
203*7f2fe78bSCy Schubert } else {
204*7f2fe78bSCy Schubert *stringp = values[0];
205*7f2fe78bSCy Schubert values[0] = values[lastidx];
206*7f2fe78bSCy Schubert values[lastidx] = NULL;
207*7f2fe78bSCy Schubert }
208*7f2fe78bSCy Schubert
209*7f2fe78bSCy Schubert profile_free_list(values);
210*7f2fe78bSCy Schubert return 0;
211*7f2fe78bSCy Schubert }
212*7f2fe78bSCy Schubert
213*7f2fe78bSCy Schubert /*
214*7f2fe78bSCy Schubert * krb5_aprof_get_string_all() - When the attr identified by "hierarchy" is
215*7f2fe78bSCy Schubert * specified multiple times, concatenate all of
216*7f2fe78bSCy Schubert * its string values from the alternate profile,
217*7f2fe78bSCy Schubert * separated with spaces.
218*7f2fe78bSCy Schubert *
219*7f2fe78bSCy Schubert * Parameters:
220*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile.
221*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve.
222*7f2fe78bSCy Schubert * stringp - Returned string value.
223*7f2fe78bSCy Schubert *
224*7f2fe78bSCy Schubert * Returns:
225*7f2fe78bSCy Schubert * error codes from profile_get_values() or ENOMEM
226*7f2fe78bSCy Schubert * Caller is responsible for deallocating stringp buffer
227*7f2fe78bSCy Schubert */
228*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_get_string_all(krb5_pointer acontext,const char ** hierarchy,char ** stringp)229*7f2fe78bSCy Schubert krb5_aprof_get_string_all(krb5_pointer acontext, const char **hierarchy,
230*7f2fe78bSCy Schubert char **stringp)
231*7f2fe78bSCy Schubert {
232*7f2fe78bSCy Schubert krb5_error_code ret;
233*7f2fe78bSCy Schubert char **values;
234*7f2fe78bSCy Schubert int idx = 0;
235*7f2fe78bSCy Schubert size_t buf_size = 0;
236*7f2fe78bSCy Schubert
237*7f2fe78bSCy Schubert ret = krb5_aprof_getvals(acontext, hierarchy, &values);
238*7f2fe78bSCy Schubert if (ret)
239*7f2fe78bSCy Schubert return ret;
240*7f2fe78bSCy Schubert
241*7f2fe78bSCy Schubert buf_size = strlen(values[0]) + 3;
242*7f2fe78bSCy Schubert for (idx = 1; values[idx] != NULL; idx++)
243*7f2fe78bSCy Schubert buf_size += strlen(values[idx]) + 3;
244*7f2fe78bSCy Schubert
245*7f2fe78bSCy Schubert *stringp = calloc(1, buf_size);
246*7f2fe78bSCy Schubert if (*stringp == NULL) {
247*7f2fe78bSCy Schubert profile_free_list(values);
248*7f2fe78bSCy Schubert return ENOMEM;
249*7f2fe78bSCy Schubert }
250*7f2fe78bSCy Schubert strlcpy(*stringp, values[0], buf_size);
251*7f2fe78bSCy Schubert for (idx = 1; values[idx] != NULL; idx++) {
252*7f2fe78bSCy Schubert strlcat(*stringp, " ", buf_size);
253*7f2fe78bSCy Schubert strlcat(*stringp, values[idx], buf_size);
254*7f2fe78bSCy Schubert }
255*7f2fe78bSCy Schubert
256*7f2fe78bSCy Schubert profile_free_list(values);
257*7f2fe78bSCy Schubert return 0;
258*7f2fe78bSCy Schubert }
259*7f2fe78bSCy Schubert
260*7f2fe78bSCy Schubert
261*7f2fe78bSCy Schubert /*
262*7f2fe78bSCy Schubert * krb5_aprof_get_int32() - Get a 32-bit integer value from the alternate
263*7f2fe78bSCy Schubert * profile.
264*7f2fe78bSCy Schubert *
265*7f2fe78bSCy Schubert * Parameters:
266*7f2fe78bSCy Schubert * acontext - opaque context for alternate profile.
267*7f2fe78bSCy Schubert * hierarchy - hierarchy of value to retrieve.
268*7f2fe78bSCy Schubert * uselast - if true, use last value, otherwise use first
269*7f2fe78bSCy Schubert * value found.
270*7f2fe78bSCy Schubert * intp - returned 32-bit integer value.
271*7f2fe78bSCy Schubert *
272*7f2fe78bSCy Schubert * Returns:
273*7f2fe78bSCy Schubert * error codes from profile_get_values()
274*7f2fe78bSCy Schubert * EINVAL - value is not an integer
275*7f2fe78bSCy Schubert */
276*7f2fe78bSCy Schubert krb5_error_code
krb5_aprof_get_int32(krb5_pointer acontext,const char ** hierarchy,krb5_boolean uselast,krb5_int32 * intp)277*7f2fe78bSCy Schubert krb5_aprof_get_int32(krb5_pointer acontext, const char **hierarchy,
278*7f2fe78bSCy Schubert krb5_boolean uselast, krb5_int32 *intp)
279*7f2fe78bSCy Schubert {
280*7f2fe78bSCy Schubert krb5_error_code ret;
281*7f2fe78bSCy Schubert char **values;
282*7f2fe78bSCy Schubert int idx;
283*7f2fe78bSCy Schubert
284*7f2fe78bSCy Schubert ret = krb5_aprof_getvals(acontext, hierarchy, &values);
285*7f2fe78bSCy Schubert if (ret)
286*7f2fe78bSCy Schubert return ret;
287*7f2fe78bSCy Schubert
288*7f2fe78bSCy Schubert idx = 0;
289*7f2fe78bSCy Schubert if (uselast) {
290*7f2fe78bSCy Schubert for (idx = 0; values[idx] != NULL; idx++);
291*7f2fe78bSCy Schubert idx--;
292*7f2fe78bSCy Schubert }
293*7f2fe78bSCy Schubert
294*7f2fe78bSCy Schubert if (sscanf(values[idx], "%d", intp) != 1)
295*7f2fe78bSCy Schubert ret = EINVAL;
296*7f2fe78bSCy Schubert
297*7f2fe78bSCy Schubert profile_free_list(values);
298*7f2fe78bSCy Schubert return ret;
299*7f2fe78bSCy Schubert }
300*7f2fe78bSCy Schubert
301*7f2fe78bSCy Schubert /*
302*7f2fe78bSCy Schubert * Returns nonzero if it found something to copy; the caller may still need to
303*7f2fe78bSCy Schubert * check the output field or mask to see if the copy (allocation) was
304*7f2fe78bSCy Schubert * successful. Returns zero if nothing was found to copy, and thus the caller
305*7f2fe78bSCy Schubert * may want to apply some default heuristic. If the default action is just to
306*7f2fe78bSCy Schubert * use a fixed, compiled-in string, supply it as the default value here and
307*7f2fe78bSCy Schubert * ignore the return value.
308*7f2fe78bSCy Schubert */
309*7f2fe78bSCy Schubert static int
get_string_param(char ** param_out,char * param_in,long * mask_out,long mask_in,long mask_bit,krb5_pointer aprofile,const char ** hierarchy,const char * config_name,const char * default_value)310*7f2fe78bSCy Schubert get_string_param(char **param_out, char *param_in, long *mask_out,
311*7f2fe78bSCy Schubert long mask_in, long mask_bit, krb5_pointer aprofile,
312*7f2fe78bSCy Schubert const char **hierarchy, const char *config_name,
313*7f2fe78bSCy Schubert const char *default_value)
314*7f2fe78bSCy Schubert {
315*7f2fe78bSCy Schubert char *svalue;
316*7f2fe78bSCy Schubert
317*7f2fe78bSCy Schubert hierarchy[2] = config_name;
318*7f2fe78bSCy Schubert if (mask_in & mask_bit) {
319*7f2fe78bSCy Schubert *param_out = strdup(param_in);
320*7f2fe78bSCy Schubert if (*param_out)
321*7f2fe78bSCy Schubert *mask_out |= mask_bit;
322*7f2fe78bSCy Schubert return 1;
323*7f2fe78bSCy Schubert } else if (aprofile != NULL &&
324*7f2fe78bSCy Schubert !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
325*7f2fe78bSCy Schubert *param_out = svalue;
326*7f2fe78bSCy Schubert *mask_out |= mask_bit;
327*7f2fe78bSCy Schubert return 1;
328*7f2fe78bSCy Schubert } else if (default_value) {
329*7f2fe78bSCy Schubert *param_out = strdup(default_value);
330*7f2fe78bSCy Schubert if (*param_out)
331*7f2fe78bSCy Schubert *mask_out |= mask_bit;
332*7f2fe78bSCy Schubert return 1;
333*7f2fe78bSCy Schubert } else {
334*7f2fe78bSCy Schubert return 0;
335*7f2fe78bSCy Schubert }
336*7f2fe78bSCy Schubert }
337*7f2fe78bSCy Schubert /*
338*7f2fe78bSCy Schubert * Similar, for (host-order) port number, if not already set in the output
339*7f2fe78bSCy Schubert * field; default_value == 0 means no default.
340*7f2fe78bSCy Schubert */
341*7f2fe78bSCy Schubert static void
get_port_param(int * param_out,int param_in,long * mask_out,long mask_in,long mask_bit,krb5_pointer aprofile,const char ** hierarchy,const char * config_name,int default_value)342*7f2fe78bSCy Schubert get_port_param(int *param_out, int param_in, long *mask_out, long mask_in,
343*7f2fe78bSCy Schubert long mask_bit, krb5_pointer aprofile, const char **hierarchy,
344*7f2fe78bSCy Schubert const char *config_name, int default_value)
345*7f2fe78bSCy Schubert {
346*7f2fe78bSCy Schubert krb5_int32 ivalue;
347*7f2fe78bSCy Schubert
348*7f2fe78bSCy Schubert if (*mask_out & mask_bit)
349*7f2fe78bSCy Schubert return;
350*7f2fe78bSCy Schubert hierarchy[2] = config_name;
351*7f2fe78bSCy Schubert if (mask_in & mask_bit) {
352*7f2fe78bSCy Schubert *mask_out |= mask_bit;
353*7f2fe78bSCy Schubert *param_out = param_in;
354*7f2fe78bSCy Schubert } else if (aprofile != NULL &&
355*7f2fe78bSCy Schubert !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
356*7f2fe78bSCy Schubert *param_out = ivalue;
357*7f2fe78bSCy Schubert *mask_out |= mask_bit;
358*7f2fe78bSCy Schubert } else if (default_value) {
359*7f2fe78bSCy Schubert *param_out = default_value;
360*7f2fe78bSCy Schubert *mask_out |= mask_bit;
361*7f2fe78bSCy Schubert }
362*7f2fe78bSCy Schubert }
363*7f2fe78bSCy Schubert
364*7f2fe78bSCy Schubert /*
365*7f2fe78bSCy Schubert * Similar, for delta_t; default is required.
366*7f2fe78bSCy Schubert */
367*7f2fe78bSCy Schubert static void
get_deltat_param(krb5_deltat * param_out,krb5_deltat param_in,long * mask_out,long mask_in,long mask_bit,krb5_pointer aprofile,const char ** hierarchy,const char * config_name,krb5_deltat default_value)368*7f2fe78bSCy Schubert get_deltat_param(krb5_deltat *param_out, krb5_deltat param_in, long *mask_out,
369*7f2fe78bSCy Schubert long mask_in, long mask_bit, krb5_pointer aprofile,
370*7f2fe78bSCy Schubert const char **hierarchy, const char *config_name,
371*7f2fe78bSCy Schubert krb5_deltat default_value)
372*7f2fe78bSCy Schubert {
373*7f2fe78bSCy Schubert krb5_deltat dtvalue;
374*7f2fe78bSCy Schubert
375*7f2fe78bSCy Schubert hierarchy[2] = config_name;
376*7f2fe78bSCy Schubert if (mask_in & mask_bit) {
377*7f2fe78bSCy Schubert *mask_out |= mask_bit;
378*7f2fe78bSCy Schubert *param_out = param_in;
379*7f2fe78bSCy Schubert } else if (aprofile &&
380*7f2fe78bSCy Schubert !krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
381*7f2fe78bSCy Schubert *param_out = dtvalue;
382*7f2fe78bSCy Schubert *mask_out |= mask_bit;
383*7f2fe78bSCy Schubert } else {
384*7f2fe78bSCy Schubert *param_out = default_value;
385*7f2fe78bSCy Schubert *mask_out |= mask_bit;
386*7f2fe78bSCy Schubert }
387*7f2fe78bSCy Schubert }
388*7f2fe78bSCy Schubert
389*7f2fe78bSCy Schubert /*
390*7f2fe78bSCy Schubert * Parse out the port number from an admin_server setting. Modify server to
391*7f2fe78bSCy Schubert * contain just the hostname or address. If a port is given, set *port, and
392*7f2fe78bSCy Schubert * set the appropriate bit in *mask.
393*7f2fe78bSCy Schubert */
394*7f2fe78bSCy Schubert static void
parse_admin_server_port(char * server,int * port,long * mask)395*7f2fe78bSCy Schubert parse_admin_server_port(char *server, int *port, long *mask)
396*7f2fe78bSCy Schubert {
397*7f2fe78bSCy Schubert char *end, *portstr;
398*7f2fe78bSCy Schubert
399*7f2fe78bSCy Schubert /* Allow the name or addr to be enclosed in brackets, for IPv6 addrs. */
400*7f2fe78bSCy Schubert if (*server == '[' && (end = strchr(server + 1, ']')) != NULL) {
401*7f2fe78bSCy Schubert portstr = (*(end + 1) == ':') ? end + 2 : NULL;
402*7f2fe78bSCy Schubert /* Shift the bracketed name or address back into server. */
403*7f2fe78bSCy Schubert memmove(server, server + 1, end - (server + 1));
404*7f2fe78bSCy Schubert *(end - 1) = '\0';
405*7f2fe78bSCy Schubert } else {
406*7f2fe78bSCy Schubert /* Terminate the name at the colon, if any. */
407*7f2fe78bSCy Schubert end = server + strcspn(server, ":");
408*7f2fe78bSCy Schubert portstr = (*end == ':') ? end + 1 : NULL;
409*7f2fe78bSCy Schubert *end = '\0';
410*7f2fe78bSCy Schubert }
411*7f2fe78bSCy Schubert
412*7f2fe78bSCy Schubert /* If we found a port string, parse it and set the appropriate bit. */
413*7f2fe78bSCy Schubert if (portstr) {
414*7f2fe78bSCy Schubert *port = atoi(portstr);
415*7f2fe78bSCy Schubert *mask |= KADM5_CONFIG_KADMIND_PORT;
416*7f2fe78bSCy Schubert }
417*7f2fe78bSCy Schubert }
418*7f2fe78bSCy Schubert
419*7f2fe78bSCy Schubert /*
420*7f2fe78bSCy Schubert * Function: kadm5_get_config_params
421*7f2fe78bSCy Schubert *
422*7f2fe78bSCy Schubert * Purpose: Merge configuration parameters provided by the caller with values
423*7f2fe78bSCy Schubert * specified in configuration files and with default values.
424*7f2fe78bSCy Schubert *
425*7f2fe78bSCy Schubert * Arguments:
426*7f2fe78bSCy Schubert *
427*7f2fe78bSCy Schubert * context (r) krb5_context to use
428*7f2fe78bSCy Schubert * profile (r) profile file to use
429*7f2fe78bSCy Schubert * envname (r) envname that contains a profile name to
430*7f2fe78bSCy Schubert * override profile
431*7f2fe78bSCy Schubert * params_in (r) params structure containing user-supplied
432*7f2fe78bSCy Schubert * values, or NULL
433*7f2fe78bSCy Schubert * params_out (w) params structure to be filled in
434*7f2fe78bSCy Schubert *
435*7f2fe78bSCy Schubert * Effects:
436*7f2fe78bSCy Schubert *
437*7f2fe78bSCy Schubert * The fields and mask of params_out are filled in with values obtained from
438*7f2fe78bSCy Schubert * params_in, the specified profile, and default values. Only and all fields
439*7f2fe78bSCy Schubert * specified in params_out->mask are set. The context of params_out must be
440*7f2fe78bSCy Schubert * freed with kadm5_free_config_params.
441*7f2fe78bSCy Schubert *
442*7f2fe78bSCy Schubert * params_in and params_out may be the same pointer. However, all pointers in
443*7f2fe78bSCy Schubert * params_in for which the mask is set will be re-assigned to newly copied
444*7f2fe78bSCy Schubert * versions, overwriting the old pointer value.
445*7f2fe78bSCy Schubert */
kadm5_get_config_params(krb5_context context,int use_kdc_config,kadm5_config_params * params_in,kadm5_config_params * params_out)446*7f2fe78bSCy Schubert krb5_error_code kadm5_get_config_params(krb5_context context,
447*7f2fe78bSCy Schubert int use_kdc_config,
448*7f2fe78bSCy Schubert kadm5_config_params *params_in,
449*7f2fe78bSCy Schubert kadm5_config_params *params_out)
450*7f2fe78bSCy Schubert {
451*7f2fe78bSCy Schubert char *lrealm, *svalue, *sp, *ep, *tp;
452*7f2fe78bSCy Schubert krb5_pointer aprofile = context->profile;
453*7f2fe78bSCy Schubert const char *hierarchy[4];
454*7f2fe78bSCy Schubert krb5_int32 ivalue;
455*7f2fe78bSCy Schubert kadm5_config_params params, empty_params;
456*7f2fe78bSCy Schubert krb5_boolean bvalue;
457*7f2fe78bSCy Schubert krb5_error_code ret = 0;
458*7f2fe78bSCy Schubert
459*7f2fe78bSCy Schubert memset(¶ms, 0, sizeof(params));
460*7f2fe78bSCy Schubert memset(&empty_params, 0, sizeof(empty_params));
461*7f2fe78bSCy Schubert
462*7f2fe78bSCy Schubert if (params_in == NULL)
463*7f2fe78bSCy Schubert params_in = &empty_params;
464*7f2fe78bSCy Schubert
465*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_REALM) {
466*7f2fe78bSCy Schubert lrealm = params.realm = strdup(params_in->realm);
467*7f2fe78bSCy Schubert if (params.realm == NULL) {
468*7f2fe78bSCy Schubert ret = ENOMEM;
469*7f2fe78bSCy Schubert goto cleanup;
470*7f2fe78bSCy Schubert }
471*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_REALM;
472*7f2fe78bSCy Schubert } else {
473*7f2fe78bSCy Schubert ret = krb5_get_default_realm(context, &lrealm);
474*7f2fe78bSCy Schubert if (ret)
475*7f2fe78bSCy Schubert goto cleanup;
476*7f2fe78bSCy Schubert params.realm = lrealm;
477*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_REALM;
478*7f2fe78bSCy Schubert }
479*7f2fe78bSCy Schubert
480*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_KVNO) {
481*7f2fe78bSCy Schubert params.kvno = params_in->kvno;
482*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_KVNO;
483*7f2fe78bSCy Schubert }
484*7f2fe78bSCy Schubert
485*7f2fe78bSCy Schubert /* Initialize realm parameters. */
486*7f2fe78bSCy Schubert hierarchy[0] = KRB5_CONF_REALMS;
487*7f2fe78bSCy Schubert hierarchy[1] = lrealm;
488*7f2fe78bSCy Schubert hierarchy[3] = NULL;
489*7f2fe78bSCy Schubert
490*7f2fe78bSCy Schubert #define GET_STRING_PARAM(FIELD, BIT, CONFTAG, DEFAULT) \
491*7f2fe78bSCy Schubert get_string_param(¶ms.FIELD, params_in->FIELD, \
492*7f2fe78bSCy Schubert ¶ms.mask, params_in->mask, BIT, \
493*7f2fe78bSCy Schubert aprofile, hierarchy, CONFTAG, DEFAULT)
494*7f2fe78bSCy Schubert
495*7f2fe78bSCy Schubert /* Get the value for the admin server. */
496*7f2fe78bSCy Schubert GET_STRING_PARAM(admin_server, KADM5_CONFIG_ADMIN_SERVER,
497*7f2fe78bSCy Schubert KRB5_CONF_ADMIN_SERVER, NULL);
498*7f2fe78bSCy Schubert
499*7f2fe78bSCy Schubert if (params.mask & KADM5_CONFIG_ADMIN_SERVER) {
500*7f2fe78bSCy Schubert parse_admin_server_port(params.admin_server, ¶ms.kadmind_port,
501*7f2fe78bSCy Schubert ¶ms.mask);
502*7f2fe78bSCy Schubert }
503*7f2fe78bSCy Schubert
504*7f2fe78bSCy Schubert /* Get the value for the database. */
505*7f2fe78bSCy Schubert GET_STRING_PARAM(dbname, KADM5_CONFIG_DBNAME, KRB5_CONF_DATABASE_NAME,
506*7f2fe78bSCy Schubert DEFAULT_KDB_FILE);
507*7f2fe78bSCy Schubert
508*7f2fe78bSCy Schubert /* Get the name of the acl file. */
509*7f2fe78bSCy Schubert GET_STRING_PARAM(acl_file, KADM5_CONFIG_ACL_FILE, KRB5_CONF_ACL_FILE,
510*7f2fe78bSCy Schubert DEFAULT_KADM5_ACL_FILE);
511*7f2fe78bSCy Schubert
512*7f2fe78bSCy Schubert /* Get the name of the dict file. */
513*7f2fe78bSCy Schubert GET_STRING_PARAM(dict_file, KADM5_CONFIG_DICT_FILE, KRB5_CONF_DICT_FILE,
514*7f2fe78bSCy Schubert NULL);
515*7f2fe78bSCy Schubert
516*7f2fe78bSCy Schubert /* Get the kadmind listen addresses. */
517*7f2fe78bSCy Schubert GET_STRING_PARAM(kadmind_listen, KADM5_CONFIG_KADMIND_LISTEN,
518*7f2fe78bSCy Schubert KRB5_CONF_KADMIND_LISTEN, NULL);
519*7f2fe78bSCy Schubert GET_STRING_PARAM(kpasswd_listen, KADM5_CONFIG_KPASSWD_LISTEN,
520*7f2fe78bSCy Schubert KRB5_CONF_KPASSWD_LISTEN, NULL);
521*7f2fe78bSCy Schubert GET_STRING_PARAM(iprop_listen, KADM5_CONFIG_IPROP_LISTEN,
522*7f2fe78bSCy Schubert KRB5_CONF_IPROP_LISTEN, NULL);
523*7f2fe78bSCy Schubert
524*7f2fe78bSCy Schubert #define GET_PORT_PARAM(FIELD, BIT, CONFTAG, DEFAULT) \
525*7f2fe78bSCy Schubert get_port_param(¶ms.FIELD, params_in->FIELD, \
526*7f2fe78bSCy Schubert ¶ms.mask, params_in->mask, BIT, \
527*7f2fe78bSCy Schubert aprofile, hierarchy, CONFTAG, DEFAULT)
528*7f2fe78bSCy Schubert
529*7f2fe78bSCy Schubert /* Get the value for the kadmind port. */
530*7f2fe78bSCy Schubert GET_PORT_PARAM(kadmind_port, KADM5_CONFIG_KADMIND_PORT,
531*7f2fe78bSCy Schubert KRB5_CONF_KADMIND_PORT, DEFAULT_KADM5_PORT);
532*7f2fe78bSCy Schubert
533*7f2fe78bSCy Schubert /* Get the value for the kpasswd port. */
534*7f2fe78bSCy Schubert GET_PORT_PARAM(kpasswd_port, KADM5_CONFIG_KPASSWD_PORT,
535*7f2fe78bSCy Schubert KRB5_CONF_KPASSWD_PORT, DEFAULT_KPASSWD_PORT);
536*7f2fe78bSCy Schubert
537*7f2fe78bSCy Schubert /* Get the value for the master key name. */
538*7f2fe78bSCy Schubert GET_STRING_PARAM(mkey_name, KADM5_CONFIG_MKEY_NAME,
539*7f2fe78bSCy Schubert KRB5_CONF_MASTER_KEY_NAME, NULL);
540*7f2fe78bSCy Schubert
541*7f2fe78bSCy Schubert /* Get the value for the master key type. */
542*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_MASTER_KEY_TYPE;
543*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_ENCTYPE) {
544*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPE;
545*7f2fe78bSCy Schubert params.enctype = params_in->enctype;
546*7f2fe78bSCy Schubert } else if (aprofile != NULL &&
547*7f2fe78bSCy Schubert !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
548*7f2fe78bSCy Schubert if (!krb5_string_to_enctype(svalue, ¶ms.enctype)) {
549*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPE;
550*7f2fe78bSCy Schubert free(svalue);
551*7f2fe78bSCy Schubert }
552*7f2fe78bSCy Schubert } else {
553*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPE;
554*7f2fe78bSCy Schubert params.enctype = DEFAULT_KDC_ENCTYPE;
555*7f2fe78bSCy Schubert }
556*7f2fe78bSCy Schubert
557*7f2fe78bSCy Schubert /* Get the value for mkey_from_kbd. */
558*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_MKEY_FROM_KBD) {
559*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
560*7f2fe78bSCy Schubert params.mkey_from_kbd = params_in->mkey_from_kbd;
561*7f2fe78bSCy Schubert }
562*7f2fe78bSCy Schubert
563*7f2fe78bSCy Schubert /* Get the value for the stashfile. */
564*7f2fe78bSCy Schubert GET_STRING_PARAM(stash_file, KADM5_CONFIG_STASH_FILE,
565*7f2fe78bSCy Schubert KRB5_CONF_KEY_STASH_FILE, NULL);
566*7f2fe78bSCy Schubert
567*7f2fe78bSCy Schubert /* Get the value for maximum ticket lifetime. */
568*7f2fe78bSCy Schubert #define GET_DELTAT_PARAM(FIELD, BIT, CONFTAG, DEFAULT) \
569*7f2fe78bSCy Schubert get_deltat_param(¶ms.FIELD, params_in->FIELD, \
570*7f2fe78bSCy Schubert ¶ms.mask, params_in->mask, BIT, \
571*7f2fe78bSCy Schubert aprofile, hierarchy, CONFTAG, DEFAULT)
572*7f2fe78bSCy Schubert
573*7f2fe78bSCy Schubert GET_DELTAT_PARAM(max_life, KADM5_CONFIG_MAX_LIFE, KRB5_CONF_MAX_LIFE,
574*7f2fe78bSCy Schubert 24 * 60 * 60); /* 1 day */
575*7f2fe78bSCy Schubert
576*7f2fe78bSCy Schubert /* Get the value for maximum renewable ticket lifetime. */
577*7f2fe78bSCy Schubert GET_DELTAT_PARAM(max_rlife, KADM5_CONFIG_MAX_RLIFE,
578*7f2fe78bSCy Schubert KRB5_CONF_MAX_RENEWABLE_LIFE, 0);
579*7f2fe78bSCy Schubert
580*7f2fe78bSCy Schubert /* Get the value for the default principal expiration */
581*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_DEFAULT_PRINCIPAL_EXPIRATION;
582*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_EXPIRATION) {
583*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_EXPIRATION;
584*7f2fe78bSCy Schubert params.expiration = params_in->expiration;
585*7f2fe78bSCy Schubert } else if (aprofile &&
586*7f2fe78bSCy Schubert !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
587*7f2fe78bSCy Schubert if (!krb5_string_to_timestamp(svalue, ¶ms.expiration)) {
588*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_EXPIRATION;
589*7f2fe78bSCy Schubert free(svalue);
590*7f2fe78bSCy Schubert }
591*7f2fe78bSCy Schubert } else {
592*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_EXPIRATION;
593*7f2fe78bSCy Schubert params.expiration = 0;
594*7f2fe78bSCy Schubert }
595*7f2fe78bSCy Schubert
596*7f2fe78bSCy Schubert /* Get the value for the default principal flags */
597*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_DEFAULT_PRINCIPAL_FLAGS;
598*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_FLAGS) {
599*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_FLAGS;
600*7f2fe78bSCy Schubert params.flags = params_in->flags;
601*7f2fe78bSCy Schubert } else if (aprofile != NULL &&
602*7f2fe78bSCy Schubert !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
603*7f2fe78bSCy Schubert sp = svalue;
604*7f2fe78bSCy Schubert params.flags = 0;
605*7f2fe78bSCy Schubert while (sp != NULL) {
606*7f2fe78bSCy Schubert if ((ep = strchr(sp, ',')) != NULL ||
607*7f2fe78bSCy Schubert (ep = strchr(sp, ' ')) != NULL ||
608*7f2fe78bSCy Schubert (ep = strchr(sp, '\t')) != NULL) {
609*7f2fe78bSCy Schubert /* Fill in trailing whitespace of sp. */
610*7f2fe78bSCy Schubert tp = ep - 1;
611*7f2fe78bSCy Schubert while (isspace((unsigned char)*tp) && tp > sp) {
612*7f2fe78bSCy Schubert *tp = '\0';
613*7f2fe78bSCy Schubert tp--;
614*7f2fe78bSCy Schubert }
615*7f2fe78bSCy Schubert *ep = '\0';
616*7f2fe78bSCy Schubert ep++;
617*7f2fe78bSCy Schubert /* Skip over trailing whitespace of ep. */
618*7f2fe78bSCy Schubert while (isspace((unsigned char)*ep) && *ep != '\0')
619*7f2fe78bSCy Schubert ep++;
620*7f2fe78bSCy Schubert }
621*7f2fe78bSCy Schubert /* Convert this flag. */
622*7f2fe78bSCy Schubert if (krb5_flagspec_to_mask(sp, ¶ms.flags, ¶ms.flags))
623*7f2fe78bSCy Schubert break;
624*7f2fe78bSCy Schubert sp = ep;
625*7f2fe78bSCy Schubert }
626*7f2fe78bSCy Schubert if (sp == NULL)
627*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_FLAGS;
628*7f2fe78bSCy Schubert free(svalue);
629*7f2fe78bSCy Schubert } else {
630*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_FLAGS;
631*7f2fe78bSCy Schubert params.flags = KRB5_KDB_DEF_FLAGS;
632*7f2fe78bSCy Schubert }
633*7f2fe78bSCy Schubert
634*7f2fe78bSCy Schubert /* Get the value for the supported enctype/salttype matrix. */
635*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_SUPPORTED_ENCTYPES;
636*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_ENCTYPES) {
637*7f2fe78bSCy Schubert if (params_in->keysalts) {
638*7f2fe78bSCy Schubert params.keysalts = copy_key_salt_tuple(params_in->keysalts,
639*7f2fe78bSCy Schubert params_in->num_keysalts);
640*7f2fe78bSCy Schubert if (params.keysalts) {
641*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPES;
642*7f2fe78bSCy Schubert params.num_keysalts = params_in->num_keysalts;
643*7f2fe78bSCy Schubert }
644*7f2fe78bSCy Schubert } else {
645*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPES;
646*7f2fe78bSCy Schubert params.keysalts = NULL;
647*7f2fe78bSCy Schubert params.num_keysalts = params_in->num_keysalts;
648*7f2fe78bSCy Schubert }
649*7f2fe78bSCy Schubert } else {
650*7f2fe78bSCy Schubert svalue = NULL;
651*7f2fe78bSCy Schubert if (aprofile != NULL)
652*7f2fe78bSCy Schubert krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
653*7f2fe78bSCy Schubert if (svalue == NULL)
654*7f2fe78bSCy Schubert svalue = strdup(KRB5_DEFAULT_SUPPORTED_ENCTYPES);
655*7f2fe78bSCy Schubert if (svalue == NULL) {
656*7f2fe78bSCy Schubert ret = ENOMEM;
657*7f2fe78bSCy Schubert goto cleanup;
658*7f2fe78bSCy Schubert }
659*7f2fe78bSCy Schubert
660*7f2fe78bSCy Schubert params.keysalts = NULL;
661*7f2fe78bSCy Schubert params.num_keysalts = 0;
662*7f2fe78bSCy Schubert krb5_string_to_keysalts(svalue,
663*7f2fe78bSCy Schubert NULL, /* Tuple separators */
664*7f2fe78bSCy Schubert NULL, /* Key/salt separators */
665*7f2fe78bSCy Schubert 0, /* No duplicates */
666*7f2fe78bSCy Schubert ¶ms.keysalts,
667*7f2fe78bSCy Schubert ¶ms.num_keysalts);
668*7f2fe78bSCy Schubert if (params.num_keysalts)
669*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ENCTYPES;
670*7f2fe78bSCy Schubert
671*7f2fe78bSCy Schubert free(svalue);
672*7f2fe78bSCy Schubert }
673*7f2fe78bSCy Schubert
674*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_IPROP_ENABLE;
675*7f2fe78bSCy Schubert
676*7f2fe78bSCy Schubert params.iprop_enabled = FALSE;
677*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_IPROP_ENABLED;
678*7f2fe78bSCy Schubert
679*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_IPROP_ENABLED) {
680*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_IPROP_ENABLED;
681*7f2fe78bSCy Schubert params.iprop_enabled = params_in->iprop_enabled;
682*7f2fe78bSCy Schubert } else {
683*7f2fe78bSCy Schubert if (aprofile &&
684*7f2fe78bSCy Schubert !krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
685*7f2fe78bSCy Schubert params.iprop_enabled = bvalue;
686*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_IPROP_ENABLED;
687*7f2fe78bSCy Schubert }
688*7f2fe78bSCy Schubert }
689*7f2fe78bSCy Schubert
690*7f2fe78bSCy Schubert if (!GET_STRING_PARAM(iprop_logfile, KADM5_CONFIG_IPROP_LOGFILE,
691*7f2fe78bSCy Schubert KRB5_CONF_IPROP_LOGFILE, NULL)) {
692*7f2fe78bSCy Schubert if (params.mask & KADM5_CONFIG_DBNAME) {
693*7f2fe78bSCy Schubert if (asprintf(¶ms.iprop_logfile, "%s.ulog",
694*7f2fe78bSCy Schubert params.dbname) >= 0)
695*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_IPROP_LOGFILE;
696*7f2fe78bSCy Schubert }
697*7f2fe78bSCy Schubert }
698*7f2fe78bSCy Schubert
699*7f2fe78bSCy Schubert GET_PORT_PARAM(iprop_port, KADM5_CONFIG_IPROP_PORT, KRB5_CONF_IPROP_PORT,
700*7f2fe78bSCy Schubert 0);
701*7f2fe78bSCy Schubert
702*7f2fe78bSCy Schubert /* 5 min for large KDBs */
703*7f2fe78bSCy Schubert GET_DELTAT_PARAM(iprop_resync_timeout, KADM5_CONFIG_IPROP_RESYNC_TIMEOUT,
704*7f2fe78bSCy Schubert KRB5_CONF_IPROP_RESYNC_TIMEOUT, 60 * 5);
705*7f2fe78bSCy Schubert
706*7f2fe78bSCy Schubert if (params_in->mask & KADM5_CONFIG_ULOG_SIZE) {
707*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ULOG_SIZE;
708*7f2fe78bSCy Schubert params.iprop_ulogsize = params_in->iprop_ulogsize;
709*7f2fe78bSCy Schubert } else {
710*7f2fe78bSCy Schubert params.iprop_ulogsize = 0;
711*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_IPROP_ULOGSIZE;
712*7f2fe78bSCy Schubert if (aprofile != NULL &&
713*7f2fe78bSCy Schubert !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue) &&
714*7f2fe78bSCy Schubert ivalue > 0)
715*7f2fe78bSCy Schubert params.iprop_ulogsize = ivalue;
716*7f2fe78bSCy Schubert hierarchy[2] = KRB5_CONF_IPROP_MASTER_ULOGSIZE;
717*7f2fe78bSCy Schubert if (params.iprop_ulogsize == 0 && aprofile != NULL &&
718*7f2fe78bSCy Schubert !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue) &&
719*7f2fe78bSCy Schubert ivalue > 0)
720*7f2fe78bSCy Schubert params.iprop_ulogsize = ivalue;
721*7f2fe78bSCy Schubert if (params.iprop_ulogsize == 0)
722*7f2fe78bSCy Schubert params.iprop_ulogsize = DEF_ULOGENTRIES;
723*7f2fe78bSCy Schubert }
724*7f2fe78bSCy Schubert params.mask |= KADM5_CONFIG_ULOG_SIZE;
725*7f2fe78bSCy Schubert
726*7f2fe78bSCy Schubert GET_DELTAT_PARAM(iprop_poll_time, KADM5_CONFIG_POLL_TIME,
727*7f2fe78bSCy Schubert KRB5_CONF_IPROP_REPLICA_POLL, -1);
728*7f2fe78bSCy Schubert if (params.iprop_poll_time == -1) {
729*7f2fe78bSCy Schubert GET_DELTAT_PARAM(iprop_poll_time, KADM5_CONFIG_POLL_TIME,
730*7f2fe78bSCy Schubert KRB5_CONF_IPROP_SLAVE_POLL, 2 * 60);
731*7f2fe78bSCy Schubert }
732*7f2fe78bSCy Schubert
733*7f2fe78bSCy Schubert *params_out = params;
734*7f2fe78bSCy Schubert
735*7f2fe78bSCy Schubert cleanup:
736*7f2fe78bSCy Schubert if (ret) {
737*7f2fe78bSCy Schubert kadm5_free_config_params(context, ¶ms);
738*7f2fe78bSCy Schubert params_out->mask = 0;
739*7f2fe78bSCy Schubert }
740*7f2fe78bSCy Schubert return ret;
741*7f2fe78bSCy Schubert }
742*7f2fe78bSCy Schubert
743*7f2fe78bSCy Schubert /*
744*7f2fe78bSCy Schubert * kadm5_free_config_params() - Free data allocated by above.
745*7f2fe78bSCy Schubert */
746*7f2fe78bSCy Schubert krb5_error_code
kadm5_free_config_params(krb5_context context,kadm5_config_params * params)747*7f2fe78bSCy Schubert kadm5_free_config_params(krb5_context context, kadm5_config_params *params)
748*7f2fe78bSCy Schubert {
749*7f2fe78bSCy Schubert if (params == NULL)
750*7f2fe78bSCy Schubert return 0;
751*7f2fe78bSCy Schubert free(params->dbname);
752*7f2fe78bSCy Schubert free(params->mkey_name);
753*7f2fe78bSCy Schubert free(params->stash_file);
754*7f2fe78bSCy Schubert free(params->keysalts);
755*7f2fe78bSCy Schubert free(params->admin_server);
756*7f2fe78bSCy Schubert free(params->dict_file);
757*7f2fe78bSCy Schubert free(params->acl_file);
758*7f2fe78bSCy Schubert free(params->realm);
759*7f2fe78bSCy Schubert free(params->iprop_logfile);
760*7f2fe78bSCy Schubert return 0;
761*7f2fe78bSCy Schubert }
762*7f2fe78bSCy Schubert
763*7f2fe78bSCy Schubert krb5_error_code
kadm5_get_admin_service_name(krb5_context ctx,char * realm_in,char * admin_name,size_t maxlen)764*7f2fe78bSCy Schubert kadm5_get_admin_service_name(krb5_context ctx, char *realm_in,
765*7f2fe78bSCy Schubert char *admin_name, size_t maxlen)
766*7f2fe78bSCy Schubert {
767*7f2fe78bSCy Schubert krb5_error_code ret;
768*7f2fe78bSCy Schubert kadm5_config_params params_in, params_out;
769*7f2fe78bSCy Schubert char *canonhost = NULL;
770*7f2fe78bSCy Schubert
771*7f2fe78bSCy Schubert memset(¶ms_in, 0, sizeof(params_in));
772*7f2fe78bSCy Schubert memset(¶ms_out, 0, sizeof(params_out));
773*7f2fe78bSCy Schubert
774*7f2fe78bSCy Schubert params_in.mask |= KADM5_CONFIG_REALM;
775*7f2fe78bSCy Schubert params_in.realm = realm_in;
776*7f2fe78bSCy Schubert ret = kadm5_get_config_params(ctx, 0, ¶ms_in, ¶ms_out);
777*7f2fe78bSCy Schubert if (ret)
778*7f2fe78bSCy Schubert return ret;
779*7f2fe78bSCy Schubert
780*7f2fe78bSCy Schubert if (!(params_out.mask & KADM5_CONFIG_ADMIN_SERVER)) {
781*7f2fe78bSCy Schubert ret = KADM5_MISSING_KRB5_CONF_PARAMS;
782*7f2fe78bSCy Schubert goto err_params;
783*7f2fe78bSCy Schubert }
784*7f2fe78bSCy Schubert
785*7f2fe78bSCy Schubert ret = krb5_expand_hostname(ctx, params_out.admin_server, &canonhost);
786*7f2fe78bSCy Schubert if (ret)
787*7f2fe78bSCy Schubert goto err_params;
788*7f2fe78bSCy Schubert
789*7f2fe78bSCy Schubert if (strlen(canonhost) + sizeof("kadmin/") > maxlen) {
790*7f2fe78bSCy Schubert ret = ENOMEM;
791*7f2fe78bSCy Schubert goto err_params;
792*7f2fe78bSCy Schubert }
793*7f2fe78bSCy Schubert snprintf(admin_name, maxlen, "kadmin/%s", canonhost);
794*7f2fe78bSCy Schubert
795*7f2fe78bSCy Schubert err_params:
796*7f2fe78bSCy Schubert krb5_free_string(ctx, canonhost);
797*7f2fe78bSCy Schubert kadm5_free_config_params(ctx, ¶ms_out);
798*7f2fe78bSCy Schubert return ret;
799*7f2fe78bSCy Schubert }
800