summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-11-26 14:19:04 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2008-11-26 14:19:04 +0100
commitdbc8762aebc66085d67bb04bb58bee56ce204596 (patch)
tree7b9ebbc2339b14bedcd4c05608e15d59d5b4ea02
parent5f44f8592761161921ceefffeedadbec2c308453 (diff)
parentdc478db1ca80ef222f83985b539dfec1c66063e2 (diff)
downloadrsyslog-dbc8762aebc66085d67bb04bb58bee56ce204596.tar.gz
rsyslog-dbc8762aebc66085d67bb04bb58bee56ce204596.tar.xz
rsyslog-dbc8762aebc66085d67bb04bb58bee56ce204596.zip
Merge branch 'droppriv'
Conflicts: doc/manual.html
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac2
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/droppriv.html60
-rw-r--r--doc/manual.html2
-rw-r--r--doc/rsyslog_conf_global.html5
-rw-r--r--tools/syslogd.c87
7 files changed, 157 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 70ad7e1f..fe8df1fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
---------------------------------------------------------------------------
+Version 4.1.1 [DEVEL] (rgerhards), 2008-11-??
+- 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
+---------------------------------------------------------------------------
Version 4.1.0 [DEVEL] (rgerhards), 2008-11-18
********************************* WARNING *********************************
diff --git a/configure.ac b/configure.ac
index 981ef193..8eecf2ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([rsyslog],[4.1.0],[rsyslog@lists.adiscon.com])
+AC_INIT([rsyslog],[4.1.1],[rsyslog@lists.adiscon.com])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([ChangeLog])
AC_CONFIG_HEADERS([config.h])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5c2f5313..b58f813b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -5,6 +5,7 @@ html_files = \
features.html \
generic_design.html \
expression.html \
+ droppriv.html \
history.html \
how2help.html \
install.html \
diff --git a/doc/droppriv.html b/doc/droppriv.html
new file mode 100644
index 00000000..7293e872
--- /dev/null
+++ b/doc/droppriv.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>dropping privileges in rsyslog</title>
+</head>
+<body>
+<h1>Dropping privileges in rsyslog</h1>
+<p><b>Available since:&nbsp;&nbsp;&nbsp;</b> 4.1.1</p>
+<p><b>Description</b>:</p>
+<p>
+Rsyslogd provides the ability to drop privileges by
+impersonating as another user and/or group after startup.
+
+<p>Please note that due to POSIX standards, rsyslogd always needs to start
+up as root if there is a listener who must bind to a network port below 1024.
+For example, the UDP listener usually needs to listen to 514 and as such
+rsyslogd needs to start up as root.
+
+<p>If you do not need this functionality, you can start rsyslog directly as an ordinary
+user. That is probably the safest way of operations. However, if a startup as
+root is required, you can use the $PrivDropToGroup and $PrivDropToUser config
+directives to specify a group and/or user that rsyslogd should drop to after initialization.
+Once this happend, the daemon runs without high privileges (depending, of
+course, on the permissions of the user account you specified).
+<p>There is some additional information available in the
+<a href="http://wiki.rsyslog.com/index.php/Security#Dropping_Privileges">rsyslog wiki</a>.
+<p><b>Configuration Directives</b>:</p>
+<ul>
+<li><b>$PrivDropToUser</b><br>
+Name of the user rsyslog should run under after startup. Please note that
+this user is looked up in the system tables. If the lookup fails, privileges are
+NOT dropped. Thus it is advisable to use the less convenient $PrivDropToUserID directive.
+If the user id can be looked up, but can not be set, rsyslog aborts.
+<br>
+</li>
+<li><b>$PrivDropToUserID</b><br>
+Much the same as $PrivDropToUser, except that a numerical user id instead of a name
+is specified.Thus, privilege drop will always happen.
+rsyslogd aborts.
+<li><b>$PrivDropToGroup</b><br>
+Name of the group rsyslog should run under after startup. Please note that
+this user is looked up in the system tables. If the lookup fails, privileges are
+NOT dropped. Thus it is advisable to use the less convenient $PrivDropToGroupID directive.
+Note that all supplementary groups are removed from the process if $PrivDropToGroup is
+specified.
+If the group id can be looked up, but can not be set, rsyslog aborts.
+<br>
+</li>
+<li><b>$PrivDropToGroupID</b><br>
+Much the same as $PrivDropToGroup, except that a numerical group id instead of a name
+is specified. Thus, privilege drop will always happen.
+</ul>
+<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
+[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
+<p><font size="2">This documentation is part of the <a href="http://www.rsyslog.com/">rsyslog</a>
+project.<br>
+Copyright &copy; 2008 by <a href="http://www.gerhards.net/rainer">Rainer
+Gerhards</a> and
+<a href="http://www.adiscon.com/">Adiscon</a>.
+Released under the GNU GPL version 3 or higher.</font></p>
+
+</body></html>
diff --git a/doc/manual.html b/doc/manual.html
index dee076b8..aea98dd3 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p>
<p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a>
to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the
project goals.</p>
-<p><b>This documentation is for version 4.1.0 (devel branch) of rsyslog.</b>
+<p><b>This documentation is for version 4.1.1 (devel branch) of rsyslog.</b>
Visit the <i> <a href="http://www.rsyslog.com/doc-status.html">rsyslog status page</a></i></b> to obtain current
version information and project status.
</p><p><b>If you like rsyslog, you might
diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html
index bc618dd0..d02245e3 100644
--- a/doc/rsyslog_conf_global.html
+++ b/doc/rsyslog_conf_global.html
@@ -200,6 +200,11 @@ time calls should usually be acceptable. The default value is two, because we ha
seen that even without optimization the kernel often returns twice the identical time.
You can set this value as high as you like, but do so at your own risk. The higher
the value, the less precise the timestamp.
+<li><a href="droppriv.html">$PrivDropToGroup</a></li>
+<li><a href="droppriv.html">$PrivDropToGroupID</a></li>
+<li><a href="droppriv.html">$PrivDropToUser</a></li>
+<li><a href="droppriv.html">$PrivDropToUserID</a></li>
+</ul>
<li><a href="rsconf1_umask.html">$UMASK</a></li>
</ul>
<p><b>Where &lt;size_nbr&gt; is specified above,</b>
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 7145779d..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>
@@ -272,6 +273,8 @@ 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()!) */
+static int gidDropPriv = 0; /* group-id to which priveleges should be dropped to (AFTER init()!) */
extern int errno;
@@ -2063,6 +2066,56 @@ 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
+ * re-design the "interface" in the long term. -- rgerhards, 2008-11-19
+ */
+static void doDropPrivUid(int iUid)
+{
+ int res;
+ uchar szBuf[1024];
+
+ res = setuid(iUid);
+ 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 +2860,10 @@ 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 *)"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
@@ -2900,8 +2957,27 @@ 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(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
@@ -3520,11 +3596,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);