155682Smarkm/* 2233294Sstas * Copyright (c) 1999 - 2005 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682Smarkm#include <getarg.h> 3690926Snectar#include <parse_bytes.h> 3790926Snectar#include <err.h> 3855682Smarkm 3955682Smarkm/* verify krb5.conf */ 4055682Smarkm 41102644Snectarstatic int dumpconfig_flag = 0; 4255682Smarkmstatic int version_flag = 0; 4355682Smarkmstatic int help_flag = 0; 44178825Sdfrstatic int warn_mit_syntax_flag = 0; 4555682Smarkm 4655682Smarkmstatic struct getargs args[] = { 47233294Sstas {"dumpconfig", 0, arg_flag, &dumpconfig_flag, 48102644Snectar "show the parsed config files", NULL }, 49233294Sstas {"warn-mit-syntax", 0, arg_flag, &warn_mit_syntax_flag, 50178825Sdfr "show the parsed config files", NULL }, 5155682Smarkm {"version", 0, arg_flag, &version_flag, 5255682Smarkm "print version", NULL }, 5355682Smarkm {"help", 0, arg_flag, &help_flag, 5455682Smarkm NULL, NULL } 5555682Smarkm}; 5655682Smarkm 5755682Smarkmstatic void 5855682Smarkmusage (int ret) 5955682Smarkm{ 6055682Smarkm arg_printusage (args, 6155682Smarkm sizeof(args)/sizeof(*args), 6255682Smarkm NULL, 6355682Smarkm "[config-file]"); 6455682Smarkm exit (ret); 6555682Smarkm} 6655682Smarkm 6790926Snectarstatic int 6890926Snectarcheck_bytes(krb5_context context, const char *path, char *data) 6990926Snectar{ 7090926Snectar if(parse_bytes(data, NULL) == -1) { 7190926Snectar krb5_warnx(context, "%s: failed to parse \"%s\" as size", path, data); 7290926Snectar return 1; 7390926Snectar } 7490926Snectar return 0; 7590926Snectar} 7690926Snectar 7790926Snectarstatic int 7890926Snectarcheck_time(krb5_context context, const char *path, char *data) 7990926Snectar{ 8090926Snectar if(parse_time(data, NULL) == -1) { 8190926Snectar krb5_warnx(context, "%s: failed to parse \"%s\" as time", path, data); 8290926Snectar return 1; 8390926Snectar } 8490926Snectar return 0; 8590926Snectar} 8690926Snectar 8790926Snectarstatic int 8890926Snectarcheck_numeric(krb5_context context, const char *path, char *data) 8990926Snectar{ 90233294Sstas long v; 9190926Snectar char *end; 9290926Snectar v = strtol(data, &end, 0); 93233294Sstas 94233294Sstas if ((v == LONG_MIN || v == LONG_MAX) && errno != 0) { 95233294Sstas krb5_warnx(context, "%s: over/under flow for \"%s\"", 96233294Sstas path, data); 97233294Sstas return 1; 98233294Sstas } 9990926Snectar if(*end != '\0') { 100233294Sstas krb5_warnx(context, "%s: failed to parse \"%s\" as a number", 10190926Snectar path, data); 10290926Snectar return 1; 10390926Snectar } 10490926Snectar return 0; 10590926Snectar} 10690926Snectar 10790926Snectarstatic int 10890926Snectarcheck_boolean(krb5_context context, const char *path, char *data) 10990926Snectar{ 11090926Snectar long int v; 11190926Snectar char *end; 11290926Snectar if(strcasecmp(data, "yes") == 0 || 11390926Snectar strcasecmp(data, "true") == 0 || 11490926Snectar strcasecmp(data, "no") == 0 || 11590926Snectar strcasecmp(data, "false") == 0) 11690926Snectar return 0; 11790926Snectar v = strtol(data, &end, 0); 11890926Snectar if(*end != '\0') { 119233294Sstas krb5_warnx(context, "%s: failed to parse \"%s\" as a boolean", 12090926Snectar path, data); 12190926Snectar return 1; 12290926Snectar } 123102644Snectar if(v != 0 && v != 1) 124233294Sstas krb5_warnx(context, "%s: numeric value \"%s\" is treated as \"true\"", 125102644Snectar path, data); 12690926Snectar return 0; 12790926Snectar} 12890926Snectar 12990926Snectarstatic int 130120945Snectarcheck_524(krb5_context context, const char *path, char *data) 131120945Snectar{ 132120945Snectar if(strcasecmp(data, "yes") == 0 || 133120945Snectar strcasecmp(data, "no") == 0 || 134120945Snectar strcasecmp(data, "2b") == 0 || 135120945Snectar strcasecmp(data, "local") == 0) 136120945Snectar return 0; 137120945Snectar 138233294Sstas krb5_warnx(context, "%s: didn't contain a valid option `%s'", 139120945Snectar path, data); 140120945Snectar return 1; 141120945Snectar} 142120945Snectar 143120945Snectarstatic int 14490926Snectarcheck_host(krb5_context context, const char *path, char *data) 14590926Snectar{ 14690926Snectar int ret; 14790926Snectar char hostname[128]; 14890926Snectar const char *p = data; 149178825Sdfr struct addrinfo hints; 150178825Sdfr char service[32]; 151178825Sdfr int defport; 15290926Snectar struct addrinfo *ai; 153178825Sdfr 154178825Sdfr hints.ai_flags = 0; 155178825Sdfr hints.ai_family = PF_UNSPEC; 156178825Sdfr hints.ai_socktype = 0; 157178825Sdfr hints.ai_protocol = 0; 158178825Sdfr 159178825Sdfr hints.ai_addrlen = 0; 160178825Sdfr hints.ai_canonname = NULL; 161178825Sdfr hints.ai_addr = NULL; 162178825Sdfr hints.ai_next = NULL; 163233294Sstas 16490926Snectar /* XXX data could be a list of hosts that this code can't handle */ 16590926Snectar /* XXX copied from krbhst.c */ 16690926Snectar if(strncmp(p, "http://", 7) == 0){ 16790926Snectar p += 7; 168178825Sdfr hints.ai_socktype = SOCK_STREAM; 169178825Sdfr strlcpy(service, "http", sizeof(service)); 170178825Sdfr defport = 80; 17190926Snectar } else if(strncmp(p, "http/", 5) == 0) { 17290926Snectar p += 5; 173178825Sdfr hints.ai_socktype = SOCK_STREAM; 174178825Sdfr strlcpy(service, "http", sizeof(service)); 175178825Sdfr defport = 80; 17690926Snectar }else if(strncmp(p, "tcp/", 4) == 0){ 17790926Snectar p += 4; 178178825Sdfr hints.ai_socktype = SOCK_STREAM; 179178825Sdfr strlcpy(service, "kerberos", sizeof(service)); 180178825Sdfr defport = 88; 18190926Snectar } else if(strncmp(p, "udp/", 4) == 0) { 18290926Snectar p += 4; 183178825Sdfr hints.ai_socktype = SOCK_DGRAM; 184178825Sdfr strlcpy(service, "kerberos", sizeof(service)); 185178825Sdfr defport = 88; 186178825Sdfr } else { 187178825Sdfr hints.ai_socktype = SOCK_DGRAM; 188178825Sdfr strlcpy(service, "kerberos", sizeof(service)); 189178825Sdfr defport = 88; 19090926Snectar } 19190926Snectar if(strsep_copy(&p, ":", hostname, sizeof(hostname)) < 0) { 19290926Snectar return 1; 19390926Snectar } 19490926Snectar hostname[strcspn(hostname, "/")] = '\0'; 195178825Sdfr if(p != NULL) { 196178825Sdfr char *end; 197178825Sdfr int tmp = strtol(p, &end, 0); 198178825Sdfr if(end == p) { 199233294Sstas krb5_warnx(context, "%s: failed to parse port number in %s", 200178825Sdfr path, data); 201178825Sdfr return 1; 202178825Sdfr } 203178825Sdfr defport = tmp; 204178825Sdfr snprintf(service, sizeof(service), "%u", defport); 205178825Sdfr } 206178825Sdfr ret = getaddrinfo(hostname, service, &hints, &ai); 207178825Sdfr if(ret == EAI_SERVICE && !isdigit((unsigned char)service[0])) { 208178825Sdfr snprintf(service, sizeof(service), "%u", defport); 209178825Sdfr ret = getaddrinfo(hostname, service, &hints, &ai); 210178825Sdfr } 21190926Snectar if(ret != 0) { 212127808Snectar krb5_warnx(context, "%s: %s (%s)", path, gai_strerror(ret), hostname); 21390926Snectar return 1; 21490926Snectar } 21590926Snectar return 0; 21690926Snectar} 21790926Snectar 218102644Snectarstatic int 219102644Snectarmit_entry(krb5_context context, const char *path, char *data) 220102644Snectar{ 221178825Sdfr if (warn_mit_syntax_flag) 222178825Sdfr krb5_warnx(context, "%s is only used by MIT Kerberos", path); 223102644Snectar return 0; 224102644Snectar} 225102644Snectar 226102644Snectarstruct s2i { 227178825Sdfr const char *s; 228102644Snectar int val; 229102644Snectar}; 230102644Snectar 231102644Snectar#define L(X) { #X, LOG_ ## X } 232102644Snectar 233102644Snectarstatic struct s2i syslogvals[] = { 234120945Snectar /* severity */ 235102644Snectar L(EMERG), 236102644Snectar L(ALERT), 237102644Snectar L(CRIT), 238102644Snectar L(ERR), 239102644Snectar L(WARNING), 240102644Snectar L(NOTICE), 241102644Snectar L(INFO), 242102644Snectar L(DEBUG), 243120945Snectar /* facility */ 244102644Snectar L(AUTH), 245102644Snectar#ifdef LOG_AUTHPRIV 246102644Snectar L(AUTHPRIV), 247102644Snectar#endif 248102644Snectar#ifdef LOG_CRON 249102644Snectar L(CRON), 250102644Snectar#endif 251102644Snectar L(DAEMON), 252102644Snectar#ifdef LOG_FTP 253102644Snectar L(FTP), 254102644Snectar#endif 255102644Snectar L(KERN), 256102644Snectar L(LPR), 257102644Snectar L(MAIL), 258102644Snectar#ifdef LOG_NEWS 259102644Snectar L(NEWS), 260102644Snectar#endif 261102644Snectar L(SYSLOG), 262102644Snectar L(USER), 263102644Snectar#ifdef LOG_UUCP 264102644Snectar L(UUCP), 265102644Snectar#endif 266102644Snectar L(LOCAL0), 267102644Snectar L(LOCAL1), 268102644Snectar L(LOCAL2), 269102644Snectar L(LOCAL3), 270102644Snectar L(LOCAL4), 271102644Snectar L(LOCAL5), 272102644Snectar L(LOCAL6), 273102644Snectar L(LOCAL7), 274102644Snectar { NULL, -1 } 275102644Snectar}; 276102644Snectar 277102644Snectarstatic int 278102644Snectarfind_value(const char *s, struct s2i *table) 279102644Snectar{ 280102644Snectar while(table->s && strcasecmp(table->s, s)) 281102644Snectar table++; 282102644Snectar return table->val; 283102644Snectar} 284102644Snectar 285102644Snectarstatic int 286102644Snectarcheck_log(krb5_context context, const char *path, char *data) 287102644Snectar{ 288102644Snectar /* XXX sync with log.c */ 289102644Snectar int min = 0, max = -1, n; 290102644Snectar char c; 291102644Snectar const char *p = data; 292102644Snectar 293102644Snectar n = sscanf(p, "%d%c%d/", &min, &c, &max); 294102644Snectar if(n == 2){ 295102644Snectar if(c == '/') { 296102644Snectar if(min < 0){ 297102644Snectar max = -min; 298102644Snectar min = 0; 299102644Snectar }else{ 300102644Snectar max = min; 301102644Snectar } 302102644Snectar } 303102644Snectar } 304102644Snectar if(n){ 305102644Snectar p = strchr(p, '/'); 306102644Snectar if(p == NULL) { 307102644Snectar krb5_warnx(context, "%s: failed to parse \"%s\"", path, data); 308102644Snectar return 1; 309102644Snectar } 310102644Snectar p++; 311102644Snectar } 312233294Sstas if(strcmp(p, "STDERR") == 0 || 313102644Snectar strcmp(p, "CONSOLE") == 0 || 314102644Snectar (strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')) || 315102644Snectar (strncmp(p, "DEVICE", 6) == 0 && p[6] == '=')) 316102644Snectar return 0; 317102644Snectar if(strncmp(p, "SYSLOG", 6) == 0){ 318102644Snectar int ret = 0; 319102644Snectar char severity[128] = ""; 320102644Snectar char facility[128] = ""; 321102644Snectar p += 6; 322102644Snectar if(*p != '\0') 323102644Snectar p++; 324102644Snectar if(strsep_copy(&p, ":", severity, sizeof(severity)) != -1) 325102644Snectar strsep_copy(&p, ":", facility, sizeof(facility)); 326102644Snectar if(*severity == '\0') 327102644Snectar strlcpy(severity, "ERR", sizeof(severity)); 328102644Snectar if(*facility == '\0') 329102644Snectar strlcpy(facility, "AUTH", sizeof(facility)); 330120945Snectar if(find_value(severity, syslogvals) == -1) { 331233294Sstas krb5_warnx(context, "%s: unknown syslog facility \"%s\"", 332102644Snectar path, facility); 333102644Snectar ret++; 334102644Snectar } 335120945Snectar if(find_value(severity, syslogvals) == -1) { 336233294Sstas krb5_warnx(context, "%s: unknown syslog severity \"%s\"", 337102644Snectar path, severity); 338102644Snectar ret++; 339102644Snectar } 340102644Snectar return ret; 341102644Snectar }else{ 342102644Snectar krb5_warnx(context, "%s: unknown log type: \"%s\"", path, data); 343102644Snectar return 1; 344102644Snectar } 345102644Snectar} 346102644Snectar 34790926Snectartypedef int (*check_func_t)(krb5_context, const char*, char*); 34890926Snectarstruct entry { 34990926Snectar const char *name; 35090926Snectar int type; 35190926Snectar void *check_data; 352233294Sstas int deprecated; 35390926Snectar}; 35490926Snectar 35590926Snectarstruct entry all_strings[] = { 35690926Snectar { "", krb5_config_string, NULL }, 35790926Snectar { NULL } 35890926Snectar}; 35990926Snectar 360178825Sdfrstruct entry all_boolean[] = { 361178825Sdfr { "", krb5_config_string, check_boolean }, 362178825Sdfr { NULL } 363178825Sdfr}; 364178825Sdfr 365178825Sdfr 36690926Snectarstruct entry v4_name_convert_entries[] = { 36790926Snectar { "host", krb5_config_list, all_strings }, 36890926Snectar { "plain", krb5_config_list, all_strings }, 36990926Snectar { NULL } 37090926Snectar}; 37190926Snectar 37290926Snectarstruct entry libdefaults_entries[] = { 37390926Snectar { "accept_null_addresses", krb5_config_string, check_boolean }, 374233294Sstas { "allow_weak_crypto", krb5_config_string, check_boolean }, 375233294Sstas { "capath", krb5_config_list, all_strings, 1 }, 376178825Sdfr { "check_pac", krb5_config_string, check_boolean }, 37790926Snectar { "clockskew", krb5_config_string, check_time }, 37890926Snectar { "date_format", krb5_config_string, NULL }, 379178825Sdfr { "default_cc_name", krb5_config_string, NULL }, 38090926Snectar { "default_etypes", krb5_config_string, NULL }, 38190926Snectar { "default_etypes_des", krb5_config_string, NULL }, 38290926Snectar { "default_keytab_modify_name", krb5_config_string, NULL }, 38390926Snectar { "default_keytab_name", krb5_config_string, NULL }, 38490926Snectar { "default_realm", krb5_config_string, NULL }, 385178825Sdfr { "dns_canonize_hostname", krb5_config_string, check_boolean }, 38690926Snectar { "dns_proxy", krb5_config_string, NULL }, 387102644Snectar { "dns_lookup_kdc", krb5_config_string, check_boolean }, 388102644Snectar { "dns_lookup_realm", krb5_config_string, check_boolean }, 389102644Snectar { "dns_lookup_realm_labels", krb5_config_string, NULL }, 39090926Snectar { "egd_socket", krb5_config_string, NULL }, 39190926Snectar { "encrypt", krb5_config_string, check_boolean }, 39290926Snectar { "extra_addresses", krb5_config_string, NULL }, 39390926Snectar { "fcache_version", krb5_config_string, check_numeric }, 394178825Sdfr { "fcc-mit-ticketflags", krb5_config_string, check_boolean }, 39590926Snectar { "forward", krb5_config_string, check_boolean }, 39690926Snectar { "forwardable", krb5_config_string, check_boolean }, 39790926Snectar { "http_proxy", krb5_config_string, check_host /* XXX */ }, 39890926Snectar { "ignore_addresses", krb5_config_string, NULL }, 39990926Snectar { "kdc_timeout", krb5_config_string, check_time }, 40090926Snectar { "kdc_timesync", krb5_config_string, check_boolean }, 40190926Snectar { "log_utc", krb5_config_string, check_boolean }, 40290926Snectar { "maxretries", krb5_config_string, check_numeric }, 40390926Snectar { "scan_interfaces", krb5_config_string, check_boolean }, 40490926Snectar { "srv_lookup", krb5_config_string, check_boolean }, 405233294Sstas { "srv_try_txt", krb5_config_string, check_boolean }, 40690926Snectar { "ticket_lifetime", krb5_config_string, check_time }, 40790926Snectar { "time_format", krb5_config_string, NULL }, 40890926Snectar { "transited_realms_reject", krb5_config_string, NULL }, 409178825Sdfr { "no-addresses", krb5_config_string, check_boolean }, 41090926Snectar { "v4_instance_resolve", krb5_config_string, check_boolean }, 41190926Snectar { "v4_name_convert", krb5_config_list, v4_name_convert_entries }, 41290926Snectar { "verify_ap_req_nofail", krb5_config_string, check_boolean }, 413178825Sdfr { "max_retries", krb5_config_string, check_time }, 414178825Sdfr { "renew_lifetime", krb5_config_string, check_time }, 415178825Sdfr { "proxiable", krb5_config_string, check_boolean }, 416178825Sdfr { "warn_pwexpire", krb5_config_string, check_time }, 417178825Sdfr /* MIT stuff */ 418178825Sdfr { "permitted_enctypes", krb5_config_string, mit_entry }, 419178825Sdfr { "default_tgs_enctypes", krb5_config_string, mit_entry }, 420178825Sdfr { "default_tkt_enctypes", krb5_config_string, mit_entry }, 42190926Snectar { NULL } 42290926Snectar}; 42390926Snectar 42490926Snectarstruct entry appdefaults_entries[] = { 425120945Snectar { "afslog", krb5_config_string, check_boolean }, 426120945Snectar { "afs-use-524", krb5_config_string, check_524 }, 427178825Sdfr { "encrypt", krb5_config_string, check_boolean }, 428178825Sdfr { "forward", krb5_config_string, check_boolean }, 42990926Snectar { "forwardable", krb5_config_string, check_boolean }, 43090926Snectar { "proxiable", krb5_config_string, check_boolean }, 43190926Snectar { "ticket_lifetime", krb5_config_string, check_time }, 43290926Snectar { "renew_lifetime", krb5_config_string, check_time }, 43390926Snectar { "no-addresses", krb5_config_string, check_boolean }, 434102644Snectar { "krb4_get_tickets", krb5_config_string, check_boolean }, 435178825Sdfr { "pkinit_anchors", krb5_config_string, NULL }, 436178825Sdfr { "pkinit_win2k", krb5_config_string, NULL }, 437178825Sdfr { "pkinit_win2k_require_binding", krb5_config_string, NULL }, 438178825Sdfr { "pkinit_require_eku", krb5_config_string, NULL }, 439178825Sdfr { "pkinit_require_krbtgt_otherName", krb5_config_string, NULL }, 440178825Sdfr { "pkinit_require_hostname_match", krb5_config_string, NULL }, 44190926Snectar#if 0 44290926Snectar { "anonymous", krb5_config_string, check_boolean }, 44390926Snectar#endif 44490926Snectar { "", krb5_config_list, appdefaults_entries }, 44590926Snectar { NULL } 44690926Snectar}; 44790926Snectar 44890926Snectarstruct entry realms_entries[] = { 44990926Snectar { "forwardable", krb5_config_string, check_boolean }, 45090926Snectar { "proxiable", krb5_config_string, check_boolean }, 45190926Snectar { "ticket_lifetime", krb5_config_string, check_time }, 45290926Snectar { "renew_lifetime", krb5_config_string, check_time }, 45390926Snectar { "warn_pwexpire", krb5_config_string, check_time }, 45490926Snectar { "kdc", krb5_config_string, check_host }, 45590926Snectar { "admin_server", krb5_config_string, check_host }, 45690926Snectar { "kpasswd_server", krb5_config_string, check_host }, 45790926Snectar { "krb524_server", krb5_config_string, check_host }, 45890926Snectar { "v4_name_convert", krb5_config_list, v4_name_convert_entries }, 45990926Snectar { "v4_instance_convert", krb5_config_list, all_strings }, 46090926Snectar { "v4_domains", krb5_config_string, NULL }, 46190926Snectar { "default_domain", krb5_config_string, NULL }, 462178825Sdfr { "win2k_pkinit", krb5_config_string, NULL }, 463102644Snectar /* MIT stuff */ 464102644Snectar { "admin_keytab", krb5_config_string, mit_entry }, 465102644Snectar { "acl_file", krb5_config_string, mit_entry }, 466102644Snectar { "dict_file", krb5_config_string, mit_entry }, 467102644Snectar { "kadmind_port", krb5_config_string, mit_entry }, 468102644Snectar { "kpasswd_port", krb5_config_string, mit_entry }, 469102644Snectar { "master_key_name", krb5_config_string, mit_entry }, 470102644Snectar { "master_key_type", krb5_config_string, mit_entry }, 471102644Snectar { "key_stash_file", krb5_config_string, mit_entry }, 472102644Snectar { "max_life", krb5_config_string, mit_entry }, 473102644Snectar { "max_renewable_life", krb5_config_string, mit_entry }, 474102644Snectar { "default_principal_expiration", krb5_config_string, mit_entry }, 475102644Snectar { "default_principal_flags", krb5_config_string, mit_entry }, 476102644Snectar { "supported_enctypes", krb5_config_string, mit_entry }, 477102644Snectar { "database_name", krb5_config_string, mit_entry }, 47890926Snectar { NULL } 47990926Snectar}; 48090926Snectar 48190926Snectarstruct entry realms_foobar[] = { 48290926Snectar { "", krb5_config_list, realms_entries }, 48390926Snectar { NULL } 48490926Snectar}; 48590926Snectar 48690926Snectar 48790926Snectarstruct entry kdc_database_entries[] = { 48890926Snectar { "realm", krb5_config_string, NULL }, 48990926Snectar { "dbname", krb5_config_string, NULL }, 49090926Snectar { "mkey_file", krb5_config_string, NULL }, 491178825Sdfr { "acl_file", krb5_config_string, NULL }, 492178825Sdfr { "log_file", krb5_config_string, NULL }, 49390926Snectar { NULL } 49490926Snectar}; 49590926Snectar 49690926Snectarstruct entry kdc_entries[] = { 49790926Snectar { "database", krb5_config_list, kdc_database_entries }, 49890926Snectar { "key-file", krb5_config_string, NULL }, 499102644Snectar { "logging", krb5_config_string, check_log }, 50090926Snectar { "max-request", krb5_config_string, check_bytes }, 50190926Snectar { "require-preauth", krb5_config_string, check_boolean }, 50290926Snectar { "ports", krb5_config_string, NULL }, 50390926Snectar { "addresses", krb5_config_string, NULL }, 50490926Snectar { "enable-kerberos4", krb5_config_string, check_boolean }, 50590926Snectar { "enable-524", krb5_config_string, check_boolean }, 50690926Snectar { "enable-http", krb5_config_string, check_boolean }, 507178825Sdfr { "check-ticket-addresses", krb5_config_string, check_boolean }, 508178825Sdfr { "allow-null-ticket-addresses", krb5_config_string, check_boolean }, 50990926Snectar { "allow-anonymous", krb5_config_string, check_boolean }, 51090926Snectar { "v4_realm", krb5_config_string, NULL }, 511234027Sstas { "enable-kaserver", krb5_config_string, check_boolean, 1 }, 51290926Snectar { "encode_as_rep_as_tgs_rep", krb5_config_string, check_boolean }, 51390926Snectar { "kdc_warn_pwexpire", krb5_config_string, check_time }, 514178825Sdfr { "use_2b", krb5_config_list, NULL }, 515178825Sdfr { "enable-pkinit", krb5_config_string, check_boolean }, 516178825Sdfr { "pkinit_identity", krb5_config_string, NULL }, 517178825Sdfr { "pkinit_anchors", krb5_config_string, NULL }, 518178825Sdfr { "pkinit_pool", krb5_config_string, NULL }, 519178825Sdfr { "pkinit_revoke", krb5_config_string, NULL }, 520178825Sdfr { "pkinit_kdc_ocsp", krb5_config_string, NULL }, 521178825Sdfr { "pkinit_principal_in_certificate", krb5_config_string, NULL }, 522178825Sdfr { "pkinit_dh_min_bits", krb5_config_string, NULL }, 523178825Sdfr { "pkinit_allow_proxy_certificate", krb5_config_string, NULL }, 524178825Sdfr { "hdb-ldap-create-base", krb5_config_string, NULL }, 525178825Sdfr { "v4-realm", krb5_config_string, NULL }, 52690926Snectar { NULL } 52790926Snectar}; 52890926Snectar 52990926Snectarstruct entry kadmin_entries[] = { 53090926Snectar { "password_lifetime", krb5_config_string, check_time }, 53190926Snectar { "default_keys", krb5_config_string, NULL }, 53290926Snectar { "use_v4_salt", krb5_config_string, NULL }, 533178825Sdfr { "require-preauth", krb5_config_string, check_boolean }, 53490926Snectar { NULL } 53590926Snectar}; 536102644Snectarstruct entry log_strings[] = { 537102644Snectar { "", krb5_config_string, check_log }, 538102644Snectar { NULL } 539102644Snectar}; 540102644Snectar 541102644Snectar 542178825Sdfr/* MIT stuff */ 543102644Snectarstruct entry kdcdefaults_entries[] = { 544120952Snectar { "kdc_ports", krb5_config_string, mit_entry }, 545120952Snectar { "v4_mode", krb5_config_string, mit_entry }, 546102644Snectar { NULL } 547102644Snectar}; 548102644Snectar 549178825Sdfrstruct entry capaths_entries[] = { 550178825Sdfr { "", krb5_config_list, all_strings }, 551178825Sdfr { NULL } 552178825Sdfr}; 553178825Sdfr 554178825Sdfrstruct entry password_quality_entries[] = { 555178825Sdfr { "policies", krb5_config_string, NULL }, 556178825Sdfr { "external_program", krb5_config_string, NULL }, 557178825Sdfr { "min_classes", krb5_config_string, check_numeric }, 558178825Sdfr { "min_length", krb5_config_string, check_numeric }, 559178825Sdfr { "", krb5_config_list, all_strings }, 560178825Sdfr { NULL } 561178825Sdfr}; 562178825Sdfr 56390926Snectarstruct entry toplevel_sections[] = { 56490926Snectar { "libdefaults" , krb5_config_list, libdefaults_entries }, 56590926Snectar { "realms", krb5_config_list, realms_foobar }, 56690926Snectar { "domain_realm", krb5_config_list, all_strings }, 567102644Snectar { "logging", krb5_config_list, log_strings }, 56890926Snectar { "kdc", krb5_config_list, kdc_entries }, 56990926Snectar { "kadmin", krb5_config_list, kadmin_entries }, 57090926Snectar { "appdefaults", krb5_config_list, appdefaults_entries }, 571178825Sdfr { "gssapi", krb5_config_list, NULL }, 572178825Sdfr { "capaths", krb5_config_list, capaths_entries }, 573178825Sdfr { "password_quality", krb5_config_list, password_quality_entries }, 574102644Snectar /* MIT stuff */ 575102644Snectar { "kdcdefaults", krb5_config_list, kdcdefaults_entries }, 57690926Snectar { NULL } 57790926Snectar}; 57890926Snectar 57990926Snectar 58090926Snectarstatic int 581233294Sstascheck_section(krb5_context context, const char *path, krb5_config_section *cf, 58290926Snectar struct entry *entries) 58390926Snectar{ 58490926Snectar int error = 0; 58590926Snectar krb5_config_section *p; 58690926Snectar struct entry *e; 587233294Sstas 58890926Snectar char *local; 589233294Sstas 59090926Snectar for(p = cf; p != NULL; p = p->next) { 591233294Sstas local = NULL; 592233294Sstas if (asprintf(&local, "%s/%s", path, p->name) < 0 || local == NULL) 593233294Sstas errx(1, "out of memory"); 59490926Snectar for(e = entries; e->name != NULL; e++) { 59590926Snectar if(*e->name == '\0' || strcmp(e->name, p->name) == 0) { 59690926Snectar if(e->type != p->type) { 59790926Snectar krb5_warnx(context, "%s: unknown or wrong type", local); 59890926Snectar error |= 1; 59990926Snectar } else if(p->type == krb5_config_string && e->check_data != NULL) { 60090926Snectar error |= (*(check_func_t)e->check_data)(context, local, p->u.string); 60190926Snectar } else if(p->type == krb5_config_list && e->check_data != NULL) { 60290926Snectar error |= check_section(context, local, p->u.list, e->check_data); 60390926Snectar } 604233294Sstas if(e->deprecated) { 605233294Sstas krb5_warnx(context, "%s: is a deprecated entry", local); 606233294Sstas error |= 1; 607233294Sstas } 60890926Snectar break; 60990926Snectar } 61090926Snectar } 61190926Snectar if(e->name == NULL) { 61290926Snectar krb5_warnx(context, "%s: unknown entry", local); 61390926Snectar error |= 1; 61490926Snectar } 61590926Snectar free(local); 61690926Snectar } 61790926Snectar return error; 61890926Snectar} 61990926Snectar 62090926Snectar 621102644Snectarstatic void 622102644Snectardumpconfig(int level, krb5_config_section *top) 623102644Snectar{ 624102644Snectar krb5_config_section *x; 625102644Snectar for(x = top; x; x = x->next) { 626102644Snectar switch(x->type) { 627102644Snectar case krb5_config_list: 628102644Snectar if(level == 0) { 629102644Snectar printf("[%s]\n", x->name); 630102644Snectar } else { 631102644Snectar printf("%*s%s = {\n", 4 * level, " ", x->name); 632102644Snectar } 633102644Snectar dumpconfig(level + 1, x->u.list); 634102644Snectar if(level > 0) 635102644Snectar printf("%*s}\n", 4 * level, " "); 636102644Snectar break; 637102644Snectar case krb5_config_string: 638102644Snectar printf("%*s%s = %s\n", 4 * level, " ", x->name, x->u.string); 639102644Snectar break; 640102644Snectar } 641102644Snectar } 642102644Snectar} 643102644Snectar 64455682Smarkmint 64555682Smarkmmain(int argc, char **argv) 64655682Smarkm{ 64778527Sassar krb5_context context; 64855682Smarkm krb5_error_code ret; 64955682Smarkm krb5_config_section *tmp_cf; 650178825Sdfr int optidx = 0; 65155682Smarkm 65278527Sassar setprogname (argv[0]); 65355682Smarkm 65478527Sassar ret = krb5_init_context(&context); 655178825Sdfr if (ret == KRB5_CONFIG_BADFORMAT) 656178825Sdfr errx (1, "krb5_init_context failed to parse configuration file"); 657178825Sdfr else if (ret) 658178825Sdfr errx (1, "krb5_init_context failed with %d", ret); 65978527Sassar 660178825Sdfr if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 66155682Smarkm usage(1); 662233294Sstas 66355682Smarkm if (help_flag) 66455682Smarkm usage (0); 66555682Smarkm 66655682Smarkm if(version_flag){ 66755682Smarkm print_version(NULL); 66855682Smarkm exit(0); 66955682Smarkm } 67055682Smarkm 671178825Sdfr argc -= optidx; 672178825Sdfr argv += optidx; 67355682Smarkm 674102644Snectar tmp_cf = NULL; 675102644Snectar if(argc == 0) 676102644Snectar krb5_get_default_config_files(&argv); 677102644Snectar 678102644Snectar while(*argv) { 679102644Snectar ret = krb5_config_parse_file_multi(context, *argv, &tmp_cf); 680102644Snectar if (ret != 0) 681102644Snectar krb5_warn (context, ret, "krb5_config_parse_file"); 682102644Snectar argv++; 68355682Smarkm } 684102644Snectar 685102644Snectar if(dumpconfig_flag) 686102644Snectar dumpconfig(0, tmp_cf); 687233294Sstas 68890926Snectar return check_section(context, "", tmp_cf, toplevel_sections); 68955682Smarkm} 690