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