diff --git a/main.c b/main.c index c3c5574..25f05dc 100644 --- a/main.c +++ b/main.c @@ -350,6 +350,7 @@ int main const char *conf_file = DEFAULT_CONF_FILE; const char *progname = argv[0]; char *user = NULL; + struct passwd *pw; int debug = 0, nofork = 0, address_family = IPADDR_UNSPEC; int do_init_rtc = 0, restarted = 0; int other_pid; @@ -488,8 +489,12 @@ int main if (!user) { user = CNF_GetUser(); } + if (user && strcmp(user, "root")) { - SYS_DropRoot(user); + if ((pw = getpwnam(user)) == NULL) + LOG_FATAL(LOGF_Main, "Could not get %s uid/gid", user); + + SYS_DropRoot(pw->pw_uid, pw->pw_gid); } LOG_CreateLogFileDir(); diff --git a/sys.c b/sys.c index f0c81df..a407fb6 100644 --- a/sys.c +++ b/sys.c @@ -27,6 +27,8 @@ #include "config.h" +#include "sysincl.h" + #include "sys.h" #include "logging.h" @@ -107,10 +109,10 @@ SYS_Finalise(void) /* ================================================== */ -void SYS_DropRoot(char *user) +void SYS_DropRoot(uid_t uid, gid_t gid) { #if defined(LINUX) && defined (FEAT_PRIVDROP) - SYS_Linux_DropRoot(user); + SYS_Linux_DropRoot(uid, gid); #else LOG_FATAL(LOGF_Sys, "dropping root privileges not supported"); #endif diff --git a/sys.h b/sys.h index 569ecdb..a3f58c0 100644 --- a/sys.h +++ b/sys.h @@ -35,8 +35,8 @@ extern void SYS_Initialise(void); /* Called at the end of the run to do final clean-up */ extern void SYS_Finalise(void); -/* Drop root privileges to the specified user */ -extern void SYS_DropRoot(char *user); +/* Drop root privileges to the specified user and group */ +extern void SYS_DropRoot(uid_t uid, gid_t gid); extern void SYS_SetScheduler(int SchedPriority); extern void SYS_LockMemory(void); diff --git a/sys_linux.c b/sys_linux.c index fc0249a..3c9b0cd 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -45,8 +45,6 @@ int LockAll = 0; #endif #ifdef FEAT_PRIVDROP -#include -#include #include #include #include @@ -382,18 +380,10 @@ SYS_Linux_Finalise(void) #ifdef FEAT_PRIVDROP void -SYS_Linux_DropRoot(char *user) +SYS_Linux_DropRoot(uid_t uid, gid_t gid) { - struct passwd *pw; cap_t cap; - if (user == NULL) - return; - - if ((pw = getpwnam(user)) == NULL) { - LOG_FATAL(LOGF_SysLinux, "getpwnam(%s) failed", user); - } - if (prctl(PR_SET_KEEPCAPS, 1)) { LOG_FATAL(LOGF_SysLinux, "prctl() failed"); } @@ -402,12 +392,12 @@ SYS_Linux_DropRoot(char *user) LOG_FATAL(LOGF_SysLinux, "setgroups() failed"); } - if (setgid(pw->pw_gid)) { - LOG_FATAL(LOGF_SysLinux, "setgid(%d) failed", pw->pw_gid); + if (setgid(gid)) { + LOG_FATAL(LOGF_SysLinux, "setgid(%d) failed", gid); } - if (setuid(pw->pw_uid)) { - LOG_FATAL(LOGF_SysLinux, "setuid(%d) failed", pw->pw_uid); + if (setuid(uid)) { + LOG_FATAL(LOGF_SysLinux, "setuid(%d) failed", uid); } if ((cap = cap_from_text("cap_net_bind_service,cap_sys_time=ep")) == NULL) { @@ -420,7 +410,7 @@ SYS_Linux_DropRoot(char *user) cap_free(cap); - DEBUG_LOG(LOGF_SysLinux, "Privileges dropped to user %s", user); + DEBUG_LOG(LOGF_SysLinux, "Root dropped to uid %d gid %d", uid, gid); } #endif diff --git a/sys_linux.h b/sys_linux.h index 46caf35..6c69082 100644 --- a/sys_linux.h +++ b/sys_linux.h @@ -31,7 +31,7 @@ extern void SYS_Linux_Initialise(void); extern void SYS_Linux_Finalise(void); -extern void SYS_Linux_DropRoot(char *user); +extern void SYS_Linux_DropRoot(uid_t uid, gid_t gid); extern void SYS_Linux_MemLockAll(int LockAll); diff --git a/sysincl.h b/sysincl.h index 5c1fb37..31ddde4 100644 --- a/sysincl.h +++ b/sysincl.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include