summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-11-26 14:17:36 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2008-11-26 14:17:36 +0100
commitdc478db1ca80ef222f83985b539dfec1c66063e2 (patch)
tree55e26c44026d2046b079715a8ed950defd4c1c40 /tools
parent57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27 (diff)
downloadrsyslog-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.c43
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,