Index: Makefile =================================================================== --- Makefile (revision 309933) +++ Makefile (working copy) @@ -7,7 +7,7 @@ PROG= syslogd MAN= syslog.conf.5 syslogd.8 -SRCS= syslogd.c ttymsg.c +SRCS= syslogd.c ttymsg.c syslogd_probes.d LIBADD= util @@ -20,6 +20,10 @@ CFLAGS+= -DINET6 .endif -CFLAGS+= -I${.CURDIR}/../../usr.bin/wall +CFLAGS+= -I${.CURDIR}/../../usr.bin/wall \ + -no-integrated-as +test: + dtrace -q -C -I${.CURDIR} -s ${.CURDIR}/syslogd_trace.d -c "${.OBJDIR}/syslogd -F -a 192.168.0.0/24 -a [2001:db8::]/64:128 -b :514" + .include Index: syslogd.8 =================================================================== --- syslogd.8 (revision 309929) +++ syslogd.8 (working copy) @@ -360,6 +360,40 @@ This can be overridden by the .Fl T flag. +.Sh DTRACE PROBES +.Nm +supports the following DTrace USDT probes for monitoring and/or +debugging the behavior: +.Pp +.Bl -tag -width /var/run/syslog.pid -compact +.It Fn log "int" "char *" +.It Fn init-entry "void" +.It Fn init-return "void" +.It Fn config-open-failed "char *" "char *" "char *" +.It Fn config-open-success "char *" +.It Fn config-include-entry "char *" +.It Fn config-include-return "void" +.It Fn sock-open-entry "char *" "char *" +.It Fn sock-open-success "int" "int" "int" +.It Fn sock-open-failed "char *" "char *" "char *" "char *" +.It Fn sock-read "int" "size_t" "struct sockaddr_storage *" +.It Fn sock-read-data "int" "char *" "size_t" "char *" +.It Fn klog-read "int" "size_t" "char *" +.It Fn logmsg-entry "int" "int" "char *" "char *" +.It Fn logmsg-return "void" +.It Fn logmsg-dedup "int" "long" "int" +.It Fn markit-dedup "int" "int" "int" +.It Fn sendlog-forward "int" "char *" "int" "int" "int" +.It Fn sendlog-file "int" "char *" "size_t" "char *" +.It Fn sendlog-pipe "int" "char *" +.It Fn sendlog-tty "int" "char *" "char *" "int" +.It Fn sendlog-user "int" "char *" +.It Fn dump-filed "void *" "char *" "char *" +.It Fn dump-rule "void *" +.It Fn peer-mismatch "void *" "char *" "char *" "char *" "char *" +.It Fn peer-rejected "char *" "char *" "char*" +.It Fn peer-accepted "void *" "char *" "char *" "char*" +.El .Sh FILES .Bl -tag -width /var/run/syslog.pid -compact .It Pa /etc/syslog.conf Index: syslogd.c =================================================================== --- syslogd.c (revision 310278) +++ syslogd.c (working copy) @@ -111,6 +111,7 @@ #include "pathnames.h" #include "ttymsg.h" +#include "syslogd_probes.h" #define SYSLOG_NAMES #include @@ -121,7 +122,16 @@ static const char include_str[] = "include"; static const char include_ext[] = ".conf"; -#define dprintf if (Debug) printf +#define DPRINTF(l, ...) do { \ + if (SYSLOGD_LOG_ENABLED()) { \ + char logmsg[BUFSIZ]; \ + \ + snprintf(logmsg, \ + sizeof(logmsg), \ + __VA_ARGS__); \ + SYSLOGD_LOG(l, logmsg); \ + } \ + } while (0) #define MAXUNAMES 20 /* maximum number of user names */ @@ -291,17 +301,11 @@ #define F_WALL 6 /* everyone logged on */ #define F_PIPE 7 /* pipe to program */ -static const char *TypeNames[8] = { - "UNUSED", "FILE", "TTY", "CONSOLE", - "FORW", "USERS", "WALL", "PIPE" -}; - static STAILQ_HEAD(, filed) fhead = STAILQ_HEAD_INITIALIZER(fhead); /* Log files that we write to */ static struct filed consfile; /* Console */ -static int Debug; /* debug flag */ -static int Foreground = 0; /* Run in foreground, instead of daemonizing */ +static int Fflag; /* Run in foreground, instead of daemonizing */ static int resolve = 1; /* resolve hostname */ static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ static const char *LocalDomain; /* our local domain name */ @@ -333,11 +337,10 @@ static int needdofsync = 0; /* Are any file(s) waiting to be fsynced? */ static struct pidfh *pfh; -static volatile sig_atomic_t MarkSet, WantDie; +static volatile sig_atomic_t MarkSet, WantDie, DumpConfig; static int allowaddr(char *); -static void cfline(const char *, struct filed *, - const char *, const char *); +static struct filed *cfline(const char *, const char *, const char *); static const char *cvthname(struct sockaddr *); static void deadq_enter(pid_t, const char *); static int deadq_remove(pid_t); @@ -346,6 +349,8 @@ static void dodie(int); static void dofsync(void); static void domark(int); +static void dumpconfig(void); +static void siginfo(int); static void fprintlog(struct filed *, int, const char *); static void init(int); static void logerror(const char *); @@ -352,6 +357,8 @@ static void logmsg(int, const char *, const char *, int); static void log_deadchild(pid_t, int, const char *); static void markit(void); +static char *masktostr(struct filed *); +static char *userstostr(struct filed *); static int socksetup(struct peer *); static int skip_message(const char *, const char *, int); static void printline(const char *, char *, int); @@ -398,9 +405,9 @@ char *p; if (madvise(NULL, 0, MADV_PROTECT) != 0) - dprintf("madvise() failed: %s\n", strerror(errno)); + DPRINTF(LOG_ERR, "madvise() failed: %s\n", strerror(errno)); - while ((ch = getopt(argc, argv, "468Aa:b:cCdf:Fkl:m:nNop:P:sS:Tuv")) + while ((ch = getopt(argc, argv, "468Aa:b:cCf:Fkl:m:nNop:P:sS:Tuv")) != -1) switch (ch) { #ifdef INET @@ -445,14 +452,11 @@ case 'C': logflags |= O_CREAT; break; - case 'd': /* debug */ - Debug++; - break; case 'f': /* configuration file */ ConfFile = optarg; break; case 'F': /* run in foreground instead of daemon */ - Foreground++; + Fflag++; break; case 'k': /* keep remote kern fac */ KeepKernFac = 1; @@ -538,7 +542,7 @@ warn("cannot open pid file"); } - if ((!Foreground) && (!Debug)) { + if (!Fflag) { ppid = waitdaemon(0, 0, 30); if (ppid < 0) { warn("could not become daemon"); @@ -545,7 +549,7 @@ pidfile_remove(pfh); exit(1); } - } else if (Debug) + } else setlinebuf(stdout); consfile.f_type = F_CONSOLE; @@ -553,8 +557,8 @@ sizeof(consfile.fu_fname)); (void)strlcpy(bootfile, getbootfile(), sizeof(bootfile)); (void)signal(SIGTERM, dodie); - (void)signal(SIGINT, Debug ? dodie : SIG_IGN); - (void)signal(SIGQUIT, Debug ? dodie : SIG_IGN); + (void)signal(SIGINT, Fflag ? dodie : SIG_IGN); + (void)signal(SIGQUIT, Fflag ? dodie : SIG_IGN); /* * We don't want the SIGCHLD and SIGHUP handlers to interfere * with each other; they are likely candidates for being called @@ -569,17 +573,26 @@ (void)sigaction(SIGCHLD, &sact, NULL); (void)signal(SIGALRM, domark); (void)signal(SIGPIPE, SIG_IGN); /* We'll catch EPIPE instead. */ + (void)signal(SIGINFO, siginfo); (void)alarm(TIMERINTVL); TAILQ_INIT(&deadq_head); + /* + * _PATH_KLOG is not a socket, but use DTrace probes + * for sockets here to report it. + */ + SYSLOGD_SOCK_OPEN_ENTRY(_PATH_KLOG, NULL); if ((fklog = open(_PATH_KLOG, O_RDONLY|O_NONBLOCK, 0)) < 0) - dprintf("can't open %s (%d)\n", _PATH_KLOG, errno); + SYSLOGD_SOCK_OPEN_FAILED("klog", strerror(errno), + _PATH_KLOG, NULL); + else + SYSLOGD_SOCK_OPEN_SUCCESS(AF_LOCAL, fklog, SecureMode); /* tuck my process id away */ pidfile_write(pfh); - dprintf("off & running....\n"); + DPRINTF(LOG_DEBUG, "off & running....\n"); init(0); /* prevent SIGHUP and SIGCHLD handlers from running in parallel */ @@ -608,6 +621,8 @@ for (;;) { if (MarkSet) markit(); + if (DumpConfig) + dumpconfig(); if (WantDie) die(WantDie); @@ -644,11 +659,11 @@ if (FD_ISSET(sl->sl_socket, fdsr)) { sslen = sizeof(ss); - dprintf("sslen(1) = %d\n", sslen); len = recvfrom(sl->sl_socket, line, sizeof(line) - 1, 0, sstosa(&ss), &sslen); - dprintf("sslen(2) = %d\n", sslen); + SYSLOGD_SOCK_READ(sl->sl_socket, + len, &sl->sl_ss); if (len == 0) continue; if (len < 0) { @@ -668,11 +683,22 @@ hname = NULL; date = RemoteAddDate ? ADDDATE : 0; } - if (hname != NULL) + if (hname != NULL) { + if (SYSLOGD_SOCK_READ_DATA_ENABLED()) { + char h[NI_MAXHOST]; + + strncpy(h, hname, sizeof(h)); + h[sizeof(h) - 1] = '\0'; + SYSLOGD_SOCK_READ_DATA( + sl->sl_socket, + h, sizeof(line), line); + } printline(hname, line, date); - else - dprintf("Invalid msg from " - "%s was ignored.", hname); + } else { + /* Invalid data */ + SYSLOGD_SOCK_READ_DATA(sl->sl_socket, + "(NULL)", 0, NULL); + } } } } @@ -709,7 +735,7 @@ { fprintf(stderr, "%s\n%s\n%s\n%s\n", - "usage: syslogd [-468ACcdFknosTuv] [-a allowed_peer]", + "usage: syslogd [-468ACcFknosTuv] [-a allowed_peer]", " [-b bind_address] [-f config_file]", " [-l [mode:]path] [-m mark_interval]", " [-P pid_file] [-p log_socket]"); @@ -811,6 +837,7 @@ if (len > 0) memmove(line, p, len + 1); } + SYSLOGD_KLOG_READ(fklog, len, line); if (len > 0) printsys(line); } @@ -909,9 +936,8 @@ char prog[NAME_MAX+1]; char buf[MAXLINE+1]; - dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", - pri, flags, from, msg); - + SYSLOGD_LOGMSG_ENTRY(pri, flags, __DECONST(char *, from), + __DECONST(char *, msg)); omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM)); /* @@ -985,6 +1011,7 @@ f->f_file = -1; } (void)sigsetmask(omask); + SYSLOGD_LOGMSG_RETURN(); return; } STAILQ_FOREACH(f, &fhead, next) { @@ -1022,8 +1049,8 @@ (void)strlcpy(f->f_lasttime, timestamp, sizeof(f->f_lasttime)); f->f_prevcount++; - dprintf("msg repeated %d times, %ld sec of %d\n", - f->f_prevcount, (long)(now - f->f_time), + SYSLOGD_LOGMSG_DEDUP(f->f_prevcount, + (long)(now - f->f_time), repeatinterval[f->f_repeatcount]); /* * If domark would have logged this by now, @@ -1057,6 +1084,7 @@ } } (void)sigsetmask(omask); + SYSLOGD_LOGMSG_RETURN(); } static void @@ -1078,7 +1106,6 @@ fprintlog(struct filed *f, int flags, const char *msg) { struct iovec iov[IOV_SIZE]; - struct iovec *v; struct addrinfo *r; int l, lsent = 0; char line[MAXLINE + 1], repbuf[80], greetings[200], *wmsg = NULL; @@ -1085,30 +1112,34 @@ char nul[] = "", space[] = " ", lf[] = "\n", crlf[] = "\r\n"; const char *msgret; - v = iov; if (f->f_type == F_WALL) { - v->iov_base = greetings; /* The time displayed is not synchornized with the other log * destinations (like messages). Following fragment was using * ctime(&now), which was updating the time every 30 sec. * With f_lasttime, time is synchronized correctly. */ - v->iov_len = snprintf(greetings, sizeof greetings, - "\r\n\7Message from syslogd@%s at %.24s ...\r\n", - f->f_prevhost, f->f_lasttime); - if (v->iov_len >= sizeof greetings) - v->iov_len = sizeof greetings - 1; - v++; - v->iov_base = nul; - v->iov_len = 0; - v++; + iov[0] = (struct iovec){ + .iov_base = greetings, + .iov_len = snprintf(greetings, sizeof(greetings), + "\r\n\7Message from syslogd@%s " + "at %.24s ...\r\n", + f->f_prevhost, f->f_lasttime) + }; + iov[1] = (struct iovec){ + .iov_base = nul, + .iov_len = 0 + }; + if (iov[0].iov_len >= sizeof(greetings)) + iov[0].iov_len = sizeof(greetings) - 1; } else { - v->iov_base = f->f_lasttime; - v->iov_len = strlen(f->f_lasttime); - v++; - v->iov_base = space; - v->iov_len = 1; - v++; + iov[0] = (struct iovec){ + .iov_base = f->f_lasttime, + .iov_len = strlen(f->f_lasttime), + }; + iov[1] = (struct iovec){ + .iov_base = space, + .iov_len = 1 + }; } if (LogFacPri) { @@ -1145,21 +1176,24 @@ p_s = p_n; } snprintf(fp_buf, sizeof fp_buf, "<%s.%s> ", f_s, p_s); - v->iov_base = fp_buf; - v->iov_len = strlen(fp_buf); + iov[2] = (struct iovec){ + .iov_base = fp_buf, + .iov_len = strlen(fp_buf) + }; } else { - v->iov_base = nul; - v->iov_len = 0; + iov[2] = (struct iovec){ + .iov_base = nul, + .iov_len = 0 + }; } - v++; - - v->iov_base = f->f_prevhost; - v->iov_len = strlen(v->iov_base); - v++; - v->iov_base = space; - v->iov_len = 1; - v++; - + iov[3] = (struct iovec){ + .iov_base = f->f_prevhost, + .iov_len = strlen(f->f_prevhost) + }; + iov[4] = (struct iovec){ + .iov_base = space, + .iov_len = 1 + }; if (msg) { wmsg = strdup(msg); /* XXX iov_base needs a `const' sibling. */ if (wmsg == NULL) { @@ -1166,33 +1200,40 @@ logerror("strdup"); exit(1); } - v->iov_base = wmsg; - v->iov_len = strlen(msg); + iov[5] = (struct iovec){ + .iov_base = wmsg, + .iov_len = strlen(msg) + }; } else if (f->f_prevcount > 1) { - v->iov_base = repbuf; - v->iov_len = snprintf(repbuf, sizeof repbuf, - "last message repeated %d times", f->f_prevcount); + iov[5] = (struct iovec){ + .iov_base = repbuf, + .iov_len = snprintf(repbuf, sizeof(repbuf), + "last message repeated %d times", f->f_prevcount) + }; } else { - v->iov_base = f->f_prevline; - v->iov_len = f->f_prevlen; + iov[5] = (struct iovec){ + .iov_base = f->f_prevline, + .iov_len = f->f_prevlen + }; } - v++; - - dprintf("Logging to %s", TypeNames[f->f_type]); f->f_time = now; switch (f->f_type) { int port; case F_UNUSED: - dprintf("\n"); break; case F_FORW: - port = ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port); - if (port != 514) { - dprintf(" %s:%d\n", f->fu_forw_hname, port); - } else { - dprintf(" %s\n", f->fu_forw_hname); + switch (f->fu_forw_addr->ai_family) { + case AF_INET: + port = ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port); + break; + case AF_INET6: + port = ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port); + break; + default: + port = 0; + break; } /* check for local vs remote messages */ if (strcasecmp(f->f_prevhost, LocalHostName)) @@ -1223,7 +1264,8 @@ if (lsent == l && !send_to_all) break; } - dprintf("lsent/l: %d/%d\n", lsent, l); + SYSLOGD_SENDLOG_FORWARD(f->f_type, f->fu_forw_hname, port, + lsent, l); if (lsent != l) { int e = errno; logerror("sendto"); @@ -1245,7 +1287,7 @@ /* case ENOBUFS: */ /* case ECONNREFUSED: */ default: - dprintf("removing entry: errno=%d\n", e); + DPRINTF(LOG_ERR, "removing entry: errno=%d\n", e); f->f_type = F_UNUSED; break; } @@ -1253,10 +1295,33 @@ break; case F_FILE: - dprintf(" %s\n", f->fu_fname); - v->iov_base = lf; - v->iov_len = 1; - if (writev(f->f_file, iov, IOV_SIZE) < 0) { + iov[6] = (struct iovec){ + .iov_base = lf, + .iov_len = 1 + }; + if (SYSLOGD_SENDLOG_FILE_ENABLED()) { + int i; + char *buf, *buf0; + size_t len = 0; + + for (i = 0; i < (int)nitems(iov); i++) + len += iov[i].iov_len; + buf0 = buf = calloc(1, len); + if (buf0 != NULL) { + for (i = 0; i < (int)nitems(iov); i++) { + if (iov[i].iov_len) { + memcpy(buf, iov[i].iov_base, + iov[i].iov_len); + buf += iov[i].iov_len; + } + } + SYSLOGD_SENDLOG_FILE(f->f_type, f->fu_fname, + len, buf); + free(buf0); + } else + DPRINTF(LOG_ERR, "malloc filed"); + } + if (writev(f->f_file, iov, nitems(iov)) < 0) { /* * If writev(2) fails for potentially transient errors * like the filesystem being full, ignore it. @@ -1275,9 +1340,11 @@ break; case F_PIPE: - dprintf(" %s\n", f->fu_pipe_pname); - v->iov_base = lf; - v->iov_len = 1; + SYSLOGD_SENDLOG_PIPE(f->f_type, f->fu_pipe_pname); + iov[6] = (struct iovec){ + .iov_base = lf, + .iov_len = 1 + }; if (f->fu_pipe_pid == 0) { if ((f->f_file = p_open(f->fu_pipe_pname, &f->fu_pipe_pid)) < 0) { @@ -1286,7 +1353,7 @@ break; } } - if (writev(f->f_file, iov, IOV_SIZE) < 0) { + if (writev(f->f_file, iov, nitems(iov)) < 0) { int e = errno; close_filed(f); if (f->fu_pipe_pid > 0) @@ -1300,18 +1367,21 @@ case F_CONSOLE: if (flags & IGN_CONS) { - dprintf(" (ignored)\n"); + SYSLOGD_SENDLOG_TTY(f->f_type, _PATH_DEV, f->fu_fname, + 0); break; } /* FALLTHROUGH */ case F_TTY: - dprintf(" %s%s\n", _PATH_DEV, f->fu_fname); - v->iov_base = crlf; - v->iov_len = 2; + SYSLOGD_SENDLOG_TTY(f->f_type, _PATH_DEV, f->fu_fname, 1); + iov[6] = (struct iovec){ + .iov_base = crlf, + .iov_len = 2 + }; errno = 0; /* ttymsg() only sometimes returns an errno */ - if ((msgret = ttymsg(iov, IOV_SIZE, f->fu_fname, 10))) { + if ((msgret = ttymsg(iov, nitems(iov), f->fu_fname, 10))) { f->f_type = F_UNUSED; logerror(msgret); } @@ -1319,10 +1389,11 @@ case F_USERS: case F_WALL: - dprintf("\n"); - v->iov_base = crlf; - v->iov_len = 2; - wallmsg(f, iov, IOV_SIZE); + iov[6] = (struct iovec){ + .iov_base = crlf, + .iov_len = 2 + }; + wallmsg(f, iov, nitems(iov)); break; } f->f_prevcount = 0; @@ -1356,6 +1427,7 @@ errno = 0; /* already in msg */ logerror(p); } + SYSLOGD_SENDLOG_USER(f->f_type, ut->ut_line); continue; } /* should we send the message to this user? */ @@ -1368,6 +1440,7 @@ errno = 0; /* already in msg */ logerror(p); } + SYSLOGD_SENDLOG_USER(f->f_type, ut->ut_line); break; } } @@ -1438,13 +1511,11 @@ sigset_t omask, nmask; static char hname[NI_MAXHOST], ip[NI_MAXHOST]; - dprintf("cvthname(%d) len = %d, %zu\n", f->sa_family, f->sa_len, sizeof(struct sockaddr_in6)); error = getnameinfo(f, f->sa_len, ip, sizeof(ip), NULL, 0, NI_NUMERICHOST); - dprintf("cvthname(%s)\n", ip); - if (error) { - dprintf("Malformed from address %s\n", gai_strerror(error)); + DPRINTF(LOG_ERR, "Malformed from address: %s\n", + gai_strerror(error)); return ("???"); } if (!resolve) @@ -1458,7 +1529,8 @@ hname, sizeof hname, NULL, 0, NI_NAMEREQD); sigprocmask(SIG_SETMASK, &omask, NULL); if (error) { - dprintf("Host name for your address (%s) unknown\n", ip); + DPRINTF(LOG_ERR, "Hostname for your address (%s) unknown: %s\n", + ip, gai_strerror(error)); return (ip); } hl = strlen(hname); @@ -1482,6 +1554,14 @@ MarkSet = 1; } +static void +siginfo(int signo __unused) +{ + + DumpConfig = 1; +} + + /* * Print syslogd errors some place. */ @@ -1492,16 +1572,14 @@ static int recursed = 0; /* If there's an error while trying to log an error, give up. */ - if (recursed) + if (recursed++) return; - recursed++; if (errno) - (void)snprintf(buf, - sizeof buf, "syslogd: %s: %s", type, strerror(errno)); + snprintf(buf, sizeof(buf), "%s: %s", type, strerror(errno)); else - (void)snprintf(buf, sizeof buf, "syslogd: %s", type); + snprintf(buf, sizeof(buf), "%s", type); errno = 0; - dprintf("%s\n", buf); + DPRINTF(LOG_ERR, "%s", buf); logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE); recursed--; } @@ -1527,7 +1605,7 @@ } Initialized = was_initialized; if (signo) { - dprintf("syslogd: exiting on signal %d\n", signo); + DPRINTF(LOG_INFO, "syslogd: exiting on signal %d\n", signo); (void)snprintf(buf, sizeof(buf), "exiting on signal %d", signo); errno = 0; logerror(buf); @@ -1579,7 +1657,6 @@ /* * Foreach line in the conf table, open that file. */ - f = NULL; include_len = sizeof(include_str) -1; (void)strlcpy(host, "*", sizeof(host)); (void)strlcpy(prog, "*", sizeof(prog)); @@ -1603,18 +1680,19 @@ while (*tmp != '\0' && !isspace(*tmp)) tmp++; *tmp = '\0'; - dprintf("Trying to include files in '%s'\n", p); + SYSLOGD_CONFIG_INCLUDE_ENTRY(p); nents = scandir(p, &ent, configfiles, alphasort); if (nents == -1) { - dprintf("Unable to open '%s': %s\n", p, - strerror(errno)); + SYSLOGD_CONFIG_OPEN_FAILED(strerror(errno), + "unable to open", p); + SYSLOGD_CONFIG_INCLUDE_RETURN(); continue; } for (i = 0; i < nents; i++) { if (snprintf(file, sizeof(file), "%s/%s", p, ent[i]->d_name) >= (int)sizeof(file)) { - dprintf("ignoring path too long: " - "'%s/%s'\n", p, ent[i]->d_name); + SYSLOGD_CONFIG_OPEN_FAILED(0, + "too long path", ent[i]->d_name); free(ent[i]); continue; } @@ -1622,11 +1700,12 @@ cf2 = fopen(file, "r"); if (cf2 == NULL) continue; - dprintf("reading %s\n", file); + SYSLOGD_CONFIG_OPEN_SUCCESS(file); readconfigfile(cf2, 0); fclose(cf2); } free(ent); + SYSLOGD_CONFIG_INCLUDE_RETURN(); continue; } if (*p == '#') { @@ -1681,13 +1760,8 @@ } for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--) cline[i] = '\0'; - f = (struct filed *)calloc(1, sizeof(*f)); - if (f == NULL) { - logerror("calloc"); - exit(1); - } + f = cfline(cline, prog, host); STAILQ_INSERT_TAIL(&fhead, f, next); - cfline(cline, f, prog, host); } } @@ -1697,7 +1771,6 @@ static void init(int signo) { - int i; FILE *cf; struct filed *f; char *p; @@ -1705,7 +1778,7 @@ char hostMsg[2*MAXHOSTNAMELEN+40]; char bootfileMsg[LINE_MAX]; - dprintf("init\n"); + SYSLOGD_INIT_ENTRY(); /* * Load hostname (may have changed). @@ -1731,7 +1804,7 @@ * reload the timezone data. Respect any initial setting of * TZ, in case the system is configured specially. */ - dprintf("loading timezone data via tzset()\n"); + DPRINTF(LOG_INFO, "loading timezone data via tzset()\n"); if (getenv("TZ")) { tzset(); } else { @@ -1776,22 +1849,13 @@ /* open the configuration file */ if ((cf = fopen(ConfFile, "r")) == NULL) { - dprintf("cannot open %s\n", ConfFile); - f = calloc(1, sizeof(*f)); - if (f == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.ERR\t/dev/console", f, "*", "*"); - STAILQ_INSERT_TAIL(&fhead, f, next); + SYSLOGD_CONFIG_OPEN_FAILED(0, strerror(errno), + __DECONST(char *, ConfFile)); - f = calloc(1, sizeof(*f)); - if (f == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.PANIC\t*", f, "*", "*"); + f = cfline("*.ERR\t/dev/console", "*", "*"); STAILQ_INSERT_TAIL(&fhead, f, next); + f = cfline("*.PANIC\t*", "*", "*"); + STAILQ_INSERT_TAIL(&fhead, f, next); Initialized = 1; return; @@ -1804,52 +1868,7 @@ Initialized = 1; - if (Debug) { - int port; - STAILQ_FOREACH(f, &fhead, next) { - for (i = 0; i <= LOG_NFACILITIES; i++) - if (f->f_pmask[i] == INTERNAL_NOPRI) - printf("X "); - else - printf("%d ", f->f_pmask[i]); - printf("%s: ", TypeNames[f->f_type]); - switch (f->f_type) { - case F_FILE: - printf("%s", f->fu_fname); - break; - - case F_CONSOLE: - case F_TTY: - printf("%s%s", _PATH_DEV, f->fu_fname); - break; - - case F_FORW: - port = ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port); - if (port != 514) { - printf("%s:%d", - f->fu_forw_hname, port); - } else { - printf("%s", f->fu_forw_hname); - } - break; - - case F_PIPE: - printf("%s", f->fu_pipe_pname); - break; - - case F_USERS: - for (i = 0; i < MAXUNAMES && *f->fu_uname[i]; i++) - printf("%s, ", f->fu_uname[i]); - break; - } - if (f->f_program) - printf(" (%s)", f->f_program); - printf("\n"); - } - } - logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE); - dprintf("syslogd: restarted\n"); /* * Log a change in hostname, but only on a restart. */ @@ -1858,7 +1877,6 @@ "syslogd: hostname changed, \"%s\" to \"%s\"", oldLocalHostName, LocalHostName); logmsg(LOG_SYSLOG|LOG_INFO, hostMsg, LocalHostName, ADDDATE); - dprintf("%s\n", hostMsg); } /* * Log the kernel boot file if we aren't going to use it as @@ -1868,28 +1886,31 @@ (void)snprintf(bootfileMsg, sizeof(bootfileMsg), "syslogd: kernel boot file is %s", bootfile); logmsg(LOG_KERN|LOG_INFO, bootfileMsg, LocalHostName, ADDDATE); - dprintf("%s\n", bootfileMsg); } + SYSLOGD_INIT_RETURN(); } /* * Crack a configuration file line */ -static void -cfline(const char *line, struct filed *f, const char *prog, const char *host) +struct filed * +cfline(const char *line, const char *prog, const char *host) { struct addrinfo hints, *res; + struct filed *f; int error, i, pri, syncfile; const char *p, *q; char *bp; char buf[MAXLINE], ebuf[100]; - dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); - + DPRINTF(LOG_DEBUG, "cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); errno = 0; /* keep strerror() stuff out of logerror messages */ - /* clear out file entry */ - memset(f, 0, sizeof(*f)); + f = calloc(1, sizeof(*f)); + if (f == NULL) { + logerror("calloc"); + exit(1); + } for (i = 0; i <= LOG_NFACILITIES; i++) f->f_pmask[i] = INTERNAL_NOPRI; @@ -1980,10 +2001,10 @@ pri = decode(buf, prioritynames); if (pri < 0) { errno = 0; - (void)snprintf(ebuf, sizeof ebuf, + (void)snprintf(ebuf, sizeof(ebuf), "unknown priority name \"%s\"", buf); logerror(ebuf); - return; + return (f); } } if (!pri_cmp) @@ -2013,7 +2034,7 @@ "unknown facility name \"%s\"", buf); logerror(ebuf); - return; + return(f); } f->f_pmask[i >> 3] = pri; f->f_pcmp[i >> 3] = pri_cmp; @@ -2130,6 +2151,17 @@ f->f_type = F_USERS; break; } + + if (SYSLOGD_DUMP_FILED_ENABLED()) { + char *mask, *users; + + mask = masktostr(f); + users = userstostr(f); + SYSLOGD_DUMP_FILED(f, mask, users); + free(mask); + free(users); + } + return (f); } @@ -2159,7 +2191,87 @@ return (-1); } +static char * +masktostr(struct filed *f) +{ + int i; + char *mask; + + mask = calloc(1, LOG_NFACILITIES * 2 + 1); + if (mask == NULL) + err(1, "malloc"); + for (i = 0; i <= LOG_NFACILITIES; i++) { + mask[i * 2] = ' '; + if (f->f_pmask[i] == INTERNAL_NOPRI) + mask[i * 2 + 1] = 'X'; + else + mask[i * 2 + 1] = '0' + f->f_pmask[i]; + } + return (mask); +} +static char * +userstostr(struct filed *f) +{ + size_t len = 0, len0 = 0; + char *users, *p; + int i; + + users = NULL; + if (f->f_type == F_USERS) { + for (i = 0; i < MAXUNAMES && *f->fu_uname[i]; i++) { + printf("%s, ", f->fu_uname[i]); + + len = strlen(f->fu_uname[i]) + 1; + if (i == 0) { + users = malloc(len); + if (users == NULL) + err(1, "malloc"); + p = users; + } else { + users = realloc(users, + len0 + 1 + len + 1); + if (users == NULL) + err(1, "malloc"); + p = users + strlen(users); + *p = ','; + p++; + *p = ' '; + p++; + } + strncpy(p, f->fu_uname[i], len); + p[len] = '\0'; + len0 += len; + } + } + return (users); +} + static void +dumpconfig(void) +{ + struct filed *f; + struct allowedpeer *ap; + char *mask, *users; + + DPRINTF(LOG_INFO, "===> Start to dump the current configuration.\n"); + if (SYSLOGD_DUMP_FILED_ENABLED()) { + STAILQ_FOREACH(f, &fhead, next) { + mask = masktostr(f); + users = masktostr(f); + SYSLOGD_DUMP_FILED(f, mask, users); + free(mask); + free(users); + } + } + if (SYSLOGD_DUMP_RULE_ENABLED()) { + STAILQ_FOREACH(ap, &aphead, next) + SYSLOGD_DUMP_RULE(ap); + } + DPRINTF(LOG_INFO, "===> End of configuration.\n"); + DumpConfig = 0; +} + +static void markit(void) { struct filed *f; @@ -2175,8 +2287,7 @@ STAILQ_FOREACH(f, &fhead, next) { if (f->f_prevcount && now >= REPEATTIME(f)) { - dprintf("flush %s: repeated %d times, %d sec.\n", - TypeNames[f->f_type], f->f_prevcount, + SYSLOGD_MARKIT_DEDUP(f->f_type, f->f_prevcount, repeatinterval[f->f_repeatcount]); fprintlog(f, 0, (char *)NULL); BACKOFF(f); @@ -2312,7 +2423,6 @@ int i; u_int32_t *addr6p, *mask6p; #endif - char ip[NI_MAXHOST]; ap = calloc(1, sizeof(*ap)); if (ap == NULL) @@ -2437,24 +2547,8 @@ #endif } STAILQ_INSERT_TAIL(&aphead, ap, next); + SYSLOGD_DUMP_RULE(ap); - if (Debug) { - printf("allowaddr: rule "); - if (ap->isnumeric) { - printf("numeric, "); - getnameinfo((struct sockaddr *)&ap->a_addr, - ((struct sockaddr *)&ap->a_addr)->sa_len, - ip, sizeof ip, NULL, 0, NI_NUMERICHOST); - printf("addr = %s, ", ip); - getnameinfo((struct sockaddr *)&ap->a_mask, - ((struct sockaddr *)&ap->a_mask)->sa_len, - ip, sizeof ip, NULL, 0, NI_NUMERICHOST); - printf("mask = %s; ", ip); - } else { - printf("domainname = %s; ", ap->a_name); - } - printf("port = %d\n", ap->port); - } return (0); } @@ -2476,13 +2570,13 @@ u_short sport; int num = 0; - STAILQ_FOREACH(ap, &aphead, next) { + STAILQ_FOREACH(ap, &aphead, next) num++; - } - dprintf("# of validation rule: %d\n", num); - if (num == 0) + if (num == 0) { /* traditional behaviour, allow everything */ + SYSLOGD_PEER_ACCEPTED(0, ip, port, name); return (1); + } (void)strlcpy(name, hname, sizeof(name)); memset(&hints, 0, sizeof(hints)); @@ -2498,7 +2592,7 @@ if (getnameinfo(sa, sa->sa_len, ip, sizeof(ip), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) != 0) return (0); /* for safety, should not occur */ - dprintf("validate: dgram from IP %s, port %s, name %s;\n", + DPRINTF(LOG_DEBUG, "validate: dgram from IP %s, port %s, name %s;\n", ip, port, name); sport = atoi(port); @@ -2507,14 +2601,14 @@ STAILQ_FOREACH(ap, &aphead, next) { i++; if (ap->port != 0 && ap->port != sport) { - dprintf("rejected in rule %d due to port mismatch.\n", - i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, name, "port"); continue; } if (ap->isnumeric) { if (ap->a_addr.ss_family != sa->sa_family) { - dprintf("rejected in rule %d due to address family mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, name, + "family"); continue; } if (ap->a_addr.ss_family == AF_INET) { @@ -2523,7 +2617,8 @@ m4p = satosin(&ap->a_mask); if ((sin4->sin_addr.s_addr & m4p->sin_addr.s_addr) != a4p->sin_addr.s_addr) { - dprintf("rejected in rule %d due to IP mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, + name, "inet ip"); continue; } } @@ -2534,12 +2629,14 @@ m6p = satosin6(&ap->a_mask); if (a6p->sin6_scope_id != 0 && sin6->sin6_scope_id != a6p->sin6_scope_id) { - dprintf("rejected in rule %d due to scope mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, + name, "inet6 scope"); continue; } if (IN6_ARE_MASKED_ADDR_EQUAL(&sin6->sin6_addr, &a6p->sin6_addr, &m6p->sin6_addr) != 0) { - dprintf("rejected in rule %d due to IP mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, + name, "inet6 ip"); continue; } } @@ -2554,7 +2651,8 @@ cp++; l2 = strlen(cp); if (l2 > l1 || memcmp(cp, &name[l1 - l2], l2) != 0) { - dprintf("rejected in rule %d due to name mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, + name, "name"); continue; } } else { @@ -2561,14 +2659,16 @@ /* exact match */ l2 = strlen(cp); if (l2 != l1 || memcmp(cp, name, l1) != 0) { - dprintf("rejected in rule %d due to name mismatch.\n", i); + SYSLOGD_PEER_MISMATCH(ap, ip, port, + name, "name"); continue; } } } - dprintf("accepted in rule %d.\n", i); + SYSLOGD_PEER_ACCEPTED(ap, ip, port, name); return (1); /* hooray! */ } + SYSLOGD_PEER_REJECTED(ip, port, name); return (0); } @@ -2767,12 +2867,17 @@ hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; - dprintf("Try %s\n", pe->pe_name); + SYSLOGD_SOCK_OPEN_ENTRY(__DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); if (pe->pe_serv == NULL) pe->pe_serv = "syslog"; error = getaddrinfo(pe->pe_name, pe->pe_serv, &hints, &res0); if (error) { logerror(gai_strerror(error)); + SYSLOGD_SOCK_OPEN_FAILED("getaddrinfo", + __DECONST(char *, gai_strerror(error)), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); errno = 0; die(0); } @@ -2784,6 +2889,11 @@ unlink(pe->pe_name); else if (SecureMode > 1) { /* Only AF_LOCAL in secure mode. */ + SYSLOGD_SOCK_OPEN_FAILED(0, + "inet/inet6 sockets not allowed in " + "secure mode > 1", + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); continue; } if (family != AF_UNSPEC && res->ai_family != family) @@ -2793,6 +2903,9 @@ res->ai_protocol); if (s < 0) { logerror("socket"); + SYSLOGD_SOCK_OPEN_FAILED("socket", strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); error++; continue; } @@ -2803,6 +2916,10 @@ logerror("setsockopt(IPV6_V6ONLY)"); close(s); error++; + SYSLOGD_SOCK_OPEN_FAILED( + "setsockopt(IPV6_V6ONLY)", strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); continue; } } @@ -2812,6 +2929,10 @@ logerror("setsockopt(SO_REUSEADDR)"); close(s); error++; + SYSLOGD_SOCK_OPEN_FAILED( + "setsockopt(SO_REUSEADDR)", strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); continue; } /* @@ -2827,6 +2948,10 @@ logerror("bind"); close(s); error++; + SYSLOGD_SOCK_OPEN_FAILED("bind", + strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); continue; } if (SecureMode == 0) @@ -2834,26 +2959,31 @@ } if (res->ai_family == AF_LOCAL && chmod(pe->pe_name, pe->pe_mode) < 0) { - dprintf("chmod %s: %s\n", pe->pe_name, - strerror(errno)); + SYSLOGD_SOCK_OPEN_FAILED("chmod", + strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); close(s); error++; continue; } - dprintf("new socket fd is %d\n", s); listen(s, 5); - dprintf("shutdown\n"); if (SecureMode) { /* Forbid communication in secure mode. */ if (shutdown(s, SHUT_RD) < 0 && errno != ENOTCONN) { logerror("shutdown"); - if (!Debug) + SYSLOGD_SOCK_OPEN_FAILED("shutdown", + strerror(errno), + __DECONST(char *, pe->pe_name), + __DECONST(char *, pe->pe_serv)); + close(s); + if (!Fflag) die(0); } - dprintf("listening on inet socket\n"); - } else - dprintf("sending on inet socket\n"); + } + SYSLOGD_SOCK_OPEN_SUCCESS(res->ai_family, s, SecureMode); + sl = calloc(1, sizeof(*sl)); if (sl == NULL) err(1, "malloc failed");