bmsd/bms.c

changeset 746
44d929ff268e
parent 745
3addb8cfcc3e
child 747
b6fbe6821468
--- 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;

mercurial