# #
#############################################################################*/
+#include <grp.h>
+#include <pwd.h>
#include <stddef.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <unistd.h>
#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);