Received: (at submit) by bugs.debian.org; 7 Jul 1998 21:18:39 +0000 Received: (qmail 16456 invoked from network); 7 Jul 1998 21:18:38 -0000 Received: from pop.medialab.sonera.net (195.156.109.69) by debian.novare.net with SMTP; 7 Jul 1998 21:18:38 -0000 Received: (from tom@localhost) by pop.medialab.sonera.net (8.9.0/8.9.0/Debian/GNU) id AAA25287; Wed, 8 Jul 1998 00:18:29 +0300 Date: Wed, 8 Jul 1998 00:18:29 +0300 Message-Id: <199807072118.AAA25287@pop.medialab.sonera.net> From: Topi Miettinen Subject: sysklogd: syslogd shouldn't run as root To: submit@bugs.debian.org X-Mailer: bug 3.1.5 Package: sysklogd Version: 1.3-26 Severity: wishlist Syslogd does not need superuser privileges except for startup. Klogd needs privileges to open /proc/kmsg, but in current kernels (2.0.34, 2.1.107) non-root reading from the file descriptor fails. That should eventually be fixed. This patch implements a new flag, -u user which causes syslogd and klogd to call setuid(user). diff -ru ./klogd.c.orig ./klogd.c --- ./klogd.c.orig Sun Jun 28 23:22:48 1998 +++ ./klogd.c Sun Jun 28 23:26:49 1998 @@ -216,6 +216,7 @@ #include #include #include +#include #include "klogd.h" #include "ksyms.h" #include "pidfile.h" @@ -240,7 +241,7 @@ static char *PidFile = "/etc/klogd.pid"; #endif -static int kmsg, +static int kmsg = -1, change_state = 0, terminate = 0, caught_TSTP = 0, @@ -490,7 +491,7 @@ return(kernel); } - if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) + if ( kmsg == -1 && (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) { fprintf(stderr, "klogd: Cannot open proc file system, " \ "%d - %s.\n", errno, strerror(errno)); @@ -878,10 +879,13 @@ auto char *log_level = (char *) 0, *output = (char *) 0; + uid_t uid = 0; + gid_t gid; + struct passwd *pw; chdir ("/"); /* Parse the command-line. */ - while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx")) != EOF) + while ((ch = getopt(argc, argv, "c:df:iIk:nopsu:vx")) != EOF) switch((char)ch) { case 'c': /* Set console message level. */ @@ -915,6 +919,15 @@ case 's': /* Use syscall interface. */ use_syscall = 1; break; + case 'u': + pw = getpwnam(optarg); + if (!pw) { + printf("Bad user name %s\n", optarg); + break; + } + uid = pw->pw_uid; + gid = pw->pw_gid; + break; case 'v': printf("klogd %s-%s\n", VERSION, PATCHLEVEL); exit (1); @@ -1044,6 +1057,11 @@ if (symbol_lookup) { InitKsyms(symfile); InitMsyms(); + } + + if (uid > 0) { + setgid(gid); + setuid(uid); } /* The main loop. */ diff -ru ./syslogd.c.orig ./syslogd.c --- ./syslogd.c.orig Sun Jun 28 23:22:49 1998 +++ ./syslogd.c Tue Jun 23 15:07:01 1998 @@ -400,6 +400,7 @@ #include #include #include +#include #include "pidfile.h" #include "version.h" @@ -700,9 +701,12 @@ char line[MAXLINE +1]; extern int optind; extern char *optarg; + uid_t uid = 0; + gid_t gid; + struct passwd *pw; chdir ("/"); - while ((ch = getopt(argc, argv, "dhf:l:m:np:rs:v")) != EOF) + while ((ch = getopt(argc, argv, "dhf:l:m:np:rs:u:v")) != EOF) switch((char)ch) { case 'd': /* debug */ Debug = 1; @@ -741,6 +745,15 @@ } StripDomains = crunch_list(optarg); break; + case 'u': /* user */ + pw = getpwnam(optarg); + if (!pw) { + printf("Bad user name %s\n", optarg); + break; + } + uid = pw->pw_uid; + gid = pw->pw_gid; + break; case 'v': printf("syslogd %s-%s\n", VERSION, PATCHLEVEL); exit (0); @@ -865,6 +878,11 @@ { dprintf("Debugging disabled, SIGUSR1 to turn on debugging.\n"); debugging_on = 0; + } + + if (uid > 0) { + setgid(gid); + setuid(uid); } /* Main loop begins here. */ --- Begin /etc/init.d/sysklogd (modified conffile) test -f /sbin/klogd || exit 0 test -f /sbin/syslogd || exit 0 SYSLOGD="-u syslogd" KLOGD="-u syslogd" case "$1" in start) echo -n "Starting system log daemon: syslogd" start-stop-daemon --start --quiet --exec /sbin/syslogd -- $SYSLOGD echo -n " klogd" start-stop-daemon --start --quiet --exec /sbin/klogd -- $KLOGD echo "." ;; stop) echo -n "Stopping system log daemon: klogd" start-stop-daemon --stop --quiet --pidfile /var/run/klogd.pid echo -n " syslogd" start-stop-daemon --stop --quiet --pidfile /var/run/syslogd.pid echo "." ;; reload|force-reload) start-stop-daemon --stop --quiet --signal 1 --pidfile /var/run/syslogd.pid ;; restart) echo -n "Stopping system log daemon: klogd" start-stop-daemon --stop --quiet --pidfile /var/run/klogd.pid echo " syslogd" start-stop-daemon --stop --quiet --pidfile /var/run/syslogd.pid sleep 1 echo -n "Starting system log daemon: syslogd" start-stop-daemon --start --quiet --exec /sbin/syslogd -- $SYSLOGD echo -n " klogd" start-stop-daemon --start --quiet --exec /sbin/klogd -- $KLOGD echo "." ;; *) echo "Usage: /etc/init.d/sysklogd {start|stop|reload|restart|force-reload}" exit 1 esac exit 0 --- End /etc/init.d/sysklogd --- Begin /etc/cron.daily/sysklogd (modified conffile) cd /var/log for LOG in `syslogd-listfiles` do if [ -f $LOG ]; then savelog -g adm -m 640 -u syslogd -c 7 $LOG >/dev/null fi done for LOG in `syslogd-listfiles --auth` do if [ -f $LOG ]; then chown syslogd.adm $LOG chmod o-rwx $LOG fi done /etc/init.d/sysklogd reload --- End /etc/cron.daily/sysklogd --- Begin /etc/cron.weekly/sysklogd (modified conffile) cd /var/log for LOG in `syslogd-listfiles --weekly` do if [ -f $LOG ]; then savelog -g adm -m 640 -u syslogd -c 4 $LOG >/dev/null fi done for LOG in `syslogd-listfiles --auth` do if [ -f $LOG ]; then chown syslogd.adm $LOG chmod o-rwx $LOG fi done /etc/init.d/sysklogd reload --- End /etc/cron.weekly/sysklogd