1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6
7 /*
8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
9 *
10 * Openvision retains the copyright to derivative works of
11 * this source code. Do *NOT* create a derivative of this
12 * source code before consulting with your legal department.
13 * Do *NOT* integrate *ANY* of this source code into another
14 * product before consulting with your legal department.
15 *
16 * For further information, read the top-level Openvision
17 * copyright which is contained in the top-level MIT Kerberos
18 * copyright.
19 *
20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
21 *
22 */
23
24
25 /*
26 * lib/kadm/alt_prof.c
27 *
28 * Copyright 1995,2001 by the Massachusetts Institute of Technology.
29 * All Rights Reserved.
30 *
31 * Export of this software from the United States of America may
32 * require a specific license from the United States Government.
33 * It is the responsibility of any person or organization contemplating
34 * export to obtain such a license before exporting.
35 *
36 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
37 * distribute this software and its documentation for any purpose and
38 * without fee is hereby granted, provided that the above copyright
39 * notice appear in all copies and that both that copyright notice and
40 * this permission notice appear in supporting documentation, and that
41 * the name of M.I.T. not be used in advertising or publicity pertaining
42 * to distribution of the software without specific, written prior
43 * permission. Furthermore if you modify this software you must label
44 * your software as modified software and not distribute it in such a
45 * fashion that it might be confused with the original M.I.T. software.
46 * M.I.T. makes no representations about the suitability of
47 * this software for any purpose. It is provided "as is" without express
48 * or implied warranty.
49 *
50 */
51
52 /*
53 * alt_prof.c - Implement alternate profile file handling.
54 */
55 #include "k5-int.h"
56 #include <kadm5/admin.h>
57 #include "adm_proto.h"
58 #include <stdio.h>
59 #include <ctype.h>
60 #include <os-proto.h>
61 #include <kdb/kdb_log.h>
62
63 krb5_error_code kadm5_free_config_params();
64
65 #define DEFAULT_ENCTYPE_LIST \
66 "aes256-cts-hmac-sha1-96:normal " \
67 "aes128-cts-hmac-sha1-96:normal " \
68 "des3-cbc-hmac-sha1-kd:normal " \
69 "arcfour-hmac-md5:normal " \
70 "arcfour-hmac-md5-exp:normal " \
71 "des-cbc-md5:normal " \
72 "des-cbc-crc:normal"
73
copy_key_salt_tuple(ksalt,len)74 static krb5_key_salt_tuple *copy_key_salt_tuple(ksalt, len)
75 krb5_key_salt_tuple *ksalt;
76 krb5_int32 len;
77 {
78 krb5_key_salt_tuple *knew;
79
80 if((knew = (krb5_key_salt_tuple *)
81 malloc((len ) * sizeof(krb5_key_salt_tuple)))) {
82 memcpy(knew, ksalt, len * sizeof(krb5_key_salt_tuple));
83 return knew;
84 }
85 return 0;
86 }
87
88 /*
89 * krb5_aprof_init() - Initialize alternate profile context.
90 *
91 * Parameters:
92 * fname - default file name of the profile.
93 * envname - environment variable name which can override fname.
94 * acontextp - Pointer to opaque context for alternate profile.
95 *
96 * Returns:
97 * error codes from profile_init()
98 */
99 krb5_error_code
krb5_aprof_init(fname,envname,acontextp)100 krb5_aprof_init(fname, envname, acontextp)
101 char *fname;
102 char *envname;
103 krb5_pointer *acontextp;
104 {
105 krb5_error_code kret;
106 profile_t profile;
107 const char *kdc_config;
108 size_t krb5_config_len, kdc_config_len;
109 char *profile_path;
110 char **filenames;
111 int i;
112
113 kret = krb5_get_default_config_files (&filenames);
114 if (kret)
115 return kret;
116 krb5_config_len = 0;
117 for (i = 0; filenames[i] != NULL; i++)
118 krb5_config_len += strlen(filenames[i]) + 1;
119 if (i > 0)
120 krb5_config_len--;
121 if (envname == NULL
122 || (kdc_config = getenv(envname)) == NULL)
123 kdc_config = fname;
124 if (kdc_config == NULL)
125 kdc_config_len = 0;
126 else
127 kdc_config_len = strlen(kdc_config);
128 profile_path = malloc(2 + krb5_config_len + kdc_config_len);
129 if (profile_path == NULL) {
130 krb5_free_config_files(filenames);
131 return errno;
132 }
133 if (kdc_config_len)
134 strcpy(profile_path, kdc_config);
135 else
136 profile_path[0] = 0;
137 if (krb5_config_len)
138 for (i = 0; filenames[i] != NULL; i++) {
139 if (kdc_config_len || i)
140 strcat(profile_path, ":");
141 strcat(profile_path, filenames[i]);
142 }
143 krb5_free_config_files(filenames);
144 profile = (profile_t) NULL;
145 kret = profile_init_path(profile_path, &profile);
146 free(profile_path);
147 if (kret)
148 return kret;
149 *acontextp = profile;
150 return 0;
151 }
152
153 /*
154 * krb5_aprof_getvals() - Get values from alternate profile.
155 *
156 * Parameters:
157 * acontext - opaque context for alternate profile.
158 * hierarchy - hierarchy of value to retrieve.
159 * retdata - Returned data values.
160 *
161 * Returns:
162 * error codes from profile_get_values()
163 */
164 krb5_error_code
krb5_aprof_getvals(acontext,hierarchy,retdata)165 krb5_aprof_getvals(acontext, hierarchy, retdata)
166 krb5_pointer acontext;
167 const char **hierarchy;
168 char ***retdata;
169 {
170 return(profile_get_values((profile_t) acontext,
171 hierarchy,
172 retdata));
173 }
174
175 /*
176 * krb5_aprof_get_boolean()
177 *
178 * Parameters:
179 * acontext - opaque context for alternate profile
180 * hierarchy - hierarchy of value to retrieve
181 * retdata - Returned data value
182 * Returns:
183 * error codes
184 */
185
186 static krb5_error_code
string_to_boolean(const char * string,krb5_boolean * out)187 string_to_boolean (const char *string, krb5_boolean *out)
188 {
189 static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" };
190 static const char *const no[] = { "n", "no", "false", "f", "nil", "0", "off" };
191 int i;
192
193 for (i = 0; i < sizeof(yes)/sizeof(yes[0]); i++)
194 if (!strcasecmp(string, yes[i])) {
195 *out = 1;
196 return 0;
197 }
198 for (i = 0; i < sizeof(no)/sizeof(no[0]); i++)
199 if (!strcasecmp(string, no[i])) {
200 *out = 0;
201 return 0;
202 }
203 return PROF_BAD_BOOLEAN;
204 }
205
206 krb5_error_code
krb5_aprof_get_boolean(krb5_pointer acontext,const char ** hierarchy,int uselast,krb5_boolean * retdata)207 krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy,
208 int uselast, krb5_boolean *retdata)
209 {
210 krb5_error_code kret;
211 char **values;
212 char *valp;
213 int idx;
214 krb5_boolean val;
215
216 kret = krb5_aprof_getvals (acontext, hierarchy, &values);
217 if (kret)
218 return kret;
219 idx = 0;
220 if (uselast) {
221 while (values[idx])
222 idx++;
223 idx--;
224 }
225 valp = values[idx];
226 kret = string_to_boolean (valp, &val);
227 if (kret)
228 return kret;
229 *retdata = val;
230 return 0;
231 }
232
233 /*
234 * krb5_aprof_get_deltat() - Get a delta time value from the alternate
235 * profile.
236 *
237 * Parameters:
238 * acontext - opaque context for alternate profile.
239 * hierarchy - hierarchy of value to retrieve.
240 * uselast - if true, use last value, otherwise use
241 * first value found.
242 * deltatp - returned delta time value.
243 *
244 * Returns:
245 * error codes from profile_get_values()
246 * error codes from krb5_string_to_deltat()
247 */
248 krb5_error_code
krb5_aprof_get_deltat(acontext,hierarchy,uselast,deltatp)249 krb5_aprof_get_deltat(acontext, hierarchy, uselast, deltatp)
250 krb5_pointer acontext;
251 const char **hierarchy;
252 krb5_boolean uselast;
253 krb5_deltat *deltatp;
254 {
255 krb5_error_code kret;
256 char **values;
257 char *valp;
258 int idx;
259
260 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
261 idx = 0;
262 if (uselast) {
263 for (idx=0; values[idx]; idx++);
264 idx--;
265 }
266 valp = values[idx];
267 kret = krb5_string_to_deltat(valp, deltatp);
268
269 /* Free the string storage */
270 for (idx=0; values[idx]; idx++)
271 krb5_xfree(values[idx]);
272 krb5_xfree(values);
273 }
274 return(kret);
275 }
276
277 /*
278 * krb5_aprof_get_string() - Get a string value from the alternate
279 * profile.
280 *
281 * Parameters:
282 * acontext - opaque context for alternate profile.
283 * hierarchy - hierarchy of value to retrieve.
284 * uselast - if true, use last value, otherwise use
285 * first value found.
286 * stringp - returned string value.
287 *
288 * Returns:
289 * error codes from profile_get_values()
290 */
291 krb5_error_code
krb5_aprof_get_string(acontext,hierarchy,uselast,stringp)292 krb5_aprof_get_string(acontext, hierarchy, uselast, stringp)
293 krb5_pointer acontext;
294 const char **hierarchy;
295 krb5_boolean uselast;
296 char **stringp;
297 {
298 krb5_error_code kret;
299 char **values;
300 int idx, i;
301
302 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
303 idx = 0;
304 if (uselast) {
305 for (idx=0; values[idx]; idx++);
306 idx--;
307 }
308
309 *stringp = values[idx];
310
311 /* Free the string storage */
312 for (i=0; values[i]; i++)
313 if (i != idx)
314 krb5_xfree(values[i]);
315 krb5_xfree(values);
316 }
317 return(kret);
318 }
319
320 /*
321 * krb5_aprof_get_int32() - Get a 32-bit integer value from the alternate
322 * profile.
323 *
324 * Parameters:
325 * acontext - opaque context for alternate profile.
326 * hierarchy - hierarchy of value to retrieve.
327 * uselast - if true, use last value, otherwise use
328 * first value found.
329 * intp - returned 32-bit integer value.
330 *
331 * Returns:
332 * error codes from profile_get_values()
333 * EINVAL - value is not an integer
334 */
335 krb5_error_code
krb5_aprof_get_int32(acontext,hierarchy,uselast,intp)336 krb5_aprof_get_int32(acontext, hierarchy, uselast, intp)
337 krb5_pointer acontext;
338 const char **hierarchy;
339 krb5_boolean uselast;
340 krb5_int32 *intp;
341 {
342 krb5_error_code kret;
343 char **values;
344 int idx;
345
346 if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
347 idx = 0;
348 if (uselast) {
349 for (idx=0; values[idx]; idx++);
350 idx--;
351 }
352
353 if (sscanf(values[idx], "%d", intp) != 1)
354 kret = EINVAL;
355
356 /* Free the string storage */
357 for (idx=0; values[idx]; idx++)
358 krb5_xfree(values[idx]);
359 krb5_xfree(values);
360 }
361 return(kret);
362 }
363
364 /*
365 * krb5_aprof_finish() - Finish alternate profile context.
366 *
367 * Parameter:
368 * acontext - opaque context for alternate profile.
369 *
370 * Returns:
371 * 0 on success, something else on failure.
372 */
373 krb5_error_code
krb5_aprof_finish(acontext)374 krb5_aprof_finish(acontext)
375 krb5_pointer acontext;
376 {
377 profile_release(acontext);
378 return(0);
379 }
380
381 /*
382 * Function: kadm5_get_config_params
383 *
384 * Purpose: Merge configuration parameters provided by the caller with
385 * values specified in configuration files and with default values.
386 *
387 * Arguments:
388 *
389 * context (r) krb5_context to use
390 * profile (r) profile file to use
391 * envname (r) envname that contains a profile name to
392 * override profile
393 * params_in (r) params structure containing user-supplied
394 * values, or NULL
395 * params_out (w) params structure to be filled in
396 *
397 * Effects:
398 *
399 * The fields and mask of params_out are filled in with values
400 * obtained from params_in, the specified profile, and default
401 * values. Only and all fields specified in params_out->mask are
402 * set. The context of params_out must be freed with
403 * kadm5_free_config_params.
404 *
405 * params_in and params_out may be the same pointer. However, all pointers
406 * in params_in for which the mask is set will be re-assigned to newly copied
407 * versions, overwriting the old pointer value.
408 */
kadm5_get_config_params(context,use_kdc_config,params_in,params_out)409 krb5_error_code kadm5_get_config_params(context, use_kdc_config,
410 params_in, params_out)
411 krb5_context context;
412 int use_kdc_config;
413 kadm5_config_params *params_in, *params_out;
414 {
415 char *filename;
416 char *envname;
417 char *lrealm;
418 krb5_pointer aprofile = 0;
419 const char *hierarchy[4];
420 char *svalue;
421 krb5_int32 ivalue;
422 kadm5_config_params params, empty_params;
423
424 krb5_error_code kret = 0;
425 krb5_error_code dnsret = 1;
426
427 #ifdef KRB5_DNS_LOOKUP
428 char dns_host[MAX_DNS_NAMELEN];
429 unsigned short dns_portno;
430 krb5_data dns_realm;
431 memset((char *)&dns_realm, 0, sizeof (dns_realm));
432 #endif /* KRB5_DNS_LOOKUP */
433
434 memset((char *) ¶ms, 0, sizeof(params));
435 memset((char *) &empty_params, 0, sizeof(empty_params));
436
437 if (params_in == NULL) params_in = &empty_params;
438
439 if (params_in->mask & KADM5_CONFIG_REALM) {
440 lrealm = params.realm = strdup(params_in->realm);
441 if (params.realm)
442 params.mask |= KADM5_CONFIG_REALM;
443 } else {
444 kret = krb5_get_default_realm(context, &lrealm);
445 if (kret)
446 goto cleanup;
447 params.realm = lrealm;
448 params.mask |= KADM5_CONFIG_REALM;
449 }
450 /*
451 * XXX These defaults should to work on both client and
452 * server. kadm5_get_config_params can be implemented as a
453 * wrapper function in each library that provides correct
454 * defaults for NULL values.
455 */
456 if (use_kdc_config) {
457 filename = DEFAULT_KDC_PROFILE;
458 envname = KDC_PROFILE_ENV;
459 } else {
460 filename = DEFAULT_PROFILE_PATH;
461 envname = "KRB5_CONFIG";
462 }
463 if (context->profile_secure == TRUE) envname = 0;
464
465 kret = krb5_aprof_init(filename, envname, &aprofile);
466 if (kret)
467 goto cleanup;
468
469 /* Initialize realm parameters */
470 hierarchy[0] = "realms";
471 hierarchy[1] = lrealm;
472 hierarchy[3] = (char *) NULL;
473
474 #ifdef KRB5_DNS_LOOKUP
475 /*
476 * Initialize realm info for (possible) DNS lookups.
477 */
478 dns_realm.data = strdup(lrealm);
479 dns_realm.length = strlen(lrealm);
480 dns_realm.magic = 0;
481 #endif /* KRB5_DNS_LOOKUP */
482
483 /* Get the value for the admin server */
484 hierarchy[2] = "admin_server";
485 if (params_in->mask & KADM5_CONFIG_ADMIN_SERVER) {
486 params.admin_server = strdup(params_in->admin_server);
487 if (params.admin_server)
488 params.mask |= KADM5_CONFIG_ADMIN_SERVER;
489 } else if (aprofile &&
490 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
491 params.admin_server = svalue;
492 params.mask |= KADM5_CONFIG_ADMIN_SERVER;
493 }
494 #ifdef KRB5_DNS_LOOKUP
495 else if (strcmp(envname, "KRB5_CONFIG") == 0) {
496 /*
497 * Solaris Kerberos: only do DNS lookup for admin_server if this
498 * is a krb5.conf type of config file. Note, the filename may
499 * not be /etc/krb5/krb5.conf so we assume that the KRB5_CONFIG
500 * envname string will consistently indicate the type of config
501 * file.
502 */
503 dnsret = krb5_get_servername(context, &dns_realm,
504 "_kerberos-adm", "_udp",
505 dns_host, &dns_portno);
506 if (dnsret == 0) {
507 params.admin_server = strdup(dns_host);
508 if (params.admin_server)
509 params.mask |= KADM5_CONFIG_ADMIN_SERVER;
510 params.kadmind_port = dns_portno;
511 params.mask |= KADM5_CONFIG_KADMIND_PORT;
512 }
513 }
514 #endif /* KRB5_DNS_LOOKUP */
515
516 if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) && dnsret) {
517 char *p;
518 p = strchr(params.admin_server, ':');
519 if (p) {
520 params.kadmind_port = atoi(p+1);
521 params.mask |= KADM5_CONFIG_KADMIND_PORT;
522 *p = '\0';
523 }
524 }
525
526 /* Get the value for the database */
527 hierarchy[2] = "database_name";
528 if (params_in->mask & KADM5_CONFIG_DBNAME) {
529 params.dbname = strdup(params_in->dbname);
530 if (params.dbname)
531 params.mask |= KADM5_CONFIG_DBNAME;
532 } else if (aprofile &&
533 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
534 params.dbname = svalue;
535 params.mask |= KADM5_CONFIG_DBNAME;
536 } else {
537 params.dbname = strdup(DEFAULT_KDB_FILE);
538 if (params.dbname)
539 params.mask |= KADM5_CONFIG_DBNAME;
540 }
541
542 /*
543 * admin database name and lockfile are now always derived from dbname
544 */
545 if (params.mask & KADM5_CONFIG_DBNAME) {
546 params.admin_dbname = (char *) malloc(strlen(params.dbname) + 7);
547 if (params.admin_dbname) {
548 sprintf(params.admin_dbname, "%s.kadm5", params.dbname);
549 params.mask |= KADM5_CONFIG_ADBNAME;
550 }
551 }
552
553 if (params.mask & KADM5_CONFIG_ADBNAME) {
554 params.admin_lockfile = (char *) malloc(strlen(params.admin_dbname)
555 + 6);
556 if (params.admin_lockfile) {
557 sprintf(params.admin_lockfile, "%s.lock", params.admin_dbname);
558 params.mask |= KADM5_CONFIG_ADB_LOCKFILE;
559 }
560 }
561
562 /* Get the value for the admin (policy) database lock file*/
563 hierarchy[2] = "admin_keytab";
564 if (params_in->mask & KADM5_CONFIG_ADMIN_KEYTAB) {
565 params.admin_keytab = strdup(params_in->admin_keytab);
566 if (params.admin_keytab)
567 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
568 } else if (aprofile &&
569 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
570 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
571 params.admin_keytab = svalue;
572 } else if ((params.admin_keytab = (char *) getenv("KRB5_KTNAME"))) {
573 params.admin_keytab = strdup(params.admin_keytab);
574 if (params.admin_keytab)
575 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
576 } else {
577 params.admin_keytab = strdup(DEFAULT_KADM5_KEYTAB);
578 if (params.admin_keytab)
579 params.mask |= KADM5_CONFIG_ADMIN_KEYTAB;
580 }
581
582 /* Get the name of the acl file */
583 hierarchy[2] = "acl_file";
584 if (params_in->mask & KADM5_CONFIG_ACL_FILE) {
585 params.acl_file = strdup(params_in->acl_file);
586 if (params.acl_file)
587 params.mask |= KADM5_CONFIG_ACL_FILE;
588 } else if (aprofile &&
589 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
590 params.mask |= KADM5_CONFIG_ACL_FILE;
591 params.acl_file = svalue;
592 } else {
593 params.acl_file = strdup(DEFAULT_KADM5_ACL_FILE);
594 if (params.acl_file)
595 params.mask |= KADM5_CONFIG_ACL_FILE;
596 }
597
598 /* Get the name of the dict file */
599 hierarchy[2] = "dict_file";
600 if (params_in->mask & KADM5_CONFIG_DICT_FILE) {
601 params.dict_file = strdup(params_in->dict_file);
602 if (params.dict_file)
603 params.mask |= KADM5_CONFIG_DICT_FILE;
604 } else if (aprofile &&
605 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
606 params.mask |= KADM5_CONFIG_DICT_FILE;
607 params.dict_file = svalue;
608 }
609
610 /* Get the value for the kadmind port */
611 if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) {
612 hierarchy[2] = "kadmind_port";
613 if (params_in->mask & KADM5_CONFIG_KADMIND_PORT) {
614 params.mask |= KADM5_CONFIG_KADMIND_PORT;
615 params.kadmind_port = params_in->kadmind_port;
616 } else if (aprofile &&
617 !krb5_aprof_get_int32(aprofile, hierarchy, TRUE,
618 &ivalue)) {
619 params.kadmind_port = ivalue;
620 params.mask |= KADM5_CONFIG_KADMIND_PORT;
621 } else {
622 params.kadmind_port = DEFAULT_KADM5_PORT;
623 params.mask |= KADM5_CONFIG_KADMIND_PORT;
624 }
625 }
626
627 /* Get the value for the kpasswd port */
628 if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) {
629 hierarchy[2] = "kpasswd_port";
630 if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT) {
631 params.mask |= KADM5_CONFIG_KPASSWD_PORT;
632 params.kpasswd_port = params_in->kpasswd_port;
633 } else if (aprofile &&
634 !krb5_aprof_get_int32(aprofile, hierarchy, TRUE,
635 &ivalue)) {
636 params.kpasswd_port = ivalue;
637 params.mask |= KADM5_CONFIG_KPASSWD_PORT;
638 } else {
639 params.kpasswd_port = DEFAULT_KPASSWD_PORT;
640 params.mask |= KADM5_CONFIG_KPASSWD_PORT;
641 }
642 }
643
644 /* Get the value for the master key name */
645 hierarchy[2] = "master_key_name";
646 if (params_in->mask & KADM5_CONFIG_MKEY_NAME) {
647 params.mkey_name = strdup(params_in->mkey_name);
648 if (params.mkey_name)
649 params.mask |= KADM5_CONFIG_MKEY_NAME;
650 } else if (aprofile &&
651 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
652 params.mask |= KADM5_CONFIG_MKEY_NAME;
653 params.mkey_name = svalue;
654 }
655
656 /* Get the value for the master key type */
657 hierarchy[2] = "master_key_type";
658 if (params_in->mask & KADM5_CONFIG_ENCTYPE) {
659 params.mask |= KADM5_CONFIG_ENCTYPE;
660 params.enctype = params_in->enctype;
661 } else if (aprofile &&
662 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
663 if (!krb5_string_to_enctype(svalue, ¶ms.enctype)) {
664 params.mask |= KADM5_CONFIG_ENCTYPE;
665 krb5_xfree(svalue);
666 }
667 } else {
668 params.mask |= KADM5_CONFIG_ENCTYPE;
669 params.enctype = DEFAULT_KDC_ENCTYPE;
670 }
671
672 /* Get the value for mkey_from_kbd */
673 if (params_in->mask & KADM5_CONFIG_MKEY_FROM_KBD) {
674 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
675 params.mkey_from_kbd = params_in->mkey_from_kbd;
676 }
677
678 /* Get the value for the stashfile */
679 hierarchy[2] = "key_stash_file";
680 if (params_in->mask & KADM5_CONFIG_STASH_FILE) {
681 params.stash_file = strdup(params_in->stash_file);
682 if (params.stash_file)
683 params.mask |= KADM5_CONFIG_STASH_FILE;
684 } else if (aprofile &&
685 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
686 params.mask |= KADM5_CONFIG_STASH_FILE;
687 params.stash_file = svalue;
688 }
689
690 /*
691 * Solaris Kerberos
692 * Get the value for maximum ticket lifetime.
693 * See SEAM documentation or the Bug ID 4184504
694 * We have changed the logic so that the entries are
695 * created in the database with the maximum duration
696 * for life and renew life KRB5_INT32_MAX
697 * However this wil get negotiated down when
698 * as or tgs request is processed by KDC.
699 */
700 hierarchy[2] = "max_life";
701 if (params_in->mask & KADM5_CONFIG_MAX_LIFE) {
702 params.mask |= KADM5_CONFIG_MAX_LIFE;
703 params.max_life = params_in->max_life;
704 } else {
705 params.max_life = KRB5_INT32_MAX;
706 params.mask |= KADM5_CONFIG_MAX_LIFE;
707 }
708
709 /* Get the value for maximum renewable ticket lifetime. */
710 hierarchy[2] = "max_renewable_life";
711 if (params_in->mask & KADM5_CONFIG_MAX_RLIFE) {
712 params.mask |= KADM5_CONFIG_MAX_RLIFE;
713 params.max_rlife = params_in->max_rlife;
714 } else {
715 params.max_rlife = KRB5_INT32_MAX;
716 params.mask |= KADM5_CONFIG_MAX_RLIFE;
717 }
718
719 /* Get the value for the default principal expiration */
720 hierarchy[2] = "default_principal_expiration";
721 if (params_in->mask & KADM5_CONFIG_EXPIRATION) {
722 params.mask |= KADM5_CONFIG_EXPIRATION;
723 params.expiration = params_in->expiration;
724 } else if (aprofile &&
725 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
726 if (!krb5_string_to_timestamp(svalue, ¶ms.expiration)) {
727 params.mask |= KADM5_CONFIG_EXPIRATION;
728 krb5_xfree(svalue);
729 }
730 } else {
731 params.mask |= KADM5_CONFIG_EXPIRATION;
732 params.expiration = 0;
733 }
734
735 /* Get the value for the default principal flags */
736 hierarchy[2] = "default_principal_flags";
737 if (params_in->mask & KADM5_CONFIG_FLAGS) {
738 params.mask |= KADM5_CONFIG_FLAGS;
739 params.flags = params_in->flags;
740 } else if (aprofile &&
741 !krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
742 char *sp, *ep, *tp;
743
744 sp = svalue;
745 params.flags = 0;
746 while (sp) {
747 if ((ep = strchr(sp, (int) ',')) ||
748 (ep = strchr(sp, (int) ' ')) ||
749 (ep = strchr(sp, (int) '\t'))) {
750 /* Fill in trailing whitespace of sp */
751 tp = ep - 1;
752 while (isspace((int) *tp) && (tp > sp)) {
753 *tp = '\0';
754 tp--;
755 }
756 *ep = '\0';
757 ep++;
758 /* Skip over trailing whitespace of ep */
759 while (isspace((int) *ep) && (*ep)) ep++;
760 }
761 /* Convert this flag */
762 if (krb5_string_to_flags(sp,
763 "+",
764 "-",
765 ¶ms.flags))
766 break;
767 sp = ep;
768 }
769 if (!sp)
770 params.mask |= KADM5_CONFIG_FLAGS;
771 krb5_xfree(svalue);
772 } else {
773 params.mask |= KADM5_CONFIG_FLAGS;
774 params.flags = KRB5_KDB_DEF_FLAGS;
775 }
776
777 /* Get the value for the supported enctype/salttype matrix */
778 hierarchy[2] = "supported_enctypes";
779 if (params_in->mask & KADM5_CONFIG_ENCTYPES) {
780 params.mask |= KADM5_CONFIG_ENCTYPES;
781 if (params_in->num_keysalts > 0) {
782 params.keysalts = malloc(params_in->num_keysalts *
783 sizeof (*params.keysalts));
784 if (params.keysalts == NULL) {
785 kret = ENOMEM;
786 goto cleanup;
787 }
788 (void) memcpy(params.keysalts, params_in->keysalts,
789 (params_in->num_keysalts *
790 sizeof (*params.keysalts)));
791 params.num_keysalts = params_in->num_keysalts;
792 }
793 } else {
794 svalue = NULL;
795 if (aprofile)
796 krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
797 if (svalue == NULL)
798 svalue = strdup(DEFAULT_ENCTYPE_LIST);
799
800 params.keysalts = NULL;
801 params.num_keysalts = 0;
802 krb5_string_to_keysalts(svalue,
803 ", \t",/* Tuple separators */
804 ":.-", /* Key/salt separators */
805 0, /* No duplicates */
806 ¶ms.keysalts,
807 ¶ms.num_keysalts);
808 if (params.num_keysalts)
809 params.mask |= KADM5_CONFIG_ENCTYPES;
810
811 if (svalue)
812 krb5_xfree(svalue);
813 }
814
815 hierarchy[2] = "kpasswd_server";
816 if (params_in->mask & KADM5_CONFIG_KPASSWD_SERVER) {
817 params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
818 params.kpasswd_server = strdup(params_in->kpasswd_server);
819 } else {
820 svalue = NULL;
821
822 if (aprofile)
823 krb5_aprof_get_string(aprofile, hierarchy,
824 TRUE, &svalue);
825 if (svalue == NULL) {
826 #ifdef KRB5_DNS_LOOKUP
827 if (strcmp(envname, "KRB5_CONFIG") == 0) {
828 /*
829 * Solaris Kerberos: only do DNS lookup for
830 * kpasswd_server if this is a krb5.conf type of
831 * config file. Note, the filename may not be
832 * /etc/krb5/krb5.conf so we assume that the
833 * KRB5_CONFIG envname string will consistently
834 * indicate the type of config file.
835 */
836 dnsret = krb5_get_servername(context,
837 &dns_realm, "_kpasswd", "_udp",
838 dns_host, &dns_portno);
839
840 if (dnsret == 0) {
841 params.kpasswd_server =
842 strdup(dns_host);
843 if (params.kpasswd_server) {
844 params.mask |=
845 KADM5_CONFIG_KPASSWD_SERVER;
846 }
847 params.kpasswd_port = dns_portno;
848 params.mask |=
849 KADM5_CONFIG_KPASSWD_PORT;
850 }
851 }
852 #endif /* KRB5_DNS_LOOKUP */
853
854 /*
855 * If a unique 'kpasswd_server' is not specified,
856 * use the normal 'admin_server'.
857 */
858 if ((params.mask & KADM5_CONFIG_ADMIN_SERVER) &&
859 dnsret) {
860 params.kpasswd_server =
861 strdup(params.admin_server);
862 params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
863 }
864 } else {
865 char *p;
866 params.kpasswd_server = svalue;
867 params.mask |= KADM5_CONFIG_KPASSWD_SERVER;
868
869 if ((p = strchr(params.kpasswd_server, ':'))) {
870 params.kpasswd_port = atoi(p+1);
871 params.mask |= KADM5_CONFIG_KPASSWD_PORT;
872 *p = '\0';
873 }
874 }
875 }
876
877 hierarchy[2] = "kpasswd_protocol";
878
879 /* default to current RPCSEC_GSS protocol */
880 params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
881 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
882
883 if (params_in->mask & KADM5_CONFIG_KPASSWD_PROTOCOL) {
884 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
885 params.kpasswd_protocol = params_in->kpasswd_protocol;
886 } else {
887 svalue = NULL;
888
889 if (aprofile)
890 krb5_aprof_get_string(aprofile, hierarchy,
891 TRUE, &svalue);
892 if (svalue != NULL) {
893 if (strcasecmp(svalue, "RPCSEC_GSS") == 0) {
894 params.kpasswd_protocol = KRB5_CHGPWD_RPCSEC;
895 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
896 } else if (strcasecmp(svalue, "SET_CHANGE") == 0) {
897 params.kpasswd_protocol =
898 KRB5_CHGPWD_CHANGEPW_V2;
899 params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL;
900 }
901 }
902 if (svalue)
903 krb5_xfree(svalue);
904 }
905
906 /*
907 * If the kpasswd_port is not yet defined, define it now.
908 */
909 if (! (params.mask & KADM5_CONFIG_KPASSWD_PORT)) {
910 if (params_in->mask & KADM5_CONFIG_KPASSWD_PORT)
911 params.kpasswd_port = params_in->kpasswd_port;
912 /*
913 * If kpasswd_port is not explicitly defined,
914 * determine the port to use based on the protocol.
915 * The alternative protocol uses a different port
916 * than the standard admind port.
917 */
918 else if (params.kpasswd_protocol == KRB5_CHGPWD_RPCSEC) {
919 params.kpasswd_port = DEFAULT_KADM5_PORT;
920 } else {
921 /*
922 * When using the Horowitz/IETF protocol for
923 * password changing, the default port is 464
924 * (officially recognized by IANA).
925 */
926 params.kpasswd_port = DEFAULT_KPASSWD_PORT;
927 }
928 params.mask |= KADM5_CONFIG_KPASSWD_PORT;
929 }
930
931 hierarchy[2] = "sunw_dbprop_enable";
932
933 params.iprop_enabled = FALSE;
934 params.mask |= KADM5_CONFIG_IPROP_ENABLED;
935
936 if (params_in->mask & KADM5_CONFIG_IPROP_ENABLED) {
937 params.mask |= KADM5_CONFIG_IPROP_ENABLED;
938 params.iprop_enabled = params_in->iprop_enabled;
939 } else {
940 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
941 TRUE, &svalue)) {
942 if (strncasecmp(svalue, "Y", 1) == 0)
943 params.iprop_enabled = TRUE;
944 if (strncasecmp(svalue, "true", 4) == 0)
945 params.iprop_enabled = TRUE;
946 params.mask |= KADM5_CONFIG_IPROP_ENABLED;
947 krb5_xfree(svalue);
948 }
949 }
950
951 hierarchy[2] = "sunw_dbprop_master_ulogsize";
952
953 params.iprop_ulogsize = DEF_ULOGENTRIES;
954 params.mask |= KADM5_CONFIG_ULOG_SIZE;
955
956 if (params_in->mask & KADM5_CONFIG_ULOG_SIZE) {
957 params.mask |= KADM5_CONFIG_ULOG_SIZE;
958 params.iprop_ulogsize = params_in->iprop_ulogsize;
959 } else {
960 if (aprofile && !krb5_aprof_get_int32(aprofile, hierarchy,
961 TRUE, &ivalue)) {
962 if (ivalue > MAX_ULOGENTRIES)
963 params.iprop_ulogsize = MAX_ULOGENTRIES;
964 else if (ivalue <= 0)
965 params.iprop_ulogsize = DEF_ULOGENTRIES;
966 else
967 params.iprop_ulogsize = ivalue;
968 params.mask |= KADM5_CONFIG_ULOG_SIZE;
969 }
970 }
971
972 hierarchy[2] = "sunw_dbprop_slave_poll";
973
974 params.iprop_polltime = strdup("2m");
975 if (params.iprop_polltime)
976 params.mask |= KADM5_CONFIG_POLL_TIME;
977
978 if (params_in->mask & KADM5_CONFIG_POLL_TIME) {
979 if (params.iprop_polltime)
980 free(params.iprop_polltime);
981 params.iprop_polltime = strdup(params_in->iprop_polltime);
982 if (params.iprop_polltime)
983 params.mask |= KADM5_CONFIG_POLL_TIME;
984 } else {
985 if (aprofile && !krb5_aprof_get_string(aprofile, hierarchy,
986 TRUE, &svalue)) {
987 if (params.iprop_polltime)
988 free(params.iprop_polltime);
989 params.iprop_polltime = strdup(svalue);
990 params.mask |= KADM5_CONFIG_POLL_TIME;
991 krb5_xfree(svalue);
992 }
993 }
994
995 *params_out = params;
996
997 cleanup:
998 if (aprofile)
999 krb5_aprof_finish(aprofile);
1000 if (kret) {
1001 kadm5_free_config_params(context, ¶ms);
1002 params_out->mask = 0;
1003 }
1004 #ifdef KRB5_DNS_LOOKUP
1005 if (dns_realm.data)
1006 free(dns_realm.data);
1007 #endif /* KRB5_DNS_LOOKUP */
1008
1009 return(kret);
1010 }
1011 /*
1012 * kadm5_free_config_params() - Free data allocated by above.
1013 */
1014 /*ARGSUSED*/
1015 krb5_error_code
kadm5_free_config_params(context,params)1016 kadm5_free_config_params(context, params)
1017 krb5_context context;
1018 kadm5_config_params *params;
1019 {
1020 if (params) {
1021 if (params->dbname) {
1022 krb5_xfree(params->dbname);
1023 params->dbname = NULL;
1024 }
1025 if (params->mkey_name) {
1026 krb5_xfree(params->mkey_name);
1027 params->mkey_name = NULL;
1028 }
1029 if (params->stash_file) {
1030 krb5_xfree(params->stash_file);
1031 params->stash_file = NULL;
1032 }
1033 if (params->keysalts) {
1034 krb5_xfree(params->keysalts);
1035 params->keysalts = NULL;
1036 params->num_keysalts = 0;
1037 }
1038 if (params->admin_keytab) {
1039 free(params->admin_keytab);
1040 params->admin_keytab = NULL;
1041 }
1042 if (params->dict_file) {
1043 free(params->dict_file);
1044 params->dict_file = NULL;
1045 }
1046 if (params->acl_file) {
1047 free(params->acl_file);
1048 params->acl_file = NULL;
1049 }
1050 if (params->realm) {
1051 free(params->realm);
1052 params->realm = NULL;
1053 }
1054 if (params->admin_dbname) {
1055 free(params->admin_dbname);
1056 params->admin_dbname = NULL;
1057 }
1058 if (params->admin_lockfile) {
1059 free(params->admin_lockfile);
1060 params->admin_lockfile = NULL;
1061 }
1062 if (params->admin_server) {
1063 free(params->admin_server);
1064 params->admin_server = NULL;
1065 }
1066 if (params->kpasswd_server) {
1067 free(params->kpasswd_server);
1068 params->kpasswd_server = NULL;
1069 }
1070 if (params->iprop_polltime) {
1071 free(params->iprop_polltime);
1072 params->iprop_polltime = NULL;
1073 }
1074 }
1075 return (0);
1076 }
1077
1078 krb5_error_code
kadm5_get_admin_service_name(krb5_context ctx,char * realm_in,char * admin_name,size_t maxlen)1079 kadm5_get_admin_service_name(krb5_context ctx,
1080 char *realm_in,
1081 char *admin_name,
1082 size_t maxlen)
1083 {
1084 krb5_error_code ret;
1085 kadm5_config_params params_in, params_out;
1086 struct hostent *hp;
1087
1088 memset(¶ms_in, 0, sizeof(params_in));
1089 memset(¶ms_out, 0, sizeof(params_out));
1090
1091 params_in.mask |= KADM5_CONFIG_REALM;
1092 params_in.realm = realm_in;
1093 ret = kadm5_get_config_params(ctx, 0, ¶ms_in, ¶ms_out);
1094 if (ret)
1095 return ret;
1096
1097 if (!(params_out.mask & KADM5_CONFIG_ADMIN_SERVER)) {
1098 ret = KADM5_MISSING_KRB5_CONF_PARAMS;
1099 goto err_params;
1100 }
1101
1102 hp = gethostbyname(params_out.admin_server);
1103 if (hp == NULL) {
1104 ret = errno;
1105 goto err_params;
1106 }
1107 if (strlen(hp->h_name) + sizeof("kadmin/") > maxlen) {
1108 ret = ENOMEM;
1109 goto err_params;
1110 }
1111 sprintf(admin_name, "kadmin/%s", hp->h_name);
1112
1113 err_params:
1114 kadm5_free_config_params(ctx, ¶ms_out);
1115 return ret;
1116 }
1117
1118 /***********************************************************************
1119 * This is the old krb5_realm_read_params, which I mutated into
1120 * kadm5_get_config_params but which old code (kdb5_* and krb5kdc)
1121 * still uses.
1122 ***********************************************************************/
1123
1124 /*
1125 * krb5_read_realm_params() - Read per-realm parameters from KDC
1126 * alternate profile.
1127 */
1128 krb5_error_code
krb5_read_realm_params(kcontext,realm,rparamp)1129 krb5_read_realm_params(kcontext, realm, rparamp)
1130 krb5_context kcontext;
1131 char *realm;
1132 krb5_realm_params **rparamp;
1133 {
1134 char *filename;
1135 char *envname;
1136 char *lrealm;
1137 krb5_pointer aprofile = 0;
1138 krb5_realm_params *rparams;
1139 const char *hierarchy[4];
1140 char *svalue;
1141 krb5_int32 ivalue;
1142 krb5_boolean bvalue;
1143 krb5_deltat dtvalue;
1144
1145 char *kdcprofile = 0;
1146 char *kdcenv = 0;
1147
1148 krb5_error_code kret;
1149
1150 filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
1151 envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
1152
1153 if (kcontext->profile_secure == TRUE) envname = 0;
1154
1155 rparams = (krb5_realm_params *) NULL;
1156 if (realm)
1157 lrealm = strdup(realm);
1158 else {
1159 kret = krb5_get_default_realm(kcontext, &lrealm);
1160 if (kret)
1161 goto cleanup;
1162 }
1163
1164 kret = krb5_aprof_init(filename, envname, &aprofile);
1165 if (kret)
1166 goto cleanup;
1167
1168 rparams = (krb5_realm_params *) malloc(sizeof(krb5_realm_params));
1169 if (rparams == 0) {
1170 kret = ENOMEM;
1171 goto cleanup;
1172 }
1173
1174 /* Initialize realm parameters */
1175 memset((char *) rparams, 0, sizeof(krb5_realm_params));
1176
1177 /* Get the value for the database */
1178 hierarchy[0] = "realms";
1179 hierarchy[1] = lrealm;
1180 hierarchy[2] = "database_name";
1181 hierarchy[3] = (char *) NULL;
1182 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1183 rparams->realm_dbname = svalue;
1184
1185 /* Get the value for the KDC port list */
1186 hierarchy[2] = "kdc_ports";
1187 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1188 rparams->realm_kdc_ports = svalue;
1189 hierarchy[2] = "kdc_tcp_ports";
1190 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1191 rparams->realm_kdc_tcp_ports = svalue;
1192
1193 /* Get the name of the acl file */
1194 hierarchy[2] = "acl_file";
1195 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1196 rparams->realm_acl_file = svalue;
1197
1198 /* Get the value for the kadmind port */
1199 hierarchy[2] = "kadmind_port";
1200 if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
1201 rparams->realm_kadmind_port = ivalue;
1202 rparams->realm_kadmind_port_valid = 1;
1203 }
1204
1205 /* Get the value for the master key name */
1206 hierarchy[2] = "master_key_name";
1207 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1208 rparams->realm_mkey_name = svalue;
1209
1210 /* Get the value for the master key type */
1211 hierarchy[2] = "master_key_type";
1212 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
1213 if (!krb5_string_to_enctype(svalue, &rparams->realm_enctype))
1214 rparams->realm_enctype_valid = 1;
1215 krb5_xfree(svalue);
1216 }
1217
1218 /* Get the value for the stashfile */
1219 hierarchy[2] = "key_stash_file";
1220 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
1221 rparams->realm_stash_file = svalue;
1222
1223 /* Get the value for maximum ticket lifetime. */
1224 hierarchy[2] = "max_life";
1225 if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
1226 rparams->realm_max_life = dtvalue;
1227 rparams->realm_max_life_valid = 1;
1228 }
1229
1230 /* Get the value for maximum renewable ticket lifetime. */
1231 hierarchy[2] = "max_renewable_life";
1232 if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
1233 rparams->realm_max_rlife = dtvalue;
1234 rparams->realm_max_rlife_valid = 1;
1235 }
1236
1237 /* Get the value for the default principal expiration */
1238 hierarchy[2] = "default_principal_expiration";
1239 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
1240 if (!krb5_string_to_timestamp(svalue,
1241 &rparams->realm_expiration))
1242 rparams->realm_expiration_valid = 1;
1243 krb5_xfree(svalue);
1244 }
1245
1246 hierarchy[2] = "reject_bad_transit";
1247 if (!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
1248 rparams->realm_reject_bad_transit = bvalue;
1249 rparams->realm_reject_bad_transit_valid = 1;
1250 }
1251
1252 /* Get the value for the default principal flags */
1253 hierarchy[2] = "default_principal_flags";
1254 if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
1255 char *sp, *ep, *tp;
1256
1257 sp = svalue;
1258 rparams->realm_flags = 0;
1259 while (sp) {
1260 if ((ep = strchr(sp, (int) ',')) ||
1261 (ep = strchr(sp, (int) ' ')) ||
1262 (ep = strchr(sp, (int) '\t'))) {
1263 /* Fill in trailing whitespace of sp */
1264 tp = ep - 1;
1265 while (isspace((int) *tp) && (tp < sp)) {
1266 *tp = '\0';
1267 tp--;
1268 }
1269 *ep = '\0';
1270 ep++;
1271 /* Skip over trailing whitespace of ep */
1272 while (isspace((int) *ep) && (*ep)) ep++;
1273 }
1274 /* Convert this flag */
1275 if (krb5_string_to_flags(sp,
1276 "+",
1277 "-",
1278 &rparams->realm_flags))
1279 break;
1280 sp = ep;
1281 }
1282 if (!sp)
1283 rparams->realm_flags_valid = 1;
1284 krb5_xfree(svalue);
1285 }
1286
1287 /* Get the value for the supported enctype/salttype matrix */
1288 /*
1289 * SUNWresync121
1290 * Solaris kerberos: updated this code to support default values for
1291 * the supported_enctypes.
1292 */
1293 hierarchy[2] = "supported_enctypes";
1294 svalue = NULL;
1295 krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue);
1296
1297 /*
1298 * Set the default value if supported_enctypes was not explicitly
1299 * set in the kdc.conf.
1300 */
1301 if (svalue == NULL) {
1302 svalue = strdup(DEFAULT_ENCTYPE_LIST);
1303 }
1304 if (svalue != NULL) {
1305 krb5_string_to_keysalts(svalue,
1306 ", \t", /* Tuple separators */
1307 ":.-", /* Key/salt separators */
1308 0, /* No duplicates */
1309 &rparams->realm_keysalts,
1310 &rparams->realm_num_keysalts);
1311 krb5_xfree(svalue);
1312 svalue = NULL;
1313 }
1314 cleanup:
1315 if (aprofile)
1316 krb5_aprof_finish(aprofile);
1317 if (lrealm)
1318 free(lrealm);
1319 if (kret) {
1320 if (rparams)
1321 krb5_free_realm_params(kcontext, rparams);
1322 rparams = 0;
1323 }
1324 *rparamp = rparams;
1325 return(kret);
1326 }
1327
1328 /*
1329 * krb5_free_realm_params() - Free data allocated by above.
1330 */
1331 krb5_error_code
krb5_free_realm_params(kcontext,rparams)1332 krb5_free_realm_params(kcontext, rparams)
1333 krb5_context kcontext;
1334 krb5_realm_params *rparams;
1335 {
1336 if (rparams) {
1337 if (rparams->realm_profile)
1338 krb5_xfree(rparams->realm_profile);
1339 if (rparams->realm_dbname)
1340 krb5_xfree(rparams->realm_dbname);
1341 if (rparams->realm_mkey_name)
1342 krb5_xfree(rparams->realm_mkey_name);
1343 if (rparams->realm_stash_file)
1344 krb5_xfree(rparams->realm_stash_file);
1345 if (rparams->realm_keysalts)
1346 krb5_xfree(rparams->realm_keysalts);
1347 if (rparams->realm_kdc_ports)
1348 krb5_xfree(rparams->realm_kdc_ports);
1349 if (rparams->realm_kdc_tcp_ports)
1350 krb5_xfree(rparams->realm_kdc_tcp_ports);
1351 if (rparams->realm_acl_file)
1352 krb5_xfree(rparams->realm_acl_file);
1353 krb5_xfree(rparams);
1354 }
1355 return(0);
1356 }
1357
1358