xref: /freebsd/crypto/krb5/src/lib/kadm5/alt_prof.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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(&params, 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(&params.FIELD, params_in->FIELD,           \
492*7f2fe78bSCy Schubert                      &params.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, &params.kadmind_port,
501*7f2fe78bSCy Schubert                                 &params.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(&params.FIELD, params_in->FIELD,             \
526*7f2fe78bSCy Schubert                    &params.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, &params.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(&params.FIELD, params_in->FIELD,           \
570*7f2fe78bSCy Schubert                      &params.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, &params.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, &params.flags, &params.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                                 &params.keysalts,
667*7f2fe78bSCy Schubert                                 &params.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(&params.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, &params);
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(&params_in, 0, sizeof(params_in));
772*7f2fe78bSCy Schubert     memset(&params_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, &params_in, &params_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, &params_out);
798*7f2fe78bSCy Schubert     return ret;
799*7f2fe78bSCy Schubert }
800