summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-11-19 13:20:31 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2008-11-19 13:20:31 +0100
commit57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27 (patch)
tree64edfe56c7ce2bfa8f215a90b148cf53bf947511
parentafd425232f3198e7bb6f3dbcf0aa3cb4c24d5f7e (diff)
downloadrsyslog-57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27.tar.gz
rsyslog-57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27.tar.xz
rsyslog-57c9a3accee3a3e9b46d984c76c9aae7e2ec9c27.zip
exprimental implementaiton of $PrivDropToUser directive
... which permits to drop root privileges. This is not a completely secure way of dropping permissions, e.g. the group permissions need to be dropped, too. Also, there are several vulnerability Windows (see code comments). Finally, at least the imklog module on linux does not work when privileges are dropped. This code may still be a valuable addition, and so I have created an experimental branch so that people can check it out.
-rw-r--r--tools/syslogd.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 7145779d..51ce1830 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -272,6 +272,7 @@ static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode -
* If the main queue is either not yet ready or not running in
* 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()!) */
extern int errno;
@@ -2063,6 +2064,30 @@ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask)
}
+/* 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
+ * re-design the "interface" in the long term. -- rgerhards, 2008-11-19
+ */
+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");
+ exit(1);
+ }
+ DBGPRINTF("setuid(%d): %d\n", iUid, res);
+ snprintf((char*)szBuf, sizeof(szBuf)/sizeof(uchar), "rsyslogd's userid changed to %d", iUid);
+ logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, szBuf, 0);
+}
+
+
/* helper to freeSelectors(), used with llExecFunc() to flush
* pending output. -- rgerhards, 2007-08-02
* We do not need to lock the action object here as the processing
@@ -2807,6 +2832,8 @@ static rsRetVal loadBuildInModules(void)
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
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));
/* 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
@@ -2900,8 +2927,20 @@ static rsRetVal mainThread()
}
/* Send a signal to the parent so it can terminate.
*/
- if (myPid != ppid)
- kill (ppid, SIGTERM);
+ if(myPid != ppid)
+ kill(ppid, SIGTERM);
+
+
+ /* If instructed to do so, we now drop privileges. Note that this is not 100% secure,
+ * because inputs and outputs are already running at this time. However, we can implement
+ * dropping of privileges rather quickly and it will work in many cases. While it is not
+ * the ultimate solution, the current one is still much better than not being able to
+ * drop privileges at all. Doing it correctly, requires a change in architecture, which
+ * we should do over time. TODO -- rgerhards, 2008-11-19
+ */
+ if(uidDropPriv != 0) {
+ doDropPrivUid(uidDropPriv);
+ }
/* END OF INTIALIZATION
* ... but keep in mind that we might do a restart and thus init() might
@@ -3520,11 +3559,14 @@ int realMain(int argc, char **argv)
/* process compatibility mode settings */
- if(iCompatibilityMode < 3) {
+ if(iCompatibilityMode < 4) {
errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically "
"generated config directives may interfer with your rsyslog.conf settings. "
- "We suggest upgrading your config and adding -c3 as the first "
+ "We suggest upgrading your config and adding -c4 as the first "
"rsyslogd option.");
+ }
+
+ if(iCompatibilityMode < 3) {
if(MarkInterval > 0) {
legacyOptsEnq((uchar *) "ModLoad immark");
snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "MarkMessagePeriod %d", MarkInterval);