diff --git a/etc/server.conf b/etc/server.conf index 5f6ff6cce..356a29402 100644 --- a/etc/server.conf +++ b/etc/server.conf @@ -5,6 +5,9 @@ name = "s2ss"; # The name of this node affinity = 0x02; # Mask of cores the server should run on priority = 50; # Scheduler priority for the server +user = "acs-admin"; # Drop privileges after initialization +group = "acs-admin"; + nodes = { acs = { id = 1, # Device ID diff --git a/include/cfg.h b/include/cfg.h index 97937d060..c3dee1944 100644 --- a/include/cfg.h +++ b/include/cfg.h @@ -23,6 +23,10 @@ struct settings { int affinity; /** Protocol version of UDP packages */ int protocol; + /** User for the server process */ + int uid; + /** Group for the server process */ + int gid; /** A libconfig object pointing to the root of the config file */ config_setting_t *cfg; diff --git a/src/cfg.c b/src/cfg.c index f1397f0b8..3e4f68283 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -5,10 +5,12 @@ * @copyright 2014, Institute for Automation of Complex Power Systems, EONERC */ +#include #include #include #include -#include +#include +#include #include "cfg.h" #include "node.h" @@ -86,6 +88,30 @@ int config_parse_global(config_setting_t *cfg, struct settings *set) config_setting_lookup_int(cfg, "priority", &set->priority); config_setting_lookup_int(cfg, "protocol", &set->protocol); + const char *user = NULL; + const char *group = NULL; + + config_setting_lookup_string(cfg, "user", &user); + config_setting_lookup_string(cfg, "group", &group); + + /* Lookup uid and gid */ + if (user) { + struct passwd *pw = getpwnam(user); + if (!pw) + error("Unknown username: '%s'", user); + + set->uid = pw->pw_uid; + set->gid = pw->pw_gid; + } + + if (group) { + struct group *gr = getgrnam(group); + if (!gr) + error("Unknown group: '%s'", group); + + set->gid = gr->gr_gid; + } + set->cfg = cfg; return CONFIG_TRUE; diff --git a/src/server.c b/src/server.c index ffe17581b..fe2797ae0 100644 --- a/src/server.c +++ b/src/server.c @@ -120,6 +120,15 @@ int main(int argc, char *argv[]) /* Connect all nodes and start one thread per path */ start(); + /* Process is running as root, drop privileges */ + if (getuid() == 0) { + if (setgid(settings.gid) || setuid(settings.uid)) + perror("Unable to drop privileges"); + else + debug(3, "Dropped privileges to uid = %u, gid = %u", + settings.uid, settings.gid); + } + /* Main thread is sleeping */ pause();