From: Michael Tremer Date: Sun, 5 Feb 2023 12:06:19 +0000 (+0000) Subject: networkd: Change to a non-privileged user right away X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb3f6449e9319715fbb6135b1a47d18eaac2169e;p=network.git networkd: Change to a non-privileged user right away Signed-off-by: Michael Tremer --- diff --git a/src/networkd/main.c b/src/networkd/main.c index 51a9bbab..fbd6c3b9 100644 --- a/src/networkd/main.c +++ b/src/networkd/main.c @@ -18,15 +18,86 @@ # # #############################################################################*/ +#include +#include #include +#include +#include +#include #include "daemon.h" +#include "logging.h" + +static int drop_privileges(const char* user) { + struct passwd* passwd = NULL; + int r; + + // Fetch the current user + uid_t current_uid = getuid(); + + // If we have not been launched by root, we will assume that we have already + // been launched with a minimal set of privileges. + if (current_uid > 0) + return 0; + + DEBUG("Dropping privileges...\n"); + + // Fetch information about the desired user + passwd = getpwnam(user); + if (!passwd) { + ERROR("Could not find user %s: %m\n", user); + return 1; + } + + uid_t uid = passwd->pw_uid; + gid_t gid = passwd->pw_gid; + + // Change group + r = setresgid(gid, gid, gid); + if (r) { + ERROR("Could not change group to %d: %m\n", gid); + return 1; + } + + // Set any supplementary groups + r = setgroups(0, NULL); + if (r) { + ERROR("Could not set supplementary groups: %m\n"); + return 1; + } + + // Do not drop any capabilities when we change to the new user + r = prctl(PR_SET_KEEPCAPS, 1); + if (r) { + ERROR("Could not set PR_SET_KEEPCAPS: %m\n"); + return 1; + } + + // Change to the new user + r = setresuid(uid, uid, uid); + if (r) { + ERROR("Could not change user to %d: %m\n", uid); + return 1; + } + + // Reset PR_SET_KEEPCAPS + r = prctl(PR_SET_KEEPCAPS, 0); + if (r) { + ERROR("Could not set PR_SET_KEEPCAPS: %m\n"); + return 1; + } + + return 0; +} int main(int argc, char** argv) { struct nw_daemon* daemon = NULL; int r; - // XXX Drop privileges + // Drop privileges + r = drop_privileges("network"); + if (r) + return r; // Create the daemon r = nw_daemon_create(&daemon);