1b528cefcSMark Murray /* 2c19800e8SDoug Rabson * Copyright (c) 1997 - 2004 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" 35c19800e8SDoug Rabson RCSID("$Id: config_file.c 19213 2006-12-04 23:36:36Z lha $"); 36b528cefcSMark Murray 37b528cefcSMark Murray #ifndef HAVE_NETINFO 38b528cefcSMark Murray 39c19800e8SDoug Rabson /* Gaah! I want a portable funopen */ 40c19800e8SDoug Rabson struct fileptr { 41c19800e8SDoug Rabson const char *s; 42c19800e8SDoug Rabson FILE *f; 43c19800e8SDoug Rabson }; 44c19800e8SDoug Rabson 45c19800e8SDoug Rabson static char * 46c19800e8SDoug Rabson config_fgets(char *str, size_t len, struct fileptr *ptr) 47c19800e8SDoug Rabson { 48c19800e8SDoug Rabson /* XXX this is not correct, in that they don't do the same if the 49c19800e8SDoug Rabson line is longer than len */ 50c19800e8SDoug Rabson if(ptr->f != NULL) 51c19800e8SDoug Rabson return fgets(str, len, ptr->f); 52c19800e8SDoug Rabson else { 53c19800e8SDoug Rabson /* this is almost strsep_copy */ 54c19800e8SDoug Rabson const char *p; 55c19800e8SDoug Rabson ssize_t l; 56c19800e8SDoug Rabson if(*ptr->s == '\0') 57c19800e8SDoug Rabson return NULL; 58c19800e8SDoug Rabson p = ptr->s + strcspn(ptr->s, "\n"); 59c19800e8SDoug Rabson if(*p == '\n') 60c19800e8SDoug Rabson p++; 61c19800e8SDoug Rabson l = min(len, p - ptr->s); 62c19800e8SDoug Rabson if(len > 0) { 63c19800e8SDoug Rabson memcpy(str, ptr->s, l); 64c19800e8SDoug Rabson str[l] = '\0'; 65c19800e8SDoug Rabson } 66c19800e8SDoug Rabson ptr->s = p; 67c19800e8SDoug Rabson return str; 68c19800e8SDoug Rabson } 69c19800e8SDoug Rabson } 70c19800e8SDoug Rabson 71adb0ddaeSAssar Westerlund static krb5_error_code parse_section(char *p, krb5_config_section **s, 72b528cefcSMark Murray krb5_config_section **res, 738373020dSJacques Vidrine const char **error_message); 74c19800e8SDoug Rabson static krb5_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p, 75b528cefcSMark Murray krb5_config_binding **b, 76b528cefcSMark Murray krb5_config_binding **parent, 778373020dSJacques Vidrine const char **error_message); 78c19800e8SDoug Rabson static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno, 79adb0ddaeSAssar Westerlund krb5_config_binding **parent, 808373020dSJacques Vidrine const char **error_message); 818373020dSJacques Vidrine 828373020dSJacques Vidrine static krb5_config_section * 838373020dSJacques Vidrine get_entry(krb5_config_section **parent, const char *name, int type) 848373020dSJacques Vidrine { 858373020dSJacques Vidrine krb5_config_section **q; 868373020dSJacques Vidrine 878373020dSJacques Vidrine for(q = parent; *q != NULL; q = &(*q)->next) 888373020dSJacques Vidrine if(type == krb5_config_list && 898373020dSJacques Vidrine type == (*q)->type && 908373020dSJacques Vidrine strcmp(name, (*q)->name) == 0) 918373020dSJacques Vidrine return *q; 928373020dSJacques Vidrine *q = calloc(1, sizeof(**q)); 938373020dSJacques Vidrine if(*q == NULL) 948373020dSJacques Vidrine return NULL; 958373020dSJacques Vidrine (*q)->name = strdup(name); 968373020dSJacques Vidrine (*q)->type = type; 978373020dSJacques Vidrine if((*q)->name == NULL) { 988373020dSJacques Vidrine free(*q); 998373020dSJacques Vidrine *q = NULL; 1008373020dSJacques Vidrine return NULL; 1018373020dSJacques Vidrine } 1028373020dSJacques Vidrine return *q; 1038373020dSJacques Vidrine } 104b528cefcSMark Murray 105b528cefcSMark Murray /* 106b528cefcSMark Murray * Parse a section: 107b528cefcSMark Murray * 108b528cefcSMark Murray * [section] 109b528cefcSMark Murray * foo = bar 110b528cefcSMark Murray * b = { 111b528cefcSMark Murray * a 112b528cefcSMark Murray * } 113b528cefcSMark Murray * ... 114b528cefcSMark Murray * 115b528cefcSMark Murray * starting at the line in `p', storing the resulting structure in 116b528cefcSMark Murray * `s' and hooking it into `parent'. 117b528cefcSMark Murray * Store the error message in `error_message'. 118b528cefcSMark Murray */ 119b528cefcSMark Murray 120adb0ddaeSAssar Westerlund static krb5_error_code 121b528cefcSMark Murray parse_section(char *p, krb5_config_section **s, krb5_config_section **parent, 1228373020dSJacques Vidrine const char **error_message) 123b528cefcSMark Murray { 124b528cefcSMark Murray char *p1; 125b528cefcSMark Murray krb5_config_section *tmp; 126b528cefcSMark Murray 127b528cefcSMark Murray p1 = strchr (p + 1, ']'); 128b528cefcSMark Murray if (p1 == NULL) { 129b528cefcSMark Murray *error_message = "missing ]"; 130adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 131b528cefcSMark Murray } 132b528cefcSMark Murray *p1 = '\0'; 1338373020dSJacques Vidrine tmp = get_entry(parent, p + 1, krb5_config_list); 134b528cefcSMark Murray if(tmp == NULL) { 135b528cefcSMark Murray *error_message = "out of memory"; 136adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 137b528cefcSMark Murray } 138b528cefcSMark Murray *s = tmp; 139b528cefcSMark Murray return 0; 140b528cefcSMark Murray } 141b528cefcSMark Murray 142b528cefcSMark Murray /* 143b528cefcSMark Murray * Parse a brace-enclosed list from `f', hooking in the structure at 144b528cefcSMark Murray * `parent'. 145b528cefcSMark Murray * Store the error message in `error_message'. 146b528cefcSMark Murray */ 147b528cefcSMark Murray 1481c43270aSJacques Vidrine static krb5_error_code 149c19800e8SDoug Rabson parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent, 1508373020dSJacques Vidrine const char **error_message) 151b528cefcSMark Murray { 152b528cefcSMark Murray char buf[BUFSIZ]; 1531c43270aSJacques Vidrine krb5_error_code ret; 154b528cefcSMark Murray krb5_config_binding *b = NULL; 155b528cefcSMark Murray unsigned beg_lineno = *lineno; 156b528cefcSMark Murray 157c19800e8SDoug Rabson while(config_fgets(buf, sizeof(buf), f) != NULL) { 158b528cefcSMark Murray char *p; 159b528cefcSMark Murray 160b528cefcSMark Murray ++*lineno; 161c19800e8SDoug Rabson buf[strcspn(buf, "\r\n")] = '\0'; 162b528cefcSMark Murray p = buf; 163b528cefcSMark Murray while(isspace((unsigned char)*p)) 164b528cefcSMark Murray ++p; 165b528cefcSMark Murray if (*p == '#' || *p == ';' || *p == '\0') 166b528cefcSMark Murray continue; 167b528cefcSMark Murray while(isspace((unsigned char)*p)) 168b528cefcSMark Murray ++p; 169b528cefcSMark Murray if (*p == '}') 170b528cefcSMark Murray return 0; 171b528cefcSMark Murray if (*p == '\0') 172b528cefcSMark Murray continue; 173b528cefcSMark Murray ret = parse_binding (f, lineno, p, &b, parent, error_message); 174b528cefcSMark Murray if (ret) 175b528cefcSMark Murray return ret; 176b528cefcSMark Murray } 177b528cefcSMark Murray *lineno = beg_lineno; 178b528cefcSMark Murray *error_message = "unclosed {"; 179adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 180b528cefcSMark Murray } 181b528cefcSMark Murray 182b528cefcSMark Murray /* 183b528cefcSMark Murray * 184b528cefcSMark Murray */ 185b528cefcSMark Murray 1861c43270aSJacques Vidrine static krb5_error_code 187c19800e8SDoug Rabson parse_binding(struct fileptr *f, unsigned *lineno, char *p, 188b528cefcSMark Murray krb5_config_binding **b, krb5_config_binding **parent, 1898373020dSJacques Vidrine const char **error_message) 190b528cefcSMark Murray { 191b528cefcSMark Murray krb5_config_binding *tmp; 192b528cefcSMark Murray char *p1, *p2; 1931c43270aSJacques Vidrine krb5_error_code ret = 0; 194b528cefcSMark Murray 195b528cefcSMark Murray p1 = p; 196b528cefcSMark Murray while (*p && *p != '=' && !isspace((unsigned char)*p)) 197b528cefcSMark Murray ++p; 198b528cefcSMark Murray if (*p == '\0') { 1998373020dSJacques Vidrine *error_message = "missing ="; 200adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 201b528cefcSMark Murray } 202b528cefcSMark Murray p2 = p; 203b528cefcSMark Murray while (isspace((unsigned char)*p)) 204b528cefcSMark Murray ++p; 205b528cefcSMark Murray if (*p != '=') { 2068373020dSJacques Vidrine *error_message = "missing ="; 207adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 208b528cefcSMark Murray } 209b528cefcSMark Murray ++p; 210b528cefcSMark Murray while(isspace((unsigned char)*p)) 211b528cefcSMark Murray ++p; 2128373020dSJacques Vidrine *p2 = '\0'; 2138373020dSJacques Vidrine if (*p == '{') { 2148373020dSJacques Vidrine tmp = get_entry(parent, p1, krb5_config_list); 215b528cefcSMark Murray if (tmp == NULL) { 216b528cefcSMark Murray *error_message = "out of memory"; 217adb0ddaeSAssar Westerlund return KRB5_CONFIG_BADFORMAT; 218b528cefcSMark Murray } 219b528cefcSMark Murray ret = parse_list (f, lineno, &tmp->u.list, error_message); 220b528cefcSMark Murray } else { 2218373020dSJacques Vidrine tmp = get_entry(parent, p1, krb5_config_string); 2228373020dSJacques Vidrine if (tmp == NULL) { 2238373020dSJacques Vidrine *error_message = "out of memory"; 2248373020dSJacques Vidrine return KRB5_CONFIG_BADFORMAT; 2258373020dSJacques Vidrine } 226b528cefcSMark Murray p1 = p; 227b528cefcSMark Murray p = p1 + strlen(p1); 228b528cefcSMark Murray while(p > p1 && isspace((unsigned char)*(p-1))) 229b528cefcSMark Murray --p; 230b528cefcSMark Murray *p = '\0'; 231b528cefcSMark Murray tmp->u.string = strdup(p1); 232b528cefcSMark Murray } 233b528cefcSMark Murray *b = tmp; 234b528cefcSMark Murray return ret; 235b528cefcSMark Murray } 236b528cefcSMark Murray 237b528cefcSMark Murray /* 238b528cefcSMark Murray * Parse the config file `fname', generating the structures into `res' 239b528cefcSMark Murray * returning error messages in `error_message' 240b528cefcSMark Murray */ 241b528cefcSMark Murray 242adb0ddaeSAssar Westerlund static krb5_error_code 243c19800e8SDoug Rabson krb5_config_parse_debug (struct fileptr *f, 244b528cefcSMark Murray krb5_config_section **res, 245b528cefcSMark Murray unsigned *lineno, 2468373020dSJacques Vidrine const char **error_message) 247b528cefcSMark Murray { 248c19800e8SDoug Rabson krb5_config_section *s = NULL; 249c19800e8SDoug Rabson krb5_config_binding *b = NULL; 250b528cefcSMark Murray char buf[BUFSIZ]; 251c19800e8SDoug Rabson krb5_error_code ret; 252b528cefcSMark Murray 253c19800e8SDoug Rabson while (config_fgets(buf, sizeof(buf), f) != NULL) { 254b528cefcSMark Murray char *p; 255b528cefcSMark Murray 256b528cefcSMark Murray ++*lineno; 257c19800e8SDoug Rabson buf[strcspn(buf, "\r\n")] = '\0'; 258b528cefcSMark Murray p = buf; 259b528cefcSMark Murray while(isspace((unsigned char)*p)) 260b528cefcSMark Murray ++p; 261b528cefcSMark Murray if (*p == '#' || *p == ';') 262b528cefcSMark Murray continue; 263b528cefcSMark Murray if (*p == '[') { 264b528cefcSMark Murray ret = parse_section(p, &s, res, error_message); 265c19800e8SDoug Rabson if (ret) 266c19800e8SDoug Rabson return ret; 267b528cefcSMark Murray b = NULL; 268b528cefcSMark Murray } else if (*p == '}') { 269b528cefcSMark Murray *error_message = "unmatched }"; 270c19800e8SDoug Rabson return EINVAL; /* XXX */ 271b528cefcSMark Murray } else if(*p != '\0') { 2721c43270aSJacques Vidrine if (s == NULL) { 2731c43270aSJacques Vidrine *error_message = "binding before section"; 274c19800e8SDoug Rabson return EINVAL; 2751c43270aSJacques Vidrine } 276b528cefcSMark Murray ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message); 277b528cefcSMark Murray if (ret) 2785e9cd1aeSAssar Westerlund return ret; 279b528cefcSMark Murray } 280c19800e8SDoug Rabson } 281c19800e8SDoug Rabson return 0; 282c19800e8SDoug Rabson } 283b528cefcSMark Murray 284c19800e8SDoug Rabson krb5_error_code KRB5_LIB_FUNCTION 285c19800e8SDoug Rabson krb5_config_parse_string_multi(krb5_context context, 286c19800e8SDoug Rabson const char *string, 287c19800e8SDoug Rabson krb5_config_section **res) 288c19800e8SDoug Rabson { 289c19800e8SDoug Rabson const char *str; 290c19800e8SDoug Rabson unsigned lineno = 0; 291c19800e8SDoug Rabson krb5_error_code ret; 292c19800e8SDoug Rabson struct fileptr f; 293c19800e8SDoug Rabson f.f = NULL; 294c19800e8SDoug Rabson f.s = string; 295c19800e8SDoug Rabson 296c19800e8SDoug Rabson ret = krb5_config_parse_debug (&f, res, &lineno, &str); 297c19800e8SDoug Rabson if (ret) { 298c19800e8SDoug Rabson krb5_set_error_string (context, "%s:%u: %s", "<constant>", lineno, str); 299c19800e8SDoug Rabson return ret; 300c19800e8SDoug Rabson } 301c19800e8SDoug Rabson return 0; 302c19800e8SDoug Rabson } 303c19800e8SDoug Rabson 304c19800e8SDoug Rabson krb5_error_code KRB5_LIB_FUNCTION 3058373020dSJacques Vidrine krb5_config_parse_file_multi (krb5_context context, 306adb0ddaeSAssar Westerlund const char *fname, 307adb0ddaeSAssar Westerlund krb5_config_section **res) 308b528cefcSMark Murray { 3098373020dSJacques Vidrine const char *str; 310c19800e8SDoug Rabson unsigned lineno = 0; 311adb0ddaeSAssar Westerlund krb5_error_code ret; 312c19800e8SDoug Rabson struct fileptr f; 313c19800e8SDoug Rabson f.f = fopen(fname, "r"); 314c19800e8SDoug Rabson f.s = NULL; 315c19800e8SDoug Rabson if(f.f == NULL) { 316c19800e8SDoug Rabson ret = errno; 317c19800e8SDoug Rabson krb5_set_error_string (context, "open %s: %s", fname, strerror(ret)); 318c19800e8SDoug Rabson return ret; 319c19800e8SDoug Rabson } 320b528cefcSMark Murray 321c19800e8SDoug Rabson ret = krb5_config_parse_debug (&f, res, &lineno, &str); 322c19800e8SDoug Rabson fclose(f.f); 323adb0ddaeSAssar Westerlund if (ret) { 324adb0ddaeSAssar Westerlund krb5_set_error_string (context, "%s:%u: %s", fname, lineno, str); 325adb0ddaeSAssar Westerlund return ret; 326adb0ddaeSAssar Westerlund } 327adb0ddaeSAssar Westerlund return 0; 328b528cefcSMark Murray } 329b528cefcSMark Murray 330c19800e8SDoug Rabson krb5_error_code KRB5_LIB_FUNCTION 3318373020dSJacques Vidrine krb5_config_parse_file (krb5_context context, 3328373020dSJacques Vidrine const char *fname, 3338373020dSJacques Vidrine krb5_config_section **res) 3348373020dSJacques Vidrine { 3358373020dSJacques Vidrine *res = NULL; 3368373020dSJacques Vidrine return krb5_config_parse_file_multi(context, fname, res); 3378373020dSJacques Vidrine } 3388373020dSJacques Vidrine 339b528cefcSMark Murray #endif /* !HAVE_NETINFO */ 340b528cefcSMark Murray 341b528cefcSMark Murray static void 342b528cefcSMark Murray free_binding (krb5_context context, krb5_config_binding *b) 343b528cefcSMark Murray { 344b528cefcSMark Murray krb5_config_binding *next_b; 345b528cefcSMark Murray 346b528cefcSMark Murray while (b) { 347b528cefcSMark Murray free (b->name); 348b528cefcSMark Murray if (b->type == krb5_config_string) 349b528cefcSMark Murray free (b->u.string); 350b528cefcSMark Murray else if (b->type == krb5_config_list) 351b528cefcSMark Murray free_binding (context, b->u.list); 352b528cefcSMark Murray else 353b528cefcSMark Murray krb5_abortx(context, "unknown binding type (%d) in free_binding", 354b528cefcSMark Murray b->type); 355b528cefcSMark Murray next_b = b->next; 356b528cefcSMark Murray free (b); 357b528cefcSMark Murray b = next_b; 358b528cefcSMark Murray } 359b528cefcSMark Murray } 360b528cefcSMark Murray 361c19800e8SDoug Rabson krb5_error_code KRB5_LIB_FUNCTION 362b528cefcSMark Murray krb5_config_file_free (krb5_context context, krb5_config_section *s) 363b528cefcSMark Murray { 364b528cefcSMark Murray free_binding (context, s); 365b528cefcSMark Murray return 0; 366b528cefcSMark Murray } 367b528cefcSMark Murray 368b528cefcSMark Murray const void * 369b528cefcSMark Murray krb5_config_get_next (krb5_context context, 3708373020dSJacques Vidrine const krb5_config_section *c, 3718373020dSJacques Vidrine const krb5_config_binding **pointer, 372b528cefcSMark Murray int type, 373b528cefcSMark Murray ...) 374b528cefcSMark Murray { 375b528cefcSMark Murray const char *ret; 376b528cefcSMark Murray va_list args; 377b528cefcSMark Murray 378b528cefcSMark Murray va_start(args, type); 379b528cefcSMark Murray ret = krb5_config_vget_next (context, c, pointer, type, args); 380b528cefcSMark Murray va_end(args); 381b528cefcSMark Murray return ret; 382b528cefcSMark Murray } 383b528cefcSMark Murray 3848373020dSJacques Vidrine static const void * 3858373020dSJacques Vidrine vget_next(krb5_context context, 3868373020dSJacques Vidrine const krb5_config_binding *b, 3878373020dSJacques Vidrine const krb5_config_binding **pointer, 3888373020dSJacques Vidrine int type, 3898373020dSJacques Vidrine const char *name, 3908373020dSJacques Vidrine va_list args) 3918373020dSJacques Vidrine { 3928373020dSJacques Vidrine const char *p = va_arg(args, const char *); 3938373020dSJacques Vidrine while(b != NULL) { 3940cadf2f4SJacques Vidrine if(strcmp(b->name, name) == 0) { 3958373020dSJacques Vidrine if(b->type == type && p == NULL) { 3968373020dSJacques Vidrine *pointer = b; 3978373020dSJacques Vidrine return b->u.generic; 3988373020dSJacques Vidrine } else if(b->type == krb5_config_list && p != NULL) { 3998373020dSJacques Vidrine return vget_next(context, b->u.list, pointer, type, p, args); 4008373020dSJacques Vidrine } 4018373020dSJacques Vidrine } 4028373020dSJacques Vidrine b = b->next; 4038373020dSJacques Vidrine } 4048373020dSJacques Vidrine return NULL; 4058373020dSJacques Vidrine } 4068373020dSJacques Vidrine 407b528cefcSMark Murray const void * 408b528cefcSMark Murray krb5_config_vget_next (krb5_context context, 4098373020dSJacques Vidrine const krb5_config_section *c, 4108373020dSJacques Vidrine const krb5_config_binding **pointer, 411b528cefcSMark Murray int type, 412b528cefcSMark Murray va_list args) 413b528cefcSMark Murray { 4148373020dSJacques Vidrine const krb5_config_binding *b; 415b528cefcSMark Murray const char *p; 416b528cefcSMark Murray 417b528cefcSMark Murray if(c == NULL) 418b528cefcSMark Murray c = context->cf; 419b528cefcSMark Murray 420b528cefcSMark Murray if (c == NULL) 421b528cefcSMark Murray return NULL; 422b528cefcSMark Murray 423b528cefcSMark Murray if (*pointer == NULL) { 4248373020dSJacques Vidrine /* first time here, walk down the tree looking for the right 4258373020dSJacques Vidrine section */ 426b528cefcSMark Murray p = va_arg(args, const char *); 427b528cefcSMark Murray if (p == NULL) 428b528cefcSMark Murray return NULL; 4298373020dSJacques Vidrine return vget_next(context, c, pointer, type, p, args); 430b528cefcSMark Murray } 431b528cefcSMark Murray 4328373020dSJacques Vidrine /* we were called again, so just look for more entries with the 4338373020dSJacques Vidrine same name and type */ 4348373020dSJacques Vidrine for (b = (*pointer)->next; b != NULL; b = b->next) { 4358373020dSJacques Vidrine if(strcmp(b->name, (*pointer)->name) == 0 && b->type == type) { 436b528cefcSMark Murray *pointer = b; 437b528cefcSMark Murray return b->u.generic; 438b528cefcSMark Murray } 439b528cefcSMark Murray } 440b528cefcSMark Murray return NULL; 441b528cefcSMark Murray } 442b528cefcSMark Murray 443b528cefcSMark Murray const void * 444b528cefcSMark Murray krb5_config_get (krb5_context context, 4458373020dSJacques Vidrine const krb5_config_section *c, 446b528cefcSMark Murray int type, 447b528cefcSMark Murray ...) 448b528cefcSMark Murray { 449b528cefcSMark Murray const void *ret; 450b528cefcSMark Murray va_list args; 451b528cefcSMark Murray 452b528cefcSMark Murray va_start(args, type); 453b528cefcSMark Murray ret = krb5_config_vget (context, c, type, args); 454b528cefcSMark Murray va_end(args); 455b528cefcSMark Murray return ret; 456b528cefcSMark Murray } 457b528cefcSMark Murray 458b528cefcSMark Murray const void * 459b528cefcSMark Murray krb5_config_vget (krb5_context context, 4608373020dSJacques Vidrine const krb5_config_section *c, 461b528cefcSMark Murray int type, 462b528cefcSMark Murray va_list args) 463b528cefcSMark Murray { 4648373020dSJacques Vidrine const krb5_config_binding *foo = NULL; 465b528cefcSMark Murray 466b528cefcSMark Murray return krb5_config_vget_next (context, c, &foo, type, args); 467b528cefcSMark Murray } 468b528cefcSMark Murray 469b528cefcSMark Murray const krb5_config_binding * 470b528cefcSMark Murray krb5_config_get_list (krb5_context context, 4718373020dSJacques Vidrine const krb5_config_section *c, 472b528cefcSMark Murray ...) 473b528cefcSMark Murray { 474b528cefcSMark Murray const krb5_config_binding *ret; 475b528cefcSMark Murray va_list args; 476b528cefcSMark Murray 477b528cefcSMark Murray va_start(args, c); 478b528cefcSMark Murray ret = krb5_config_vget_list (context, c, args); 479b528cefcSMark Murray va_end(args); 480b528cefcSMark Murray return ret; 481b528cefcSMark Murray } 482b528cefcSMark Murray 483b528cefcSMark Murray const krb5_config_binding * 484b528cefcSMark Murray krb5_config_vget_list (krb5_context context, 4858373020dSJacques Vidrine const krb5_config_section *c, 486b528cefcSMark Murray va_list args) 487b528cefcSMark Murray { 488b528cefcSMark Murray return krb5_config_vget (context, c, krb5_config_list, args); 489b528cefcSMark Murray } 490b528cefcSMark Murray 491c19800e8SDoug Rabson const char* KRB5_LIB_FUNCTION 492b528cefcSMark Murray krb5_config_get_string (krb5_context context, 4938373020dSJacques Vidrine const krb5_config_section *c, 494b528cefcSMark Murray ...) 495b528cefcSMark Murray { 496b528cefcSMark Murray const char *ret; 497b528cefcSMark Murray va_list args; 498b528cefcSMark Murray 499b528cefcSMark Murray va_start(args, c); 500b528cefcSMark Murray ret = krb5_config_vget_string (context, c, args); 501b528cefcSMark Murray va_end(args); 502b528cefcSMark Murray return ret; 503b528cefcSMark Murray } 504b528cefcSMark Murray 505c19800e8SDoug Rabson const char* KRB5_LIB_FUNCTION 506b528cefcSMark Murray krb5_config_vget_string (krb5_context context, 5078373020dSJacques Vidrine const krb5_config_section *c, 508b528cefcSMark Murray va_list args) 509b528cefcSMark Murray { 510b528cefcSMark Murray return krb5_config_vget (context, c, krb5_config_string, args); 511b528cefcSMark Murray } 512b528cefcSMark Murray 513c19800e8SDoug Rabson const char* KRB5_LIB_FUNCTION 5145e9cd1aeSAssar Westerlund krb5_config_vget_string_default (krb5_context context, 5158373020dSJacques Vidrine const krb5_config_section *c, 5165e9cd1aeSAssar Westerlund const char *def_value, 5175e9cd1aeSAssar Westerlund va_list args) 5185e9cd1aeSAssar Westerlund { 5195e9cd1aeSAssar Westerlund const char *ret; 5205e9cd1aeSAssar Westerlund 5215e9cd1aeSAssar Westerlund ret = krb5_config_vget_string (context, c, args); 5225e9cd1aeSAssar Westerlund if (ret == NULL) 5235e9cd1aeSAssar Westerlund ret = def_value; 5245e9cd1aeSAssar Westerlund return ret; 5255e9cd1aeSAssar Westerlund } 5265e9cd1aeSAssar Westerlund 527c19800e8SDoug Rabson const char* KRB5_LIB_FUNCTION 5285e9cd1aeSAssar Westerlund krb5_config_get_string_default (krb5_context context, 5298373020dSJacques Vidrine const krb5_config_section *c, 5305e9cd1aeSAssar Westerlund const char *def_value, 5315e9cd1aeSAssar Westerlund ...) 5325e9cd1aeSAssar Westerlund { 5335e9cd1aeSAssar Westerlund const char *ret; 5345e9cd1aeSAssar Westerlund va_list args; 5355e9cd1aeSAssar Westerlund 5365e9cd1aeSAssar Westerlund va_start(args, def_value); 5375e9cd1aeSAssar Westerlund ret = krb5_config_vget_string_default (context, c, def_value, args); 5385e9cd1aeSAssar Westerlund va_end(args); 5395e9cd1aeSAssar Westerlund return ret; 5405e9cd1aeSAssar Westerlund } 5415e9cd1aeSAssar Westerlund 542c19800e8SDoug Rabson char ** KRB5_LIB_FUNCTION 543b528cefcSMark Murray krb5_config_vget_strings(krb5_context context, 5448373020dSJacques Vidrine const krb5_config_section *c, 545b528cefcSMark Murray va_list args) 546b528cefcSMark Murray { 547b528cefcSMark Murray char **strings = NULL; 548b528cefcSMark Murray int nstr = 0; 5498373020dSJacques Vidrine const krb5_config_binding *b = NULL; 550b528cefcSMark Murray const char *p; 551b528cefcSMark Murray 552b528cefcSMark Murray while((p = krb5_config_vget_next(context, c, &b, 553b528cefcSMark Murray krb5_config_string, args))) { 554b528cefcSMark Murray char *tmp = strdup(p); 555b528cefcSMark Murray char *pos = NULL; 556b528cefcSMark Murray char *s; 557b528cefcSMark Murray if(tmp == NULL) 558b528cefcSMark Murray goto cleanup; 559b528cefcSMark Murray s = strtok_r(tmp, " \t", &pos); 560b528cefcSMark Murray while(s){ 561c19800e8SDoug Rabson char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings)); 562c19800e8SDoug Rabson if(tmp2 == NULL) 563b528cefcSMark Murray goto cleanup; 564c19800e8SDoug Rabson strings = tmp2; 565b528cefcSMark Murray strings[nstr] = strdup(s); 566b528cefcSMark Murray nstr++; 567b528cefcSMark Murray if(strings[nstr-1] == NULL) 568b528cefcSMark Murray goto cleanup; 569b528cefcSMark Murray s = strtok_r(NULL, " \t", &pos); 570b528cefcSMark Murray } 571b528cefcSMark Murray free(tmp); 572b528cefcSMark Murray } 573b528cefcSMark Murray if(nstr){ 574b528cefcSMark Murray char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings)); 575c19800e8SDoug Rabson if(tmp == NULL) 576b528cefcSMark Murray goto cleanup; 577b528cefcSMark Murray strings = tmp; 578b528cefcSMark Murray strings[nstr] = NULL; 579b528cefcSMark Murray } 580b528cefcSMark Murray return strings; 581b528cefcSMark Murray cleanup: 582b528cefcSMark Murray while(nstr--) 583b528cefcSMark Murray free(strings[nstr]); 584b528cefcSMark Murray free(strings); 585b528cefcSMark Murray return NULL; 586b528cefcSMark Murray 587b528cefcSMark Murray } 588b528cefcSMark Murray 589b528cefcSMark Murray char** 590b528cefcSMark Murray krb5_config_get_strings(krb5_context context, 5918373020dSJacques Vidrine const krb5_config_section *c, 592b528cefcSMark Murray ...) 593b528cefcSMark Murray { 594b528cefcSMark Murray va_list ap; 595b528cefcSMark Murray char **ret; 596b528cefcSMark Murray va_start(ap, c); 597b528cefcSMark Murray ret = krb5_config_vget_strings(context, c, ap); 598b528cefcSMark Murray va_end(ap); 599b528cefcSMark Murray return ret; 600b528cefcSMark Murray } 601b528cefcSMark Murray 602c19800e8SDoug Rabson void KRB5_LIB_FUNCTION 603b528cefcSMark Murray krb5_config_free_strings(char **strings) 604b528cefcSMark Murray { 605b528cefcSMark Murray char **s = strings; 606b528cefcSMark Murray while(s && *s){ 607b528cefcSMark Murray free(*s); 608b528cefcSMark Murray s++; 609b528cefcSMark Murray } 610b528cefcSMark Murray free(strings); 611b528cefcSMark Murray } 612b528cefcSMark Murray 613c19800e8SDoug Rabson krb5_boolean KRB5_LIB_FUNCTION 614b528cefcSMark Murray krb5_config_vget_bool_default (krb5_context context, 6158373020dSJacques Vidrine const krb5_config_section *c, 616b528cefcSMark Murray krb5_boolean def_value, 617b528cefcSMark Murray va_list args) 618b528cefcSMark Murray { 619b528cefcSMark Murray const char *str; 620b528cefcSMark Murray str = krb5_config_vget_string (context, c, args); 621b528cefcSMark Murray if(str == NULL) 622b528cefcSMark Murray return def_value; 623b528cefcSMark Murray if(strcasecmp(str, "yes") == 0 || 624b528cefcSMark Murray strcasecmp(str, "true") == 0 || 625b528cefcSMark Murray atoi(str)) return TRUE; 626b528cefcSMark Murray return FALSE; 627b528cefcSMark Murray } 628b528cefcSMark Murray 629c19800e8SDoug Rabson krb5_boolean KRB5_LIB_FUNCTION 630b528cefcSMark Murray krb5_config_vget_bool (krb5_context context, 6318373020dSJacques Vidrine const krb5_config_section *c, 632b528cefcSMark Murray va_list args) 633b528cefcSMark Murray { 634b528cefcSMark Murray return krb5_config_vget_bool_default (context, c, FALSE, args); 635b528cefcSMark Murray } 636b528cefcSMark Murray 637c19800e8SDoug Rabson krb5_boolean KRB5_LIB_FUNCTION 638b528cefcSMark Murray krb5_config_get_bool_default (krb5_context context, 6398373020dSJacques Vidrine const krb5_config_section *c, 640b528cefcSMark Murray krb5_boolean def_value, 641b528cefcSMark Murray ...) 642b528cefcSMark Murray { 643b528cefcSMark Murray va_list ap; 644b528cefcSMark Murray krb5_boolean ret; 645b528cefcSMark Murray va_start(ap, def_value); 646b528cefcSMark Murray ret = krb5_config_vget_bool_default(context, c, def_value, ap); 647b528cefcSMark Murray va_end(ap); 648b528cefcSMark Murray return ret; 649b528cefcSMark Murray } 650b528cefcSMark Murray 651c19800e8SDoug Rabson krb5_boolean KRB5_LIB_FUNCTION 652b528cefcSMark Murray krb5_config_get_bool (krb5_context context, 6538373020dSJacques Vidrine const krb5_config_section *c, 654b528cefcSMark Murray ...) 655b528cefcSMark Murray { 656b528cefcSMark Murray va_list ap; 657b528cefcSMark Murray krb5_boolean ret; 658b528cefcSMark Murray va_start(ap, c); 659b528cefcSMark Murray ret = krb5_config_vget_bool (context, c, ap); 660b528cefcSMark Murray va_end(ap); 661b528cefcSMark Murray return ret; 662b528cefcSMark Murray } 663b528cefcSMark Murray 664c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 665b528cefcSMark Murray krb5_config_vget_time_default (krb5_context context, 6668373020dSJacques Vidrine const krb5_config_section *c, 667b528cefcSMark Murray int def_value, 668b528cefcSMark Murray va_list args) 669b528cefcSMark Murray { 670b528cefcSMark Murray const char *str; 671c19800e8SDoug Rabson krb5_deltat t; 672c19800e8SDoug Rabson 673b528cefcSMark Murray str = krb5_config_vget_string (context, c, args); 674b528cefcSMark Murray if(str == NULL) 675b528cefcSMark Murray return def_value; 676c19800e8SDoug Rabson if (krb5_string_to_deltat(str, &t)) 677c19800e8SDoug Rabson return def_value; 678c19800e8SDoug Rabson return t; 679b528cefcSMark Murray } 680b528cefcSMark Murray 681c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 682b528cefcSMark Murray krb5_config_vget_time (krb5_context context, 6838373020dSJacques Vidrine const krb5_config_section *c, 684b528cefcSMark Murray va_list args) 685b528cefcSMark Murray { 686b528cefcSMark Murray return krb5_config_vget_time_default (context, c, -1, args); 687b528cefcSMark Murray } 688b528cefcSMark Murray 689c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 690b528cefcSMark Murray krb5_config_get_time_default (krb5_context context, 6918373020dSJacques Vidrine const krb5_config_section *c, 692b528cefcSMark Murray int def_value, 693b528cefcSMark Murray ...) 694b528cefcSMark Murray { 695b528cefcSMark Murray va_list ap; 696b528cefcSMark Murray int ret; 697b528cefcSMark Murray va_start(ap, def_value); 698b528cefcSMark Murray ret = krb5_config_vget_time_default(context, c, def_value, ap); 699b528cefcSMark Murray va_end(ap); 700b528cefcSMark Murray return ret; 701b528cefcSMark Murray } 702b528cefcSMark Murray 703c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 704b528cefcSMark Murray krb5_config_get_time (krb5_context context, 7058373020dSJacques Vidrine const krb5_config_section *c, 706b528cefcSMark Murray ...) 707b528cefcSMark Murray { 708b528cefcSMark Murray va_list ap; 709b528cefcSMark Murray int ret; 710b528cefcSMark Murray va_start(ap, c); 711b528cefcSMark Murray ret = krb5_config_vget_time (context, c, ap); 712b528cefcSMark Murray va_end(ap); 713b528cefcSMark Murray return ret; 714b528cefcSMark Murray } 715b528cefcSMark Murray 716b528cefcSMark Murray 717c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 718b528cefcSMark Murray krb5_config_vget_int_default (krb5_context context, 7198373020dSJacques Vidrine const krb5_config_section *c, 720b528cefcSMark Murray int def_value, 721b528cefcSMark Murray va_list args) 722b528cefcSMark Murray { 723b528cefcSMark Murray const char *str; 724b528cefcSMark Murray str = krb5_config_vget_string (context, c, args); 725b528cefcSMark Murray if(str == NULL) 726b528cefcSMark Murray return def_value; 727b528cefcSMark Murray else { 728b528cefcSMark Murray char *endptr; 729b528cefcSMark Murray long l; 730b528cefcSMark Murray l = strtol(str, &endptr, 0); 731b528cefcSMark Murray if (endptr == str) 732b528cefcSMark Murray return def_value; 733b528cefcSMark Murray else 734b528cefcSMark Murray return l; 735b528cefcSMark Murray } 736b528cefcSMark Murray } 737b528cefcSMark Murray 738c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 739b528cefcSMark Murray krb5_config_vget_int (krb5_context context, 7408373020dSJacques Vidrine const krb5_config_section *c, 741b528cefcSMark Murray va_list args) 742b528cefcSMark Murray { 743b528cefcSMark Murray return krb5_config_vget_int_default (context, c, -1, args); 744b528cefcSMark Murray } 745b528cefcSMark Murray 746c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 747b528cefcSMark Murray krb5_config_get_int_default (krb5_context context, 7488373020dSJacques Vidrine const krb5_config_section *c, 749b528cefcSMark Murray int def_value, 750b528cefcSMark Murray ...) 751b528cefcSMark Murray { 752b528cefcSMark Murray va_list ap; 753b528cefcSMark Murray int ret; 754b528cefcSMark Murray va_start(ap, def_value); 755b528cefcSMark Murray ret = krb5_config_vget_int_default(context, c, def_value, ap); 756b528cefcSMark Murray va_end(ap); 757b528cefcSMark Murray return ret; 758b528cefcSMark Murray } 759b528cefcSMark Murray 760c19800e8SDoug Rabson int KRB5_LIB_FUNCTION 761b528cefcSMark Murray krb5_config_get_int (krb5_context context, 7628373020dSJacques Vidrine const krb5_config_section *c, 763b528cefcSMark Murray ...) 764b528cefcSMark Murray { 765b528cefcSMark Murray va_list ap; 766b528cefcSMark Murray int ret; 767b528cefcSMark Murray va_start(ap, c); 768b528cefcSMark Murray ret = krb5_config_vget_int (context, c, ap); 769b528cefcSMark Murray va_end(ap); 770b528cefcSMark Murray return ret; 771b528cefcSMark Murray } 772