diff -r 3addb8cfcc3e -r 44d929ff268e bmsd/bms.c --- 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;