xref: /freebsd/crypto/heimdal/lib/krb5/config_file.c (revision 8373020d34ceb1ac55d8f43333c1ca3680185b39)
1b528cefcSMark Murray /*
28373020dSJacques Vidrine  * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "krb5_locl.h"
358373020dSJacques Vidrine RCSID("$Id: config_file.c,v 1.45 2002/08/14 17:35:03 joda Exp $");
36b528cefcSMark Murray 
37b528cefcSMark Murray #ifndef HAVE_NETINFO
38b528cefcSMark Murray 
39adb0ddaeSAssar Westerlund static krb5_error_code parse_section(char *p, krb5_config_section **s,
40b528cefcSMark Murray 				     krb5_config_section **res,
418373020dSJacques Vidrine 				     const char **error_message);
42adb0ddaeSAssar Westerlund static krb5_error_code parse_binding(FILE *f, unsigned *lineno, char *p,
43b528cefcSMark Murray 				     krb5_config_binding **b,
44b528cefcSMark Murray 				     krb5_config_binding **parent,
458373020dSJacques Vidrine 				     const char **error_message);
46adb0ddaeSAssar Westerlund static krb5_error_code parse_list(FILE *f, unsigned *lineno,
47adb0ddaeSAssar Westerlund 				  krb5_config_binding **parent,
488373020dSJacques Vidrine 				  const char **error_message);
498373020dSJacques Vidrine 
508373020dSJacques Vidrine static krb5_config_section *
518373020dSJacques Vidrine get_entry(krb5_config_section **parent, const char *name, int type)
528373020dSJacques Vidrine {
538373020dSJacques Vidrine     krb5_config_section **q;
548373020dSJacques Vidrine 
558373020dSJacques Vidrine     for(q = parent; *q != NULL; q = &(*q)->next)
568373020dSJacques Vidrine 	if(type == krb5_config_list &&
578373020dSJacques Vidrine 	   type == (*q)->type &&
588373020dSJacques Vidrine 	   strcmp(name, (*q)->name) == 0)
598373020dSJacques Vidrine 	    return *q;
608373020dSJacques Vidrine     *q = calloc(1, sizeof(**q));
618373020dSJacques Vidrine     if(*q == NULL)
628373020dSJacques Vidrine 	return NULL;
638373020dSJacques Vidrine     (*q)->name = strdup(name);
648373020dSJacques Vidrine     (*q)->type = type;
658373020dSJacques Vidrine     if((*q)->name == NULL) {
668373020dSJacques Vidrine 	free(*q);
678373020dSJacques Vidrine 	*q = NULL;
688373020dSJacques Vidrine 	return NULL;
698373020dSJacques Vidrine     }
708373020dSJacques Vidrine     return *q;
718373020dSJacques Vidrine }
72b528cefcSMark Murray 
73b528cefcSMark Murray /*
74b528cefcSMark Murray  * Parse a section:
75b528cefcSMark Murray  *
76b528cefcSMark Murray  * [section]
77b528cefcSMark Murray  *	foo = bar
78b528cefcSMark Murray  *	b = {
79b528cefcSMark Murray  *		a
80b528cefcSMark Murray  *	    }
81b528cefcSMark Murray  * ...
82b528cefcSMark Murray  *
83b528cefcSMark Murray  * starting at the line in `p', storing the resulting structure in
84b528cefcSMark Murray  * `s' and hooking it into `parent'.
85b528cefcSMark Murray  * Store the error message in `error_message'.
86b528cefcSMark Murray  */
87b528cefcSMark Murray 
88adb0ddaeSAssar Westerlund static krb5_error_code
89b528cefcSMark Murray parse_section(char *p, krb5_config_section **s, krb5_config_section **parent,
908373020dSJacques Vidrine 	      const char **error_message)
91b528cefcSMark Murray {
92b528cefcSMark Murray     char *p1;
93b528cefcSMark Murray     krb5_config_section *tmp;
94b528cefcSMark Murray 
95b528cefcSMark Murray     p1 = strchr (p + 1, ']');
96b528cefcSMark Murray     if (p1 == NULL) {
97b528cefcSMark Murray 	*error_message = "missing ]";
98adb0ddaeSAssar Westerlund 	return KRB5_CONFIG_BADFORMAT;
99b528cefcSMark Murray     }
100b528cefcSMark Murray     *p1 = '\0';
1018373020dSJacques Vidrine     tmp = get_entry(parent, p + 1, krb5_config_list);
102b528cefcSMark Murray     if(tmp == NULL) {
103b528cefcSMark Murray 	*error_message = "out of memory";
104adb0ddaeSAssar Westerlund 	return KRB5_CONFIG_BADFORMAT;
105b528cefcSMark Murray     }
106b528cefcSMark Murray     *s = tmp;
107b528cefcSMark Murray     return 0;
108b528cefcSMark Murray }
109b528cefcSMark Murray 
110b528cefcSMark Murray /*
111b528cefcSMark Murray  * Parse a brace-enclosed list from `f', hooking in the structure at
112b528cefcSMark Murray  * `parent'.
113b528cefcSMark Murray  * Store the error message in `error_message'.
114b528cefcSMark Murray  */
115b528cefcSMark Murray 
116b528cefcSMark Murray static int
117b528cefcSMark Murray parse_list(FILE *f, unsigned *lineno, krb5_config_binding **parent,
1188373020dSJacques Vidrine 	   const char **error_message)
119b528cefcSMark Murray {
120b528cefcSMark Murray     char buf[BUFSIZ];
121b528cefcSMark Murray     int ret;
122b528cefcSMark Murray     krb5_config_binding *b = NULL;
123b528cefcSMark Murray     unsigned beg_lineno = *lineno;
124b528cefcSMark Murray 
125b528cefcSMark Murray     while(fgets(buf, sizeof(buf), f) != NULL) {
126b528cefcSMark Murray 	char *p;
127b528cefcSMark Murray 
128b528cefcSMark Murray 	++*lineno;
129b528cefcSMark Murray 	if (buf[strlen(buf) - 1] == '\n')
130b528cefcSMark Murray 	    buf[strlen(buf) - 1] = '\0';
131b528cefcSMark Murray 	p = buf;
132b528cefcSMark Murray 	while(isspace((unsigned char)*p))
133b528cefcSMark Murray 	    ++p;
134b528cefcSMark Murray 	if (*p == '#' || *p == ';' || *p == '\0')
135b528cefcSMark Murray 	    continue;
136b528cefcSMark Murray 	while(isspace((unsigned char)*p))
137b528cefcSMark Murray 	    ++p;
138b528cefcSMark Murray 	if (*p == '}')
139b528cefcSMark Murray 	    return 0;
140b528cefcSMark Murray 	if (*p == '\0')
141b528cefcSMark Murray 	    continue;
142b528cefcSMark Murray 	ret = parse_binding (f, lineno, p, &b, parent, error_message);
143b528cefcSMark Murray 	if (ret)
144b528cefcSMark Murray 	    return ret;
145b528cefcSMark Murray     }
146b528cefcSMark Murray     *lineno = beg_lineno;
147b528cefcSMark Murray     *error_message = "unclosed {";
148adb0ddaeSAssar Westerlund     return KRB5_CONFIG_BADFORMAT;
149b528cefcSMark Murray }
150b528cefcSMark Murray 
151b528cefcSMark Murray /*
152b528cefcSMark Murray  *
153b528cefcSMark Murray  */
154b528cefcSMark Murray 
155b528cefcSMark Murray static int
156b528cefcSMark Murray parse_binding(FILE *f, unsigned *lineno, char *p,
157b528cefcSMark Murray 	      krb5_config_binding **b, krb5_config_binding **parent,
1588373020dSJacques Vidrine 	      const char **error_message)
159b528cefcSMark Murray {
160b528cefcSMark Murray     krb5_config_binding *tmp;
161b528cefcSMark Murray     char *p1, *p2;
162b528cefcSMark Murray     int ret = 0;
163b528cefcSMark Murray 
164b528cefcSMark Murray     p1 = p;
165b528cefcSMark Murray     while (*p && *p != '=' && !isspace((unsigned char)*p))
166b528cefcSMark Murray 	++p;
167b528cefcSMark Murray     if (*p == '\0') {
1688373020dSJacques Vidrine 	*error_message = "missing =";
169adb0ddaeSAssar Westerlund 	return KRB5_CONFIG_BADFORMAT;
170b528cefcSMark Murray     }
171b528cefcSMark Murray     p2 = p;
172b528cefcSMark Murray     while (isspace((unsigned char)*p))
173b528cefcSMark Murray 	++p;
174b528cefcSMark Murray     if (*p != '=') {
1758373020dSJacques Vidrine 	*error_message = "missing =";
176adb0ddaeSAssar Westerlund 	return KRB5_CONFIG_BADFORMAT;
177b528cefcSMark Murray     }
178b528cefcSMark Murray     ++p;
179b528cefcSMark Murray     while(isspace((unsigned char)*p))
180b528cefcSMark Murray 	++p;
1818373020dSJacques Vidrine     *p2 = '\0';
1828373020dSJacques Vidrine     if (*p == '{') {
1838373020dSJacques Vidrine 	tmp = get_entry(parent, p1, krb5_config_list);
184b528cefcSMark Murray 	if (tmp == NULL) {
185b528cefcSMark Murray 	    *error_message = "out of memory";
186adb0ddaeSAssar Westerlund 	    return KRB5_CONFIG_BADFORMAT;
187b528cefcSMark Murray 	}
188b528cefcSMark Murray 	ret = parse_list (f, lineno, &tmp->u.list, error_message);
189b528cefcSMark Murray     } else {
1908373020dSJacques Vidrine 	tmp = get_entry(parent, p1, krb5_config_string);
1918373020dSJacques Vidrine 	if (tmp == NULL) {
1928373020dSJacques Vidrine 	    *error_message = "out of memory";
1938373020dSJacques Vidrine 	    return KRB5_CONFIG_BADFORMAT;
1948373020dSJacques Vidrine 	}
195b528cefcSMark Murray 	p1 = p;
196b528cefcSMark Murray 	p = p1 + strlen(p1);
197b528cefcSMark Murray 	while(p > p1 && isspace((unsigned char)*(p-1)))
198b528cefcSMark Murray 	    --p;
199b528cefcSMark Murray 	*p = '\0';
200b528cefcSMark Murray 	tmp->u.string = strdup(p1);
201b528cefcSMark Murray     }
202b528cefcSMark Murray     *b = tmp;
203b528cefcSMark Murray     return ret;
204b528cefcSMark Murray }
205b528cefcSMark Murray 
206b528cefcSMark Murray /*
207b528cefcSMark Murray  * Parse the config file `fname', generating the structures into `res'
208b528cefcSMark Murray  * returning error messages in `error_message'
209b528cefcSMark Murray  */
210b528cefcSMark Murray 
211adb0ddaeSAssar Westerlund static krb5_error_code
212b528cefcSMark Murray krb5_config_parse_file_debug (const char *fname,
213b528cefcSMark Murray 			      krb5_config_section **res,
214b528cefcSMark Murray 			      unsigned *lineno,
2158373020dSJacques Vidrine 			      const char **error_message)
216b528cefcSMark Murray {
217b528cefcSMark Murray     FILE *f;
218b528cefcSMark Murray     krb5_config_section *s;
219b528cefcSMark Murray     krb5_config_binding *b;
220b528cefcSMark Murray     char buf[BUFSIZ];
221adb0ddaeSAssar Westerlund     krb5_error_code ret = 0;
222b528cefcSMark Murray 
223b528cefcSMark Murray     s = NULL;
224b528cefcSMark Murray     b = NULL;
225b528cefcSMark Murray     *lineno = 0;
226b528cefcSMark Murray     f = fopen (fname, "r");
227b528cefcSMark Murray     if (f == NULL) {
228b528cefcSMark Murray 	*error_message = "cannot open file";
2295e9cd1aeSAssar Westerlund 	return ENOENT;
230b528cefcSMark Murray     }
231b528cefcSMark Murray     while (fgets(buf, sizeof(buf), f) != NULL) {
232b528cefcSMark Murray 	char *p;
233b528cefcSMark Murray 
234b528cefcSMark Murray 	++*lineno;
235b528cefcSMark Murray 	if(buf[strlen(buf) - 1] == '\n')
236b528cefcSMark Murray 	    buf[strlen(buf) - 1] = '\0';
237b528cefcSMark Murray 	p = buf;
238b528cefcSMark Murray 	while(isspace((unsigned char)*p))
239b528cefcSMark Murray 	    ++p;
240b528cefcSMark Murray 	if (*p == '#' || *p == ';')
241b528cefcSMark Murray 	    continue;
242b528cefcSMark Murray 	if (*p == '[') {
243b528cefcSMark Murray 	    ret = parse_section(p, &s, res, error_message);
2445e9cd1aeSAssar Westerlund 	    if (ret) {
2455e9cd1aeSAssar Westerlund 		goto out;
2465e9cd1aeSAssar Westerlund 	    }
247b528cefcSMark Murray 	    b = NULL;
248b528cefcSMark Murray 	} else if (*p == '}') {
249b528cefcSMark Murray 	    *error_message = "unmatched }";
250adb0ddaeSAssar Westerlund 	    ret = EINVAL;	/* XXX */
2515e9cd1aeSAssar Westerlund 	    goto out;
252b528cefcSMark Murray 	} else if(*p != '\0') {
253b528cefcSMark Murray 	    ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message);
254b528cefcSMark Murray 	    if (ret)
2555e9cd1aeSAssar Westerlund 		goto out;
256b528cefcSMark Murray 	}
257b528cefcSMark Murray     }
2585e9cd1aeSAssar Westerlund out:
259b528cefcSMark Murray     fclose (f);
2605e9cd1aeSAssar Westerlund     return ret;
261b528cefcSMark Murray }
262b528cefcSMark Murray 
263b528cefcSMark Murray krb5_error_code
2648373020dSJacques Vidrine krb5_config_parse_file_multi (krb5_context context,
265adb0ddaeSAssar Westerlund 			      const char *fname,
266adb0ddaeSAssar Westerlund 			      krb5_config_section **res)
267b528cefcSMark Murray {
2688373020dSJacques Vidrine     const char *str;
269b528cefcSMark Murray     unsigned lineno;
270adb0ddaeSAssar Westerlund     krb5_error_code ret;
271b528cefcSMark Murray 
272adb0ddaeSAssar Westerlund     ret = krb5_config_parse_file_debug (fname, res, &lineno, &str);
273adb0ddaeSAssar Westerlund     if (ret) {
274adb0ddaeSAssar Westerlund 	krb5_set_error_string (context, "%s:%u: %s", fname, lineno, str);
275adb0ddaeSAssar Westerlund 	return ret;
276adb0ddaeSAssar Westerlund     }
277adb0ddaeSAssar Westerlund     return 0;
278b528cefcSMark Murray }
279b528cefcSMark Murray 
2808373020dSJacques Vidrine krb5_error_code
2818373020dSJacques Vidrine krb5_config_parse_file (krb5_context context,
2828373020dSJacques Vidrine 			const char *fname,
2838373020dSJacques Vidrine 			krb5_config_section **res)
2848373020dSJacques Vidrine {
2858373020dSJacques Vidrine     *res = NULL;
2868373020dSJacques Vidrine     return krb5_config_parse_file_multi(context, fname, res);
2878373020dSJacques Vidrine }
2888373020dSJacques Vidrine 
289b528cefcSMark Murray #endif /* !HAVE_NETINFO */
290b528cefcSMark Murray 
291b528cefcSMark Murray static void
292b528cefcSMark Murray free_binding (krb5_context context, krb5_config_binding *b)
293b528cefcSMark Murray {
294b528cefcSMark Murray     krb5_config_binding *next_b;
295b528cefcSMark Murray 
296b528cefcSMark Murray     while (b) {
297b528cefcSMark Murray 	free (b->name);
298b528cefcSMark Murray 	if (b->type == krb5_config_string)
299b528cefcSMark Murray 	    free (b->u.string);
300b528cefcSMark Murray 	else if (b->type == krb5_config_list)
301b528cefcSMark Murray 	    free_binding (context, b->u.list);
302b528cefcSMark Murray 	else
303b528cefcSMark Murray 	    krb5_abortx(context, "unknown binding type (%d) in free_binding",
304b528cefcSMark Murray 			b->type);
305b528cefcSMark Murray 	next_b = b->next;
306b528cefcSMark Murray 	free (b);
307b528cefcSMark Murray 	b = next_b;
308b528cefcSMark Murray     }
309b528cefcSMark Murray }
310b528cefcSMark Murray 
311b528cefcSMark Murray krb5_error_code
312b528cefcSMark Murray krb5_config_file_free (krb5_context context, krb5_config_section *s)
313b528cefcSMark Murray {
314b528cefcSMark Murray     free_binding (context, s);
315b528cefcSMark Murray     return 0;
316b528cefcSMark Murray }
317b528cefcSMark Murray 
318b528cefcSMark Murray const void *
319b528cefcSMark Murray krb5_config_get_next (krb5_context context,
3208373020dSJacques Vidrine 		      const krb5_config_section *c,
3218373020dSJacques Vidrine 		      const krb5_config_binding **pointer,
322b528cefcSMark Murray 		      int type,
323b528cefcSMark Murray 		      ...)
324b528cefcSMark Murray {
325b528cefcSMark Murray     const char *ret;
326b528cefcSMark Murray     va_list args;
327b528cefcSMark Murray 
328b528cefcSMark Murray     va_start(args, type);
329b528cefcSMark Murray     ret = krb5_config_vget_next (context, c, pointer, type, args);
330b528cefcSMark Murray     va_end(args);
331b528cefcSMark Murray     return ret;
332b528cefcSMark Murray }
333b528cefcSMark Murray 
3348373020dSJacques Vidrine static const void *
3358373020dSJacques Vidrine vget_next(krb5_context context,
3368373020dSJacques Vidrine 	  const krb5_config_binding *b,
3378373020dSJacques Vidrine 	  const krb5_config_binding **pointer,
3388373020dSJacques Vidrine 	  int type,
3398373020dSJacques Vidrine 	  const char *name,
3408373020dSJacques Vidrine 	  va_list args)
3418373020dSJacques Vidrine {
3428373020dSJacques Vidrine     const char *p = va_arg(args, const char *);
3438373020dSJacques Vidrine     while(b != NULL) {
3448373020dSJacques Vidrine 	if(strcmp(b->name, name) == NULL) {
3458373020dSJacques Vidrine 	    if(b->type == type && p == NULL) {
3468373020dSJacques Vidrine 		*pointer = b;
3478373020dSJacques Vidrine 		return b->u.generic;
3488373020dSJacques Vidrine 	    } else if(b->type == krb5_config_list && p != NULL) {
3498373020dSJacques Vidrine 		return vget_next(context, b->u.list, pointer, type, p, args);
3508373020dSJacques Vidrine 	    }
3518373020dSJacques Vidrine 	}
3528373020dSJacques Vidrine 	b = b->next;
3538373020dSJacques Vidrine     }
3548373020dSJacques Vidrine     return NULL;
3558373020dSJacques Vidrine }
3568373020dSJacques Vidrine 
357b528cefcSMark Murray const void *
358b528cefcSMark Murray krb5_config_vget_next (krb5_context context,
3598373020dSJacques Vidrine 		       const krb5_config_section *c,
3608373020dSJacques Vidrine 		       const krb5_config_binding **pointer,
361b528cefcSMark Murray 		       int type,
362b528cefcSMark Murray 		       va_list args)
363b528cefcSMark Murray {
3648373020dSJacques Vidrine     const krb5_config_binding *b;
365b528cefcSMark Murray     const char *p;
366b528cefcSMark Murray 
367b528cefcSMark Murray     if(c == NULL)
368b528cefcSMark Murray 	c = context->cf;
369b528cefcSMark Murray 
370b528cefcSMark Murray     if (c == NULL)
371b528cefcSMark Murray 	return NULL;
372b528cefcSMark Murray 
373b528cefcSMark Murray     if (*pointer == NULL) {
3748373020dSJacques Vidrine 	/* first time here, walk down the tree looking for the right
3758373020dSJacques Vidrine            section */
376b528cefcSMark Murray 	p = va_arg(args, const char *);
377b528cefcSMark Murray 	if (p == NULL)
378b528cefcSMark Murray 	    return NULL;
3798373020dSJacques Vidrine 	return vget_next(context, c, pointer, type, p, args);
380b528cefcSMark Murray     }
381b528cefcSMark Murray 
3828373020dSJacques Vidrine     /* we were called again, so just look for more entries with the
3838373020dSJacques Vidrine        same name and type */
3848373020dSJacques Vidrine     for (b = (*pointer)->next; b != NULL; b = b->next) {
3858373020dSJacques Vidrine 	if(strcmp(b->name, (*pointer)->name) == 0 && b->type == type) {
386b528cefcSMark Murray 	    *pointer = b;
387b528cefcSMark Murray 	    return b->u.generic;
388b528cefcSMark Murray 	}
389b528cefcSMark Murray     }
390b528cefcSMark Murray     return NULL;
391b528cefcSMark Murray }
392b528cefcSMark Murray 
393b528cefcSMark Murray const void *
394b528cefcSMark Murray krb5_config_get (krb5_context context,
3958373020dSJacques Vidrine 		 const krb5_config_section *c,
396b528cefcSMark Murray 		 int type,
397b528cefcSMark Murray 		 ...)
398b528cefcSMark Murray {
399b528cefcSMark Murray     const void *ret;
400b528cefcSMark Murray     va_list args;
401b528cefcSMark Murray 
402b528cefcSMark Murray     va_start(args, type);
403b528cefcSMark Murray     ret = krb5_config_vget (context, c, type, args);
404b528cefcSMark Murray     va_end(args);
405b528cefcSMark Murray     return ret;
406b528cefcSMark Murray }
407b528cefcSMark Murray 
408b528cefcSMark Murray const void *
409b528cefcSMark Murray krb5_config_vget (krb5_context context,
4108373020dSJacques Vidrine 		  const krb5_config_section *c,
411b528cefcSMark Murray 		  int type,
412b528cefcSMark Murray 		  va_list args)
413b528cefcSMark Murray {
4148373020dSJacques Vidrine     const krb5_config_binding *foo = NULL;
415b528cefcSMark Murray 
416b528cefcSMark Murray     return krb5_config_vget_next (context, c, &foo, type, args);
417b528cefcSMark Murray }
418b528cefcSMark Murray 
419b528cefcSMark Murray const krb5_config_binding *
420b528cefcSMark Murray krb5_config_get_list (krb5_context context,
4218373020dSJacques Vidrine 		      const krb5_config_section *c,
422b528cefcSMark Murray 		      ...)
423b528cefcSMark Murray {
424b528cefcSMark Murray     const krb5_config_binding *ret;
425b528cefcSMark Murray     va_list args;
426b528cefcSMark Murray 
427b528cefcSMark Murray     va_start(args, c);
428b528cefcSMark Murray     ret = krb5_config_vget_list (context, c, args);
429b528cefcSMark Murray     va_end(args);
430b528cefcSMark Murray     return ret;
431b528cefcSMark Murray }
432b528cefcSMark Murray 
433b528cefcSMark Murray const krb5_config_binding *
434b528cefcSMark Murray krb5_config_vget_list (krb5_context context,
4358373020dSJacques Vidrine 		       const krb5_config_section *c,
436b528cefcSMark Murray 		       va_list args)
437b528cefcSMark Murray {
438b528cefcSMark Murray     return krb5_config_vget (context, c, krb5_config_list, args);
439b528cefcSMark Murray }
440b528cefcSMark Murray 
441b528cefcSMark Murray const char *
442b528cefcSMark Murray krb5_config_get_string (krb5_context context,
4438373020dSJacques Vidrine 			const krb5_config_section *c,
444b528cefcSMark Murray 			...)
445b528cefcSMark Murray {
446b528cefcSMark Murray     const char *ret;
447b528cefcSMark Murray     va_list args;
448b528cefcSMark Murray 
449b528cefcSMark Murray     va_start(args, c);
450b528cefcSMark Murray     ret = krb5_config_vget_string (context, c, args);
451b528cefcSMark Murray     va_end(args);
452b528cefcSMark Murray     return ret;
453b528cefcSMark Murray }
454b528cefcSMark Murray 
455b528cefcSMark Murray const char *
456b528cefcSMark Murray krb5_config_vget_string (krb5_context context,
4578373020dSJacques Vidrine 			 const krb5_config_section *c,
458b528cefcSMark Murray 			 va_list args)
459b528cefcSMark Murray {
460b528cefcSMark Murray     return krb5_config_vget (context, c, krb5_config_string, args);
461b528cefcSMark Murray }
462b528cefcSMark Murray 
4635e9cd1aeSAssar Westerlund const char *
4645e9cd1aeSAssar Westerlund krb5_config_vget_string_default (krb5_context context,
4658373020dSJacques Vidrine 				 const krb5_config_section *c,
4665e9cd1aeSAssar Westerlund 				 const char *def_value,
4675e9cd1aeSAssar Westerlund 				 va_list args)
4685e9cd1aeSAssar Westerlund {
4695e9cd1aeSAssar Westerlund     const char *ret;
4705e9cd1aeSAssar Westerlund 
4715e9cd1aeSAssar Westerlund     ret = krb5_config_vget_string (context, c, args);
4725e9cd1aeSAssar Westerlund     if (ret == NULL)
4735e9cd1aeSAssar Westerlund 	ret = def_value;
4745e9cd1aeSAssar Westerlund     return ret;
4755e9cd1aeSAssar Westerlund }
4765e9cd1aeSAssar Westerlund 
4775e9cd1aeSAssar Westerlund const char *
4785e9cd1aeSAssar Westerlund krb5_config_get_string_default (krb5_context context,
4798373020dSJacques Vidrine 				const krb5_config_section *c,
4805e9cd1aeSAssar Westerlund 				const char *def_value,
4815e9cd1aeSAssar Westerlund 				...)
4825e9cd1aeSAssar Westerlund {
4835e9cd1aeSAssar Westerlund     const char *ret;
4845e9cd1aeSAssar Westerlund     va_list args;
4855e9cd1aeSAssar Westerlund 
4865e9cd1aeSAssar Westerlund     va_start(args, def_value);
4875e9cd1aeSAssar Westerlund     ret = krb5_config_vget_string_default (context, c, def_value, args);
4885e9cd1aeSAssar Westerlund     va_end(args);
4895e9cd1aeSAssar Westerlund     return ret;
4905e9cd1aeSAssar Westerlund }
4915e9cd1aeSAssar Westerlund 
492b528cefcSMark Murray char **
493b528cefcSMark Murray krb5_config_vget_strings(krb5_context context,
4948373020dSJacques Vidrine 			 const krb5_config_section *c,
495b528cefcSMark Murray 			 va_list args)
496b528cefcSMark Murray {
497b528cefcSMark Murray     char **strings = NULL;
498b528cefcSMark Murray     int nstr = 0;
4998373020dSJacques Vidrine     const krb5_config_binding *b = NULL;
500b528cefcSMark Murray     const char *p;
501b528cefcSMark Murray 
502b528cefcSMark Murray     while((p = krb5_config_vget_next(context, c, &b,
503b528cefcSMark Murray 				     krb5_config_string, args))) {
504b528cefcSMark Murray 	char *tmp = strdup(p);
505b528cefcSMark Murray 	char *pos = NULL;
506b528cefcSMark Murray 	char *s;
507b528cefcSMark Murray 	if(tmp == NULL)
508b528cefcSMark Murray 	    goto cleanup;
509b528cefcSMark Murray 	s = strtok_r(tmp, " \t", &pos);
510b528cefcSMark Murray 	while(s){
511b528cefcSMark Murray 	    char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
512b528cefcSMark Murray 	    if(tmp == NULL)
513b528cefcSMark Murray 		goto cleanup;
514b528cefcSMark Murray 	    strings = tmp;
515b528cefcSMark Murray 	    strings[nstr] = strdup(s);
516b528cefcSMark Murray 	    nstr++;
517b528cefcSMark Murray 	    if(strings[nstr-1] == NULL)
518b528cefcSMark Murray 		goto cleanup;
519b528cefcSMark Murray 	    s = strtok_r(NULL, " \t", &pos);
520b528cefcSMark Murray 	}
521b528cefcSMark Murray 	free(tmp);
522b528cefcSMark Murray     }
523b528cefcSMark Murray     if(nstr){
524b528cefcSMark Murray 	char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
525b528cefcSMark Murray 	if(strings == NULL)
526b528cefcSMark Murray 	    goto cleanup;
527b528cefcSMark Murray 	strings = tmp;
528b528cefcSMark Murray 	strings[nstr] = NULL;
529b528cefcSMark Murray     }
530b528cefcSMark Murray     return strings;
531b528cefcSMark Murray cleanup:
532b528cefcSMark Murray     while(nstr--)
533b528cefcSMark Murray 	free(strings[nstr]);
534b528cefcSMark Murray     free(strings);
535b528cefcSMark Murray     return NULL;
536b528cefcSMark Murray 
537b528cefcSMark Murray }
538b528cefcSMark Murray 
539b528cefcSMark Murray char**
540b528cefcSMark Murray krb5_config_get_strings(krb5_context context,
5418373020dSJacques Vidrine 			const krb5_config_section *c,
542b528cefcSMark Murray 			...)
543b528cefcSMark Murray {
544b528cefcSMark Murray     va_list ap;
545b528cefcSMark Murray     char **ret;
546b528cefcSMark Murray     va_start(ap, c);
547b528cefcSMark Murray     ret = krb5_config_vget_strings(context, c, ap);
548b528cefcSMark Murray     va_end(ap);
549b528cefcSMark Murray     return ret;
550b528cefcSMark Murray }
551b528cefcSMark Murray 
552b528cefcSMark Murray void
553b528cefcSMark Murray krb5_config_free_strings(char **strings)
554b528cefcSMark Murray {
555b528cefcSMark Murray     char **s = strings;
556b528cefcSMark Murray     while(s && *s){
557b528cefcSMark Murray 	free(*s);
558b528cefcSMark Murray 	s++;
559b528cefcSMark Murray     }
560b528cefcSMark Murray     free(strings);
561b528cefcSMark Murray }
562b528cefcSMark Murray 
563b528cefcSMark Murray krb5_boolean
564b528cefcSMark Murray krb5_config_vget_bool_default (krb5_context context,
5658373020dSJacques Vidrine 			       const krb5_config_section *c,
566b528cefcSMark Murray 			       krb5_boolean def_value,
567b528cefcSMark Murray 			       va_list args)
568b528cefcSMark Murray {
569b528cefcSMark Murray     const char *str;
570b528cefcSMark Murray     str = krb5_config_vget_string (context, c, args);
571b528cefcSMark Murray     if(str == NULL)
572b528cefcSMark Murray 	return def_value;
573b528cefcSMark Murray     if(strcasecmp(str, "yes") == 0 ||
574b528cefcSMark Murray        strcasecmp(str, "true") == 0 ||
575b528cefcSMark Murray        atoi(str)) return TRUE;
576b528cefcSMark Murray     return FALSE;
577b528cefcSMark Murray }
578b528cefcSMark Murray 
579b528cefcSMark Murray krb5_boolean
580b528cefcSMark Murray krb5_config_vget_bool  (krb5_context context,
5818373020dSJacques Vidrine 			const krb5_config_section *c,
582b528cefcSMark Murray 			va_list args)
583b528cefcSMark Murray {
584b528cefcSMark Murray     return krb5_config_vget_bool_default (context, c, FALSE, args);
585b528cefcSMark Murray }
586b528cefcSMark Murray 
587b528cefcSMark Murray krb5_boolean
588b528cefcSMark Murray krb5_config_get_bool_default (krb5_context context,
5898373020dSJacques Vidrine 			      const krb5_config_section *c,
590b528cefcSMark Murray 			      krb5_boolean def_value,
591b528cefcSMark Murray 			      ...)
592b528cefcSMark Murray {
593b528cefcSMark Murray     va_list ap;
594b528cefcSMark Murray     krb5_boolean ret;
595b528cefcSMark Murray     va_start(ap, def_value);
596b528cefcSMark Murray     ret = krb5_config_vget_bool_default(context, c, def_value, ap);
597b528cefcSMark Murray     va_end(ap);
598b528cefcSMark Murray     return ret;
599b528cefcSMark Murray }
600b528cefcSMark Murray 
601b528cefcSMark Murray krb5_boolean
602b528cefcSMark Murray krb5_config_get_bool (krb5_context context,
6038373020dSJacques Vidrine 		      const krb5_config_section *c,
604b528cefcSMark Murray 		      ...)
605b528cefcSMark Murray {
606b528cefcSMark Murray     va_list ap;
607b528cefcSMark Murray     krb5_boolean ret;
608b528cefcSMark Murray     va_start(ap, c);
609b528cefcSMark Murray     ret = krb5_config_vget_bool (context, c, ap);
610b528cefcSMark Murray     va_end(ap);
611b528cefcSMark Murray     return ret;
612b528cefcSMark Murray }
613b528cefcSMark Murray 
614b528cefcSMark Murray int
615b528cefcSMark Murray krb5_config_vget_time_default (krb5_context context,
6168373020dSJacques Vidrine 			       const krb5_config_section *c,
617b528cefcSMark Murray 			       int def_value,
618b528cefcSMark Murray 			       va_list args)
619b528cefcSMark Murray {
620b528cefcSMark Murray     const char *str;
621b528cefcSMark Murray     str = krb5_config_vget_string (context, c, args);
622b528cefcSMark Murray     if(str == NULL)
623b528cefcSMark Murray 	return def_value;
624b528cefcSMark Murray     return parse_time (str, NULL);
625b528cefcSMark Murray }
626b528cefcSMark Murray 
627b528cefcSMark Murray int
628b528cefcSMark Murray krb5_config_vget_time  (krb5_context context,
6298373020dSJacques Vidrine 			const krb5_config_section *c,
630b528cefcSMark Murray 			va_list args)
631b528cefcSMark Murray {
632b528cefcSMark Murray     return krb5_config_vget_time_default (context, c, -1, args);
633b528cefcSMark Murray }
634b528cefcSMark Murray 
635b528cefcSMark Murray int
636b528cefcSMark Murray krb5_config_get_time_default (krb5_context context,
6378373020dSJacques Vidrine 			      const krb5_config_section *c,
638b528cefcSMark Murray 			      int def_value,
639b528cefcSMark Murray 			      ...)
640b528cefcSMark Murray {
641b528cefcSMark Murray     va_list ap;
642b528cefcSMark Murray     int ret;
643b528cefcSMark Murray     va_start(ap, def_value);
644b528cefcSMark Murray     ret = krb5_config_vget_time_default(context, c, def_value, ap);
645b528cefcSMark Murray     va_end(ap);
646b528cefcSMark Murray     return ret;
647b528cefcSMark Murray }
648b528cefcSMark Murray 
649b528cefcSMark Murray int
650b528cefcSMark Murray krb5_config_get_time (krb5_context context,
6518373020dSJacques Vidrine 		      const krb5_config_section *c,
652b528cefcSMark Murray 		      ...)
653b528cefcSMark Murray {
654b528cefcSMark Murray     va_list ap;
655b528cefcSMark Murray     int ret;
656b528cefcSMark Murray     va_start(ap, c);
657b528cefcSMark Murray     ret = krb5_config_vget_time (context, c, ap);
658b528cefcSMark Murray     va_end(ap);
659b528cefcSMark Murray     return ret;
660b528cefcSMark Murray }
661b528cefcSMark Murray 
662b528cefcSMark Murray 
663b528cefcSMark Murray int
664b528cefcSMark Murray krb5_config_vget_int_default (krb5_context context,
6658373020dSJacques Vidrine 			      const krb5_config_section *c,
666b528cefcSMark Murray 			      int def_value,
667b528cefcSMark Murray 			      va_list args)
668b528cefcSMark Murray {
669b528cefcSMark Murray     const char *str;
670b528cefcSMark Murray     str = krb5_config_vget_string (context, c, args);
671b528cefcSMark Murray     if(str == NULL)
672b528cefcSMark Murray 	return def_value;
673b528cefcSMark Murray     else {
674b528cefcSMark Murray 	char *endptr;
675b528cefcSMark Murray 	long l;
676b528cefcSMark Murray 	l = strtol(str, &endptr, 0);
677b528cefcSMark Murray 	if (endptr == str)
678b528cefcSMark Murray 	    return def_value;
679b528cefcSMark Murray 	else
680b528cefcSMark Murray 	    return l;
681b528cefcSMark Murray     }
682b528cefcSMark Murray }
683b528cefcSMark Murray 
684b528cefcSMark Murray int
685b528cefcSMark Murray krb5_config_vget_int  (krb5_context context,
6868373020dSJacques Vidrine 		       const krb5_config_section *c,
687b528cefcSMark Murray 		       va_list args)
688b528cefcSMark Murray {
689b528cefcSMark Murray     return krb5_config_vget_int_default (context, c, -1, args);
690b528cefcSMark Murray }
691b528cefcSMark Murray 
692b528cefcSMark Murray int
693b528cefcSMark Murray krb5_config_get_int_default (krb5_context context,
6948373020dSJacques Vidrine 			     const krb5_config_section *c,
695b528cefcSMark Murray 			     int def_value,
696b528cefcSMark Murray 			     ...)
697b528cefcSMark Murray {
698b528cefcSMark Murray     va_list ap;
699b528cefcSMark Murray     int ret;
700b528cefcSMark Murray     va_start(ap, def_value);
701b528cefcSMark Murray     ret = krb5_config_vget_int_default(context, c, def_value, ap);
702b528cefcSMark Murray     va_end(ap);
703b528cefcSMark Murray     return ret;
704b528cefcSMark Murray }
705b528cefcSMark Murray 
706b528cefcSMark Murray int
707b528cefcSMark Murray krb5_config_get_int (krb5_context context,
7088373020dSJacques Vidrine 		     const krb5_config_section *c,
709b528cefcSMark Murray 		     ...)
710b528cefcSMark Murray {
711b528cefcSMark Murray     va_list ap;
712b528cefcSMark Murray     int ret;
713b528cefcSMark Murray     va_start(ap, c);
714b528cefcSMark Murray     ret = krb5_config_vget_int (context, c, ap);
715b528cefcSMark Murray     va_end(ap);
716b528cefcSMark Murray     return ret;
717b528cefcSMark Murray }
718