2 * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <parse_bytes.h>
40 static const char *config_file
; /* location of kdc config file */
42 int require_preauth
= -1; /* 1 == require preauth for all principals */
44 size_t max_request
; /* maximal size of a request */
46 static char *max_request_str
; /* `max_request' as a string */
48 time_t kdc_warn_pwexpire
; /* time before expiration to print a warning */
50 struct dbinfo
*databases
;
57 int detach_from_console
= -1;
58 #define DETACH_IS_DEFAULT FALSE
62 krb5_boolean encode_as_rep_as_tgs_rep
; /* bug compatibility */
64 krb5_boolean check_ticket_addresses
;
65 krb5_boolean allow_null_ticket_addresses
;
66 krb5_boolean allow_anonymous
;
68 static const char *trpolicy_str
;
70 static struct getarg_strings addresses_str
; /* addresses to listen on */
71 krb5_addresses explicit_addresses
;
73 static int disable_des
= -1;
78 int enable_kaserver
= -1;
82 int enable_v4_cross_realm
= -1;
84 static int builtin_hdb_flag
;
86 static int version_flag
;
88 static struct getargs args
[] = {
90 "config-file", 'c', arg_string
, &config_file
,
91 "location of config file", "file"
94 "require-preauth", 'p', arg_negative_flag
, &require_preauth
,
95 "don't require pa-data in as-reqs"
98 "max-request", 0, arg_string
, &max_request
,
99 "max size for a kdc-request", "size"
103 "database", 'd', arg_string
, &databases
,
104 "location of database", "database"
107 { "enable-http", 'H', arg_flag
, &enable_http
, "turn on HTTP support" },
108 { "524", 0, arg_negative_flag
, &enable_524
,
109 "don't respond to 524 requests"
113 "kaserver", 'K', arg_flag
, &enable_kaserver
,
114 "enable kaserver support"
116 { "kerberos4", 0, arg_flag
, &enable_v4
,
117 "respond to kerberos 4 requests"
120 "v4-realm", 'r', arg_string
, &v4_realm
,
121 "realm to serve v4-requests for"
124 { "kerberos4-cross-realm", 0, arg_flag
,
125 &enable_v4_cross_realm
,
126 "respond to kerberos 4 requests from foreign realms"
128 { "ports", 'P', arg_string
, &port_str
,
129 "ports to listen to", "portspec"
132 #if DETACH_IS_DEFAULT
134 "detach", 'D', arg_negative_flag
, &detach_from_console
,
135 "don't detach from console"
139 "detach", 0 , arg_flag
, &detach_from_console
,
140 "detach from console"
144 { "addresses", 0, arg_strings
, &addresses_str
,
145 "addresses to listen on", "list of addresses" },
146 { "disable-des", 0, arg_flag
, &disable_des
,
148 { "builtin-hdb", 0, arg_flag
, &builtin_hdb_flag
,
149 "list builtin hdb backends"},
150 { "help", 'h', arg_flag
, &help_flag
},
151 { "version", 'v', arg_flag
, &version_flag
}
154 static int num_args
= sizeof(args
) / sizeof(args
[0]);
159 arg_printusage (args
, num_args
, NULL
, "");
166 const krb5_config_binding
*top_binding
= NULL
;
167 const krb5_config_binding
*db_binding
;
168 const krb5_config_binding
*default_binding
= NULL
;
169 struct dbinfo
*di
, **dt
;
170 const char *default_dbname
= HDB_DEFAULT_DB
;
171 const char *default_mkey
= HDB_DB_DIR
"/m-key";
176 while((db_binding
= (const krb5_config_binding
*)
177 krb5_config_get_next(context
, NULL
, &top_binding
,
182 p
= krb5_config_get_string(context
, db_binding
, "realm", NULL
);
184 if(default_binding
) {
185 krb5_warnx(context
, "WARNING: more than one realm-less "
186 "database specification");
187 krb5_warnx(context
, "WARNING: using the first encountered");
189 default_binding
= db_binding
;
192 di
= calloc(1, sizeof(*di
));
193 di
->realm
= strdup(p
);
194 p
= krb5_config_get_string(context
, db_binding
, "dbname", NULL
);
196 di
->dbname
= strdup(p
);
197 p
= krb5_config_get_string(context
, db_binding
, "mkey_file", NULL
);
199 di
->mkey_file
= strdup(p
);
203 if(default_binding
) {
204 di
= calloc(1, sizeof(*di
));
205 p
= krb5_config_get_string(context
, default_binding
, "dbname", NULL
);
207 di
->dbname
= strdup(p
);
210 p
= krb5_config_get_string(context
, default_binding
, "mkey_file", NULL
);
212 di
->mkey_file
= strdup(p
);
217 } else if(databases
== NULL
) {
218 /* if there are none specified, use some default */
219 di
= calloc(1, sizeof(*di
));
220 di
->dbname
= strdup(default_dbname
);
221 di
->mkey_file
= strdup(default_mkey
);
225 for(di
= databases
; di
; di
= di
->next
) {
226 if(di
->dbname
== NULL
)
227 di
->dbname
= strdup(default_dbname
);
228 if(di
->mkey_file
== NULL
) {
229 p
= strrchr(di
->dbname
, '.');
230 if(p
== NULL
|| strchr(p
, '/') != NULL
)
231 /* final pathname component does not contain a . */
232 asprintf(&di
->mkey_file
, "%s.mkey", di
->dbname
);
234 /* the filename is something.else, replace .else with
236 asprintf(&di
->mkey_file
, "%.*s.mkey",
237 (int)(p
- di
->dbname
), di
->dbname
);
243 add_one_address (const char *str
, int first
)
248 ret
= krb5_parse_address (context
, str
, &tmp
);
250 krb5_err (context
, 1, ret
, "parse_address `%s'", str
);
252 krb5_copy_addresses(context
, &tmp
, &explicit_addresses
);
254 krb5_append_addresses(context
, &explicit_addresses
, &tmp
);
255 krb5_free_addresses (context
, &tmp
);
259 configure(int argc
, char **argv
)
265 while(getarg(args
, num_args
, argc
, argv
, &optind
))
266 warnx("error at argument `%s'", argv
[optind
]);
276 if (builtin_hdb_flag
) {
278 ret
= hdb_list_builtin(context
, &list
);
280 krb5_err(context
, 1, ret
, "listing builtin hdb backends");
281 printf("builtin hdb backends: %s\n", list
);
295 if(config_file
== NULL
)
296 config_file
= _PATH_KDC_CONF
;
298 ret
= krb5_prepend_config_files_default(config_file
, &files
);
300 krb5_err(context
, 1, ret
, "getting configuration files");
302 ret
= krb5_set_config_files(context
, files
);
303 krb5_free_config_files(files
);
305 krb5_err(context
, 1, ret
, "reading configuration files");
311 max_request
= parse_bytes(max_request_str
, NULL
);
313 if(max_request
== 0){
314 p
= krb5_config_get_string (context
,
320 max_request
= parse_bytes(p
, NULL
);
323 if(require_preauth
== -1)
324 require_preauth
= krb5_config_get_bool(context
, NULL
, "kdc",
325 "require-preauth", NULL
);
327 if(port_str
== NULL
){
328 p
= krb5_config_get_string(context
, NULL
, "kdc", "ports", NULL
);
330 port_str
= strdup(p
);
333 explicit_addresses
.len
= 0;
335 if (addresses_str
.num_strings
) {
338 for (i
= 0; i
< addresses_str
.num_strings
; ++i
)
339 add_one_address (addresses_str
.strings
[i
], i
== 0);
340 free_getarg_strings (&addresses_str
);
342 char **foo
= krb5_config_get_strings (context
, NULL
,
343 "kdc", "addresses", NULL
);
346 add_one_address (*foo
++, TRUE
);
348 add_one_address (*foo
++, FALSE
);
354 enable_v4
= krb5_config_get_bool_default(context
, NULL
, FALSE
, "kdc",
355 "enable-kerberos4", NULL
);
359 if(enable_v4_cross_realm
== -1)
360 enable_v4_cross_realm
=
361 krb5_config_get_bool_default(context
, NULL
,
363 "enable-kerberos4-cross-realm",
366 enable_524
= krb5_config_get_bool_default(context
, NULL
, enable_v4
,
367 "kdc", "enable-524", NULL
);
369 if(enable_http
== -1)
370 enable_http
= krb5_config_get_bool(context
, NULL
, "kdc",
371 "enable-http", NULL
);
372 check_ticket_addresses
=
373 krb5_config_get_bool_default(context
, NULL
, TRUE
, "kdc",
374 "check-ticket-addresses", NULL
);
375 allow_null_ticket_addresses
=
376 krb5_config_get_bool_default(context
, NULL
, TRUE
, "kdc",
377 "allow-null-ticket-addresses", NULL
);
380 krb5_config_get_bool(context
, NULL
, "kdc",
381 "allow-anonymous", NULL
);
383 krb5_config_get_string_default(context
, NULL
, "always-check", "kdc",
384 "transited-policy", NULL
);
385 if(strcasecmp(trpolicy_str
, "always-check") == 0)
386 trpolicy
= TRPOLICY_ALWAYS_CHECK
;
387 else if(strcasecmp(trpolicy_str
, "allow-per-principal") == 0)
388 trpolicy
= TRPOLICY_ALLOW_PER_PRINCIPAL
;
389 else if(strcasecmp(trpolicy_str
, "always-honour-request") == 0)
390 trpolicy
= TRPOLICY_ALWAYS_HONOUR_REQUEST
;
392 kdc_log(0, "unknown transited-policy: %s, reverting to always-check",
394 trpolicy
= TRPOLICY_ALWAYS_CHECK
;
397 if (krb5_config_get_string(context
, NULL
, "kdc",
398 "enforce-transited-policy", NULL
))
399 krb5_errx(context
, 1, "enforce-transited-policy deprecated, "
400 "use [kdc]transited-policy instead");
403 if(v4_realm
== NULL
){
404 p
= krb5_config_get_string (context
, NULL
,
409 v4_realm
= strdup(p
);
410 if (v4_realm
== NULL
)
411 krb5_errx(context
, 1, "out of memory");
414 if (enable_kaserver
== -1)
415 enable_kaserver
= krb5_config_get_bool_default(context
, NULL
, FALSE
,
421 encode_as_rep_as_tgs_rep
= krb5_config_get_bool(context
, NULL
, "kdc",
422 "encode_as_rep_as_tgs_rep",
425 kdc_warn_pwexpire
= krb5_config_get_time (context
, NULL
,
431 if(detach_from_console
== -1)
432 detach_from_console
= krb5_config_get_bool_default(context
, NULL
,
439 max_request
= 64 * 1024;
440 if(require_preauth
== -1)
442 if (port_str
== NULL
)
446 enable_pkinit
= krb5_config_get_bool_default(context
, NULL
, FALSE
,
451 const char *user_id
, *x509_anchors
;
453 user_id
= krb5_config_get_string(context
, NULL
,
458 krb5_errx(context
, 1, "pkinit enabled but no identity");
460 x509_anchors
= krb5_config_get_string(context
, NULL
,
464 if (x509_anchors
== NULL
)
465 krb5_errx(context
, 1, "pkinit enabled but no X509 anchors");
467 pk_initialize(user_id
, x509_anchors
);
469 enable_pkinit_princ_in_cert
=
470 krb5_config_get_bool_default(context
,
473 "pkinit-principal-in-certificate",
479 if(v4_realm
== NULL
){
480 v4_realm
= malloc(40); /* REALM_SZ */
481 if (v4_realm
== NULL
)
482 krb5_errx(context
, 1, "out of memory");
483 krb_get_lrealm(v4_realm
, 1);
486 if(disable_des
== -1)
487 disable_des
= krb5_config_get_bool_default(context
, NULL
,
490 "disable-des", NULL
);
492 krb5_enctype_disable(context
, ETYPE_DES_CBC_CRC
);
493 krb5_enctype_disable(context
, ETYPE_DES_CBC_MD4
);
494 krb5_enctype_disable(context
, ETYPE_DES_CBC_MD5
);
495 krb5_enctype_disable(context
, ETYPE_DES_CBC_NONE
);
496 krb5_enctype_disable(context
, ETYPE_DES_CFB64_NONE
);
497 krb5_enctype_disable(context
, ETYPE_DES_PCBC_NONE
);