summaryrefslogtreecommitdiffstats
path: root/src/config.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-12-24 23:52:18 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-12-24 23:52:18 +0100
commit78440eab81959ec7a95effd579fd87b7c56dbe3d (patch)
tree23a962d528fa2ac50b7c4fba92c36a63df25b479 /src/config.c
parenteaac49427339a365aac2d3505f567572cfbdbb96 (diff)
downloadfastd-78440eab81959ec7a95effd579fd87b7c56dbe3d.tar
fastd-78440eab81959ec7a95effd579fd87b7c56dbe3d.zip
Add user switching and capability support
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c70
1 files changed, 69 insertions, 1 deletions
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 <config.ll.h>
#include <config.yy.h>
-#include <arpa/inet.h>
#include <dirent.h>
+#include <grp.h>
#include <libgen.h>
+#include <pwd.h>
#include <stdarg.h>
#include <strings.h>
+
+#include <arpa/inet.h>
+
#include <sys/stat.h>
#include <sys/types.h>
@@ -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", "<user>", "Sets the user to run fastd as") \
+ OPTION_ARG(option_group, "--group", "<group>", "Sets the group to run fastd as") \
OPTION_ARG(option_pid_file, "--pid-file", "<filename>", "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);