Can start the daemon as root, and it will drop privileges.

Fri, 07 May 2021 13:20:53 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 07 May 2021 13:20:53 +0200
changeset 746
44d929ff268e
parent 745
3addb8cfcc3e
child 747
b6fbe6821468

Can start the daemon as root, and it will drop privileges.

bmsd/bms.c file | annotate | diff | comparison | revisions
bmsd/bms.h file | annotate | diff | comparison | revisions
bmsd/lock.c file | annotate | diff | comparison | revisions
tools/init.slackware file | annotate | diff | comparison | revisions
--- a/bmsd/bms.c	Wed May 05 20:32:07 2021 +0200
+++ b/bmsd/bms.c	Fri May 07 13:20:53 2021 +0200
@@ -71,14 +71,51 @@
 
 
 
-int server(void) {
-    uid_t               myuid;
+/**
+ * @brief Drop privileges in a safe way.
+ * @return 0 on success and -1 on failure.
+ */
+int drop_root_privileges(uid_t pw_uid, gid_t pw_gid, char *pw_dir)
+{
+    // no need to "drop" the privileges that you don't have in the first place!
+    if (getuid() == pw_uid && getgid() == pw_gid) {
+	syslog(LOG_NOTICE, "No need to drop privileges");
+    } else {
+	if (setgid(pw_gid) != 0) {
+	    syslog(LOG_NOTICE, "setgid: %s", strerror(errno));
+	    return -1;
+	}
+	if (setuid(pw_uid) != 0) {
+	    syslog(LOG_NOTICE, "setgid: %s", strerror(errno));
+	    return -1;
+	}
+    }
+
+    /* Change to the home directory */
+    if (chdir(pw_dir) != 0) {
+	syslog(LOG_NOTICE, "chdir(%s): %s", pw_dir, strerror(errno));
+	return -1;
+    }
+
+    /* check if we successfully dropped the root privileges */
+    if (setuid(0) == 0 || seteuid(0) == 0) {
+        syslog(LOG_NOTICE, "could not drop root privileges!");
+        return -1;
+    }
+
+    syslog(LOG_NOTICE, "Privileges dropped to %d:%d", pw_uid, pw_gid);
+    return 0;
+}
+
+
+
+int server(void)
+{
     struct passwd       *mypwd;
     int			rc = 0;
     char		*tmppath = NULL;
 
-    myuid = getuid();
-    mypwd = getpwuid(myuid);
+    mypwd = getpwnam("brewery");
     if (mypwd == NULL) {
 	fprintf(stderr, "[main] Could not find passwd entry\n");
 	return 1;
@@ -87,6 +124,11 @@
     Private_Path = xstrcpy(mypwd->pw_dir);
     Private_Path = xstrcat(Private_Path, (char *)"/.bms");
 
+    if (drop_root_privileges(mypwd->pw_uid, mypwd->pw_gid, mypwd->pw_dir) < 0) {
+	syslog(LOG_NOTICE, "Can't drop privileges");
+	return 1;
+    }
+
     if (lockprog((char *)"bmsd")) {
 	syslog(LOG_NOTICE, "Can't lock");
 	return 1;
--- a/bmsd/bms.h	Wed May 05 20:32:07 2021 +0200
+++ b/bmsd/bms.h	Fri May 07 13:20:53 2021 +0200
@@ -8,6 +8,8 @@
 #define TRUE 1
 #define FALSE 0
 
+#define _GNU_SOURCE  // for secure_getenv()
+
 #include "../config.h"
 
 #include <stdlib.h>
--- a/bmsd/lock.c	Wed May 05 20:32:07 2021 +0200
+++ b/bmsd/lock.c	Fri May 07 13:20:53 2021 +0200
@@ -56,7 +56,7 @@
 	free(lockfile);
 	return 1;
     }
-    fprintf(fp, "%10u\n", getpid());
+    fprintf(fp, "%u\n", getpid());
     fclose(fp);
 
     while (TRUE) {
--- a/tools/init.slackware	Wed May 05 20:32:07 2021 +0200
+++ b/tools/init.slackware	Fri May 07 13:20:53 2021 +0200
@@ -12,7 +12,7 @@
       if [ -f /var/lib/bms/.bms/run/bmsd.pid ]; then
   	echo "already running."
       else
-	su - brewery -c "/var/lib/bms/bin/bmsd"  >/dev/null 2>/dev/null
+	/var/lib/bms/bin/bmsd
 	sleep 1
         echo "done."
       fi

mercurial