1 1.1 elric /* $NetBSD: verify_krb5_conf.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 1999 - 2005 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "krb5_locl.h" 37 1.1 elric #include <krb5/getarg.h> 38 1.1 elric #include <krb5/parse_bytes.h> 39 1.1 elric #include <err.h> 40 1.1 elric 41 1.1 elric /* verify krb5.conf */ 42 1.1 elric 43 1.1 elric static int dumpconfig_flag = 0; 44 1.1 elric static int version_flag = 0; 45 1.1 elric static int help_flag = 0; 46 1.1 elric static int warn_mit_syntax_flag = 0; 47 1.1 elric 48 1.1 elric static struct getargs args[] = { 49 1.1 elric {"dumpconfig", 0, arg_flag, &dumpconfig_flag, 50 1.1 elric "show the parsed config files", NULL }, 51 1.1 elric {"warn-mit-syntax", 0, arg_flag, &warn_mit_syntax_flag, 52 1.1 elric "show the parsed config files", NULL }, 53 1.1 elric {"version", 0, arg_flag, &version_flag, 54 1.1 elric "print version", NULL }, 55 1.1 elric {"help", 0, arg_flag, &help_flag, 56 1.1 elric NULL, NULL } 57 1.1 elric }; 58 1.1 elric 59 1.1 elric static void 60 1.1 elric usage (int ret) 61 1.1 elric { 62 1.1 elric arg_printusage (args, 63 1.1 elric sizeof(args)/sizeof(*args), 64 1.1 elric NULL, 65 1.1 elric "[config-file]"); 66 1.1 elric exit (ret); 67 1.1 elric } 68 1.1 elric 69 1.1 elric static int 70 1.1 elric check_bytes(krb5_context context, const char *path, char *data) 71 1.1 elric { 72 1.1 elric if(parse_bytes(data, NULL) == -1) { 73 1.1 elric krb5_warnx(context, "%s: failed to parse \"%s\" as size", path, data); 74 1.1 elric return 1; 75 1.1 elric } 76 1.1 elric return 0; 77 1.1 elric } 78 1.1 elric 79 1.1 elric static int 80 1.1 elric check_time(krb5_context context, const char *path, char *data) 81 1.1 elric { 82 1.1 elric if(parse_time(data, NULL) == -1) { 83 1.1 elric krb5_warnx(context, "%s: failed to parse \"%s\" as time", path, data); 84 1.1 elric return 1; 85 1.1 elric } 86 1.1 elric return 0; 87 1.1 elric } 88 1.1 elric 89 1.1 elric static int 90 1.1 elric check_numeric(krb5_context context, const char *path, char *data) 91 1.1 elric { 92 1.1 elric long v; 93 1.1 elric char *end; 94 1.1 elric v = strtol(data, &end, 0); 95 1.1 elric 96 1.1 elric if ((v == LONG_MIN || v == LONG_MAX) && errno != 0) { 97 1.1 elric krb5_warnx(context, "%s: over/under flow for \"%s\"", 98 1.1 elric path, data); 99 1.1 elric return 1; 100 1.1 elric } 101 1.1 elric if(*end != '\0') { 102 1.1 elric krb5_warnx(context, "%s: failed to parse \"%s\" as a number", 103 1.1 elric path, data); 104 1.1 elric return 1; 105 1.1 elric } 106 1.1 elric return 0; 107 1.1 elric } 108 1.1 elric 109 1.1 elric static int 110 1.1 elric check_boolean(krb5_context context, const char *path, char *data) 111 1.1 elric { 112 1.1 elric long int v; 113 1.1 elric char *end; 114 1.1 elric if(strcasecmp(data, "yes") == 0 || 115 1.1 elric strcasecmp(data, "true") == 0 || 116 1.1 elric strcasecmp(data, "no") == 0 || 117 1.1 elric strcasecmp(data, "false") == 0) 118 1.1 elric return 0; 119 1.1 elric v = strtol(data, &end, 0); 120 1.1 elric if(*end != '\0') { 121 1.1 elric krb5_warnx(context, "%s: failed to parse \"%s\" as a boolean", 122 1.1 elric path, data); 123 1.1 elric return 1; 124 1.1 elric } 125 1.1 elric if(v != 0 && v != 1) 126 1.1 elric krb5_warnx(context, "%s: numeric value \"%s\" is treated as \"true\"", 127 1.1 elric path, data); 128 1.1 elric return 0; 129 1.1 elric } 130 1.1 elric 131 1.1 elric static int 132 1.1 elric check_524(krb5_context context, const char *path, char *data) 133 1.1 elric { 134 1.1 elric if(strcasecmp(data, "yes") == 0 || 135 1.1 elric strcasecmp(data, "no") == 0 || 136 1.1 elric strcasecmp(data, "2b") == 0 || 137 1.1 elric strcasecmp(data, "local") == 0) 138 1.1 elric return 0; 139 1.1 elric 140 1.1 elric krb5_warnx(context, "%s: didn't contain a valid option `%s'", 141 1.1 elric path, data); 142 1.1 elric return 1; 143 1.1 elric } 144 1.1 elric 145 1.1 elric static int 146 1.1 elric check_host(krb5_context context, const char *path, char *data) 147 1.1 elric { 148 1.1 elric int ret; 149 1.1 elric char hostname[128]; 150 1.1 elric const char *p = data; 151 1.1 elric struct addrinfo hints; 152 1.1 elric char service[32]; 153 1.1 elric int defport; 154 1.1 elric struct addrinfo *ai; 155 1.1 elric 156 1.1 elric hints.ai_flags = 0; 157 1.1 elric hints.ai_family = PF_UNSPEC; 158 1.1 elric hints.ai_socktype = 0; 159 1.1 elric hints.ai_protocol = 0; 160 1.1 elric 161 1.1 elric hints.ai_addrlen = 0; 162 1.1 elric hints.ai_canonname = NULL; 163 1.1 elric hints.ai_addr = NULL; 164 1.1 elric hints.ai_next = NULL; 165 1.1 elric 166 1.1 elric /* XXX data could be a list of hosts that this code can't handle */ 167 1.1 elric /* XXX copied from krbhst.c */ 168 1.2 christos if (strncmp(p, "http://", 7) == 0){ 169 1.1 elric p += 7; 170 1.1 elric hints.ai_socktype = SOCK_STREAM; 171 1.1 elric strlcpy(service, "http", sizeof(service)); 172 1.1 elric defport = 80; 173 1.2 christos } else if (strncmp(p, "http/", 5) == 0) { 174 1.1 elric p += 5; 175 1.1 elric hints.ai_socktype = SOCK_STREAM; 176 1.1 elric strlcpy(service, "http", sizeof(service)); 177 1.1 elric defport = 80; 178 1.2 christos } else if (strncmp(p, "tcp/", 4) == 0){ 179 1.1 elric p += 4; 180 1.1 elric hints.ai_socktype = SOCK_STREAM; 181 1.1 elric strlcpy(service, "kerberos", sizeof(service)); 182 1.1 elric defport = 88; 183 1.2 christos } else if (strncmp(p, "udp/", 4) == 0) { 184 1.1 elric p += 4; 185 1.1 elric hints.ai_socktype = SOCK_DGRAM; 186 1.1 elric strlcpy(service, "kerberos", sizeof(service)); 187 1.1 elric defport = 88; 188 1.1 elric } else { 189 1.1 elric hints.ai_socktype = SOCK_DGRAM; 190 1.1 elric strlcpy(service, "kerberos", sizeof(service)); 191 1.1 elric defport = 88; 192 1.1 elric } 193 1.2 christos if (strsep_copy(&p, ":", hostname, sizeof(hostname)) < 0) { 194 1.1 elric return 1; 195 1.1 elric } 196 1.1 elric hostname[strcspn(hostname, "/")] = '\0'; 197 1.2 christos if (p != NULL) { 198 1.1 elric char *end; 199 1.1 elric int tmp = strtol(p, &end, 0); 200 1.2 christos if (end == p) { 201 1.1 elric krb5_warnx(context, "%s: failed to parse port number in %s", 202 1.1 elric path, data); 203 1.1 elric return 1; 204 1.1 elric } 205 1.1 elric defport = tmp; 206 1.1 elric snprintf(service, sizeof(service), "%u", defport); 207 1.1 elric } 208 1.1 elric ret = getaddrinfo(hostname, service, &hints, &ai); 209 1.2 christos if (ret == EAI_SERVICE && !isdigit((unsigned char)service[0])) { 210 1.1 elric snprintf(service, sizeof(service), "%u", defport); 211 1.1 elric ret = getaddrinfo(hostname, service, &hints, &ai); 212 1.1 elric } 213 1.2 christos if (ret != 0) { 214 1.1 elric krb5_warnx(context, "%s: %s (%s)", path, gai_strerror(ret), hostname); 215 1.1 elric return 1; 216 1.1 elric } 217 1.2 christos freeaddrinfo(ai); 218 1.1 elric return 0; 219 1.1 elric } 220 1.1 elric 221 1.1 elric static int 222 1.1 elric mit_entry(krb5_context context, const char *path, char *data) 223 1.1 elric { 224 1.1 elric if (warn_mit_syntax_flag) 225 1.1 elric krb5_warnx(context, "%s is only used by MIT Kerberos", path); 226 1.1 elric return 0; 227 1.1 elric } 228 1.1 elric 229 1.1 elric struct s2i { 230 1.1 elric const char *s; 231 1.1 elric int val; 232 1.1 elric }; 233 1.1 elric 234 1.1 elric #define L(X) { #X, LOG_ ## X } 235 1.1 elric 236 1.1 elric static struct s2i syslogvals[] = { 237 1.1 elric /* severity */ 238 1.1 elric L(EMERG), 239 1.1 elric L(ALERT), 240 1.1 elric L(CRIT), 241 1.1 elric L(ERR), 242 1.1 elric L(WARNING), 243 1.1 elric L(NOTICE), 244 1.1 elric L(INFO), 245 1.1 elric L(DEBUG), 246 1.1 elric /* facility */ 247 1.1 elric L(AUTH), 248 1.1 elric #ifdef LOG_AUTHPRIV 249 1.1 elric L(AUTHPRIV), 250 1.1 elric #endif 251 1.1 elric #ifdef LOG_CRON 252 1.1 elric L(CRON), 253 1.1 elric #endif 254 1.1 elric L(DAEMON), 255 1.1 elric #ifdef LOG_FTP 256 1.1 elric L(FTP), 257 1.1 elric #endif 258 1.1 elric L(KERN), 259 1.1 elric L(LPR), 260 1.1 elric L(MAIL), 261 1.1 elric #ifdef LOG_NEWS 262 1.1 elric L(NEWS), 263 1.1 elric #endif 264 1.1 elric L(SYSLOG), 265 1.1 elric L(USER), 266 1.1 elric #ifdef LOG_UUCP 267 1.1 elric L(UUCP), 268 1.1 elric #endif 269 1.1 elric L(LOCAL0), 270 1.1 elric L(LOCAL1), 271 1.1 elric L(LOCAL2), 272 1.1 elric L(LOCAL3), 273 1.1 elric L(LOCAL4), 274 1.1 elric L(LOCAL5), 275 1.1 elric L(LOCAL6), 276 1.1 elric L(LOCAL7), 277 1.1 elric { NULL, -1 } 278 1.1 elric }; 279 1.1 elric 280 1.1 elric static int 281 1.1 elric find_value(const char *s, struct s2i *table) 282 1.1 elric { 283 1.1 elric while(table->s && strcasecmp(table->s, s)) 284 1.1 elric table++; 285 1.1 elric return table->val; 286 1.1 elric } 287 1.1 elric 288 1.1 elric static int 289 1.1 elric check_log(krb5_context context, const char *path, char *data) 290 1.1 elric { 291 1.1 elric /* XXX sync with log.c */ 292 1.1 elric int min = 0, max = -1, n; 293 1.1 elric char c; 294 1.1 elric const char *p = data; 295 1.2 christos #ifdef _WIN32 296 1.2 christos const char *q; 297 1.2 christos #endif 298 1.1 elric 299 1.1 elric n = sscanf(p, "%d%c%d/", &min, &c, &max); 300 1.1 elric if(n == 2){ 301 1.2 christos if(ISPATHSEP(c)) { 302 1.1 elric if(min < 0){ 303 1.1 elric max = -min; 304 1.1 elric min = 0; 305 1.1 elric }else{ 306 1.1 elric max = min; 307 1.1 elric } 308 1.1 elric } 309 1.1 elric } 310 1.1 elric if(n){ 311 1.2 christos #ifdef _WIN32 312 1.2 christos q = strrchr(p, '\\'); 313 1.2 christos if (q != NULL) 314 1.2 christos p = q; 315 1.2 christos else 316 1.2 christos #endif 317 1.1 elric p = strchr(p, '/'); 318 1.1 elric if(p == NULL) { 319 1.1 elric krb5_warnx(context, "%s: failed to parse \"%s\"", path, data); 320 1.1 elric return 1; 321 1.1 elric } 322 1.1 elric p++; 323 1.1 elric } 324 1.1 elric if(strcmp(p, "STDERR") == 0 || 325 1.1 elric strcmp(p, "CONSOLE") == 0 || 326 1.1 elric (strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')) || 327 1.1 elric (strncmp(p, "DEVICE", 6) == 0 && p[6] == '=')) 328 1.1 elric return 0; 329 1.1 elric if(strncmp(p, "SYSLOG", 6) == 0){ 330 1.1 elric int ret = 0; 331 1.1 elric char severity[128] = ""; 332 1.1 elric char facility[128] = ""; 333 1.1 elric p += 6; 334 1.1 elric if(*p != '\0') 335 1.1 elric p++; 336 1.1 elric if(strsep_copy(&p, ":", severity, sizeof(severity)) != -1) 337 1.1 elric strsep_copy(&p, ":", facility, sizeof(facility)); 338 1.1 elric if(*severity == '\0') 339 1.1 elric strlcpy(severity, "ERR", sizeof(severity)); 340 1.1 elric if(*facility == '\0') 341 1.1 elric strlcpy(facility, "AUTH", sizeof(facility)); 342 1.2 christos if(find_value(facility, syslogvals) == -1) { 343 1.1 elric krb5_warnx(context, "%s: unknown syslog facility \"%s\"", 344 1.1 elric path, facility); 345 1.1 elric ret++; 346 1.1 elric } 347 1.1 elric if(find_value(severity, syslogvals) == -1) { 348 1.1 elric krb5_warnx(context, "%s: unknown syslog severity \"%s\"", 349 1.1 elric path, severity); 350 1.1 elric ret++; 351 1.1 elric } 352 1.1 elric return ret; 353 1.1 elric }else{ 354 1.1 elric krb5_warnx(context, "%s: unknown log type: \"%s\"", path, data); 355 1.1 elric return 1; 356 1.1 elric } 357 1.1 elric } 358 1.1 elric 359 1.1 elric typedef int (*check_func_t)(krb5_context, const char*, char*); 360 1.1 elric struct entry { 361 1.1 elric const char *name; 362 1.1 elric int type; 363 1.1 elric void *check_data; 364 1.1 elric int deprecated; 365 1.1 elric }; 366 1.1 elric 367 1.1 elric struct entry all_strings[] = { 368 1.2 christos { "", krb5_config_string, NULL, 0 }, 369 1.2 christos { NULL, 0, NULL, 0 } 370 1.1 elric }; 371 1.1 elric 372 1.1 elric struct entry all_boolean[] = { 373 1.2 christos { "", krb5_config_string, check_boolean, 0 }, 374 1.2 christos { NULL, 0, NULL, 0 } 375 1.1 elric }; 376 1.1 elric 377 1.1 elric 378 1.1 elric struct entry v4_name_convert_entries[] = { 379 1.2 christos { "host", krb5_config_list, all_strings, 0 }, 380 1.2 christos { "plain", krb5_config_list, all_strings, 0 }, 381 1.2 christos { NULL, 0, NULL, 0 } 382 1.1 elric }; 383 1.1 elric 384 1.1 elric struct entry libdefaults_entries[] = { 385 1.2 christos { "accept_null_addresses", krb5_config_string, check_boolean, 0 }, 386 1.2 christos { "allow_weak_crypto", krb5_config_string, check_boolean, 0 }, 387 1.1 elric { "capath", krb5_config_list, all_strings, 1 }, 388 1.2 christos { "ccapi_library", krb5_config_string, NULL, 0 }, 389 1.2 christos { "check_pac", krb5_config_string, check_boolean, 0 }, 390 1.2 christos { "check-rd-req-server", krb5_config_string, check_boolean, 0 }, 391 1.2 christos { "clockskew", krb5_config_string, check_time, 0 }, 392 1.2 christos { "date_format", krb5_config_string, NULL, 0 }, 393 1.2 christos { "default_as_etypes", krb5_config_string, NULL, 0 }, 394 1.2 christos { "default_cc_name", krb5_config_string, NULL, 0 }, 395 1.2 christos { "default_cc_type", krb5_config_string, NULL, 0 }, 396 1.2 christos { "default_etypes", krb5_config_string, NULL, 0 }, 397 1.2 christos { "default_etypes_des", krb5_config_string, NULL, 0 }, 398 1.2 christos { "default_keytab_modify_name", krb5_config_string, NULL, 0 }, 399 1.2 christos { "default_keytab_name", krb5_config_string, NULL, 0 }, 400 1.2 christos { "default_keytab_modify_name", krb5_config_string, NULL, 0 }, 401 1.2 christos { "default_realm", krb5_config_string, NULL, 0 }, 402 1.2 christos { "default_tgs_etypes", krb5_config_string, NULL, 0 }, 403 1.2 christos { "dns_canonize_hostname", krb5_config_string, check_boolean, 0 }, 404 1.2 christos { "dns_proxy", krb5_config_string, NULL, 0 }, 405 1.2 christos { "dns_lookup_kdc", krb5_config_string, check_boolean, 0 }, 406 1.2 christos { "dns_lookup_realm", krb5_config_string, check_boolean, 0 }, 407 1.2 christos { "dns_lookup_realm_labels", krb5_config_string, NULL, 0 }, 408 1.2 christos { "egd_socket", krb5_config_string, NULL, 0 }, 409 1.2 christos { "encrypt", krb5_config_string, check_boolean, 0 }, 410 1.2 christos { "extra_addresses", krb5_config_string, NULL, 0 }, 411 1.2 christos { "fcache_version", krb5_config_string, check_numeric, 0 }, 412 1.2 christos { "fcache_strict_checking", krb5_config_string, check_boolean, 0 }, 413 1.2 christos { "fcc-mit-ticketflags", krb5_config_string, check_boolean, 0 }, 414 1.2 christos { "forward", krb5_config_string, check_boolean, 0 }, 415 1.2 christos { "forwardable", krb5_config_string, check_boolean, 0 }, 416 1.2 christos { "allow_hierarchical_capaths", krb5_config_string, check_boolean, 0 }, 417 1.2 christos { "host_timeout", krb5_config_string, check_time, 0 }, 418 1.2 christos { "http_proxy", krb5_config_string, check_host /* XXX */, 0 }, 419 1.2 christos { "ignore_addresses", krb5_config_string, NULL, 0 }, 420 1.2 christos { "k5login_authoritative", krb5_config_string, check_boolean, 0 }, 421 1.2 christos { "k5login_directory", krb5_config_string, NULL, 0 }, 422 1.2 christos { "kdc_timeout", krb5_config_string, check_time, 0 }, 423 1.2 christos { "kdc_timesync", krb5_config_string, check_boolean, 0 }, 424 1.2 christos { "kuserok", krb5_config_string, NULL, 0 }, 425 1.2 christos { "large_message_size", krb5_config_string, check_numeric, 0 }, 426 1.2 christos { "log_utc", krb5_config_string, check_boolean, 0 }, 427 1.2 christos { "max_retries", krb5_config_string, check_numeric, 0 }, 428 1.2 christos { "maximum_message_size", krb5_config_string, check_numeric, 0 }, 429 1.2 christos { "moduli", krb5_config_string, NULL, 0 }, 430 1.2 christos { "name_canon_rules", krb5_config_string, NULL, 0 }, 431 1.2 christos { "no-addresses", krb5_config_string, check_boolean, 0 }, 432 1.2 christos { "pkinit_dh_min_bits", krb5_config_string, NULL, 0 }, 433 1.2 christos { "proxiable", krb5_config_string, check_boolean, 0 }, 434 1.2 christos { "renew_lifetime", krb5_config_string, check_time, 0 }, 435 1.2 christos { "scan_interfaces", krb5_config_string, check_boolean, 0 }, 436 1.2 christos { "srv_lookup", krb5_config_string, check_boolean, 0 }, 437 1.2 christos { "srv_try_txt", krb5_config_string, check_boolean, 0 }, 438 1.2 christos { "ticket_lifetime", krb5_config_string, check_time, 0 }, 439 1.2 christos { "time_format", krb5_config_string, NULL, 0 }, 440 1.2 christos { "transited_realms_reject", krb5_config_string, NULL, 0 }, 441 1.2 christos { "use_fallback", krb5_config_string, check_boolean, 0 }, 442 1.2 christos { "v4_instance_resolve", krb5_config_string, check_boolean, 0 }, 443 1.2 christos { "v4_name_convert", krb5_config_list, v4_name_convert_entries, 0 }, 444 1.2 christos { "verify_ap_req_nofail", krb5_config_string, check_boolean, 0 }, 445 1.2 christos { "warn_pwexpire", krb5_config_string, check_time, 0 }, 446 1.2 christos 447 1.1 elric /* MIT stuff */ 448 1.2 christos { "permitted_enctypes", krb5_config_string, mit_entry, 0 }, 449 1.2 christos { "default_tgs_enctypes", krb5_config_string, mit_entry, 0 }, 450 1.2 christos { "default_tkt_enctypes", krb5_config_string, mit_entry, 0 }, 451 1.2 christos { NULL, 0, NULL, 0 } 452 1.1 elric }; 453 1.1 elric 454 1.1 elric struct entry appdefaults_entries[] = { 455 1.2 christos { "afslog", krb5_config_string, check_boolean, 0 }, 456 1.2 christos { "afs-use-524", krb5_config_string, check_524, 0 }, 457 1.1 elric #if 0 458 1.2 christos { "anonymous", krb5_config_string, check_boolean, 0 }, 459 1.1 elric #endif 460 1.2 christos { "encrypt", krb5_config_string, check_boolean, 0 }, 461 1.2 christos { "forward", krb5_config_string, check_boolean, 0 }, 462 1.2 christos { "forwardable", krb5_config_string, check_boolean, 0 }, 463 1.2 christos { "krb4_get_tickets", krb5_config_string, check_boolean, 0 }, 464 1.2 christos { "proxiable", krb5_config_string, check_boolean, 0 }, 465 1.2 christos { "renew_lifetime", krb5_config_string, check_time, 0 }, 466 1.2 christos { "no-addresses", krb5_config_string, check_boolean, 0 }, 467 1.2 christos { "pkinit_anchors", krb5_config_string, NULL, 0 }, 468 1.2 christos { "pkinit_pool", krb5_config_string, NULL, 0 }, 469 1.2 christos { "pkinit_require_eku", krb5_config_string, NULL, 0 }, 470 1.2 christos { "pkinit_require_hostname_match", krb5_config_string, NULL, 0 }, 471 1.2 christos { "pkinit_require_krbtgt_otherName", krb5_config_string, NULL, 0 }, 472 1.2 christos { "pkinit_revoke", krb5_config_string, NULL, 0 }, 473 1.2 christos { "pkinit_trustedCertifiers", krb5_config_string, check_boolean, 0 }, 474 1.2 christos { "pkinit_win2k", krb5_config_string, NULL, 0 }, 475 1.2 christos { "pkinit_win2k_require_binding", krb5_config_string, NULL, 0 }, 476 1.2 christos { "ticket_lifetime", krb5_config_string, check_time, 0 }, 477 1.2 christos { "", krb5_config_list, appdefaults_entries, 0 }, 478 1.2 christos { NULL, 0, NULL, 0 } 479 1.1 elric }; 480 1.1 elric 481 1.1 elric struct entry realms_entries[] = { 482 1.2 christos { "admin_server", krb5_config_string, check_host, 0 }, 483 1.2 christos { "auth_to_local", krb5_config_string, NULL, 0 }, 484 1.2 christos { "auth_to_local_names", krb5_config_string, NULL, 0 }, 485 1.2 christos { "default_domain", krb5_config_string, NULL, 0 }, 486 1.2 christos { "forwardable", krb5_config_string, check_boolean, 0 }, 487 1.2 christos { "allow_hierarchical_capaths", krb5_config_string, check_boolean, 0 }, 488 1.2 christos { "kdc", krb5_config_string, check_host, 0 }, 489 1.2 christos { "kpasswd_server", krb5_config_string, check_host, 0 }, 490 1.2 christos { "krb524_server", krb5_config_string, check_host, 0 }, 491 1.2 christos { "kx509_ca", krb5_config_string, NULL, 0 }, 492 1.2 christos { "kx509_include_pkinit_san", krb5_config_string, check_boolean, 0 }, 493 1.2 christos { "name_canon_rules", krb5_config_string, NULL, 0 }, 494 1.2 christos { "no-addresses", krb5_config_string, check_boolean, 0 }, 495 1.2 christos { "pkinit_anchors", krb5_config_string, NULL, 0 }, 496 1.2 christos { "pkinit_require_eku", krb5_config_string, NULL, 0 }, 497 1.2 christos { "pkinit_require_hostname_match", krb5_config_string, NULL, 0 }, 498 1.2 christos { "pkinit_require_krbtgt_otherName", krb5_config_string, NULL, 0 }, 499 1.2 christos { "pkinit_trustedCertifiers", krb5_config_string, check_boolean, 0 }, 500 1.2 christos { "pkinit_win2k", krb5_config_string, NULL, 0 }, 501 1.2 christos { "pkinit_win2k_require_binding", krb5_config_string, NULL, 0 }, 502 1.2 christos { "proxiable", krb5_config_string, check_boolean, 0 }, 503 1.2 christos { "renew_lifetime", krb5_config_string, check_time, 0 }, 504 1.2 christos { "require_initial_kca_tickets", krb5_config_string, check_boolean, 0 }, 505 1.2 christos { "ticket_lifetime", krb5_config_string, check_time, 0 }, 506 1.2 christos { "v4_domains", krb5_config_string, NULL, 0 }, 507 1.2 christos { "v4_instance_convert", krb5_config_list, all_strings, 0 }, 508 1.2 christos { "v4_name_convert", krb5_config_list, v4_name_convert_entries, 0 }, 509 1.2 christos { "warn_pwexpire", krb5_config_string, check_time, 0 }, 510 1.2 christos { "win2k_pkinit", krb5_config_string, NULL, 0 }, 511 1.2 christos 512 1.1 elric /* MIT stuff */ 513 1.2 christos { "admin_keytab", krb5_config_string, mit_entry, 0 }, 514 1.2 christos { "acl_file", krb5_config_string, mit_entry, 0 }, 515 1.2 christos { "database_name", krb5_config_string, mit_entry, 0 }, 516 1.2 christos { "default_principal_expiration", krb5_config_string, mit_entry, 0 }, 517 1.2 christos { "default_principal_flags", krb5_config_string, mit_entry, 0 }, 518 1.2 christos { "dict_file", krb5_config_string, mit_entry, 0 }, 519 1.2 christos { "kadmind_port", krb5_config_string, mit_entry, 0 }, 520 1.2 christos { "kpasswd_port", krb5_config_string, mit_entry, 0 }, 521 1.2 christos { "master_kdc", krb5_config_string, mit_entry, 0 }, 522 1.2 christos { "master_key_name", krb5_config_string, mit_entry, 0 }, 523 1.2 christos { "master_key_type", krb5_config_string, mit_entry, 0 }, 524 1.2 christos { "key_stash_file", krb5_config_string, mit_entry, 0 }, 525 1.2 christos { "max_life", krb5_config_string, mit_entry, 0 }, 526 1.2 christos { "max_renewable_life", krb5_config_string, mit_entry, 0 }, 527 1.2 christos { "supported_enctypes", krb5_config_string, mit_entry, 0 }, 528 1.2 christos { NULL, 0, NULL, 0 } 529 1.1 elric }; 530 1.1 elric 531 1.1 elric struct entry realms_foobar[] = { 532 1.2 christos { "", krb5_config_list, realms_entries, 0 }, 533 1.2 christos { NULL, 0, NULL, 0 } 534 1.1 elric }; 535 1.1 elric 536 1.1 elric 537 1.1 elric struct entry kdc_database_entries[] = { 538 1.2 christos { "acl_file", krb5_config_string, NULL, 0 }, 539 1.2 christos { "dbname", krb5_config_string, NULL, 0 }, 540 1.2 christos { "log_file", krb5_config_string, NULL, 0 }, 541 1.2 christos { "mkey_file", krb5_config_string, NULL, 0 }, 542 1.2 christos { "realm", krb5_config_string, NULL, 0 }, 543 1.2 christos { NULL, 0, NULL, 0 } 544 1.1 elric }; 545 1.1 elric 546 1.1 elric struct entry kdc_entries[] = { 547 1.2 christos { "addresses", krb5_config_string, NULL, 0 }, 548 1.2 christos { "allow-anonymous", krb5_config_string, check_boolean, 0 }, 549 1.2 christos { "allow-null-ticket-addresses", krb5_config_string, check_boolean, 0 }, 550 1.2 christos { "check-ticket-addresses", krb5_config_string, check_boolean, 0 }, 551 1.2 christos { "database", krb5_config_list, kdc_database_entries, 0 }, 552 1.2 christos { "detach", krb5_config_string, check_boolean, 0 }, 553 1.2 christos { "digests_allowed", krb5_config_string, NULL, 0 }, 554 1.2 christos { "disable-des", krb5_config_string, check_boolean, 0 }, 555 1.2 christos { "enable-524", krb5_config_string, check_boolean, 0 }, 556 1.2 christos { "enable-digest", krb5_config_string, check_boolean, 0 }, 557 1.2 christos { "enable-kaserver", krb5_config_string, check_boolean, 1 }, 558 1.2 christos { "enable-kerberos4", krb5_config_string, check_boolean, 1 }, 559 1.2 christos { "enable-kx509", krb5_config_string, check_boolean, 0 }, 560 1.2 christos { "enable-http", krb5_config_string, check_boolean, 0 }, 561 1.2 christos { "enable-pkinit", krb5_config_string, check_boolean, 0 }, 562 1.2 christos { "encode_as_rep_as_tgs_rep", krb5_config_string, check_boolean, 0 }, 563 1.2 christos { "enforce-transited-policy", krb5_config_string, NULL, 1 }, 564 1.2 christos { "hdb-ldap-create-base", krb5_config_string, NULL, 0 }, 565 1.2 christos { "iprop-acl", krb5_config_string, NULL, 0 }, 566 1.2 christos { "iprop-stats", krb5_config_string, NULL, 0 }, 567 1.2 christos { "kdc-request-log", krb5_config_string, NULL, 0 }, 568 1.2 christos { "kdc_warn_pwexpire", krb5_config_string, check_time, 0 }, 569 1.2 christos { "key-file", krb5_config_string, NULL, 0 }, 570 1.2 christos { "kx509_ca", krb5_config_string, NULL, 0 }, 571 1.2 christos { "kx509_include_pkinit_san", krb5_config_string, check_boolean, 0 }, 572 1.2 christos { "kx509_template", krb5_config_string, NULL, 0 }, 573 1.2 christos { "logging", krb5_config_string, check_log, 0 }, 574 1.2 christos { "max-kdc-datagram-reply-length", krb5_config_string, check_bytes, 0 }, 575 1.2 christos { "max-request", krb5_config_string, check_bytes, 0 }, 576 1.2 christos { "pkinit_allow_proxy_certificate", krb5_config_string, check_boolean, 0 }, 577 1.2 christos { "pkinit_anchors", krb5_config_string, NULL, 0 }, 578 1.2 christos { "pkinit_dh_min_bits", krb5_config_string, check_numeric, 0 }, 579 1.2 christos { "pkinit_identity", krb5_config_string, NULL, 0 }, 580 1.2 christos { "pkinit_kdc_friendly_name", krb5_config_string, NULL, 0 }, 581 1.2 christos { "pkinit_kdc_ocsp", krb5_config_string, NULL, 0 }, 582 1.2 christos { "pkinit_mappings_file", krb5_config_string, NULL, 0 }, 583 1.2 christos { "pkinit_pool", krb5_config_string, NULL, 0 }, 584 1.2 christos { "pkinit_principal_in_certificate", krb5_config_string, check_boolean, 0 }, 585 1.2 christos { "pkinit_revoke", krb5_config_string, NULL, 0 }, 586 1.2 christos { "pkinit_win2k_require_binding", krb5_config_string, check_boolean, 0 }, 587 1.2 christos { "ports", krb5_config_string, NULL, 0 }, 588 1.2 christos { "preauth-use-strongest-session-key", krb5_config_string, check_boolean, 0 }, 589 1.2 christos { "require_initial_kca_tickets", krb5_config_string, check_boolean, 0 }, 590 1.2 christos { "require-preauth", krb5_config_string, check_boolean, 0 }, 591 1.2 christos { "svc-use-strongest-session-key", krb5_config_string, check_boolean, 0 }, 592 1.2 christos { "tgt-use-strongest-session-key", krb5_config_string, check_boolean, 0 }, 593 1.2 christos { "transited-policy", krb5_config_string, NULL, 0 }, 594 1.2 christos { "use_2b", krb5_config_list, NULL, 0 }, 595 1.2 christos { "use-strongest-server-key", krb5_config_string, check_boolean, 0 }, 596 1.2 christos { "v4_realm", krb5_config_string, NULL, 0 }, 597 1.2 christos { NULL, 0, NULL, 0 } 598 1.1 elric }; 599 1.1 elric 600 1.1 elric struct entry kadmin_entries[] = { 601 1.2 christos { "allow_self_change_password", krb5_config_string, check_boolean, 0 }, 602 1.2 christos { "default_keys", krb5_config_string, NULL, 0 }, 603 1.2 christos { "password_lifetime", krb5_config_string, check_time, 0 }, 604 1.2 christos { "require-preauth", krb5_config_string, check_boolean, 0 }, 605 1.2 christos { "save-password", krb5_config_string, check_boolean, 0 }, 606 1.2 christos { "use_v4_salt", krb5_config_string, NULL, 0 }, 607 1.2 christos { NULL, 0, NULL, 0 } 608 1.1 elric }; 609 1.1 elric struct entry log_strings[] = { 610 1.2 christos { "", krb5_config_string, check_log, 0 }, 611 1.2 christos { NULL, 0, NULL, 0 } 612 1.1 elric }; 613 1.1 elric 614 1.1 elric 615 1.1 elric /* MIT stuff */ 616 1.1 elric struct entry kdcdefaults_entries[] = { 617 1.2 christos { "kdc_ports", krb5_config_string, mit_entry, 0 }, 618 1.2 christos { "v4_mode", krb5_config_string, mit_entry, 0 }, 619 1.2 christos { NULL, 0, NULL, 0 } 620 1.1 elric }; 621 1.1 elric 622 1.1 elric struct entry capaths_entries[] = { 623 1.2 christos { "", krb5_config_list, all_strings, 0 }, 624 1.2 christos { NULL, 0, NULL, 0 } 625 1.2 christos }; 626 1.2 christos 627 1.2 christos struct entry kcm_entries[] = { 628 1.2 christos { "detach", krb5_config_string, check_boolean, 0 }, 629 1.2 christos { "disallow-getting-krbtgt", krb5_config_string, check_boolean, 0 }, 630 1.2 christos { "logging", krb5_config_string, NULL, 0 }, 631 1.2 christos { "max-request", krb5_config_string, NULL, 0 }, 632 1.2 christos { "system_ccache", krb5_config_string, NULL, 0 }, 633 1.2 christos { NULL, 0, NULL, 0 } 634 1.1 elric }; 635 1.1 elric 636 1.1 elric struct entry password_quality_entries[] = { 637 1.2 christos { "check_function", krb5_config_string, NULL, 0 }, 638 1.2 christos { "check_library", krb5_config_string, NULL, 0 }, 639 1.2 christos { "external_program", krb5_config_string, NULL, 0 }, 640 1.2 christos { "min_classes", krb5_config_string, check_numeric, 0 }, 641 1.2 christos { "min_length", krb5_config_string, check_numeric, 0 }, 642 1.2 christos { "policies", krb5_config_string, NULL, 0 }, 643 1.2 christos { "policy_libraries", krb5_config_string, NULL, 0 }, 644 1.2 christos { "", krb5_config_list, all_strings, 0 }, 645 1.2 christos { NULL, 0, NULL, 0 } 646 1.1 elric }; 647 1.1 elric 648 1.1 elric struct entry toplevel_sections[] = { 649 1.2 christos { "appdefaults", krb5_config_list, appdefaults_entries, 0 }, 650 1.2 christos { "capaths", krb5_config_list, capaths_entries, 0 }, 651 1.2 christos { "domain_realm", krb5_config_list, all_strings, 0 }, 652 1.2 christos { "gssapi", krb5_config_list, NULL, 0 }, 653 1.2 christos { "kadmin", krb5_config_list, kadmin_entries, 0 }, 654 1.2 christos { "kcm", krb5_config_list, kcm_entries, 0 }, 655 1.2 christos { "kdc", krb5_config_list, kdc_entries, 0 }, 656 1.2 christos { "libdefaults" , krb5_config_list, libdefaults_entries, 0 }, 657 1.2 christos { "logging", krb5_config_list, log_strings, 0 }, 658 1.2 christos { "password_quality", krb5_config_list, password_quality_entries, 0 }, 659 1.2 christos { "realms", krb5_config_list, realms_foobar, 0 }, 660 1.2 christos 661 1.1 elric /* MIT stuff */ 662 1.2 christos { "kdcdefaults", krb5_config_list, kdcdefaults_entries, 0 }, 663 1.2 christos { NULL, 0, NULL, 0 } 664 1.1 elric }; 665 1.1 elric 666 1.1 elric 667 1.1 elric static int 668 1.1 elric check_section(krb5_context context, const char *path, krb5_config_section *cf, 669 1.1 elric struct entry *entries) 670 1.1 elric { 671 1.1 elric int error = 0; 672 1.1 elric krb5_config_section *p; 673 1.1 elric struct entry *e; 674 1.1 elric 675 1.1 elric char *local; 676 1.1 elric 677 1.1 elric for(p = cf; p != NULL; p = p->next) { 678 1.1 elric local = NULL; 679 1.1 elric if (asprintf(&local, "%s/%s", path, p->name) < 0 || local == NULL) 680 1.1 elric errx(1, "out of memory"); 681 1.1 elric for(e = entries; e->name != NULL; e++) { 682 1.1 elric if(*e->name == '\0' || strcmp(e->name, p->name) == 0) { 683 1.1 elric if(e->type != p->type) { 684 1.1 elric krb5_warnx(context, "%s: unknown or wrong type", local); 685 1.1 elric error |= 1; 686 1.1 elric } else if(p->type == krb5_config_string && e->check_data != NULL) { 687 1.1 elric error |= (*(check_func_t)e->check_data)(context, local, p->u.string); 688 1.1 elric } else if(p->type == krb5_config_list && e->check_data != NULL) { 689 1.1 elric error |= check_section(context, local, p->u.list, e->check_data); 690 1.1 elric } 691 1.1 elric if(e->deprecated) { 692 1.1 elric krb5_warnx(context, "%s: is a deprecated entry", local); 693 1.1 elric error |= 1; 694 1.1 elric } 695 1.1 elric break; 696 1.1 elric } 697 1.1 elric } 698 1.1 elric if(e->name == NULL) { 699 1.1 elric krb5_warnx(context, "%s: unknown entry", local); 700 1.1 elric error |= 1; 701 1.1 elric } 702 1.1 elric free(local); 703 1.1 elric } 704 1.1 elric return error; 705 1.1 elric } 706 1.1 elric 707 1.1 elric 708 1.1 elric static void 709 1.1 elric dumpconfig(int level, krb5_config_section *top) 710 1.1 elric { 711 1.1 elric krb5_config_section *x; 712 1.1 elric for(x = top; x; x = x->next) { 713 1.1 elric switch(x->type) { 714 1.1 elric case krb5_config_list: 715 1.1 elric if(level == 0) { 716 1.1 elric printf("[%s]\n", x->name); 717 1.1 elric } else { 718 1.1 elric printf("%*s%s = {\n", 4 * level, " ", x->name); 719 1.1 elric } 720 1.1 elric dumpconfig(level + 1, x->u.list); 721 1.1 elric if(level > 0) 722 1.1 elric printf("%*s}\n", 4 * level, " "); 723 1.1 elric break; 724 1.1 elric case krb5_config_string: 725 1.1 elric printf("%*s%s = %s\n", 4 * level, " ", x->name, x->u.string); 726 1.1 elric break; 727 1.1 elric } 728 1.1 elric } 729 1.1 elric } 730 1.1 elric 731 1.1 elric int 732 1.1 elric main(int argc, char **argv) 733 1.1 elric { 734 1.1 elric krb5_context context; 735 1.1 elric krb5_error_code ret; 736 1.1 elric krb5_config_section *tmp_cf; 737 1.1 elric int optidx = 0; 738 1.1 elric 739 1.1 elric setprogname (argv[0]); 740 1.1 elric 741 1.1 elric ret = krb5_init_context(&context); 742 1.1 elric if (ret == KRB5_CONFIG_BADFORMAT) 743 1.1 elric errx (1, "krb5_init_context failed to parse configuration file"); 744 1.1 elric else if (ret) 745 1.1 elric errx (1, "krb5_init_context failed with %d", ret); 746 1.1 elric 747 1.1 elric if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 748 1.1 elric usage(1); 749 1.1 elric 750 1.1 elric if (help_flag) 751 1.1 elric usage (0); 752 1.1 elric 753 1.1 elric if(version_flag){ 754 1.1 elric print_version(NULL); 755 1.1 elric exit(0); 756 1.1 elric } 757 1.1 elric 758 1.1 elric argc -= optidx; 759 1.1 elric argv += optidx; 760 1.1 elric 761 1.1 elric tmp_cf = NULL; 762 1.1 elric if(argc == 0) 763 1.1 elric krb5_get_default_config_files(&argv); 764 1.1 elric 765 1.1 elric while(*argv) { 766 1.1 elric ret = krb5_config_parse_file_multi(context, *argv, &tmp_cf); 767 1.1 elric if (ret != 0) 768 1.1 elric krb5_warn (context, ret, "krb5_config_parse_file"); 769 1.1 elric argv++; 770 1.1 elric } 771 1.1 elric 772 1.1 elric if(dumpconfig_flag) 773 1.1 elric dumpconfig(0, tmp_cf); 774 1.1 elric 775 1.1 elric return check_section(context, "", tmp_cf, toplevel_sections); 776 1.1 elric } 777