Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/syslogd - No more lost error messages during syslog...



details:   https://anonhg.NetBSD.org/src/rev/80b7ed1c3259
branches:  trunk
changeset: 512754:80b7ed1c3259
user:      manu <manu%NetBSD.org@localhost>
date:      Mon Jul 16 05:04:47 2001 +0000

description:
- No more lost error messages during syslogd startup, they now all appear on
stdout before syslogd becomes a daemon.
- Flags for setuid/setgid/chroot syslogd after initialization is completed
- Warning instead of silent ignoring for malformed lines (with spaces instead
of tags)
Approved by Christos

diffstat:

 usr.sbin/syslogd/syslogd.8 |   24 +++-
 usr.sbin/syslogd/syslogd.c |  298 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 243 insertions(+), 79 deletions(-)

diffs (truncated from 630 to 300 lines):

diff -r 04de01f7181b -r 80b7ed1c3259 usr.sbin/syslogd/syslogd.8
--- a/usr.sbin/syslogd/syslogd.8        Mon Jul 16 05:04:29 2001 +0000
+++ b/usr.sbin/syslogd/syslogd.8        Mon Jul 16 05:04:47 2001 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: syslogd.8,v 1.22 2001/07/01 16:23:42 itojun Exp $
+.\"    $NetBSD: syslogd.8,v 1.23 2001/07/16 05:04:47 manu Exp $
 .\"
 .\" Copyright (c) 1983, 1986, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -46,6 +46,15 @@
 .Op Fl f Ar config_file
 .Ek
 .Bk -words
+.Op Fl u Ar user
+.Ek
+.Bk -words
+.Op Fl g Ar user
+.Ek
+.Bk -words
+.Op Fl t Ar chroot_dir
+.Ek
+.Bk -words
 .Op Fl m Ar mark_interval
 .Ek
 .Bk -words
@@ -70,6 +79,19 @@
 Specify the pathname of an alternative configuration file;
 the default is
 .Pa /etc/syslog.conf .
+.It Fl u Ar user
+Set UID to 
+.Ar user 
+after the sockets and log files have been open.
+.It Fl g Ar group
+Set GID to 
+.Ar group 
+after the sockets and log files have been open.
+.It Fl t Ar chroot_dir
+.Xr chroot 2
+to
+.Ar chroot_dir
+after the sockets and log files        have been open.
 .It Fl m
 Select the number of minutes between ``mark'' messages;
 the default is 20 minutes.
diff -r 04de01f7181b -r 80b7ed1c3259 usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c        Mon Jul 16 05:04:29 2001 +0000
+++ b/usr.sbin/syslogd/syslogd.c        Mon Jul 16 05:04:47 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: syslogd.c,v 1.46 2001/07/01 16:23:42 itojun Exp $      */
+/*     $NetBSD: syslogd.c,v 1.47 2001/07/16 05:04:47 manu Exp $        */
 
 /*
  * Copyright (c) 1983, 1988, 1993, 1994
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)syslogd.c  8.3 (Berkeley) 4/4/94";
 #else
-__RCSID("$NetBSD: syslogd.c,v 1.46 2001/07/01 16:23:42 itojun Exp $");
+__RCSID("$NetBSD: syslogd.c,v 1.47 2001/07/16 05:04:47 manu Exp $");
 #endif
 #endif /* not lint */
 
@@ -105,6 +105,9 @@
 #include <unistd.h>
 #include <utmp.h>
 #include <util.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdarg.h>
 #include "pathnames.h"
 
 #define SYSLOG_NAMES
@@ -193,6 +196,7 @@
 struct filed consfile;
 
 int    Debug;                  /* debug flag */
+int    daemonized = 0;         /* we are not daemonized yet */
 char   LocalHostName[MAXHOSTNAMELEN+1];        /* our hostname */
 char   *LocalDomain;           /* our local domain name */
 int    *finet = NULL;                  /* Internet datagram sockets */
@@ -213,7 +217,7 @@
 int    getmsgbufsize __P((void));
 int*   socksetup __P((int));
 void   init __P((int));
-void   logerror __P((char *));
+void   logerror __P((const char *, ...));
 void   logmsg __P((int, char *, char *, int));
 void   printline __P((char *, char *));
 void   printsys __P((char *));
@@ -236,11 +240,35 @@
        struct sockaddr_storage frominet;
        char *p, *line, **pp;
        struct pollfd *readfds;
+       uid_t uid = 0;
+       gid_t gid = 0;
+       char *user = NULL;
+       char *group = NULL;
+       char *root = "/";
+       char *endp;
+       struct group   *gr;
+       struct passwd  *pw;
+       
 
        (void)setlocale(LC_ALL, "");
 
-       while ((ch = getopt(argc, argv, "dnsf:m:p:P:")) != -1)
+       while ((ch = getopt(argc, argv, "dnsf:m:p:P:u:g:t:")) != -1)
                switch(ch) {
+               case 'u':
+                       user = optarg;
+                       if (*user == '\0')
+                               usage();
+                       break;
+               case 'g':
+                       group = optarg;
+                       if (*group == '\0')
+                               usage();
+                       break;
+               case 't':
+                       root = optarg;
+                       if (*root == '\0')
+                               usage();
+                       break;
                case 'd':               /* debug */
                        Debug++;
                        break;
@@ -271,10 +299,46 @@
        if ((argc -= optind) != 0)
                usage();
 
-       if (!Debug)
-               (void)daemon(0, 0);
-       else
-               setlinebuf(stdout);
+       setlinebuf(stdout);
+
+       if (user != NULL) {
+               if (isdigit((unsigned char)*user)) {
+                       uid = (uid_t)strtoul(user, &endp, 0);
+                       if (*endp != '\0')
+                               goto getuser;
+               } else {
+getuser:
+                       if ((pw = getpwnam(user)) != NULL) {
+                               uid = pw->pw_uid;
+                       } else {
+                               errno = 0;  
+                               logerror("Cannot find user `%s'", user);
+                               die (0);
+                       }
+               }
+       }
+
+       if (group != NULL) {
+               if (isdigit((unsigned char)*group)) {
+                       gid = (gid_t)strtoul(group, &endp, 0);
+                       if (*endp != '\0')
+                               goto getgroup;
+               } else {
+getgroup:
+                       if ((gr = getgrnam(group)) != NULL) {
+                               gid = gr->gr_gid;
+                       } else {
+                               errno = 0;
+                               logerror("Cannot find group `%s'", group);
+                               die(0);
+                       }
+               }
+       }
+
+       if (access (root, F_OK | R_OK)) {
+               logerror ("Cannot access `%s'", root);
+               die (0);
+       }
 
        consfile.f_type = F_CONSOLE;
        (void)strcpy(consfile.f_un.f_fname, ctty);
@@ -291,7 +355,7 @@
        linesize++;
        line = malloc(linesize);
        if (line == NULL) {
-               logerror("couldn't allocate line buffer");
+               logerror("Couldn't allocate line buffer");
                die(0);
        }
        (void)signal(SIGTERM, die);
@@ -309,11 +373,11 @@
                    &funixmaxsize, _PATH_LOG);
        funix = (int *)malloc(sizeof(int) * funixsize);
        if (funix == NULL) {
-               logerror("couldn't allocate funix descriptors");
+               logerror("Couldn't allocate funix descriptors");
                die(0);
        }
        for (j = 0, pp = LogPaths; *pp; pp++, j++) {
-               dprintf("making unix dgram socket %s\n", *pp);
+               dprintf("Making unix dgram socket `%s'\n", *pp);
                unlink(*pp);
                memset(&sunx, 0, sizeof(sunx));
                sunx.sun_family = AF_LOCAL;
@@ -322,31 +386,25 @@
                if (funix[j] < 0 || bind(funix[j],
                    (struct sockaddr *)&sunx, SUN_LEN(&sunx)) < 0 ||
                    chmod(*pp, 0666) < 0) {
-                       int serrno = errno;
-                       (void)snprintf(line, sizeof line,
-                           "cannot create %s", *pp);
-                       errno = serrno;
-                       logerror(line);
-                       errno = serrno;
-                       dprintf("cannot create %s (%d)\n", *pp, errno);
+                       logerror("Cannot create `%s'", *pp);
                        die(0);
                }
-               dprintf("listening on unix dgram socket %s\n", *pp);
+               dprintf("Listening on unix dgram socket `%s'\n", *pp);
        }
 
        init(0);
 
        if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0) {
-               dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
+               dprintf("Can't open `%s' (%d)\n", _PATH_KLOG, errno);
        } else {
-               dprintf("listening on kernel log %s\n", _PATH_KLOG);
+               dprintf("Listening on kernel log `%s'\n", _PATH_KLOG);
        }
 
        /* tuck my process id away, if i'm not in debug mode */
        if (Debug == 0)
                pidfile(NULL);
 
-       dprintf("off & running....\n");
+       dprintf("Off & running....\n");
 
        (void)signal(SIGHUP, init);
 
@@ -354,7 +412,7 @@
        readfds = (struct pollfd *)malloc(sizeof(struct pollfd) *
                        (funixsize + (finet ? *finet : 0) + 1));
        if (readfds == NULL) {
-               logerror("couldn't allocate pollfds");
+               logerror("Couldn't allocate pollfds");
                die(0);
        }
        nfds = 0;
@@ -377,6 +435,36 @@
                readfds[nfds++].events = POLLIN | POLLPRI;
        }
 
+       /* 
+        * All files are open, we can drop privileges and chroot
+        */
+       dprintf ("Attempt to chroot to `%s'\n", root);  
+       if (chroot (root)) {
+               logerror ("Failed to chroot to `%s'", root);
+               die(0);
+       }
+       dprintf ("Attempt to set GID/EGID to `%d'\n", gid);  
+       if (setgid (gid) || setegid (gid)) {
+               logerror ("Failed to set gid to `%d'", gid);
+               die(0);
+       }
+       dprintf ("Attempt to set UID/EUID to `%d'\n", uid);  
+       if (setuid (uid) || seteuid (uid)) {
+               logerror ("Failed to set uid to `%d'", uid);
+               die(0);
+       }
+
+       /* 
+        * We cannot detach from the terminal before we are sure we won't 
+        * have a fatal error, because error message would not go to the
+        * terminal and would not be logged because syslogd dies. 
+        * All die() calls are behind us, we can call daemon()
+        */
+       if (!Debug) {
+               (void)daemon(0, 0);
+               daemonized = 1;
+       }
+
        for (;;) {
                int rv;
 
@@ -385,19 +473,19 @@
                        continue;
                if (rv < 0) {
                        if (errno != EINTR)
-                               logerror("poll");
+                               logerror("poll() failed");
                        continue;
                }
-               dprintf("got a message (%d)\n", rv);
+               dprintf("Got a message (%d)\n", rv);
                if (fklog >= 0 &&
                    (readfds[nfklogix].revents & (POLLIN | POLLPRI))) {
-                       dprintf("kernel log active\n");
+                       dprintf("Kernel log active\n");
                        i = read(fklog, line, linesize - 1);
                        if (i > 0) {



Home | Main Index | Thread Index | Old Index