config.c revision 72445
1/*
2 * Copyright (c) 1997-2000 Kungliga Tekniska H�gskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
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.
16 *
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.
20 *
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
31 * SUCH DAMAGE.
32 */
33
34#include "kdc_locl.h"
35#include <getarg.h>
36#include <parse_bytes.h>
37
38RCSID("$Id: config.c,v 1.33 2000/09/10 19:27:17 joda Exp $");
39
40static char *config_file;	/* location of kdc config file */
41
42int require_preauth = -1;	/* 1 == require preauth for all principals */
43
44size_t max_request;		/* maximal size of a request */
45
46static char *max_request_str;	/* `max_request' as a string */
47
48time_t kdc_warn_pwexpire;	/* time before expiration to print a warning */
49
50struct dbinfo *databases;
51HDB **db;
52int num_db;
53
54char *port_str;
55
56int enable_http = -1;
57krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
58
59krb5_boolean check_ticket_addresses;
60krb5_boolean allow_null_ticket_addresses;
61krb5_boolean allow_anonymous;
62
63static struct getarg_strings addresses_str;	/* addresses to listen on */
64krb5_addresses explicit_addresses;
65
66#ifdef KRB4
67char *v4_realm;
68int enable_v4 = -1;
69int enable_524 = -1;
70#endif
71#ifdef KASERVER
72krb5_boolean enable_kaserver = -1;
73#endif
74
75static int help_flag;
76static int version_flag;
77
78static struct getargs args[] = {
79    {
80	"config-file",	'c',	arg_string,	&config_file,
81	"location of config file",	"file"
82    },
83    {
84	"require-preauth",	'p',	arg_negative_flag, &require_preauth,
85	"don't require pa-data in as-reqs"
86    },
87    {
88	"max-request",	0,	arg_string, &max_request,
89	"max size for a kdc-request", "size"
90    },
91#if 0
92    {
93	"database",	'd', 	arg_string, &databases,
94	"location of database", "database"
95    },
96#endif
97    { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support" },
98#ifdef KRB4
99    {	"kerberos4",	0, 	arg_negative_flag, &enable_v4,
100	"don't respond to kerberos 4 requests"
101    },
102    {	"524",		0, 	arg_negative_flag, &enable_524,
103	"don't respond to 524 requests"
104    },
105    {
106	"v4-realm",	'r',	arg_string, &v4_realm,
107	"realm to serve v4-requests for"
108    },
109#endif
110#ifdef KASERVER
111    {
112	"kaserver", 'K', arg_negative_flag,   &enable_kaserver,
113	"turn off kaserver support"
114    },
115#endif
116    {	"ports",	'P', 	arg_string, &port_str,
117	"ports to listen to"
118    },
119    {	"addresses",	0,	arg_strings, &addresses_str,
120	"addresses to listen on", "list of addresses" },
121    {	"help",		'h',	arg_flag,   &help_flag },
122    {	"version",	'v',	arg_flag,   &version_flag }
123};
124
125static int num_args = sizeof(args) / sizeof(args[0]);
126
127static void
128usage(int ret)
129{
130    arg_printusage (args, num_args, NULL, "");
131    exit (ret);
132}
133
134static void
135get_dbinfo(krb5_config_section *cf)
136{
137    krb5_config_binding *top_binding = NULL;
138    krb5_config_binding *db_binding;
139    krb5_config_binding *default_binding = NULL;
140    struct dbinfo *di, **dt;
141    const char *default_dbname = HDB_DEFAULT_DB;
142    const char *default_mkey = HDB_DB_DIR "/m-key";
143    const char *p;
144
145    databases = NULL;
146    dt = &databases;
147    while((db_binding = (krb5_config_binding *)
148	   krb5_config_get_next(context, cf, &top_binding,
149				krb5_config_list,
150				"kdc",
151				"database",
152				NULL))) {
153	p = krb5_config_get_string(context, db_binding, "realm", NULL);
154	if(p == NULL) {
155	    if(default_binding) {
156		krb5_warnx(context, "WARNING: more than one realm-less "
157			   "database specification");
158		krb5_warnx(context, "WARNING: using the first encountered");
159	    } else
160		default_binding = db_binding;
161	    continue;
162	}
163	di = calloc(1, sizeof(*di));
164	di->realm = strdup(p);
165	p = krb5_config_get_string(context, db_binding, "dbname", NULL);
166	if(p)
167	    di->dbname = strdup(p);
168	p = krb5_config_get_string(context, db_binding, "mkey_file", NULL);
169	if(p)
170	    di->mkey_file = strdup(p);
171	*dt = di;
172	dt = &di->next;
173    }
174    if(default_binding) {
175	di = calloc(1, sizeof(*di));
176	p = krb5_config_get_string(context, default_binding, "dbname", NULL);
177	if(p) {
178	    di->dbname = strdup(p);
179	    default_dbname = p;
180	}
181	p = krb5_config_get_string(context, default_binding, "mkey_file", NULL);
182	if(p) {
183	    di->mkey_file = strdup(p);
184	    default_mkey = p;
185	}
186	*dt = di;
187	dt = &di->next;
188    } else {
189	di = calloc(1, sizeof(*di));
190	di->dbname = strdup(default_dbname);
191	di->mkey_file = strdup(default_mkey);
192	*dt = di;
193	dt = &di->next;
194    }
195    for(di = databases; di; di = di->next) {
196	if(di->dbname == NULL)
197	    di->dbname = strdup(default_dbname);
198	if(di->mkey_file == NULL) {
199	    p = strrchr(di->dbname, '.');
200	    if(p == NULL || strchr(p, '/') != NULL)
201		asprintf(&di->mkey_file, "%s.mkey", di->dbname);
202	    else
203		asprintf(&di->mkey_file, "%.*s.mkey",
204			 (int)(p - di->dbname), di->dbname);
205	}
206    }
207}
208
209static void
210add_one_address (const char *str, int first)
211{
212    krb5_error_code ret;
213    krb5_addresses tmp;
214
215    ret = krb5_parse_address (context, str, &tmp);
216    if (ret)
217	krb5_err (context, 1, ret, "parse_address `%s'", str);
218    if (first)
219	krb5_copy_addresses(context, &tmp, &explicit_addresses);
220    else
221	krb5_append_addresses(context, &explicit_addresses, &tmp);
222    krb5_free_addresses (context, &tmp);
223}
224
225void
226configure(int argc, char **argv)
227{
228    krb5_config_section *cf = NULL;
229    int optind = 0;
230    int e;
231    const char *p;
232
233    while((e = getarg(args, num_args, argc, argv, &optind)))
234	warnx("error at argument `%s'", argv[optind]);
235
236    if(help_flag)
237	usage (0);
238
239    if (version_flag) {
240	print_version(NULL);
241	exit(0);
242    }
243
244    argc -= optind;
245    argv += optind;
246
247    if (argc != 0)
248	usage(1);
249
250    if(config_file == NULL)
251	config_file = _PATH_KDC_CONF;
252
253    if(krb5_config_parse_file(config_file, &cf))
254	cf = NULL;
255
256    get_dbinfo(cf);
257
258    if(max_request_str){
259	max_request = parse_bytes(max_request_str, NULL);
260    }
261
262    if(max_request == 0){
263	p = krb5_config_get_string (context,
264				    cf,
265				    "kdc",
266				    "max-request",
267				    NULL);
268	if(p)
269	    max_request = parse_bytes(p, NULL);
270    }
271
272    if(require_preauth == -1)
273	require_preauth = krb5_config_get_bool(context, cf, "kdc",
274					       "require-preauth", NULL);
275
276    if(port_str == NULL){
277	p = krb5_config_get_string(context, cf, "kdc", "ports", NULL);
278	if (p != NULL)
279	    port_str = strdup(p);
280    }
281
282    explicit_addresses.len = 0;
283
284    if (addresses_str.num_strings) {
285	int i;
286
287	for (i = 0; i < addresses_str.num_strings; ++i)
288	    add_one_address (addresses_str.strings[i], i == 0);
289    } else {
290	char **foo = krb5_config_get_strings (context, cf,
291					      "kdc", "addresses", NULL);
292
293	if (foo != NULL) {
294	    add_one_address (*foo++, TRUE);
295	    while (*foo)
296		add_one_address (*foo++, FALSE);
297	}
298    }
299
300#ifdef KRB4
301    if(enable_v4 == -1)
302	enable_v4 = krb5_config_get_bool_default(context, cf, TRUE, "kdc",
303					 "enable-kerberos4", NULL);
304    if(enable_524 == -1)
305	enable_524 = krb5_config_get_bool_default(context, cf, enable_v4,
306						  "kdc", "enable-524", NULL);
307#endif
308
309    if(enable_http == -1)
310	enable_http = krb5_config_get_bool(context, cf, "kdc",
311					   "enable-http", NULL);
312    check_ticket_addresses =
313	krb5_config_get_bool(context, cf, "kdc",
314			     "check-ticket-addresses", NULL);
315    allow_null_ticket_addresses =
316	krb5_config_get_bool(context, cf, "kdc",
317			     "allow-null-ticket-addresses", NULL);
318
319    allow_anonymous =
320	krb5_config_get_bool(context, cf, "kdc",
321			     "allow-anonymous", NULL);
322#ifdef KRB4
323    if(v4_realm == NULL){
324	p = krb5_config_get_string (context, cf,
325				    "kdc",
326				    "v4-realm",
327				    NULL);
328	if(p)
329	    v4_realm = strdup(p);
330    }
331#endif
332#ifdef KASERVER
333    if (enable_kaserver == -1)
334	enable_kaserver = krb5_config_get_bool_default(context, cf, TRUE,
335						       "kdc",
336						       "enable-kaserver",
337						       NULL);
338#endif
339
340    encode_as_rep_as_tgs_rep = krb5_config_get_bool(context, cf, "kdc",
341						    "encode_as_rep_as_tgs_rep",
342						    NULL);
343
344    kdc_warn_pwexpire = krb5_config_get_time (context, cf,
345					      "kdc",
346					      "kdc_warn_pwexpire",
347					      NULL);
348    kdc_openlog(cf);
349    if(cf)
350	krb5_config_file_free (context, cf);
351    if(max_request == 0)
352	max_request = 64 * 1024;
353    if(require_preauth == -1)
354	require_preauth = 1;
355    if (port_str == NULL)
356	port_str = "+";
357#ifdef KRB4
358    if(v4_realm == NULL){
359	v4_realm = malloc(40); /* REALM_SZ */
360	krb_get_lrealm(v4_realm, 1);
361    }
362#endif
363}
364