From 78440eab81959ec7a95effd579fd87b7c56dbe3d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 24 Dec 2012 23:52:18 +0100 Subject: Add user switching and capability support --- src/config.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'src/config.c') diff --git a/src/config.c b/src/config.c index 57059e5..2d387f3 100644 --- a/src/config.c +++ b/src/config.c @@ -31,11 +31,15 @@ #include #include -#include #include +#include #include +#include #include #include + +#include + #include #include @@ -104,6 +108,8 @@ static void default_config(fastd_config_t *conf) { conf->mtu = 1500; conf->mode = MODE_TAP; + conf->drop_caps = DROP_CAPS_ON; + conf->protocol = &fastd_protocol_ec25519_fhmqvc; conf->method_default = &fastd_method_null; conf->key_valid = 3600; /* 60 minutes */ @@ -522,6 +528,8 @@ static void count_peers(fastd_context_t *ctx, fastd_config_t *conf) { OPTION(usage, "--help" OR "-h", "Shows this help text") \ OPTION(version, "--version" OR "-v", "Shows the fastd version") \ OPTION(option_daemon, "--daemon" OR "-d", "Runs fastd in the background") \ + OPTION_ARG(option_user, "--user", "", "Sets the user to run fastd as") \ + OPTION_ARG(option_group, "--group", "", "Sets the group to run fastd as") \ OPTION_ARG(option_pid_file, "--pid-file", "", "Writes fastd's PID to the specified file") \ OPTION_ARG(option_log_level, "--log-level", "error|warn|info|verbose|debug", "Sets the stderr log level; default is info, if no alternative log destination ist configured") \ OPTION_ARG(option_syslog_level, "--syslog-level", "error|warn|info|verbose|debug", "Sets the log level for syslog output; default is not to use syslog") \ @@ -600,6 +608,16 @@ static int parse_log_level(fastd_context_t *ctx, const char *arg) { +static void option_user(fastd_context_t *ctx, fastd_config_t *conf, const char *arg) { + free(conf->user); + conf->user = strdup(arg); +} + +static void option_group(fastd_context_t *ctx, fastd_config_t *conf, const char *arg) { + free(conf->group); + conf->group = strdup(arg); +} + static void option_log_level(fastd_context_t *ctx, fastd_config_t *conf, const char *arg) { conf->log_stderr_level = parse_log_level(ctx, arg); } @@ -786,6 +804,52 @@ static void option_machine_readable(fastd_context_t *ctx, fastd_config_t *conf) } +static void configure_user(fastd_context_t *ctx, fastd_config_t *conf) { + conf->uid = getuid(); + conf->gid = getgid(); + + if (conf->user) { + struct passwd pwd, *pwdr; + size_t bufspace = 1024; + int error; + + do { + char buf[bufspace]; + error = getpwnam_r(conf->user, &pwd, buf, bufspace, &pwdr); + bufspace *= 2; + } while(error == ERANGE); + + if (error) + exit_errno(ctx, "getpwnam_r"); + + if (!pwdr) + exit_error(ctx, "Unable to find user `%s'.", conf->user); + + conf->uid = pwdr->pw_uid; + conf->gid = pwdr->pw_gid; + } + + if (conf->group) { + struct group grp, *grpr; + size_t bufspace = 1024; + int error; + + do { + char buf[bufspace]; + error = getgrnam_r(conf->group, &grp, buf, bufspace, &grpr); + bufspace *= 2; + } while(error == ERANGE); + + if (error) + exit_errno(ctx, "getgrnam_r"); + + if (!grpr) + exit_error(ctx, "Unable to find group `%s'.", conf->group); + + conf->gid = grpr->gr_gid; + } +} + void fastd_configure(fastd_context_t *ctx, fastd_config_t *conf, int argc, char *const argv[]) { #define OR , #define OPTION(func, options, message) \ @@ -831,6 +895,8 @@ void fastd_configure(fastd_context_t *ctx, fastd_config_t *conf, int argc, char if (!conf->peers && !has_peer_group_peer_dirs(conf->peer_group)) exit_error(ctx, "config error: neither fixed peers nor peer dirs have been configured"); + configure_user(ctx, conf); + count_peers(ctx, conf); #undef OR @@ -968,6 +1034,8 @@ void fastd_config_release(fastd_context_t *ctx, fastd_config_t *conf) { free_peer_group(conf->peer_group); + free(conf->user); + free(conf->group); free(conf->ifname); free(conf->secret); free(conf->on_up); -- cgit v1.2.3