Allow specifying runing user and chroot() enviroment

Allow the admin to switch the user the kdc is running under and
specify the chroot() directory to run in.

Please note you need a very special setup to get this working.
This commit is contained in:
Love Hornquist Astrand
2009-07-16 22:15:26 -07:00
parent 2076c1c93e
commit 3634423f36
3 changed files with 51 additions and 0 deletions

View File

@@ -64,6 +64,10 @@ static struct getarg_strings addresses_str; /* addresses to listen on */
static char *v4_realm;
char *runas_string;
char *chroot_string;
static struct getargs args[] = {
{
"config-file", 'c', arg_string, &config_file,
@@ -118,6 +122,12 @@ static struct getargs args[] = {
"disable DES" },
{ "builtin-hdb", 0, arg_flag, &builtin_hdb_flag,
"list builtin hdb backends"},
{ "runas-user", 0, arg_string, &runas_string,
"run as this user when connected to network"
},
{ "chroot", 0, arg_string, &chroot_string,
"chroot directory to run in"
},
{ "help", 'h', arg_flag, &help_flag },
{ "version", 'v', arg_flag, &version_flag }
};

View File

@@ -67,6 +67,9 @@ extern const struct units _kdc_digestunits[];
extern struct timeval _kdc_now;
#define kdc_time (_kdc_now.tv_sec)
extern char *runas_string;
extern char *chroot_string;
void
loop(krb5_context context, krb5_kdc_configuration *config);

View File

@@ -48,6 +48,41 @@ sigterm(int sig)
exit_flag = sig;
}
/*
* Allow dropping root bit, since heimdal reopens the database all the
* time the database needs to be owned by the user you are switched
* too. A better solution is to split the kdc in to more processes and
* run the network facing part with very low privilege.
*/
static void
switch_environment(void)
{
if ((runas_string || chroot_string) && geteuid() != 0)
errx(1, "no running as root, can't switch user/chroot");
if (chroot_string && chroot(chroot_string) != 0)
errx(1, "chroot(%s)", "chroot_string failed");
if (runas_string) {
struct passwd *pw;
pw = getpwnam(runas_string);
if (pw == NULL)
errx(1, "unknown user %s", runas_string);
if (initgroups(pw->pw_name, pw->pw_gid) < 0)
err(1, "initgroups failed");
if (setgid(pw->pw_gid) < 0)
err(1, "setgid(%s) failed", runas_string);
if (setuid(pw->pw_uid) < 0)
err(1, "setuid(%s)", runas_string);
}
}
int
main(int argc, char **argv)
{
@@ -95,6 +130,9 @@ main(int argc, char **argv)
daemon(0, 0);
#endif
pidfile(NULL);
switch_environment();
loop(context, config);
krb5_free_context(context);
return 0;