]> git.ipfire.org Git - network.git/blame - src/networkd/main.c
networkd: Change to a non-privileged user right away
[network.git] / src / networkd / main.c
CommitLineData
050f4ece
MT
1/*#############################################################################
2# #
3# IPFire.org - A linux based firewall #
4# Copyright (C) 2023 IPFire Network Development Team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
11# This program is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
20
eb3f6449
MT
21#include <grp.h>
22#include <pwd.h>
8a88982f 23#include <stddef.h>
eb3f6449
MT
24#include <sys/prctl.h>
25#include <sys/types.h>
26#include <unistd.h>
26acbb4e 27
112358f3 28#include "daemon.h"
eb3f6449
MT
29#include "logging.h"
30
31static int drop_privileges(const char* user) {
32 struct passwd* passwd = NULL;
33 int r;
34
35 // Fetch the current user
36 uid_t current_uid = getuid();
37
38 // If we have not been launched by root, we will assume that we have already
39 // been launched with a minimal set of privileges.
40 if (current_uid > 0)
41 return 0;
42
43 DEBUG("Dropping privileges...\n");
44
45 // Fetch information about the desired user
46 passwd = getpwnam(user);
47 if (!passwd) {
48 ERROR("Could not find user %s: %m\n", user);
49 return 1;
50 }
51
52 uid_t uid = passwd->pw_uid;
53 gid_t gid = passwd->pw_gid;
54
55 // Change group
56 r = setresgid(gid, gid, gid);
57 if (r) {
58 ERROR("Could not change group to %d: %m\n", gid);
59 return 1;
60 }
61
62 // Set any supplementary groups
63 r = setgroups(0, NULL);
64 if (r) {
65 ERROR("Could not set supplementary groups: %m\n");
66 return 1;
67 }
68
69 // Do not drop any capabilities when we change to the new user
70 r = prctl(PR_SET_KEEPCAPS, 1);
71 if (r) {
72 ERROR("Could not set PR_SET_KEEPCAPS: %m\n");
73 return 1;
74 }
75
76 // Change to the new user
77 r = setresuid(uid, uid, uid);
78 if (r) {
79 ERROR("Could not change user to %d: %m\n", uid);
80 return 1;
81 }
82
83 // Reset PR_SET_KEEPCAPS
84 r = prctl(PR_SET_KEEPCAPS, 0);
85 if (r) {
86 ERROR("Could not set PR_SET_KEEPCAPS: %m\n");
87 return 1;
88 }
89
90 return 0;
91}
112358f3 92
050f4ece 93int main(int argc, char** argv) {
112358f3
MT
94 struct nw_daemon* daemon = NULL;
95 int r;
96
eb3f6449
MT
97 // Drop privileges
98 r = drop_privileges("network");
99 if (r)
100 return r;
26acbb4e 101
112358f3
MT
102 // Create the daemon
103 r = nw_daemon_create(&daemon);
104 if (r)
8a88982f 105 return r;
26acbb4e 106
c7e1b5db
MT
107 // Run the daemon
108 r = nw_daemon_run(daemon);
26acbb4e 109
8a88982f 110 // Cleanup
112358f3
MT
111 if (daemon)
112 nw_daemon_unref(daemon);
113
8a88982f 114 return r;
050f4ece 115}