]>
Commit | Line | Data |
---|---|---|
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 | ||
31 | static 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 | 93 | int 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 | } |