diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-11-26 14:17:36 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-11-26 14:17:36 +0100 |
commit | dc478db1ca80ef222f83985b539dfec1c66063e2 (patch) | |
tree | 55e26c44026d2046b079715a8ed950defd4c1c40 /tools | |
parent | 57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27 (diff) | |
download | rsyslog-dc478db1ca80ef222f83985b539dfec1c66063e2.tar.gz rsyslog-dc478db1ca80ef222f83985b539dfec1c66063e2.tar.xz rsyslog-dc478db1ca80ef222f83985b539dfec1c66063e2.zip |
added ability to drop privileges
Added $PrivDropToGroup, $PrivDropToUser, $PrivDropToGroupID,
$PrivDropToUserID config directives to enable dropping privileges.
This is an effort to provide a security enhancement. For the limits of this
approach, see http://wiki.rsyslog.com/index.php/Security
Diffstat (limited to 'tools')
-rw-r--r-- | tools/syslogd.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/tools/syslogd.c b/tools/syslogd.c index 51ce1830..d132d139 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -82,6 +82,7 @@ #include <sys/ioctl.h> #include <sys/wait.h> #include <sys/file.h> +#include <grp.h> #if HAVE_SYS_TIMESPEC_H # include <sys/timespec.h> @@ -273,6 +274,7 @@ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - * queueing mode (mode DIRECT!), then this is set to 0. */ static int uidDropPriv = 0; /* user-id to which priveleges should be dropped to (AFTER init()!) */ +static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to (AFTER init()!) */ extern int errno; @@ -2064,6 +2066,34 @@ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) } +/* drop to specified group + * if something goes wrong, the function never returns + * Note that such an abort can cause damage to on-disk structures, so we should + * re-design the "interface" in the long term. -- rgerhards, 2008-11-26 + */ +static void doDropPrivGid(int iGid) +{ + int res; + uchar szBuf[1024]; + + res = setgroups(0, NULL); /* remove all supplementary group IDs */ + if(res) { + perror("could not remove supplemental group IDs"); + exit(1); + } + DBGPRINTF("setgroups(0, NULL): %d\n", res); + res = setgid(iGid); + if(res) { + /* if we can not set the userid, this is fatal, so let's unconditionally abort */ + perror("could not set requested group id"); + exit(1); + } + DBGPRINTF("setgid(%d): %d\n", iGid, res); + snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's groupid changed to %d", iGid); + logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0); +} + + /* drop to specified user * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should @@ -2074,9 +2104,7 @@ static void doDropPrivUid(int iUid) int res; uchar szBuf[1024]; -dbgprintf("userid before drop: %d\n", getuid()); res = setuid(iUid); -dbgprintf("userid after drop: %d\n", getuid()); if(res) { /* if we can not set the userid, this is fatal, so let's unconditionally abort */ perror("could not set requested userid"); @@ -2833,7 +2861,9 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, setMaxMsgSize, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &uidDropPriv, NULL)); -// CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, doDropPrivGroup, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &uidDropPriv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrGID, NULL, &gidDropPriv, NULL)); /* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far * that is not possible). -- rgerhards, 2008-01-28 @@ -2938,10 +2968,17 @@ static rsRetVal mainThread() * drop privileges at all. Doing it correctly, requires a change in architecture, which * we should do over time. TODO -- rgerhards, 2008-11-19 */ + if(gidDropPriv != 0) { + doDropPrivGid(gidDropPriv); + glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ + } + if(uidDropPriv != 0) { doDropPrivUid(uidDropPriv); + glbl.SetHUPisRestart(0); /* we can not do restart-type HUPs with dropped privs */ } + /* END OF INTIALIZATION * ... but keep in mind that we might do a restart and thus init() might * be called again. If that happens, we must shut down the worker thread, |