config.c revision 267654
174298Ssos/*
2230132Suqs * Copyright (c) 2005, PADL Software Pty Ltd.
374298Ssos * All rights reserved.
474298Ssos *
574298Ssos * Redistribution and use in source and binary forms, with or without
674298Ssos * modification, are permitted provided that the following conditions
774298Ssos * are met:
874298Ssos *
974298Ssos * 1. Redistributions of source code must retain the above copyright
1074298Ssos *    notice, this list of conditions and the following disclaimer.
1174298Ssos *
1274298Ssos * 2. Redistributions in binary form must reproduce the above copyright
1374298Ssos *    notice, this list of conditions and the following disclaimer in the
1474298Ssos *    documentation and/or other materials provided with the distribution.
1574298Ssos *
1674298Ssos * 3. Neither the name of PADL Software nor the names of its contributors
1774298Ssos *    may be used to endorse or promote products derived from this software
1874298Ssos *    without specific prior written permission.
1974298Ssos *
2074298Ssos * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
2174298Ssos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2274298Ssos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2374298Ssos * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
2474298Ssos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2574298Ssos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2674298Ssos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2774298Ssos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2874298Ssos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2974298Ssos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3074298Ssos * SUCH DAMAGE.
3174298Ssos */
3274298Ssos
3374298Ssos#include "kcm_locl.h"
34119404Ssos#include <getarg.h>
3593881Ssos#include <parse_bytes.h>
36146266Ssos
37146266SsosRCSID("$Id: config.c 15296 2005-05-30 10:17:43Z lha $");
38146266Ssos
39146266Ssosstatic const char *config_file;	/* location of kcm config file */
40146266Ssos
41174682Sphksize_t max_request = 0;		/* maximal size of a request */
42146266Ssoschar *socket_path = NULL;
43146266Ssoschar *door_path = NULL;
44146266Ssos
45146266Ssosstatic char *max_request_str;	/* `max_request' as a string */
46146266Ssos
47146266Ssosint detach_from_console = -1;
48146266Ssos#define DETACH_IS_DEFAULT FALSE
49146266Ssos
50146266Ssosstatic const char *system_cache_name = NULL;
51203421Smavstatic const char *system_keytab = NULL;
5293881Ssosstatic const char *system_principal = NULL;
53146266Ssosstatic const char *system_server = NULL;
54204354Smavstatic const char *system_perms = NULL;
55146266Ssosstatic const char *system_user = NULL;
56146266Ssosstatic const char *system_group = NULL;
57146266Ssos
58146266Ssosstatic const char *renew_life = NULL;
59146266Ssosstatic const char *ticket_life = NULL;
60146266Ssos
61146266Ssosint disallow_getting_krbtgt = -1;
62146266Ssosint name_constraints = -1;
63146266Ssos
64146266Ssosstatic int help_flag;
65146266Ssosstatic int version_flag;
66146266Ssos
67146266Ssosstatic struct getargs args[] = {
68146266Ssos    {
69146266Ssos	"cache-name",	0,	arg_string,	&system_cache_name,
70146266Ssos	"system cache name", "cachename"
71197540Smav    },
72197540Smav    {
73146266Ssos	"config-file",	'c',	arg_string,	&config_file,
7493881Ssos	"location of config file",	"file"
75146266Ssos    },
76146266Ssos    {
77146266Ssos	"group",	'g',	arg_string,	&system_group,
7874298Ssos	"system cache group",	"group"
79146266Ssos    },
80146266Ssos    {
8174298Ssos	"max-request",	0,	arg_string, &max_request,
82146266Ssos	"max size for a kcm-request", "size"
83146266Ssos    },
84146266Ssos#if DETACH_IS_DEFAULT
85146266Ssos    {
8674298Ssos	"detach",       'D',      arg_negative_flag, &detach_from_console,
87146266Ssos	"don't detach from console"
88146266Ssos    },
89146266Ssos#else
90146266Ssos    {
91146266Ssos	"detach",       0 ,      arg_flag, &detach_from_console,
92146266Ssos	"detach from console"
93146266Ssos    },
9493881Ssos#endif
95146266Ssos    {	"help",		'h',	arg_flag,   &help_flag },
96146266Ssos    {
97146266Ssos	"system-principal",	'k',	arg_string,	&system_principal,
98146266Ssos	"system principal name",	"principal"
99146266Ssos    },
10074298Ssos    {
101146266Ssos	"lifetime",	'l', arg_string, &ticket_life,
102146266Ssos	"lifetime of system tickets", "time"
103146266Ssos    },
104146266Ssos    {
105201139Smav	"mode",		'm', arg_string, &system_perms,
106201139Smav	"octal mode of system cache", "mode"
107201139Smav    },
108146266Ssos    {
109146266Ssos	"name-constraints",	'n', arg_negative_flag, &name_constraints,
110146266Ssos	"disable credentials cache name constraints"
111146266Ssos    },
112146266Ssos    {
113146266Ssos	"disallow-getting-krbtgt", 0, arg_flag, &disallow_getting_krbtgt,
114146266Ssos	"disable fetching krbtgt from the cache"
11574298Ssos    },
116197540Smav    {
117146266Ssos	"renewable-life",	'r', arg_string, &renew_life,
118146266Ssos    	"renewable lifetime of system tickets", "time"
119197540Smav    },
120146266Ssos    {
121146266Ssos	"socket-path",		's', arg_string, &socket_path,
122194902Smav    	"path to kcm domain socket", "path"
123194902Smav    },
124194902Smav#ifdef HAVE_DOOR_CREATE
125197540Smav    {
126197540Smav	"door-path",		's', arg_string, &door_path,
127197540Smav    	"path to kcm door", "path"
128127021Ssos    },
129197540Smav#endif
130197540Smav    {
131197540Smav	"server",		'S', arg_string, &system_server,
132197540Smav    	"server to get system ticket for", "principal"
133197540Smav    },
134146266Ssos    {
135146266Ssos	"keytab",	't',	arg_string,	&system_keytab,
136146266Ssos	"system keytab name",	"keytab"
137146266Ssos    },
138220602Smav    {
139197540Smav	"user",		'u',	arg_string,	&system_user,
140197540Smav	"system cache owner",	"user"
141197540Smav    },
142127021Ssos    {	"version",	'v',	arg_flag,   &version_flag }
143146266Ssos};
144146266Ssos
145119404Ssosstatic int num_args = sizeof(args) / sizeof(args[0]);
14684584Ssos
147146266Ssosstatic void
148146266Ssosusage(int ret)
149146266Ssos{
150146266Ssos    arg_printusage (args, num_args, NULL, "");
151146266Ssos    exit (ret);
152146266Ssos}
153146266Ssos
154146266Ssosstatic int parse_owners(kcm_ccache ccache)
155146266Ssos{
156146266Ssos    uid_t uid = 0;
157146266Ssos    gid_t gid = 0;
158146266Ssos    struct passwd *pw;
159146266Ssos    struct group *gr;
160146266Ssos    int uid_p = 0;
161146266Ssos    int gid_p = 0;
16284584Ssos
163146266Ssos    if (system_user != NULL) {
164146266Ssos	if (isdigit((unsigned char)system_user[0])) {
165146266Ssos	    pw = getpwuid(atoi(system_user));
166146266Ssos	} else {
167146266Ssos	    pw = getpwnam(system_user);
168146266Ssos	}
169146266Ssos	if (pw == NULL) {
170146266Ssos	    return errno;
171146266Ssos	}
172146266Ssos
173146266Ssos	system_user = strdup(pw->pw_name);
174146266Ssos	if (system_user == NULL) {
175146266Ssos	    return ENOMEM;
176146266Ssos	}
17784584Ssos
178146266Ssos	uid = pw->pw_uid; uid_p = 1;
179197540Smav	gid = pw->pw_gid; gid_p = 1;
180197540Smav    }
181172606Sscottl
182172606Sscottl    if (system_group != NULL) {
183172606Sscottl	if (isdigit((unsigned char)system_group[0])) {
184172606Sscottl	    gr = getgrgid(atoi(system_group));
185172606Sscottl	} else {
186172606Sscottl	    gr = getgrnam(system_group);
187172606Sscottl	}
188197540Smav	if (gr == NULL) {
189144330Ssos	    return errno;
19084584Ssos	}
191146266Ssos
192249115Ssmh	gid = gr->gr_gid; gid_p = 1;
193249115Ssmh    }
194146266Ssos
195249115Ssmh    if (uid_p)
196146266Ssos	ccache->uid = uid;
197146266Ssos    else
19884584Ssos	ccache->uid = 0; /* geteuid() XXX */
199146266Ssos
200146266Ssos    if (gid_p)
201146266Ssos	ccache->gid = gid;
20284584Ssos    else
203146266Ssos	ccache->gid = 0; /* getegid() XXX */
204146266Ssos
205146266Ssos    return 0;
206146266Ssos}
207146266Ssos
208146266Ssosstatic const char *
209146266Ssoskcm_system_config_get_string(const char *string)
210146266Ssos{
211201139Smav    return krb5_config_get_string(kcm_context, NULL, "kcm",
212201139Smav				  "system_ccache", string, NULL);
213197540Smav}
214197540Smav
215198865Smavstatic krb5_error_code
216198865Smavccache_init_system(void)
217197540Smav{
218197540Smav    kcm_ccache ccache;
219197540Smav    krb5_error_code ret;
220197540Smav
221197540Smav    if (system_cache_name == NULL)
222197540Smav	system_cache_name = kcm_system_config_get_string("cc_name");
223197540Smav
224197540Smav    ret = kcm_ccache_new(kcm_context,
225197540Smav			 system_cache_name ? system_cache_name : "SYSTEM",
226197540Smav			 &ccache);
227197540Smav    if (ret)
228197540Smav	return ret;
229197540Smav
230146266Ssos    ccache->flags |= KCM_FLAGS_OWNER_IS_SYSTEM;
231146266Ssos    ccache->flags |= KCM_FLAGS_USE_KEYTAB;
232249115Ssmh
233249115Ssmh    ret = parse_owners(ccache);
234249115Ssmh    if (ret)
235249115Ssmh	return ret;
236249115Ssmh
237249115Ssmh    ret = krb5_parse_name(kcm_context, system_principal, &ccache->client);
238249115Ssmh    if (ret) {
239249115Ssmh	kcm_release_ccache(kcm_context, &ccache);
240146266Ssos	return ret;
241146266Ssos    }
242198587Smav
243198587Smav    if (system_server == NULL)
244198587Smav	system_server = kcm_system_config_get_string("server");
245198587Smav
246201139Smav    if (system_server != NULL) {
247201139Smav	ret = krb5_parse_name(kcm_context, system_server, &ccache->server);
248201139Smav	if (ret) {
249201139Smav	    kcm_release_ccache(kcm_context, &ccache);
250197540Smav	    return ret;
251197540Smav	}
252197540Smav    }
253198897Smav
254197540Smav    if (system_keytab == NULL)
255197540Smav	system_keytab = kcm_system_config_get_string("keytab_name");
256197540Smav
257197540Smav    if (system_keytab != NULL) {
258197540Smav	ret = krb5_kt_resolve(kcm_context, system_keytab, &ccache->key.keytab);
259197540Smav    } else {
260197540Smav	ret = krb5_kt_default(kcm_context, &ccache->key.keytab);
261197540Smav    }
262197540Smav    if (ret) {
263197540Smav	kcm_release_ccache(kcm_context, &ccache);
264197540Smav	return ret;
265197540Smav    }
266197540Smav
267197540Smav    if (renew_life == NULL)
268197540Smav	renew_life = kcm_system_config_get_string("renew_life");
269146266Ssos
270144330Ssos    if (renew_life == NULL)
27174298Ssos	renew_life = "1 month";
272238393Sbrueffer
273238393Sbrueffer    if (renew_life != NULL) {
274238393Sbrueffer	ccache->renew_life = parse_time(renew_life, "s");
275238393Sbrueffer	if (ccache->renew_life < 0) {
276238393Sbrueffer	    kcm_release_ccache(kcm_context, &ccache);
277238393Sbrueffer	    return EINVAL;
278238393Sbrueffer	}
279238393Sbrueffer    }
280238393Sbrueffer
281146266Ssos    if (ticket_life == NULL)
282238393Sbrueffer	ticket_life = kcm_system_config_get_string("ticket_life");
283238393Sbrueffer
284238393Sbrueffer    if (ticket_life != NULL) {
285238393Sbrueffer	ccache->tkt_life = parse_time(ticket_life, "s");
286238393Sbrueffer	if (ccache->tkt_life < 0) {
287119404Ssos	    kcm_release_ccache(kcm_context, &ccache);
288146266Ssos	    return EINVAL;
289146266Ssos	}
290146266Ssos    }
291146266Ssos
292146266Ssos    if (system_perms == NULL)
293146266Ssos	system_perms = kcm_system_config_get_string("mode");
294146266Ssos
295146266Ssos    if (system_perms != NULL) {
296146266Ssos	int mode;
297146266Ssos
298146266Ssos	if (sscanf(system_perms, "%o", &mode) != 1)
299146266Ssos	    return EINVAL;
300146266Ssos
301146266Ssos	ccache->mode = mode;
302146266Ssos    }
303146266Ssos
304146266Ssos    if (disallow_getting_krbtgt == -1) {
305146266Ssos	disallow_getting_krbtgt =
306146266Ssos	    krb5_config_get_bool_default(kcm_context, NULL, FALSE, "kcm",
307146266Ssos					 "disallow-getting-krbtgt", NULL);
308146266Ssos    }
309148991Ssos
310146266Ssos    /* enqueue default actions for credentials cache */
31174298Ssos    ret = kcm_ccache_enqueue_default(kcm_context, ccache, NULL);
312146266Ssos
313119404Ssos    kcm_release_ccache(kcm_context, &ccache); /* retained by event queue */
314146266Ssos
315146266Ssos    return ret;
316146266Ssos}
317201139Smav
318201139Smavvoid
319146266Ssoskcm_configure(int argc, char **argv)
320146266Ssos{
321146266Ssos    krb5_error_code ret;
322146266Ssos    int optind = 0;
323146266Ssos    const char *p;
324178067Ssos
325146266Ssos    while(getarg(args, num_args, argc, argv, &optind))
326200008Smav	warnx("error at argument `%s'", argv[optind]);
327200008Smav
328146266Ssos    if(help_flag)
329146266Ssos	usage (0);
330146266Ssos
331146266Ssos    if (version_flag) {
332152270Ssos	print_version(NULL);
333146266Ssos	exit(0);
334200008Smav    }
335200008Smav
336200008Smav    argc -= optind;
337200008Smav    argv += optind;
338200008Smav
339200008Smav    if (argc != 0)
340200008Smav	usage(1);
341146266Ssos
342146266Ssos    {
343235897Smav	char **files;
344146266Ssos
345146266Ssos	if(config_file == NULL)
346146266Ssos	    config_file = _PATH_KCM_CONF;
347146266Ssos
348166287Sremko	ret = krb5_prepend_config_files_default(config_file, &files);
349146266Ssos	if (ret)
350146266Ssos	    krb5_err(kcm_context, 1, ret, "getting configuration files");
351146266Ssos
352146266Ssos	ret = krb5_set_config_files(kcm_context, files);
353146266Ssos	krb5_free_config_files(files);
354146266Ssos	if(ret)
355146266Ssos	    krb5_err(kcm_context, 1, ret, "reading configuration files");
356146266Ssos    }
357200008Smav
358146266Ssos    if(max_request_str)
359146266Ssos	max_request = parse_bytes(max_request_str, NULL);
360146266Ssos
361146266Ssos    if(max_request == 0){
362146266Ssos	p = krb5_config_get_string (kcm_context,
363178067Ssos				    NULL,
364146266Ssos				    "kcm",
365146266Ssos				    "max-request",
366178067Ssos				    NULL);
367146266Ssos	if(p)
368146266Ssos	    max_request = parse_bytes(p, NULL);
369146266Ssos    }
370146266Ssos
371146266Ssos    if (system_principal == NULL) {
372146266Ssos	system_principal = kcm_system_config_get_string("principal");
373203421Smav    }
374203421Smav
375203421Smav    if (system_principal != NULL) {
376146266Ssos	ret = ccache_init_system();
377146266Ssos	if (ret)
378146266Ssos	    krb5_err(kcm_context, 1, ret, "initializing system ccache");
379146266Ssos    }
380146266Ssos
381146266Ssos    if(detach_from_console == -1)
382249115Ssmh	detach_from_console = krb5_config_get_bool_default(kcm_context, NULL,
383249115Ssmh							   DETACH_IS_DEFAULT,
384249115Ssmh							   "kcm",
385249115Ssmh							   "detach", NULL);
386249115Ssmh    kcm_openlog();
387249115Ssmh    if(max_request == 0)
388178067Ssos	max_request = 64 * 1024;
389146266Ssos}
390119404Ssos
391146266Ssos