http://cvsweb.openwall.com/cgi/cvsweb.cgi/~checkout~/Owl/packages/sysklogd/sysklogd-1.4.2-caen-owl-syslogd-drop-root.diff?rev=1.1;content-type=text%2Fplain diff -upk.orig sysklogd-1.4.2.orig/sysklogd.8 sysklogd-1.4.2/sysklogd.8 --- sysklogd-1.4.2.orig/sysklogd.8 2005-08-18 14:40:25 +0000 +++ sysklogd-1.4.2/sysklogd.8 2005-08-18 14:41:26 +0000 @@ -32,6 +32,9 @@ sysklogd \- Linux system logging utiliti .RB [ " \-s " .I domainlist ] +.RB [ " \-u" +.IB username +] .RB [ " \-v " ] .LP .SH DESCRIPTION @@ -161,6 +164,19 @@ is specified and the host logging resolv no domain would be cut, you will have to specify two domains like: .BR "\-s north.de:infodrom.north.de" . .TP +.BI "\-u " "username" +This causes the +.B syslogd +daemon to become the named user before starting up logging. + +Note that when this option is in use, +.B syslogd +will open all log files as root when the daemon is first started; +however, after a +.B SIGHUP +the files will be reopened as the non-privileged user. You should +take this into account when deciding the ownership of the log files. +.TP .B "\-v" Print version and exit. .LP diff -upk.orig sysklogd-1.4.2.orig/syslogd.c sysklogd-1.4.2/syslogd.c --- sysklogd-1.4.2.orig/syslogd.c 2005-08-18 14:40:25 +0000 +++ sysklogd-1.4.2/syslogd.c 2005-08-18 14:41:26 +0000 @@ -524,6 +524,10 @@ static char sccsid[] = "@(#)syslogd.c 5. #include #include #include + +#include +#include + #ifndef TESTING #include "pidfile.h" #endif @@ -775,6 +779,7 @@ int NoHops = 1; /* Can we bounce syslog intermediate host. */ char *bind_addr = NULL; /* bind UDP port to this interface only */ +char *server_user = NULL; /* user name to run server as */ extern int errno; @@ -827,6 +832,21 @@ static int set_nonblock_flag(int desc) return fcntl(desc, F_SETFL, flags | O_NONBLOCK); } +static int drop_root(void) +{ + struct passwd *pw; + + if (!(pw = getpwnam(server_user))) return -1; + + if (!pw->pw_uid) return -1; + + if (initgroups(server_user, pw->pw_gid)) return -1; + if (setgid(pw->pw_gid)) return -1; + if (setuid(pw->pw_uid)) return -1; + + return 0; +} + int main(argc, argv) int argc; char **argv; @@ -880,7 +900,7 @@ int main(argc, argv) funix[i] = -1; } - while ((ch = getopt(argc, argv, "a:dhf:i:l:m:np:rs:v")) != EOF) + while ((ch = getopt(argc, argv, "a:dhf:i:l:m:np:rs:u:v")) != EOF) switch((char)ch) { case 'a': if (nfunix < MAXFUNIX) @@ -933,6 +953,9 @@ int main(argc, argv) } StripDomains = crunch_list(optarg); break; + case 'u': + server_user = optarg; + break; case 'v': printf("syslogd %s.%s\n", VERSION, PATCHLEVEL); exit (0); @@ -1100,6 +1123,11 @@ int main(argc, argv) kill (ppid, SIGTERM); #endif + if (server_user && drop_root()) { + dprintf("syslogd: failed to drop root\n"); + exit(1); + } + /* Main loop begins here. */ for (;;) { int nfds; @@ -1254,7 +1282,7 @@ int main(argc, argv) int usage() { fprintf(stderr, "usage: syslogd [-drvh] [-l hostlist] [-m markinterval] [-n] [-p path]\n" \ - " [-s domainlist] [-f conffile] [-i IP address]\n"); + " [-s domainlist] [-f conffile] [-i IP address] [-u username]\n"); exit(1); }