xref: /minix3/crypto/external/bsd/heimdal/dist/lib/krb5/config_file.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: config_file.c,v 1.1.1.2 2014/04/24 12:45:49 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9ebfedea0SLionel Sambuc  *
10ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
12ebfedea0SLionel Sambuc  * are met:
13ebfedea0SLionel Sambuc  *
14ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
15ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
16ebfedea0SLionel Sambuc  *
17ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
18ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
19ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
20ebfedea0SLionel Sambuc  *
21ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
22ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
23ebfedea0SLionel Sambuc  *    without specific prior written permission.
24ebfedea0SLionel Sambuc  *
25ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35ebfedea0SLionel Sambuc  * SUCH DAMAGE.
36ebfedea0SLionel Sambuc  */
37ebfedea0SLionel Sambuc 
38ebfedea0SLionel Sambuc #include "krb5_locl.h"
39ebfedea0SLionel Sambuc 
40ebfedea0SLionel Sambuc #ifdef __APPLE__
41ebfedea0SLionel Sambuc #include <CoreFoundation/CoreFoundation.h>
42ebfedea0SLionel Sambuc #endif
43ebfedea0SLionel Sambuc 
44ebfedea0SLionel Sambuc /* Gaah! I want a portable funopen */
45ebfedea0SLionel Sambuc struct fileptr {
46ebfedea0SLionel Sambuc     const char *s;
47ebfedea0SLionel Sambuc     FILE *f;
48ebfedea0SLionel Sambuc };
49ebfedea0SLionel Sambuc 
50ebfedea0SLionel Sambuc static char *
config_fgets(char * str,size_t len,struct fileptr * ptr)51ebfedea0SLionel Sambuc config_fgets(char *str, size_t len, struct fileptr *ptr)
52ebfedea0SLionel Sambuc {
53ebfedea0SLionel Sambuc     /* XXX this is not correct, in that they don't do the same if the
54ebfedea0SLionel Sambuc        line is longer than len */
55ebfedea0SLionel Sambuc     if(ptr->f != NULL)
56ebfedea0SLionel Sambuc 	return fgets(str, len, ptr->f);
57ebfedea0SLionel Sambuc     else {
58ebfedea0SLionel Sambuc 	/* this is almost strsep_copy */
59ebfedea0SLionel Sambuc 	const char *p;
60ebfedea0SLionel Sambuc 	ssize_t l;
61ebfedea0SLionel Sambuc 	if(*ptr->s == '\0')
62ebfedea0SLionel Sambuc 	    return NULL;
63ebfedea0SLionel Sambuc 	p = ptr->s + strcspn(ptr->s, "\n");
64ebfedea0SLionel Sambuc 	if(*p == '\n')
65ebfedea0SLionel Sambuc 	    p++;
66*0a6a1f1dSLionel Sambuc 	l = min(len, (size_t)(p - ptr->s));
67ebfedea0SLionel Sambuc 	if(len > 0) {
68ebfedea0SLionel Sambuc 	    memcpy(str, ptr->s, l);
69ebfedea0SLionel Sambuc 	    str[l] = '\0';
70ebfedea0SLionel Sambuc 	}
71ebfedea0SLionel Sambuc 	ptr->s = p;
72ebfedea0SLionel Sambuc 	return str;
73ebfedea0SLionel Sambuc     }
74ebfedea0SLionel Sambuc }
75ebfedea0SLionel Sambuc 
76ebfedea0SLionel Sambuc static krb5_error_code parse_section(char *p, krb5_config_section **s,
77ebfedea0SLionel Sambuc 				     krb5_config_section **res,
78ebfedea0SLionel Sambuc 				     const char **err_message);
79ebfedea0SLionel Sambuc static krb5_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p,
80ebfedea0SLionel Sambuc 				     krb5_config_binding **b,
81ebfedea0SLionel Sambuc 				     krb5_config_binding **parent,
82ebfedea0SLionel Sambuc 				     const char **err_message);
83ebfedea0SLionel Sambuc static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno,
84ebfedea0SLionel Sambuc 				  krb5_config_binding **parent,
85ebfedea0SLionel Sambuc 				  const char **err_message);
86ebfedea0SLionel Sambuc 
87ebfedea0SLionel Sambuc krb5_config_section *
_krb5_config_get_entry(krb5_config_section ** parent,const char * name,int type)88ebfedea0SLionel Sambuc _krb5_config_get_entry(krb5_config_section **parent, const char *name, int type)
89ebfedea0SLionel Sambuc {
90ebfedea0SLionel Sambuc     krb5_config_section **q;
91ebfedea0SLionel Sambuc 
92ebfedea0SLionel Sambuc     for(q = parent; *q != NULL; q = &(*q)->next)
93ebfedea0SLionel Sambuc 	if(type == krb5_config_list &&
94*0a6a1f1dSLionel Sambuc 	   (unsigned)type == (*q)->type &&
95ebfedea0SLionel Sambuc 	   strcmp(name, (*q)->name) == 0)
96ebfedea0SLionel Sambuc 	    return *q;
97ebfedea0SLionel Sambuc     *q = calloc(1, sizeof(**q));
98ebfedea0SLionel Sambuc     if(*q == NULL)
99ebfedea0SLionel Sambuc 	return NULL;
100ebfedea0SLionel Sambuc     (*q)->name = strdup(name);
101ebfedea0SLionel Sambuc     (*q)->type = type;
102ebfedea0SLionel Sambuc     if((*q)->name == NULL) {
103ebfedea0SLionel Sambuc 	free(*q);
104ebfedea0SLionel Sambuc 	*q = NULL;
105ebfedea0SLionel Sambuc 	return NULL;
106ebfedea0SLionel Sambuc     }
107ebfedea0SLionel Sambuc     return *q;
108ebfedea0SLionel Sambuc }
109ebfedea0SLionel Sambuc 
110ebfedea0SLionel Sambuc /*
111ebfedea0SLionel Sambuc  * Parse a section:
112ebfedea0SLionel Sambuc  *
113ebfedea0SLionel Sambuc  * [section]
114ebfedea0SLionel Sambuc  *	foo = bar
115ebfedea0SLionel Sambuc  *	b = {
116ebfedea0SLionel Sambuc  *		a
117ebfedea0SLionel Sambuc  *	    }
118ebfedea0SLionel Sambuc  * ...
119ebfedea0SLionel Sambuc  *
120ebfedea0SLionel Sambuc  * starting at the line in `p', storing the resulting structure in
121ebfedea0SLionel Sambuc  * `s' and hooking it into `parent'.
122ebfedea0SLionel Sambuc  * Store the error message in `err_message'.
123ebfedea0SLionel Sambuc  */
124ebfedea0SLionel Sambuc 
125ebfedea0SLionel Sambuc static krb5_error_code
parse_section(char * p,krb5_config_section ** s,krb5_config_section ** parent,const char ** err_message)126ebfedea0SLionel Sambuc parse_section(char *p, krb5_config_section **s, krb5_config_section **parent,
127ebfedea0SLionel Sambuc 	      const char **err_message)
128ebfedea0SLionel Sambuc {
129ebfedea0SLionel Sambuc     char *p1;
130ebfedea0SLionel Sambuc     krb5_config_section *tmp;
131ebfedea0SLionel Sambuc 
132ebfedea0SLionel Sambuc     p1 = strchr (p + 1, ']');
133ebfedea0SLionel Sambuc     if (p1 == NULL) {
134ebfedea0SLionel Sambuc 	*err_message = "missing ]";
135ebfedea0SLionel Sambuc 	return KRB5_CONFIG_BADFORMAT;
136ebfedea0SLionel Sambuc     }
137ebfedea0SLionel Sambuc     *p1 = '\0';
138ebfedea0SLionel Sambuc     tmp = _krb5_config_get_entry(parent, p + 1, krb5_config_list);
139ebfedea0SLionel Sambuc     if(tmp == NULL) {
140ebfedea0SLionel Sambuc 	*err_message = "out of memory";
141ebfedea0SLionel Sambuc 	return KRB5_CONFIG_BADFORMAT;
142ebfedea0SLionel Sambuc     }
143ebfedea0SLionel Sambuc     *s = tmp;
144ebfedea0SLionel Sambuc     return 0;
145ebfedea0SLionel Sambuc }
146ebfedea0SLionel Sambuc 
147ebfedea0SLionel Sambuc /*
148ebfedea0SLionel Sambuc  * Parse a brace-enclosed list from `f', hooking in the structure at
149ebfedea0SLionel Sambuc  * `parent'.
150ebfedea0SLionel Sambuc  * Store the error message in `err_message'.
151ebfedea0SLionel Sambuc  */
152ebfedea0SLionel Sambuc 
153ebfedea0SLionel Sambuc static krb5_error_code
parse_list(struct fileptr * f,unsigned * lineno,krb5_config_binding ** parent,const char ** err_message)154ebfedea0SLionel Sambuc parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent,
155ebfedea0SLionel Sambuc 	   const char **err_message)
156ebfedea0SLionel Sambuc {
157ebfedea0SLionel Sambuc     char buf[KRB5_BUFSIZ];
158ebfedea0SLionel Sambuc     krb5_error_code ret;
159ebfedea0SLionel Sambuc     krb5_config_binding *b = NULL;
160ebfedea0SLionel Sambuc     unsigned beg_lineno = *lineno;
161ebfedea0SLionel Sambuc 
162ebfedea0SLionel Sambuc     while(config_fgets(buf, sizeof(buf), f) != NULL) {
163ebfedea0SLionel Sambuc 	char *p;
164ebfedea0SLionel Sambuc 
165ebfedea0SLionel Sambuc 	++*lineno;
166ebfedea0SLionel Sambuc 	buf[strcspn(buf, "\r\n")] = '\0';
167ebfedea0SLionel Sambuc 	p = buf;
168ebfedea0SLionel Sambuc 	while(isspace((unsigned char)*p))
169ebfedea0SLionel Sambuc 	    ++p;
170ebfedea0SLionel Sambuc 	if (*p == '#' || *p == ';' || *p == '\0')
171ebfedea0SLionel Sambuc 	    continue;
172ebfedea0SLionel Sambuc 	while(isspace((unsigned char)*p))
173ebfedea0SLionel Sambuc 	    ++p;
174ebfedea0SLionel Sambuc 	if (*p == '}')
175ebfedea0SLionel Sambuc 	    return 0;
176ebfedea0SLionel Sambuc 	if (*p == '\0')
177ebfedea0SLionel Sambuc 	    continue;
178ebfedea0SLionel Sambuc 	ret = parse_binding (f, lineno, p, &b, parent, err_message);
179ebfedea0SLionel Sambuc 	if (ret)
180ebfedea0SLionel Sambuc 	    return ret;
181ebfedea0SLionel Sambuc     }
182ebfedea0SLionel Sambuc     *lineno = beg_lineno;
183ebfedea0SLionel Sambuc     *err_message = "unclosed {";
184ebfedea0SLionel Sambuc     return KRB5_CONFIG_BADFORMAT;
185ebfedea0SLionel Sambuc }
186ebfedea0SLionel Sambuc 
187ebfedea0SLionel Sambuc /*
188ebfedea0SLionel Sambuc  *
189ebfedea0SLionel Sambuc  */
190ebfedea0SLionel Sambuc 
191ebfedea0SLionel Sambuc static krb5_error_code
parse_binding(struct fileptr * f,unsigned * lineno,char * p,krb5_config_binding ** b,krb5_config_binding ** parent,const char ** err_message)192ebfedea0SLionel Sambuc parse_binding(struct fileptr *f, unsigned *lineno, char *p,
193ebfedea0SLionel Sambuc 	      krb5_config_binding **b, krb5_config_binding **parent,
194ebfedea0SLionel Sambuc 	      const char **err_message)
195ebfedea0SLionel Sambuc {
196ebfedea0SLionel Sambuc     krb5_config_binding *tmp;
197ebfedea0SLionel Sambuc     char *p1, *p2;
198ebfedea0SLionel Sambuc     krb5_error_code ret = 0;
199ebfedea0SLionel Sambuc 
200ebfedea0SLionel Sambuc     p1 = p;
201ebfedea0SLionel Sambuc     while (*p && *p != '=' && !isspace((unsigned char)*p))
202ebfedea0SLionel Sambuc 	++p;
203ebfedea0SLionel Sambuc     if (*p == '\0') {
204ebfedea0SLionel Sambuc 	*err_message = "missing =";
205ebfedea0SLionel Sambuc 	return KRB5_CONFIG_BADFORMAT;
206ebfedea0SLionel Sambuc     }
207ebfedea0SLionel Sambuc     p2 = p;
208ebfedea0SLionel Sambuc     while (isspace((unsigned char)*p))
209ebfedea0SLionel Sambuc 	++p;
210ebfedea0SLionel Sambuc     if (*p != '=') {
211ebfedea0SLionel Sambuc 	*err_message = "missing =";
212ebfedea0SLionel Sambuc 	return KRB5_CONFIG_BADFORMAT;
213ebfedea0SLionel Sambuc     }
214ebfedea0SLionel Sambuc     ++p;
215ebfedea0SLionel Sambuc     while(isspace((unsigned char)*p))
216ebfedea0SLionel Sambuc 	++p;
217ebfedea0SLionel Sambuc     *p2 = '\0';
218ebfedea0SLionel Sambuc     if (*p == '{') {
219ebfedea0SLionel Sambuc 	tmp = _krb5_config_get_entry(parent, p1, krb5_config_list);
220ebfedea0SLionel Sambuc 	if (tmp == NULL) {
221ebfedea0SLionel Sambuc 	    *err_message = "out of memory";
222ebfedea0SLionel Sambuc 	    return KRB5_CONFIG_BADFORMAT;
223ebfedea0SLionel Sambuc 	}
224ebfedea0SLionel Sambuc 	ret = parse_list (f, lineno, &tmp->u.list, err_message);
225ebfedea0SLionel Sambuc     } else {
226ebfedea0SLionel Sambuc 	tmp = _krb5_config_get_entry(parent, p1, krb5_config_string);
227ebfedea0SLionel Sambuc 	if (tmp == NULL) {
228ebfedea0SLionel Sambuc 	    *err_message = "out of memory";
229ebfedea0SLionel Sambuc 	    return KRB5_CONFIG_BADFORMAT;
230ebfedea0SLionel Sambuc 	}
231ebfedea0SLionel Sambuc 	p1 = p;
232ebfedea0SLionel Sambuc 	p = p1 + strlen(p1);
233ebfedea0SLionel Sambuc 	while(p > p1 && isspace((unsigned char)*(p-1)))
234ebfedea0SLionel Sambuc 	    --p;
235ebfedea0SLionel Sambuc 	*p = '\0';
236ebfedea0SLionel Sambuc 	tmp->u.string = strdup(p1);
237ebfedea0SLionel Sambuc     }
238ebfedea0SLionel Sambuc     *b = tmp;
239ebfedea0SLionel Sambuc     return ret;
240ebfedea0SLionel Sambuc }
241ebfedea0SLionel Sambuc 
242ebfedea0SLionel Sambuc #if defined(__APPLE__)
243ebfedea0SLionel Sambuc 
244ebfedea0SLionel Sambuc #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
245ebfedea0SLionel Sambuc #define HAVE_CFPROPERTYLISTCREATEWITHSTREAM 1
246ebfedea0SLionel Sambuc #endif
247ebfedea0SLionel Sambuc 
248ebfedea0SLionel Sambuc static char *
cfstring2cstring(CFStringRef string)249ebfedea0SLionel Sambuc cfstring2cstring(CFStringRef string)
250ebfedea0SLionel Sambuc {
251ebfedea0SLionel Sambuc     CFIndex len;
252ebfedea0SLionel Sambuc     char *str;
253ebfedea0SLionel Sambuc 
254ebfedea0SLionel Sambuc     str = (char *) CFStringGetCStringPtr(string, kCFStringEncodingUTF8);
255ebfedea0SLionel Sambuc     if (str)
256ebfedea0SLionel Sambuc 	return strdup(str);
257ebfedea0SLionel Sambuc 
258ebfedea0SLionel Sambuc     len = CFStringGetLength(string);
259ebfedea0SLionel Sambuc     len = 1 + CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8);
260ebfedea0SLionel Sambuc     str = malloc(len);
261ebfedea0SLionel Sambuc     if (str == NULL)
262ebfedea0SLionel Sambuc 	return NULL;
263ebfedea0SLionel Sambuc 
264ebfedea0SLionel Sambuc     if (!CFStringGetCString (string, str, len, kCFStringEncodingUTF8)) {
265ebfedea0SLionel Sambuc 	free (str);
266ebfedea0SLionel Sambuc 	return NULL;
267ebfedea0SLionel Sambuc     }
268ebfedea0SLionel Sambuc     return str;
269ebfedea0SLionel Sambuc }
270ebfedea0SLionel Sambuc 
271ebfedea0SLionel Sambuc static void
convert_content(const void * key,const void * value,void * context)272ebfedea0SLionel Sambuc convert_content(const void *key, const void *value, void *context)
273ebfedea0SLionel Sambuc {
274ebfedea0SLionel Sambuc     krb5_config_section *tmp, **parent = context;
275ebfedea0SLionel Sambuc     char *k;
276ebfedea0SLionel Sambuc 
277ebfedea0SLionel Sambuc     if (CFGetTypeID(key) != CFStringGetTypeID())
278ebfedea0SLionel Sambuc 	return;
279ebfedea0SLionel Sambuc 
280ebfedea0SLionel Sambuc     k = cfstring2cstring(key);
281ebfedea0SLionel Sambuc     if (k == NULL)
282ebfedea0SLionel Sambuc 	return;
283ebfedea0SLionel Sambuc 
284ebfedea0SLionel Sambuc     if (CFGetTypeID(value) == CFStringGetTypeID()) {
285ebfedea0SLionel Sambuc 	tmp = _krb5_config_get_entry(parent, k, krb5_config_string);
286ebfedea0SLionel Sambuc 	tmp->u.string = cfstring2cstring(value);
287ebfedea0SLionel Sambuc     } else if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
288ebfedea0SLionel Sambuc 	tmp = _krb5_config_get_entry(parent, k, krb5_config_list);
289ebfedea0SLionel Sambuc 	CFDictionaryApplyFunction(value, convert_content, &tmp->u.list);
290ebfedea0SLionel Sambuc     } else {
291ebfedea0SLionel Sambuc 	/* log */
292ebfedea0SLionel Sambuc     }
293ebfedea0SLionel Sambuc     free(k);
294ebfedea0SLionel Sambuc }
295ebfedea0SLionel Sambuc 
296ebfedea0SLionel Sambuc static krb5_error_code
parse_plist_config(krb5_context context,const char * path,krb5_config_section ** parent)297ebfedea0SLionel Sambuc parse_plist_config(krb5_context context, const char *path, krb5_config_section **parent)
298ebfedea0SLionel Sambuc {
299ebfedea0SLionel Sambuc     CFReadStreamRef s;
300ebfedea0SLionel Sambuc     CFDictionaryRef d;
301ebfedea0SLionel Sambuc     CFURLRef url;
302ebfedea0SLionel Sambuc 
303ebfedea0SLionel Sambuc     url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE);
304ebfedea0SLionel Sambuc     if (url == NULL) {
305ebfedea0SLionel Sambuc 	krb5_clear_error_message(context);
306ebfedea0SLionel Sambuc 	return ENOMEM;
307ebfedea0SLionel Sambuc     }
308ebfedea0SLionel Sambuc 
309ebfedea0SLionel Sambuc     s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
310ebfedea0SLionel Sambuc     CFRelease(url);
311ebfedea0SLionel Sambuc     if (s == NULL) {
312ebfedea0SLionel Sambuc 	krb5_clear_error_message(context);
313ebfedea0SLionel Sambuc 	return ENOMEM;
314ebfedea0SLionel Sambuc     }
315ebfedea0SLionel Sambuc 
316ebfedea0SLionel Sambuc     if (!CFReadStreamOpen(s)) {
317ebfedea0SLionel Sambuc 	CFRelease(s);
318ebfedea0SLionel Sambuc 	krb5_clear_error_message(context);
319ebfedea0SLionel Sambuc 	return ENOENT;
320ebfedea0SLionel Sambuc     }
321ebfedea0SLionel Sambuc 
322ebfedea0SLionel Sambuc #ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM
323ebfedea0SLionel Sambuc     d = (CFDictionaryRef)CFPropertyListCreateWithStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
324ebfedea0SLionel Sambuc #else
325ebfedea0SLionel Sambuc     d = (CFDictionaryRef)CFPropertyListCreateFromStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
326ebfedea0SLionel Sambuc #endif
327ebfedea0SLionel Sambuc     CFRelease(s);
328ebfedea0SLionel Sambuc     if (d == NULL) {
329ebfedea0SLionel Sambuc 	krb5_clear_error_message(context);
330ebfedea0SLionel Sambuc 	return ENOENT;
331ebfedea0SLionel Sambuc     }
332ebfedea0SLionel Sambuc 
333ebfedea0SLionel Sambuc     CFDictionaryApplyFunction(d, convert_content, parent);
334ebfedea0SLionel Sambuc     CFRelease(d);
335ebfedea0SLionel Sambuc 
336ebfedea0SLionel Sambuc     return 0;
337ebfedea0SLionel Sambuc }
338ebfedea0SLionel Sambuc 
339ebfedea0SLionel Sambuc #endif
340ebfedea0SLionel Sambuc 
341ebfedea0SLionel Sambuc 
342ebfedea0SLionel Sambuc /*
343ebfedea0SLionel Sambuc  * Parse the config file `fname', generating the structures into `res'
344ebfedea0SLionel Sambuc  * returning error messages in `err_message'
345ebfedea0SLionel Sambuc  */
346ebfedea0SLionel Sambuc 
347ebfedea0SLionel Sambuc static krb5_error_code
krb5_config_parse_debug(struct fileptr * f,krb5_config_section ** res,unsigned * lineno,const char ** err_message)348ebfedea0SLionel Sambuc krb5_config_parse_debug (struct fileptr *f,
349ebfedea0SLionel Sambuc 			 krb5_config_section **res,
350ebfedea0SLionel Sambuc 			 unsigned *lineno,
351ebfedea0SLionel Sambuc 			 const char **err_message)
352ebfedea0SLionel Sambuc {
353ebfedea0SLionel Sambuc     krb5_config_section *s = NULL;
354ebfedea0SLionel Sambuc     krb5_config_binding *b = NULL;
355ebfedea0SLionel Sambuc     char buf[KRB5_BUFSIZ];
356ebfedea0SLionel Sambuc     krb5_error_code ret;
357ebfedea0SLionel Sambuc 
358ebfedea0SLionel Sambuc     while (config_fgets(buf, sizeof(buf), f) != NULL) {
359ebfedea0SLionel Sambuc 	char *p;
360ebfedea0SLionel Sambuc 
361ebfedea0SLionel Sambuc 	++*lineno;
362ebfedea0SLionel Sambuc 	buf[strcspn(buf, "\r\n")] = '\0';
363ebfedea0SLionel Sambuc 	p = buf;
364ebfedea0SLionel Sambuc 	while(isspace((unsigned char)*p))
365ebfedea0SLionel Sambuc 	    ++p;
366ebfedea0SLionel Sambuc 	if (*p == '#' || *p == ';')
367ebfedea0SLionel Sambuc 	    continue;
368ebfedea0SLionel Sambuc 	if (*p == '[') {
369ebfedea0SLionel Sambuc 	    ret = parse_section(p, &s, res, err_message);
370ebfedea0SLionel Sambuc 	    if (ret)
371ebfedea0SLionel Sambuc 		return ret;
372ebfedea0SLionel Sambuc 	    b = NULL;
373ebfedea0SLionel Sambuc 	} else if (*p == '}') {
374ebfedea0SLionel Sambuc 	    *err_message = "unmatched }";
375ebfedea0SLionel Sambuc 	    return EINVAL;	/* XXX */
376ebfedea0SLionel Sambuc 	} else if(*p != '\0') {
377ebfedea0SLionel Sambuc 	    if (s == NULL) {
378ebfedea0SLionel Sambuc 		*err_message = "binding before section";
379ebfedea0SLionel Sambuc 		return EINVAL;
380ebfedea0SLionel Sambuc 	    }
381ebfedea0SLionel Sambuc 	    ret = parse_binding(f, lineno, p, &b, &s->u.list, err_message);
382ebfedea0SLionel Sambuc 	    if (ret)
383ebfedea0SLionel Sambuc 		return ret;
384ebfedea0SLionel Sambuc 	}
385ebfedea0SLionel Sambuc     }
386ebfedea0SLionel Sambuc     return 0;
387ebfedea0SLionel Sambuc }
388ebfedea0SLionel Sambuc 
389ebfedea0SLionel Sambuc static int
is_plist_file(const char * fname)390ebfedea0SLionel Sambuc is_plist_file(const char *fname)
391ebfedea0SLionel Sambuc {
392ebfedea0SLionel Sambuc     size_t len = strlen(fname);
393ebfedea0SLionel Sambuc     char suffix[] = ".plist";
394ebfedea0SLionel Sambuc     if (len < sizeof(suffix))
395ebfedea0SLionel Sambuc 	return 0;
396ebfedea0SLionel Sambuc     if (strcasecmp(&fname[len - (sizeof(suffix) - 1)], suffix) != 0)
397ebfedea0SLionel Sambuc 	return 0;
398ebfedea0SLionel Sambuc     return 1;
399ebfedea0SLionel Sambuc }
400ebfedea0SLionel Sambuc 
401ebfedea0SLionel Sambuc /**
402ebfedea0SLionel Sambuc  * Parse a configuration file and add the result into res. This
403ebfedea0SLionel Sambuc  * interface can be used to parse several configuration files into one
404ebfedea0SLionel Sambuc  * resulting krb5_config_section by calling it repeatably.
405ebfedea0SLionel Sambuc  *
406ebfedea0SLionel Sambuc  * @param context a Kerberos 5 context.
407ebfedea0SLionel Sambuc  * @param fname a file name to a Kerberos configuration file
408ebfedea0SLionel Sambuc  * @param res the returned result, must be free with krb5_free_config_files().
409ebfedea0SLionel Sambuc  * @return Return an error code or 0, see krb5_get_error_message().
410ebfedea0SLionel Sambuc  *
411ebfedea0SLionel Sambuc  * @ingroup krb5_support
412ebfedea0SLionel Sambuc  */
413ebfedea0SLionel Sambuc 
414ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_config_parse_file_multi(krb5_context context,const char * fname,krb5_config_section ** res)415ebfedea0SLionel Sambuc krb5_config_parse_file_multi (krb5_context context,
416ebfedea0SLionel Sambuc 			      const char *fname,
417ebfedea0SLionel Sambuc 			      krb5_config_section **res)
418ebfedea0SLionel Sambuc {
419ebfedea0SLionel Sambuc     const char *str;
420ebfedea0SLionel Sambuc     char *newfname = NULL;
421ebfedea0SLionel Sambuc     unsigned lineno = 0;
422ebfedea0SLionel Sambuc     krb5_error_code ret;
423ebfedea0SLionel Sambuc     struct fileptr f;
424ebfedea0SLionel Sambuc 
425ebfedea0SLionel Sambuc     /**
426ebfedea0SLionel Sambuc      * If the fname starts with "~/" parse configuration file in the
427ebfedea0SLionel Sambuc      * current users home directory. The behavior can be disabled and
428ebfedea0SLionel Sambuc      * enabled by calling krb5_set_home_dir_access().
429ebfedea0SLionel Sambuc      */
430ebfedea0SLionel Sambuc     if (fname[0] == '~' && fname[1] == '/') {
431ebfedea0SLionel Sambuc #ifndef KRB5_USE_PATH_TOKENS
432ebfedea0SLionel Sambuc 	const char *home = NULL;
433ebfedea0SLionel Sambuc 
434ebfedea0SLionel Sambuc 	if (!_krb5_homedir_access(context)) {
435ebfedea0SLionel Sambuc 	    krb5_set_error_message(context, EPERM,
436ebfedea0SLionel Sambuc 				   "Access to home directory not allowed");
437ebfedea0SLionel Sambuc 	    return EPERM;
438ebfedea0SLionel Sambuc 	}
439ebfedea0SLionel Sambuc 
440ebfedea0SLionel Sambuc 	if(!issuid())
441ebfedea0SLionel Sambuc 	    home = getenv("HOME");
442ebfedea0SLionel Sambuc 
443ebfedea0SLionel Sambuc 	if (home == NULL) {
444ebfedea0SLionel Sambuc 	    struct passwd *pw = getpwuid(getuid());
445ebfedea0SLionel Sambuc 	    if(pw != NULL)
446ebfedea0SLionel Sambuc 		home = pw->pw_dir;
447ebfedea0SLionel Sambuc 	}
448ebfedea0SLionel Sambuc 	if (home) {
449ebfedea0SLionel Sambuc 	    asprintf(&newfname, "%s%s", home, &fname[1]);
450ebfedea0SLionel Sambuc 	    if (newfname == NULL) {
451ebfedea0SLionel Sambuc 		krb5_set_error_message(context, ENOMEM,
452ebfedea0SLionel Sambuc 				       N_("malloc: out of memory", ""));
453ebfedea0SLionel Sambuc 		return ENOMEM;
454ebfedea0SLionel Sambuc 	    }
455ebfedea0SLionel Sambuc 	    fname = newfname;
456ebfedea0SLionel Sambuc 	}
457ebfedea0SLionel Sambuc #else  /* KRB5_USE_PATH_TOKENS */
458ebfedea0SLionel Sambuc 	if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
459ebfedea0SLionel Sambuc 	    newfname == NULL)
460ebfedea0SLionel Sambuc 	{
461ebfedea0SLionel Sambuc 	    krb5_set_error_message(context, ENOMEM,
462ebfedea0SLionel Sambuc 				   N_("malloc: out of memory", ""));
463ebfedea0SLionel Sambuc 	    return ENOMEM;
464ebfedea0SLionel Sambuc 	}
465ebfedea0SLionel Sambuc 	fname = newfname;
466ebfedea0SLionel Sambuc #endif
467ebfedea0SLionel Sambuc     }
468ebfedea0SLionel Sambuc 
469ebfedea0SLionel Sambuc     if (is_plist_file(fname)) {
470ebfedea0SLionel Sambuc #ifdef __APPLE__
471ebfedea0SLionel Sambuc 	ret = parse_plist_config(context, fname, res);
472ebfedea0SLionel Sambuc 	if (ret) {
473ebfedea0SLionel Sambuc 	    krb5_set_error_message(context, ret,
474ebfedea0SLionel Sambuc 				   "Failed to parse plist %s", fname);
475ebfedea0SLionel Sambuc 	    if (newfname)
476ebfedea0SLionel Sambuc 		free(newfname);
477ebfedea0SLionel Sambuc 	    return ret;
478ebfedea0SLionel Sambuc 	}
479ebfedea0SLionel Sambuc #else
480ebfedea0SLionel Sambuc 	krb5_set_error_message(context, ENOENT,
481ebfedea0SLionel Sambuc 			       "no support for plist configuration files");
482ebfedea0SLionel Sambuc 	return ENOENT;
483ebfedea0SLionel Sambuc #endif
484ebfedea0SLionel Sambuc     } else {
485ebfedea0SLionel Sambuc #ifdef KRB5_USE_PATH_TOKENS
486ebfedea0SLionel Sambuc 	char * exp_fname = NULL;
487ebfedea0SLionel Sambuc 
488ebfedea0SLionel Sambuc 	ret = _krb5_expand_path_tokens(context, fname, &exp_fname);
489ebfedea0SLionel Sambuc 	if (ret) {
490ebfedea0SLionel Sambuc 	    if (newfname)
491ebfedea0SLionel Sambuc 		free(newfname);
492ebfedea0SLionel Sambuc 	    return ret;
493ebfedea0SLionel Sambuc 	}
494ebfedea0SLionel Sambuc 
495ebfedea0SLionel Sambuc 	if (newfname)
496ebfedea0SLionel Sambuc 	    free(newfname);
497ebfedea0SLionel Sambuc 	fname = newfname = exp_fname;
498ebfedea0SLionel Sambuc #endif
499ebfedea0SLionel Sambuc 
500ebfedea0SLionel Sambuc 	f.f = fopen(fname, "r");
501ebfedea0SLionel Sambuc 	f.s = NULL;
502ebfedea0SLionel Sambuc 	if(f.f == NULL) {
503ebfedea0SLionel Sambuc 	    ret = errno;
504ebfedea0SLionel Sambuc 	    krb5_set_error_message (context, ret, "open %s: %s",
505ebfedea0SLionel Sambuc 				    fname, strerror(ret));
506ebfedea0SLionel Sambuc 	    if (newfname)
507ebfedea0SLionel Sambuc 		free(newfname);
508ebfedea0SLionel Sambuc 	    return ret;
509ebfedea0SLionel Sambuc 	}
510ebfedea0SLionel Sambuc 
511ebfedea0SLionel Sambuc 	ret = krb5_config_parse_debug (&f, res, &lineno, &str);
512ebfedea0SLionel Sambuc 	fclose(f.f);
513ebfedea0SLionel Sambuc 	if (ret) {
514ebfedea0SLionel Sambuc 	    krb5_set_error_message (context, ret, "%s:%u: %s",
515ebfedea0SLionel Sambuc 				    fname, lineno, str);
516ebfedea0SLionel Sambuc 	    if (newfname)
517ebfedea0SLionel Sambuc 		free(newfname);
518ebfedea0SLionel Sambuc 	    return ret;
519ebfedea0SLionel Sambuc 	}
520ebfedea0SLionel Sambuc     }
521ebfedea0SLionel Sambuc     return 0;
522ebfedea0SLionel Sambuc }
523ebfedea0SLionel Sambuc 
524ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_config_parse_file(krb5_context context,const char * fname,krb5_config_section ** res)525ebfedea0SLionel Sambuc krb5_config_parse_file (krb5_context context,
526ebfedea0SLionel Sambuc 			const char *fname,
527ebfedea0SLionel Sambuc 			krb5_config_section **res)
528ebfedea0SLionel Sambuc {
529ebfedea0SLionel Sambuc     *res = NULL;
530ebfedea0SLionel Sambuc     return krb5_config_parse_file_multi(context, fname, res);
531ebfedea0SLionel Sambuc }
532ebfedea0SLionel Sambuc 
533ebfedea0SLionel Sambuc static void
free_binding(krb5_context context,krb5_config_binding * b)534ebfedea0SLionel Sambuc free_binding (krb5_context context, krb5_config_binding *b)
535ebfedea0SLionel Sambuc {
536ebfedea0SLionel Sambuc     krb5_config_binding *next_b;
537ebfedea0SLionel Sambuc 
538ebfedea0SLionel Sambuc     while (b) {
539ebfedea0SLionel Sambuc 	free (b->name);
540ebfedea0SLionel Sambuc 	if (b->type == krb5_config_string)
541ebfedea0SLionel Sambuc 	    free (b->u.string);
542ebfedea0SLionel Sambuc 	else if (b->type == krb5_config_list)
543ebfedea0SLionel Sambuc 	    free_binding (context, b->u.list);
544ebfedea0SLionel Sambuc 	else
545ebfedea0SLionel Sambuc 	    krb5_abortx(context, "unknown binding type (%d) in free_binding",
546ebfedea0SLionel Sambuc 			b->type);
547ebfedea0SLionel Sambuc 	next_b = b->next;
548ebfedea0SLionel Sambuc 	free (b);
549ebfedea0SLionel Sambuc 	b = next_b;
550ebfedea0SLionel Sambuc     }
551ebfedea0SLionel Sambuc }
552ebfedea0SLionel Sambuc 
553ebfedea0SLionel Sambuc /**
554ebfedea0SLionel Sambuc  * Free configuration file section, the result of
555ebfedea0SLionel Sambuc  * krb5_config_parse_file() and krb5_config_parse_file_multi().
556ebfedea0SLionel Sambuc  *
557ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context
558ebfedea0SLionel Sambuc  * @param s the configuration section to free
559ebfedea0SLionel Sambuc  *
560ebfedea0SLionel Sambuc  * @return returns 0 on successes, otherwise an error code, see
561ebfedea0SLionel Sambuc  *          krb5_get_error_message()
562ebfedea0SLionel Sambuc  *
563ebfedea0SLionel Sambuc  * @ingroup krb5_support
564ebfedea0SLionel Sambuc  */
565ebfedea0SLionel Sambuc 
566ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_config_file_free(krb5_context context,krb5_config_section * s)567ebfedea0SLionel Sambuc krb5_config_file_free (krb5_context context, krb5_config_section *s)
568ebfedea0SLionel Sambuc {
569ebfedea0SLionel Sambuc     free_binding (context, s);
570ebfedea0SLionel Sambuc     return 0;
571ebfedea0SLionel Sambuc }
572ebfedea0SLionel Sambuc 
573ebfedea0SLionel Sambuc #ifndef HEIMDAL_SMALLER
574ebfedea0SLionel Sambuc 
575ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_config_copy(krb5_context context,krb5_config_section * c,krb5_config_section ** head)576ebfedea0SLionel Sambuc _krb5_config_copy(krb5_context context,
577ebfedea0SLionel Sambuc 		  krb5_config_section *c,
578ebfedea0SLionel Sambuc 		  krb5_config_section **head)
579ebfedea0SLionel Sambuc {
580ebfedea0SLionel Sambuc     krb5_config_binding *d, *previous = NULL;
581ebfedea0SLionel Sambuc 
582ebfedea0SLionel Sambuc     *head = NULL;
583ebfedea0SLionel Sambuc 
584ebfedea0SLionel Sambuc     while (c) {
585ebfedea0SLionel Sambuc 	d = calloc(1, sizeof(*d));
586ebfedea0SLionel Sambuc 
587ebfedea0SLionel Sambuc 	if (*head == NULL)
588ebfedea0SLionel Sambuc 	    *head = d;
589ebfedea0SLionel Sambuc 
590ebfedea0SLionel Sambuc 	d->name = strdup(c->name);
591ebfedea0SLionel Sambuc 	d->type = c->type;
592ebfedea0SLionel Sambuc 	if (d->type == krb5_config_string)
593ebfedea0SLionel Sambuc 	    d->u.string = strdup(c->u.string);
594ebfedea0SLionel Sambuc 	else if (d->type == krb5_config_list)
595ebfedea0SLionel Sambuc 	    _krb5_config_copy (context, c->u.list, &d->u.list);
596ebfedea0SLionel Sambuc 	else
597ebfedea0SLionel Sambuc 	    krb5_abortx(context,
598ebfedea0SLionel Sambuc 			"unknown binding type (%d) in krb5_config_copy",
599ebfedea0SLionel Sambuc 			d->type);
600ebfedea0SLionel Sambuc 	if (previous)
601ebfedea0SLionel Sambuc 	    previous->next = d;
602ebfedea0SLionel Sambuc 
603ebfedea0SLionel Sambuc 	previous = d;
604ebfedea0SLionel Sambuc 	c = c->next;
605ebfedea0SLionel Sambuc     }
606ebfedea0SLionel Sambuc     return 0;
607ebfedea0SLionel Sambuc }
608ebfedea0SLionel Sambuc 
609ebfedea0SLionel Sambuc #endif /* HEIMDAL_SMALLER */
610ebfedea0SLionel Sambuc 
611ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL
_krb5_config_get_next(krb5_context context,const krb5_config_section * c,const krb5_config_binding ** pointer,int type,...)612ebfedea0SLionel Sambuc _krb5_config_get_next (krb5_context context,
613ebfedea0SLionel Sambuc 		       const krb5_config_section *c,
614ebfedea0SLionel Sambuc 		       const krb5_config_binding **pointer,
615ebfedea0SLionel Sambuc 		       int type,
616ebfedea0SLionel Sambuc 		       ...)
617ebfedea0SLionel Sambuc {
618ebfedea0SLionel Sambuc     const char *ret;
619ebfedea0SLionel Sambuc     va_list args;
620ebfedea0SLionel Sambuc 
621ebfedea0SLionel Sambuc     va_start(args, type);
622ebfedea0SLionel Sambuc     ret = _krb5_config_vget_next (context, c, pointer, type, args);
623ebfedea0SLionel Sambuc     va_end(args);
624ebfedea0SLionel Sambuc     return ret;
625ebfedea0SLionel Sambuc }
626ebfedea0SLionel Sambuc 
627ebfedea0SLionel Sambuc static const void *
vget_next(krb5_context context,const krb5_config_binding * b,const krb5_config_binding ** pointer,int type,const char * name,va_list args)628ebfedea0SLionel Sambuc vget_next(krb5_context context,
629ebfedea0SLionel Sambuc 	  const krb5_config_binding *b,
630ebfedea0SLionel Sambuc 	  const krb5_config_binding **pointer,
631ebfedea0SLionel Sambuc 	  int type,
632ebfedea0SLionel Sambuc 	  const char *name,
633ebfedea0SLionel Sambuc 	  va_list args)
634ebfedea0SLionel Sambuc {
635ebfedea0SLionel Sambuc     const char *p = va_arg(args, const char *);
636ebfedea0SLionel Sambuc     while(b != NULL) {
637ebfedea0SLionel Sambuc 	if(strcmp(b->name, name) == 0) {
638*0a6a1f1dSLionel Sambuc 	    if(b->type == (unsigned)type && p == NULL) {
639ebfedea0SLionel Sambuc 		*pointer = b;
640ebfedea0SLionel Sambuc 		return b->u.generic;
641ebfedea0SLionel Sambuc 	    } else if(b->type == krb5_config_list && p != NULL) {
642ebfedea0SLionel Sambuc 		return vget_next(context, b->u.list, pointer, type, p, args);
643ebfedea0SLionel Sambuc 	    }
644ebfedea0SLionel Sambuc 	}
645ebfedea0SLionel Sambuc 	b = b->next;
646ebfedea0SLionel Sambuc     }
647ebfedea0SLionel Sambuc     return NULL;
648ebfedea0SLionel Sambuc }
649ebfedea0SLionel Sambuc 
650ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL
_krb5_config_vget_next(krb5_context context,const krb5_config_section * c,const krb5_config_binding ** pointer,int type,va_list args)651ebfedea0SLionel Sambuc _krb5_config_vget_next (krb5_context context,
652ebfedea0SLionel Sambuc 			const krb5_config_section *c,
653ebfedea0SLionel Sambuc 			const krb5_config_binding **pointer,
654ebfedea0SLionel Sambuc 			int type,
655ebfedea0SLionel Sambuc 			va_list args)
656ebfedea0SLionel Sambuc {
657ebfedea0SLionel Sambuc     const krb5_config_binding *b;
658ebfedea0SLionel Sambuc     const char *p;
659ebfedea0SLionel Sambuc 
660ebfedea0SLionel Sambuc     if(c == NULL)
661ebfedea0SLionel Sambuc 	c = context->cf;
662ebfedea0SLionel Sambuc 
663ebfedea0SLionel Sambuc     if (c == NULL)
664ebfedea0SLionel Sambuc 	return NULL;
665ebfedea0SLionel Sambuc 
666ebfedea0SLionel Sambuc     if (*pointer == NULL) {
667ebfedea0SLionel Sambuc 	/* first time here, walk down the tree looking for the right
668ebfedea0SLionel Sambuc            section */
669ebfedea0SLionel Sambuc 	p = va_arg(args, const char *);
670ebfedea0SLionel Sambuc 	if (p == NULL)
671ebfedea0SLionel Sambuc 	    return NULL;
672ebfedea0SLionel Sambuc 	return vget_next(context, c, pointer, type, p, args);
673ebfedea0SLionel Sambuc     }
674ebfedea0SLionel Sambuc 
675ebfedea0SLionel Sambuc     /* we were called again, so just look for more entries with the
676ebfedea0SLionel Sambuc        same name and type */
677ebfedea0SLionel Sambuc     for (b = (*pointer)->next; b != NULL; b = b->next) {
678*0a6a1f1dSLionel Sambuc 	if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) {
679ebfedea0SLionel Sambuc 	    *pointer = b;
680ebfedea0SLionel Sambuc 	    return b->u.generic;
681ebfedea0SLionel Sambuc 	}
682ebfedea0SLionel Sambuc     }
683ebfedea0SLionel Sambuc     return NULL;
684ebfedea0SLionel Sambuc }
685ebfedea0SLionel Sambuc 
686ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL
_krb5_config_get(krb5_context context,const krb5_config_section * c,int type,...)687ebfedea0SLionel Sambuc _krb5_config_get (krb5_context context,
688ebfedea0SLionel Sambuc 		  const krb5_config_section *c,
689ebfedea0SLionel Sambuc 		  int type,
690ebfedea0SLionel Sambuc 		  ...)
691ebfedea0SLionel Sambuc {
692ebfedea0SLionel Sambuc     const void *ret;
693ebfedea0SLionel Sambuc     va_list args;
694ebfedea0SLionel Sambuc 
695ebfedea0SLionel Sambuc     va_start(args, type);
696ebfedea0SLionel Sambuc     ret = _krb5_config_vget (context, c, type, args);
697ebfedea0SLionel Sambuc     va_end(args);
698ebfedea0SLionel Sambuc     return ret;
699ebfedea0SLionel Sambuc }
700ebfedea0SLionel Sambuc 
701ebfedea0SLionel Sambuc 
702ebfedea0SLionel Sambuc const void *
_krb5_config_vget(krb5_context context,const krb5_config_section * c,int type,va_list args)703ebfedea0SLionel Sambuc _krb5_config_vget (krb5_context context,
704ebfedea0SLionel Sambuc 		   const krb5_config_section *c,
705ebfedea0SLionel Sambuc 		   int type,
706ebfedea0SLionel Sambuc 		   va_list args)
707ebfedea0SLionel Sambuc {
708ebfedea0SLionel Sambuc     const krb5_config_binding *foo = NULL;
709ebfedea0SLionel Sambuc 
710ebfedea0SLionel Sambuc     return _krb5_config_vget_next (context, c, &foo, type, args);
711ebfedea0SLionel Sambuc }
712ebfedea0SLionel Sambuc 
713ebfedea0SLionel Sambuc /**
714ebfedea0SLionel Sambuc  * Get a list of configuration binding list for more processing
715ebfedea0SLionel Sambuc  *
716ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
717ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
718ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
719ebfedea0SLionel Sambuc  *
720ebfedea0SLionel Sambuc  * @return NULL if configuration list is not found, a list otherwise
721ebfedea0SLionel Sambuc  *
722ebfedea0SLionel Sambuc  * @ingroup krb5_support
723ebfedea0SLionel Sambuc  */
724ebfedea0SLionel Sambuc 
725ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL
krb5_config_get_list(krb5_context context,const krb5_config_section * c,...)726ebfedea0SLionel Sambuc krb5_config_get_list (krb5_context context,
727ebfedea0SLionel Sambuc 		      const krb5_config_section *c,
728ebfedea0SLionel Sambuc 		      ...)
729ebfedea0SLionel Sambuc {
730ebfedea0SLionel Sambuc     const krb5_config_binding *ret;
731ebfedea0SLionel Sambuc     va_list args;
732ebfedea0SLionel Sambuc 
733ebfedea0SLionel Sambuc     va_start(args, c);
734ebfedea0SLionel Sambuc     ret = krb5_config_vget_list (context, c, args);
735ebfedea0SLionel Sambuc     va_end(args);
736ebfedea0SLionel Sambuc     return ret;
737ebfedea0SLionel Sambuc }
738ebfedea0SLionel Sambuc 
739ebfedea0SLionel Sambuc /**
740ebfedea0SLionel Sambuc  * Get a list of configuration binding list for more processing
741ebfedea0SLionel Sambuc  *
742ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
743ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
744ebfedea0SLionel Sambuc  * @param args a va_list of arguments
745ebfedea0SLionel Sambuc  *
746ebfedea0SLionel Sambuc  * @return NULL if configuration list is not found, a list otherwise
747ebfedea0SLionel Sambuc  *
748ebfedea0SLionel Sambuc  * @ingroup krb5_support
749ebfedea0SLionel Sambuc  */
750ebfedea0SLionel Sambuc 
751ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL
krb5_config_vget_list(krb5_context context,const krb5_config_section * c,va_list args)752ebfedea0SLionel Sambuc krb5_config_vget_list (krb5_context context,
753ebfedea0SLionel Sambuc 		       const krb5_config_section *c,
754ebfedea0SLionel Sambuc 		       va_list args)
755ebfedea0SLionel Sambuc {
756ebfedea0SLionel Sambuc     return _krb5_config_vget (context, c, krb5_config_list, args);
757ebfedea0SLionel Sambuc }
758ebfedea0SLionel Sambuc 
759ebfedea0SLionel Sambuc /**
760ebfedea0SLionel Sambuc  * Returns a "const char *" to a string in the configuration database.
761ebfedea0SLionel Sambuc  * The string may not be valid after a reload of the configuration
762ebfedea0SLionel Sambuc  * database so a caller should make a local copy if it needs to keep
763ebfedea0SLionel Sambuc  * the string.
764ebfedea0SLionel Sambuc  *
765ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
766ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
767ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
768ebfedea0SLionel Sambuc  *
769ebfedea0SLionel Sambuc  * @return NULL if configuration string not found, a string otherwise
770ebfedea0SLionel Sambuc  *
771ebfedea0SLionel Sambuc  * @ingroup krb5_support
772ebfedea0SLionel Sambuc  */
773ebfedea0SLionel Sambuc 
774ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_config_get_string(krb5_context context,const krb5_config_section * c,...)775ebfedea0SLionel Sambuc krb5_config_get_string (krb5_context context,
776ebfedea0SLionel Sambuc 			const krb5_config_section *c,
777ebfedea0SLionel Sambuc 			...)
778ebfedea0SLionel Sambuc {
779ebfedea0SLionel Sambuc     const char *ret;
780ebfedea0SLionel Sambuc     va_list args;
781ebfedea0SLionel Sambuc 
782ebfedea0SLionel Sambuc     va_start(args, c);
783ebfedea0SLionel Sambuc     ret = krb5_config_vget_string (context, c, args);
784ebfedea0SLionel Sambuc     va_end(args);
785ebfedea0SLionel Sambuc     return ret;
786ebfedea0SLionel Sambuc }
787ebfedea0SLionel Sambuc 
788ebfedea0SLionel Sambuc /**
789ebfedea0SLionel Sambuc  * Like krb5_config_get_string(), but uses a va_list instead of ...
790ebfedea0SLionel Sambuc  *
791ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
792ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
793ebfedea0SLionel Sambuc  * @param args a va_list of arguments
794ebfedea0SLionel Sambuc  *
795ebfedea0SLionel Sambuc  * @return NULL if configuration string not found, a string otherwise
796ebfedea0SLionel Sambuc  *
797ebfedea0SLionel Sambuc  * @ingroup krb5_support
798ebfedea0SLionel Sambuc  */
799ebfedea0SLionel Sambuc 
800ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_config_vget_string(krb5_context context,const krb5_config_section * c,va_list args)801ebfedea0SLionel Sambuc krb5_config_vget_string (krb5_context context,
802ebfedea0SLionel Sambuc 			 const krb5_config_section *c,
803ebfedea0SLionel Sambuc 			 va_list args)
804ebfedea0SLionel Sambuc {
805ebfedea0SLionel Sambuc     return _krb5_config_vget (context, c, krb5_config_string, args);
806ebfedea0SLionel Sambuc }
807ebfedea0SLionel Sambuc 
808ebfedea0SLionel Sambuc /**
809ebfedea0SLionel Sambuc  * Like krb5_config_vget_string(), but instead of returning NULL,
810ebfedea0SLionel Sambuc  * instead return a default value.
811ebfedea0SLionel Sambuc  *
812ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
813ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
814ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
815ebfedea0SLionel Sambuc  *        found in the database.
816ebfedea0SLionel Sambuc  * @param args a va_list of arguments
817ebfedea0SLionel Sambuc  *
818ebfedea0SLionel Sambuc  * @return a configuration string
819ebfedea0SLionel Sambuc  *
820ebfedea0SLionel Sambuc  * @ingroup krb5_support
821ebfedea0SLionel Sambuc  */
822ebfedea0SLionel Sambuc 
823ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_config_vget_string_default(krb5_context context,const krb5_config_section * c,const char * def_value,va_list args)824ebfedea0SLionel Sambuc krb5_config_vget_string_default (krb5_context context,
825ebfedea0SLionel Sambuc 				 const krb5_config_section *c,
826ebfedea0SLionel Sambuc 				 const char *def_value,
827ebfedea0SLionel Sambuc 				 va_list args)
828ebfedea0SLionel Sambuc {
829ebfedea0SLionel Sambuc     const char *ret;
830ebfedea0SLionel Sambuc 
831ebfedea0SLionel Sambuc     ret = krb5_config_vget_string (context, c, args);
832ebfedea0SLionel Sambuc     if (ret == NULL)
833ebfedea0SLionel Sambuc 	ret = def_value;
834ebfedea0SLionel Sambuc     return ret;
835ebfedea0SLionel Sambuc }
836ebfedea0SLionel Sambuc 
837ebfedea0SLionel Sambuc /**
838ebfedea0SLionel Sambuc  * Like krb5_config_get_string(), but instead of returning NULL,
839ebfedea0SLionel Sambuc  * instead return a default value.
840ebfedea0SLionel Sambuc  *
841ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
842ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
843ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
844ebfedea0SLionel Sambuc  *        found in the database.
845ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
846ebfedea0SLionel Sambuc  *
847ebfedea0SLionel Sambuc  * @return a configuration string
848ebfedea0SLionel Sambuc  *
849ebfedea0SLionel Sambuc  * @ingroup krb5_support
850ebfedea0SLionel Sambuc  */
851ebfedea0SLionel Sambuc 
852ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL
krb5_config_get_string_default(krb5_context context,const krb5_config_section * c,const char * def_value,...)853ebfedea0SLionel Sambuc krb5_config_get_string_default (krb5_context context,
854ebfedea0SLionel Sambuc 				const krb5_config_section *c,
855ebfedea0SLionel Sambuc 				const char *def_value,
856ebfedea0SLionel Sambuc 				...)
857ebfedea0SLionel Sambuc {
858ebfedea0SLionel Sambuc     const char *ret;
859ebfedea0SLionel Sambuc     va_list args;
860ebfedea0SLionel Sambuc 
861ebfedea0SLionel Sambuc     va_start(args, def_value);
862ebfedea0SLionel Sambuc     ret = krb5_config_vget_string_default (context, c, def_value, args);
863ebfedea0SLionel Sambuc     va_end(args);
864ebfedea0SLionel Sambuc     return ret;
865ebfedea0SLionel Sambuc }
866ebfedea0SLionel Sambuc 
867ebfedea0SLionel Sambuc static char *
next_component_string(char * begin,const char * delims,char ** state)868*0a6a1f1dSLionel Sambuc next_component_string(char * begin, const char * delims, char **state)
869ebfedea0SLionel Sambuc {
870ebfedea0SLionel Sambuc     char * end;
871ebfedea0SLionel Sambuc 
872ebfedea0SLionel Sambuc     if (begin == NULL)
873ebfedea0SLionel Sambuc         begin = *state;
874ebfedea0SLionel Sambuc 
875ebfedea0SLionel Sambuc     if (*begin == '\0')
876ebfedea0SLionel Sambuc         return NULL;
877ebfedea0SLionel Sambuc 
878ebfedea0SLionel Sambuc     end = begin;
879ebfedea0SLionel Sambuc     while (*end == '"') {
880ebfedea0SLionel Sambuc         char * t = strchr(end + 1, '"');
881ebfedea0SLionel Sambuc 
882ebfedea0SLionel Sambuc         if (t)
883ebfedea0SLionel Sambuc             end = ++t;
884ebfedea0SLionel Sambuc         else
885ebfedea0SLionel Sambuc             end += strlen(end);
886ebfedea0SLionel Sambuc     }
887ebfedea0SLionel Sambuc 
888ebfedea0SLionel Sambuc     if (*end != '\0') {
889ebfedea0SLionel Sambuc         size_t pos;
890ebfedea0SLionel Sambuc 
891ebfedea0SLionel Sambuc         pos = strcspn(end, delims);
892ebfedea0SLionel Sambuc         end = end + pos;
893ebfedea0SLionel Sambuc     }
894ebfedea0SLionel Sambuc 
895ebfedea0SLionel Sambuc     if (*end != '\0') {
896ebfedea0SLionel Sambuc         *end = '\0';
897ebfedea0SLionel Sambuc         *state = end + 1;
898ebfedea0SLionel Sambuc         if (*begin == '"' && *(end - 1) == '"' && begin + 1 < end) {
899ebfedea0SLionel Sambuc             begin++; *(end - 1) = '\0';
900ebfedea0SLionel Sambuc         }
901ebfedea0SLionel Sambuc         return begin;
902ebfedea0SLionel Sambuc     }
903ebfedea0SLionel Sambuc 
904ebfedea0SLionel Sambuc     *state = end;
905ebfedea0SLionel Sambuc     if (*begin == '"' && *(end - 1) == '"' && begin + 1 < end) {
906ebfedea0SLionel Sambuc         begin++; *(end - 1) = '\0';
907ebfedea0SLionel Sambuc     }
908ebfedea0SLionel Sambuc     return begin;
909ebfedea0SLionel Sambuc }
910ebfedea0SLionel Sambuc 
911ebfedea0SLionel Sambuc /**
912ebfedea0SLionel Sambuc  * Get a list of configuration strings, free the result with
913ebfedea0SLionel Sambuc  * krb5_config_free_strings().
914ebfedea0SLionel Sambuc  *
915ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
916ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
917ebfedea0SLionel Sambuc  * @param args a va_list of arguments
918ebfedea0SLionel Sambuc  *
919ebfedea0SLionel Sambuc  * @return TRUE or FALSE
920ebfedea0SLionel Sambuc  *
921ebfedea0SLionel Sambuc  * @ingroup krb5_support
922ebfedea0SLionel Sambuc  */
923ebfedea0SLionel Sambuc 
924ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION char ** KRB5_LIB_CALL
krb5_config_vget_strings(krb5_context context,const krb5_config_section * c,va_list args)925ebfedea0SLionel Sambuc krb5_config_vget_strings(krb5_context context,
926ebfedea0SLionel Sambuc 			 const krb5_config_section *c,
927ebfedea0SLionel Sambuc 			 va_list args)
928ebfedea0SLionel Sambuc {
929ebfedea0SLionel Sambuc     char **strings = NULL;
930ebfedea0SLionel Sambuc     int nstr = 0;
931ebfedea0SLionel Sambuc     const krb5_config_binding *b = NULL;
932ebfedea0SLionel Sambuc     const char *p;
933ebfedea0SLionel Sambuc 
934ebfedea0SLionel Sambuc     while((p = _krb5_config_vget_next(context, c, &b,
935ebfedea0SLionel Sambuc 				      krb5_config_string, args))) {
936ebfedea0SLionel Sambuc 	char *tmp = strdup(p);
937ebfedea0SLionel Sambuc 	char *pos = NULL;
938ebfedea0SLionel Sambuc 	char *s;
939ebfedea0SLionel Sambuc 	if(tmp == NULL)
940ebfedea0SLionel Sambuc 	    goto cleanup;
941ebfedea0SLionel Sambuc 	s = next_component_string(tmp, " \t", &pos);
942ebfedea0SLionel Sambuc 	while(s){
943ebfedea0SLionel Sambuc 	    char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings));
944ebfedea0SLionel Sambuc 	    if(tmp2 == NULL)
945ebfedea0SLionel Sambuc 		goto cleanup;
946ebfedea0SLionel Sambuc 	    strings = tmp2;
947ebfedea0SLionel Sambuc 	    strings[nstr] = strdup(s);
948ebfedea0SLionel Sambuc 	    nstr++;
949ebfedea0SLionel Sambuc 	    if(strings[nstr-1] == NULL)
950ebfedea0SLionel Sambuc 		goto cleanup;
951ebfedea0SLionel Sambuc 	    s = next_component_string(NULL, " \t", &pos);
952ebfedea0SLionel Sambuc 	}
953ebfedea0SLionel Sambuc 	free(tmp);
954ebfedea0SLionel Sambuc     }
955ebfedea0SLionel Sambuc     if(nstr){
956ebfedea0SLionel Sambuc 	char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
957ebfedea0SLionel Sambuc 	if(tmp == NULL)
958ebfedea0SLionel Sambuc 	    goto cleanup;
959ebfedea0SLionel Sambuc 	strings = tmp;
960ebfedea0SLionel Sambuc 	strings[nstr] = NULL;
961ebfedea0SLionel Sambuc     }
962ebfedea0SLionel Sambuc     return strings;
963ebfedea0SLionel Sambuc cleanup:
964ebfedea0SLionel Sambuc     while(nstr--)
965ebfedea0SLionel Sambuc 	free(strings[nstr]);
966ebfedea0SLionel Sambuc     free(strings);
967ebfedea0SLionel Sambuc     return NULL;
968ebfedea0SLionel Sambuc 
969ebfedea0SLionel Sambuc }
970ebfedea0SLionel Sambuc 
971ebfedea0SLionel Sambuc /**
972ebfedea0SLionel Sambuc  * Get a list of configuration strings, free the result with
973ebfedea0SLionel Sambuc  * krb5_config_free_strings().
974ebfedea0SLionel Sambuc  *
975ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
976ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
977ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
978ebfedea0SLionel Sambuc  *
979ebfedea0SLionel Sambuc  * @return TRUE or FALSE
980ebfedea0SLionel Sambuc  *
981ebfedea0SLionel Sambuc  * @ingroup krb5_support
982ebfedea0SLionel Sambuc  */
983ebfedea0SLionel Sambuc 
984ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION char** KRB5_LIB_CALL
krb5_config_get_strings(krb5_context context,const krb5_config_section * c,...)985ebfedea0SLionel Sambuc krb5_config_get_strings(krb5_context context,
986ebfedea0SLionel Sambuc 			const krb5_config_section *c,
987ebfedea0SLionel Sambuc 			...)
988ebfedea0SLionel Sambuc {
989ebfedea0SLionel Sambuc     va_list ap;
990ebfedea0SLionel Sambuc     char **ret;
991ebfedea0SLionel Sambuc     va_start(ap, c);
992ebfedea0SLionel Sambuc     ret = krb5_config_vget_strings(context, c, ap);
993ebfedea0SLionel Sambuc     va_end(ap);
994ebfedea0SLionel Sambuc     return ret;
995ebfedea0SLionel Sambuc }
996ebfedea0SLionel Sambuc 
997ebfedea0SLionel Sambuc /**
998ebfedea0SLionel Sambuc  * Free the resulting strings from krb5_config-get_strings() and
999ebfedea0SLionel Sambuc  * krb5_config_vget_strings().
1000ebfedea0SLionel Sambuc  *
1001ebfedea0SLionel Sambuc  * @param strings strings to free
1002ebfedea0SLionel Sambuc  *
1003ebfedea0SLionel Sambuc  * @ingroup krb5_support
1004ebfedea0SLionel Sambuc  */
1005ebfedea0SLionel Sambuc 
1006ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_config_free_strings(char ** strings)1007ebfedea0SLionel Sambuc krb5_config_free_strings(char **strings)
1008ebfedea0SLionel Sambuc {
1009ebfedea0SLionel Sambuc     char **s = strings;
1010ebfedea0SLionel Sambuc     while(s && *s){
1011ebfedea0SLionel Sambuc 	free(*s);
1012ebfedea0SLionel Sambuc 	s++;
1013ebfedea0SLionel Sambuc     }
1014ebfedea0SLionel Sambuc     free(strings);
1015ebfedea0SLionel Sambuc }
1016ebfedea0SLionel Sambuc 
1017ebfedea0SLionel Sambuc /**
1018ebfedea0SLionel Sambuc  * Like krb5_config_get_bool_default() but with a va_list list of
1019ebfedea0SLionel Sambuc  * configuration selection.
1020ebfedea0SLionel Sambuc  *
1021ebfedea0SLionel Sambuc  * Configuration value to a boolean value, where yes/true and any
1022ebfedea0SLionel Sambuc  * non-zero number means TRUE and other value is FALSE.
1023ebfedea0SLionel Sambuc  *
1024ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1025ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1026ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
1027ebfedea0SLionel Sambuc  *        found in the database.
1028ebfedea0SLionel Sambuc  * @param args a va_list of arguments
1029ebfedea0SLionel Sambuc  *
1030ebfedea0SLionel Sambuc  * @return TRUE or FALSE
1031ebfedea0SLionel Sambuc  *
1032ebfedea0SLionel Sambuc  * @ingroup krb5_support
1033ebfedea0SLionel Sambuc  */
1034ebfedea0SLionel Sambuc 
1035ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_config_vget_bool_default(krb5_context context,const krb5_config_section * c,krb5_boolean def_value,va_list args)1036ebfedea0SLionel Sambuc krb5_config_vget_bool_default (krb5_context context,
1037ebfedea0SLionel Sambuc 			       const krb5_config_section *c,
1038ebfedea0SLionel Sambuc 			       krb5_boolean def_value,
1039ebfedea0SLionel Sambuc 			       va_list args)
1040ebfedea0SLionel Sambuc {
1041ebfedea0SLionel Sambuc     const char *str;
1042ebfedea0SLionel Sambuc     str = krb5_config_vget_string (context, c, args);
1043ebfedea0SLionel Sambuc     if(str == NULL)
1044ebfedea0SLionel Sambuc 	return def_value;
1045ebfedea0SLionel Sambuc     if(strcasecmp(str, "yes") == 0 ||
1046ebfedea0SLionel Sambuc        strcasecmp(str, "true") == 0 ||
1047ebfedea0SLionel Sambuc        atoi(str)) return TRUE;
1048ebfedea0SLionel Sambuc     return FALSE;
1049ebfedea0SLionel Sambuc }
1050ebfedea0SLionel Sambuc 
1051ebfedea0SLionel Sambuc /**
1052ebfedea0SLionel Sambuc  * krb5_config_get_bool() will convert the configuration
1053ebfedea0SLionel Sambuc  * option value to a boolean value, where yes/true and any non-zero
1054ebfedea0SLionel Sambuc  * number means TRUE and other value is FALSE.
1055ebfedea0SLionel Sambuc  *
1056ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1057ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1058ebfedea0SLionel Sambuc  * @param args a va_list of arguments
1059ebfedea0SLionel Sambuc  *
1060ebfedea0SLionel Sambuc  * @return TRUE or FALSE
1061ebfedea0SLionel Sambuc  *
1062ebfedea0SLionel Sambuc  * @ingroup krb5_support
1063ebfedea0SLionel Sambuc  */
1064ebfedea0SLionel Sambuc 
1065ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_config_vget_bool(krb5_context context,const krb5_config_section * c,va_list args)1066ebfedea0SLionel Sambuc krb5_config_vget_bool  (krb5_context context,
1067ebfedea0SLionel Sambuc 			const krb5_config_section *c,
1068ebfedea0SLionel Sambuc 			va_list args)
1069ebfedea0SLionel Sambuc {
1070ebfedea0SLionel Sambuc     return krb5_config_vget_bool_default (context, c, FALSE, args);
1071ebfedea0SLionel Sambuc }
1072ebfedea0SLionel Sambuc 
1073ebfedea0SLionel Sambuc /**
1074ebfedea0SLionel Sambuc  * krb5_config_get_bool_default() will convert the configuration
1075ebfedea0SLionel Sambuc  * option value to a boolean value, where yes/true and any non-zero
1076ebfedea0SLionel Sambuc  * number means TRUE and other value is FALSE.
1077ebfedea0SLionel Sambuc  *
1078ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1079ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1080ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
1081ebfedea0SLionel Sambuc  *        found in the database.
1082ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
1083ebfedea0SLionel Sambuc  *
1084ebfedea0SLionel Sambuc  * @return TRUE or FALSE
1085ebfedea0SLionel Sambuc  *
1086ebfedea0SLionel Sambuc  * @ingroup krb5_support
1087ebfedea0SLionel Sambuc  */
1088ebfedea0SLionel Sambuc 
1089ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_config_get_bool_default(krb5_context context,const krb5_config_section * c,krb5_boolean def_value,...)1090ebfedea0SLionel Sambuc krb5_config_get_bool_default (krb5_context context,
1091ebfedea0SLionel Sambuc 			      const krb5_config_section *c,
1092ebfedea0SLionel Sambuc 			      krb5_boolean def_value,
1093ebfedea0SLionel Sambuc 			      ...)
1094ebfedea0SLionel Sambuc {
1095ebfedea0SLionel Sambuc     va_list ap;
1096ebfedea0SLionel Sambuc     krb5_boolean ret;
1097ebfedea0SLionel Sambuc     va_start(ap, def_value);
1098ebfedea0SLionel Sambuc     ret = krb5_config_vget_bool_default(context, c, def_value, ap);
1099ebfedea0SLionel Sambuc     va_end(ap);
1100ebfedea0SLionel Sambuc     return ret;
1101ebfedea0SLionel Sambuc }
1102ebfedea0SLionel Sambuc 
1103ebfedea0SLionel Sambuc /**
1104ebfedea0SLionel Sambuc  * Like krb5_config_get_bool() but with a va_list list of
1105ebfedea0SLionel Sambuc  * configuration selection.
1106ebfedea0SLionel Sambuc  *
1107ebfedea0SLionel Sambuc  * Configuration value to a boolean value, where yes/true and any
1108ebfedea0SLionel Sambuc  * non-zero number means TRUE and other value is FALSE.
1109ebfedea0SLionel Sambuc  *
1110ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1111ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1112ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
1113ebfedea0SLionel Sambuc  *
1114ebfedea0SLionel Sambuc  * @return TRUE or FALSE
1115ebfedea0SLionel Sambuc  *
1116ebfedea0SLionel Sambuc  * @ingroup krb5_support
1117ebfedea0SLionel Sambuc  */
1118ebfedea0SLionel Sambuc 
1119ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_config_get_bool(krb5_context context,const krb5_config_section * c,...)1120ebfedea0SLionel Sambuc krb5_config_get_bool (krb5_context context,
1121ebfedea0SLionel Sambuc 		      const krb5_config_section *c,
1122ebfedea0SLionel Sambuc 		      ...)
1123ebfedea0SLionel Sambuc {
1124ebfedea0SLionel Sambuc     va_list ap;
1125ebfedea0SLionel Sambuc     krb5_boolean ret;
1126ebfedea0SLionel Sambuc     va_start(ap, c);
1127ebfedea0SLionel Sambuc     ret = krb5_config_vget_bool (context, c, ap);
1128ebfedea0SLionel Sambuc     va_end(ap);
1129ebfedea0SLionel Sambuc     return ret;
1130ebfedea0SLionel Sambuc }
1131ebfedea0SLionel Sambuc 
1132ebfedea0SLionel Sambuc /**
1133ebfedea0SLionel Sambuc  * Get the time from the configuration file using a relative time.
1134ebfedea0SLionel Sambuc  *
1135ebfedea0SLionel Sambuc  * Like krb5_config_get_time_default() but with a va_list list of
1136ebfedea0SLionel Sambuc  * configuration selection.
1137ebfedea0SLionel Sambuc  *
1138ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1139ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1140ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
1141ebfedea0SLionel Sambuc  *        found in the database.
1142ebfedea0SLionel Sambuc  * @param args a va_list of arguments
1143ebfedea0SLionel Sambuc  *
1144ebfedea0SLionel Sambuc  * @return parsed the time (or def_value on parse error)
1145ebfedea0SLionel Sambuc  *
1146ebfedea0SLionel Sambuc  * @ingroup krb5_support
1147ebfedea0SLionel Sambuc  */
1148ebfedea0SLionel Sambuc 
1149ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_vget_time_default(krb5_context context,const krb5_config_section * c,int def_value,va_list args)1150ebfedea0SLionel Sambuc krb5_config_vget_time_default (krb5_context context,
1151ebfedea0SLionel Sambuc 			       const krb5_config_section *c,
1152ebfedea0SLionel Sambuc 			       int def_value,
1153ebfedea0SLionel Sambuc 			       va_list args)
1154ebfedea0SLionel Sambuc {
1155ebfedea0SLionel Sambuc     const char *str;
1156ebfedea0SLionel Sambuc     krb5_deltat t;
1157ebfedea0SLionel Sambuc 
1158ebfedea0SLionel Sambuc     str = krb5_config_vget_string (context, c, args);
1159ebfedea0SLionel Sambuc     if(str == NULL)
1160ebfedea0SLionel Sambuc 	return def_value;
1161ebfedea0SLionel Sambuc     if (krb5_string_to_deltat(str, &t))
1162ebfedea0SLionel Sambuc 	return def_value;
1163ebfedea0SLionel Sambuc     return t;
1164ebfedea0SLionel Sambuc }
1165ebfedea0SLionel Sambuc 
1166ebfedea0SLionel Sambuc /**
1167ebfedea0SLionel Sambuc  * Get the time from the configuration file using a relative time, for example: 1h30s
1168ebfedea0SLionel Sambuc  *
1169ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1170ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1171ebfedea0SLionel Sambuc  * @param args a va_list of arguments
1172ebfedea0SLionel Sambuc  *
1173ebfedea0SLionel Sambuc  * @return parsed the time or -1 on error
1174ebfedea0SLionel Sambuc  *
1175ebfedea0SLionel Sambuc  * @ingroup krb5_support
1176ebfedea0SLionel Sambuc  */
1177ebfedea0SLionel Sambuc 
1178ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_vget_time(krb5_context context,const krb5_config_section * c,va_list args)1179ebfedea0SLionel Sambuc krb5_config_vget_time  (krb5_context context,
1180ebfedea0SLionel Sambuc 			const krb5_config_section *c,
1181ebfedea0SLionel Sambuc 			va_list args)
1182ebfedea0SLionel Sambuc {
1183ebfedea0SLionel Sambuc     return krb5_config_vget_time_default (context, c, -1, args);
1184ebfedea0SLionel Sambuc }
1185ebfedea0SLionel Sambuc 
1186ebfedea0SLionel Sambuc /**
1187ebfedea0SLionel Sambuc  * Get the time from the configuration file using a relative time, for example: 1h30s
1188ebfedea0SLionel Sambuc  *
1189ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1190ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1191ebfedea0SLionel Sambuc  * @param def_value the default value to return if no configuration
1192ebfedea0SLionel Sambuc  *        found in the database.
1193ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
1194ebfedea0SLionel Sambuc  *
1195ebfedea0SLionel Sambuc  * @return parsed the time (or def_value on parse error)
1196ebfedea0SLionel Sambuc  *
1197ebfedea0SLionel Sambuc  * @ingroup krb5_support
1198ebfedea0SLionel Sambuc  */
1199ebfedea0SLionel Sambuc 
1200ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_get_time_default(krb5_context context,const krb5_config_section * c,int def_value,...)1201ebfedea0SLionel Sambuc krb5_config_get_time_default (krb5_context context,
1202ebfedea0SLionel Sambuc 			      const krb5_config_section *c,
1203ebfedea0SLionel Sambuc 			      int def_value,
1204ebfedea0SLionel Sambuc 			      ...)
1205ebfedea0SLionel Sambuc {
1206ebfedea0SLionel Sambuc     va_list ap;
1207ebfedea0SLionel Sambuc     int ret;
1208ebfedea0SLionel Sambuc     va_start(ap, def_value);
1209ebfedea0SLionel Sambuc     ret = krb5_config_vget_time_default(context, c, def_value, ap);
1210ebfedea0SLionel Sambuc     va_end(ap);
1211ebfedea0SLionel Sambuc     return ret;
1212ebfedea0SLionel Sambuc }
1213ebfedea0SLionel Sambuc 
1214ebfedea0SLionel Sambuc /**
1215ebfedea0SLionel Sambuc  * Get the time from the configuration file using a relative time, for example: 1h30s
1216ebfedea0SLionel Sambuc  *
1217ebfedea0SLionel Sambuc  * @param context A Kerberos 5 context.
1218ebfedea0SLionel Sambuc  * @param c a configuration section, or NULL to use the section from context
1219ebfedea0SLionel Sambuc  * @param ... a list of names, terminated with NULL.
1220ebfedea0SLionel Sambuc  *
1221ebfedea0SLionel Sambuc  * @return parsed the time or -1 on error
1222ebfedea0SLionel Sambuc  *
1223ebfedea0SLionel Sambuc  * @ingroup krb5_support
1224ebfedea0SLionel Sambuc  */
1225ebfedea0SLionel Sambuc 
1226ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_get_time(krb5_context context,const krb5_config_section * c,...)1227ebfedea0SLionel Sambuc krb5_config_get_time (krb5_context context,
1228ebfedea0SLionel Sambuc 		      const krb5_config_section *c,
1229ebfedea0SLionel Sambuc 		      ...)
1230ebfedea0SLionel Sambuc {
1231ebfedea0SLionel Sambuc     va_list ap;
1232ebfedea0SLionel Sambuc     int ret;
1233ebfedea0SLionel Sambuc     va_start(ap, c);
1234ebfedea0SLionel Sambuc     ret = krb5_config_vget_time (context, c, ap);
1235ebfedea0SLionel Sambuc     va_end(ap);
1236ebfedea0SLionel Sambuc     return ret;
1237ebfedea0SLionel Sambuc }
1238ebfedea0SLionel Sambuc 
1239ebfedea0SLionel Sambuc 
1240ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_vget_int_default(krb5_context context,const krb5_config_section * c,int def_value,va_list args)1241ebfedea0SLionel Sambuc krb5_config_vget_int_default (krb5_context context,
1242ebfedea0SLionel Sambuc 			      const krb5_config_section *c,
1243ebfedea0SLionel Sambuc 			      int def_value,
1244ebfedea0SLionel Sambuc 			      va_list args)
1245ebfedea0SLionel Sambuc {
1246ebfedea0SLionel Sambuc     const char *str;
1247ebfedea0SLionel Sambuc     str = krb5_config_vget_string (context, c, args);
1248ebfedea0SLionel Sambuc     if(str == NULL)
1249ebfedea0SLionel Sambuc 	return def_value;
1250ebfedea0SLionel Sambuc     else {
1251ebfedea0SLionel Sambuc 	char *endptr;
1252ebfedea0SLionel Sambuc 	long l;
1253ebfedea0SLionel Sambuc 	l = strtol(str, &endptr, 0);
1254ebfedea0SLionel Sambuc 	if (endptr == str)
1255ebfedea0SLionel Sambuc 	    return def_value;
1256ebfedea0SLionel Sambuc 	else
1257ebfedea0SLionel Sambuc 	    return l;
1258ebfedea0SLionel Sambuc     }
1259ebfedea0SLionel Sambuc }
1260ebfedea0SLionel Sambuc 
1261ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_vget_int(krb5_context context,const krb5_config_section * c,va_list args)1262ebfedea0SLionel Sambuc krb5_config_vget_int  (krb5_context context,
1263ebfedea0SLionel Sambuc 		       const krb5_config_section *c,
1264ebfedea0SLionel Sambuc 		       va_list args)
1265ebfedea0SLionel Sambuc {
1266ebfedea0SLionel Sambuc     return krb5_config_vget_int_default (context, c, -1, args);
1267ebfedea0SLionel Sambuc }
1268ebfedea0SLionel Sambuc 
1269ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_get_int_default(krb5_context context,const krb5_config_section * c,int def_value,...)1270ebfedea0SLionel Sambuc krb5_config_get_int_default (krb5_context context,
1271ebfedea0SLionel Sambuc 			     const krb5_config_section *c,
1272ebfedea0SLionel Sambuc 			     int def_value,
1273ebfedea0SLionel Sambuc 			     ...)
1274ebfedea0SLionel Sambuc {
1275ebfedea0SLionel Sambuc     va_list ap;
1276ebfedea0SLionel Sambuc     int ret;
1277ebfedea0SLionel Sambuc     va_start(ap, def_value);
1278ebfedea0SLionel Sambuc     ret = krb5_config_vget_int_default(context, c, def_value, ap);
1279ebfedea0SLionel Sambuc     va_end(ap);
1280ebfedea0SLionel Sambuc     return ret;
1281ebfedea0SLionel Sambuc }
1282ebfedea0SLionel Sambuc 
1283ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_config_get_int(krb5_context context,const krb5_config_section * c,...)1284ebfedea0SLionel Sambuc krb5_config_get_int (krb5_context context,
1285ebfedea0SLionel Sambuc 		     const krb5_config_section *c,
1286ebfedea0SLionel Sambuc 		     ...)
1287ebfedea0SLionel Sambuc {
1288ebfedea0SLionel Sambuc     va_list ap;
1289ebfedea0SLionel Sambuc     int ret;
1290ebfedea0SLionel Sambuc     va_start(ap, c);
1291ebfedea0SLionel Sambuc     ret = krb5_config_vget_int (context, c, ap);
1292ebfedea0SLionel Sambuc     va_end(ap);
1293ebfedea0SLionel Sambuc     return ret;
1294ebfedea0SLionel Sambuc }
1295ebfedea0SLionel Sambuc 
1296ebfedea0SLionel Sambuc 
1297ebfedea0SLionel Sambuc #ifndef HEIMDAL_SMALLER
1298ebfedea0SLionel Sambuc 
1299ebfedea0SLionel Sambuc /**
1300ebfedea0SLionel Sambuc  * Deprecated: configuration files are not strings
1301ebfedea0SLionel Sambuc  *
1302ebfedea0SLionel Sambuc  * @ingroup krb5_deprecated
1303ebfedea0SLionel Sambuc  */
1304ebfedea0SLionel Sambuc 
1305ebfedea0SLionel Sambuc KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_config_parse_string_multi(krb5_context context,const char * string,krb5_config_section ** res)1306ebfedea0SLionel Sambuc krb5_config_parse_string_multi(krb5_context context,
1307ebfedea0SLionel Sambuc 			       const char *string,
1308ebfedea0SLionel Sambuc 			       krb5_config_section **res)
1309*0a6a1f1dSLionel Sambuc     KRB5_DEPRECATED_FUNCTION("Use X instead")
1310ebfedea0SLionel Sambuc {
1311ebfedea0SLionel Sambuc     const char *str;
1312ebfedea0SLionel Sambuc     unsigned lineno = 0;
1313ebfedea0SLionel Sambuc     krb5_error_code ret;
1314ebfedea0SLionel Sambuc     struct fileptr f;
1315ebfedea0SLionel Sambuc     f.f = NULL;
1316ebfedea0SLionel Sambuc     f.s = string;
1317ebfedea0SLionel Sambuc 
1318ebfedea0SLionel Sambuc     ret = krb5_config_parse_debug (&f, res, &lineno, &str);
1319ebfedea0SLionel Sambuc     if (ret) {
1320ebfedea0SLionel Sambuc 	krb5_set_error_message (context, ret, "%s:%u: %s",
1321ebfedea0SLionel Sambuc 				"<constant>", lineno, str);
1322ebfedea0SLionel Sambuc 	return ret;
1323ebfedea0SLionel Sambuc     }
1324ebfedea0SLionel Sambuc     return 0;
1325ebfedea0SLionel Sambuc }
1326ebfedea0SLionel Sambuc 
1327ebfedea0SLionel Sambuc #endif
1328