From 1a5ad5e05f74ec0e0af686dfc8c79e64a1ca81fc Mon Sep 17 00:00:00 2001 From: ngie Date: Thu, 22 Jun 2017 07:08:18 +0000 Subject: [PATCH] MFC r308139,r308157,r308160,r316818,r318250,r318443: r308139 (by bapt): cron(8): add support for /etc/cron.d and /usr/local/etc/cron.d For automation tools it is way easier to maintain files in directories rather than modifying /etc/crontab. The files in those directories are in the same format as /etc/crontab Relnotes: yes r308157 (by bapt): Fix typo in cron(8) date r308160 (by bapt): syslogd(8): add an 'include' keyword All the '.conf' files not beginning with a '.' contained int he directory following the keyword will be included. This keyword can only be used in the first level configuration files. Modify the default syslogd.conf to 'include' /etc/syslog.d and /usr/local/etc/syslog.d It simplify a lot handling of syslog from automation tools. Relnotes: yes r316818: Conditionally install /etc/pam.d/ftp* and /etc/pam.d/telnetd /etc/pam.d/ftp* should be installed with MK_FTP != no and /etc/pam.d/telnetd should be installed when MK_TELNET != no. r318250: Handle the logfiles in newsyslog and syslogd conditionally, based on src.conf(5) knobs This will allow consumers of FreeBSD to use the unmodified configuration files out of the box more than previously. Both newsyslog.conf and syslog.conf: - /var/log/lpd-errs (MK_LPR != no) - /var/log/ppp.log (MK_PPP != no) - /var/log/xferlog (MK_FTP != no) newsyslog.conf: - /var/log/amd.log (MK_AMD != no) - /var/log/pflog (MK_PF != no) - /var/log/sendmail.st (MK_SENDMAIL != no) r318443: Conditionally handle the crontab entry for atrun(8) The default crontab prior to this commit assumes atrun(8) is always present, which isn't true if MK_AT == no. Move atrun(8) execution from /etc/crontab to /etc/cron.d/at, and base /etc/cron.d/at's installation on MK_AT. cron(8) will detect /etc/cron.d/at's presence when the configuration is loaded and run atrun every 5 minutes like it would prior to this commit. SHELL and PATH are duplicated between /etc/crontab and /etc/cron.d/at because atrun(8) executes programs, which may rely on environment set in the current default /etc/crontab. Noted by: bdrewery (in an internal review) Relnotes: yes (may need to add environmental modifications to /etc/cron.d/at) git-svn-id: svn://svn.freebsd.org/base/stable/10@320222 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- etc/Makefile | 4 +- etc/cron.d/Makefile | 11 ++ etc/cron.d/at | 7 + etc/crontab | 2 - etc/mtree/BSD.root.dist | 4 + etc/newsyslog.conf | 6 - etc/newsyslog.conf.d/Makefile | 24 +++ etc/newsyslog.conf.d/amd.conf | 2 + etc/newsyslog.conf.d/ftp.conf | 2 + etc/newsyslog.conf.d/lpr.conf | 2 + etc/newsyslog.conf.d/pf.conf | 2 + etc/newsyslog.conf.d/ppp.conf | 2 + etc/newsyslog.conf.d/sendmail.conf | 2 + etc/pam.d/Makefile | 39 +++- etc/syslog.conf | 6 +- etc/syslog.d/Makefile | 19 ++ etc/syslog.d/ftp.conf | 2 + etc/syslog.d/lpr.conf | 2 + etc/syslog.d/ppp.conf | 3 + tools/build/mk/OptionalObsoleteFiles.inc | 12 ++ usr.sbin/cron/cron/cron.8 | 8 +- usr.sbin/cron/cron/cron.h | 2 +- usr.sbin/cron/cron/database.c | 46 ++++- usr.sbin/cron/cron/pathnames.h | 2 + usr.sbin/cron/lib/misc.c | 6 +- usr.sbin/syslogd/syslog.conf.5 | 8 +- usr.sbin/syslogd/syslogd.c | 232 +++++++++++++++-------- 27 files changed, 349 insertions(+), 108 deletions(-) create mode 100644 etc/cron.d/Makefile create mode 100644 etc/cron.d/at create mode 100644 etc/newsyslog.conf.d/amd.conf create mode 100644 etc/newsyslog.conf.d/ftp.conf create mode 100644 etc/newsyslog.conf.d/lpr.conf create mode 100644 etc/newsyslog.conf.d/pf.conf create mode 100644 etc/newsyslog.conf.d/ppp.conf create mode 100644 etc/newsyslog.conf.d/sendmail.conf create mode 100644 etc/syslog.d/Makefile create mode 100644 etc/syslog.d/ftp.conf create mode 100644 etc/syslog.d/lpr.conf create mode 100644 etc/syslog.d/ppp.conf diff --git a/etc/Makefile b/etc/Makefile index ffc299f36..edf4a5ca7 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -4,7 +4,9 @@ .include SUBDIR= \ - newsyslog.conf.d + cron.d \ + newsyslog.conf.d \ + syslog.d .if ${MK_SENDMAIL} != "no" SUBDIR+=sendmail diff --git a/etc/cron.d/Makefile b/etc/cron.d/Makefile new file mode 100644 index 000000000..aa487cbfb --- /dev/null +++ b/etc/cron.d/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.include + +.if ${MK_AT} != "no" +FILES+= at +.endif + +BINDIR= /etc/cron.d + +.include diff --git a/etc/cron.d/at b/etc/cron.d/at new file mode 100644 index 000000000..61fe5a843 --- /dev/null +++ b/etc/cron.d/at @@ -0,0 +1,7 @@ +# $FreeBSD$ +# +SHELL=/bin/sh +PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin + +# See crontab(5) for field format. +*/5 * * * * root /usr/libexec/atrun diff --git a/etc/crontab b/etc/crontab index e1e6e8862..a3248dabe 100644 --- a/etc/crontab +++ b/etc/crontab @@ -7,8 +7,6 @@ PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin # #minute hour mday month wday who command # -*/5 * * * * root /usr/libexec/atrun -# # Save some entropy so that /dev/random can re-seed on boot. */11 * * * * operator /usr/libexec/save-entropy # diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist index 4f3bdfc69..b47d9816a 100644 --- a/etc/mtree/BSD.root.dist +++ b/etc/mtree/BSD.root.dist @@ -30,6 +30,8 @@ .. bluetooth .. + cron.d + .. defaults .. devd @@ -72,6 +74,8 @@ .. ssl .. + syslog.d + .. zfs .. .. diff --git a/etc/newsyslog.conf b/etc/newsyslog.conf index ab595cac6..966fb329c 100644 --- a/etc/newsyslog.conf +++ b/etc/newsyslog.conf @@ -18,7 +18,6 @@ # # logfilename [owner:group] mode count size when flags [/pid_file] [sig_num] /var/log/all.log 600 7 * @T00 J -/var/log/amd.log 644 7 100 * J /var/log/auth.log 600 7 100 @0101T JC /var/log/console.log 600 5 100 * J /var/log/cron 600 3 100 * JC @@ -26,18 +25,13 @@ /var/log/debug.log 600 7 100 * JC /var/log/init.log 644 3 100 * J /var/log/kerberos.log 600 7 100 * J -/var/log/lpd-errs 644 7 100 * JC /var/log/maillog 640 7 * @T00 JC /var/log/messages 644 5 100 @0101T JC /var/log/monthly.log 640 12 * $M1D0 JN -/var/log/pflog 600 3 100 * JB /var/run/pflogd.pid -/var/log/ppp.log root:network 640 3 100 * JC /var/log/devd.log 644 3 100 * JC /var/log/security 600 10 100 * JC -/var/log/sendmail.st 640 10 * 168 BN /var/log/utx.log 644 3 * @01T05 B /var/log/weekly.log 640 5 * $W6D0 JN -/var/log/xferlog 600 7 100 * JC /etc/newsyslog.conf.d/* /usr/local/etc/newsyslog.conf.d/* diff --git a/etc/newsyslog.conf.d/Makefile b/etc/newsyslog.conf.d/Makefile index 46609576a..58aac203b 100644 --- a/etc/newsyslog.conf.d/Makefile +++ b/etc/newsyslog.conf.d/Makefile @@ -6,8 +6,32 @@ BINDIR= /etc/newsyslog.conf.d FILES= +.if ${MK_AMD} != "no" +FILES+= amd.conf +.endif + +.if ${MK_FTP} != "no" +FILES+= ftp.conf +.endif + +.if ${MK_LPR} != "no" +FILES+= lpr.conf +.endif + .if ${MK_OFED} != "no" FILES+= opensm.conf .endif +.if ${MK_PF} != "no" +FILES+= pf.conf +.endif + +.if ${MK_PPP} != "no" +FILES+= ppp.conf +.endif + +.if ${MK_SENDMAIL} != "no" +FILES+= sendmail.conf +.endif + .include diff --git a/etc/newsyslog.conf.d/amd.conf b/etc/newsyslog.conf.d/amd.conf new file mode 100644 index 000000000..6bacc700d --- /dev/null +++ b/etc/newsyslog.conf.d/amd.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/amd.log 644 7 100 * J diff --git a/etc/newsyslog.conf.d/ftp.conf b/etc/newsyslog.conf.d/ftp.conf new file mode 100644 index 000000000..16cea6493 --- /dev/null +++ b/etc/newsyslog.conf.d/ftp.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/xferlog 600 7 100 * JC diff --git a/etc/newsyslog.conf.d/lpr.conf b/etc/newsyslog.conf.d/lpr.conf new file mode 100644 index 000000000..d3beff1eb --- /dev/null +++ b/etc/newsyslog.conf.d/lpr.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/lpd-errs 644 7 100 * JC diff --git a/etc/newsyslog.conf.d/pf.conf b/etc/newsyslog.conf.d/pf.conf new file mode 100644 index 000000000..71adbfd76 --- /dev/null +++ b/etc/newsyslog.conf.d/pf.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/pflog 600 3 100 * JB /var/run/pflogd.pid diff --git a/etc/newsyslog.conf.d/ppp.conf b/etc/newsyslog.conf.d/ppp.conf new file mode 100644 index 000000000..3e62968b1 --- /dev/null +++ b/etc/newsyslog.conf.d/ppp.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/ppp.log root:network 640 3 100 * JC diff --git a/etc/newsyslog.conf.d/sendmail.conf b/etc/newsyslog.conf.d/sendmail.conf new file mode 100644 index 000000000..5cb59c4e8 --- /dev/null +++ b/etc/newsyslog.conf.d/sendmail.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/var/log/sendmail.st 640 10 * 168 BN diff --git a/etc/pam.d/Makefile b/etc/pam.d/Makefile index 7369022cc..626e22ae9 100644 --- a/etc/pam.d/Makefile +++ b/etc/pam.d/Makefile @@ -1,23 +1,52 @@ # $FreeBSD$ +.include + NO_OBJ= +FILESGROUPS= FILES + FILES= README \ - atrun \ cron \ - ftpd \ imap \ login \ other \ passwd pop3 \ - rsh \ sshd su system \ - telnetd \ xdm FILESDIR= /etc/pam.d FILESMODE= 644 -FILESMODE_README= 444 + +.if ${MK_AT} != "no" +FILESGROUPS+= AT +AT+= atrun +ATDIR= ${FILESDIR} +ATMODE= ${FILESMODE} +.endif + +.if ${MK_FTP} != "no" +FILESGROUPS+= FTP +FTP+= ftpd +FTPDIR= ${FILESDIR} +FTPMODE= ${FILESMODE} LINKS= ${FILESDIR}/ftpd ${FILESDIR}/ftp +.endif + +.if ${MK_RCMDS} != "no" +FILESGROUPS+= RCMDS +RCMDS+= rsh +RCMDSDIR= ${FILESDIR} +RCMDSMODE= ${FILESMODE} +.endif + +.if ${MK_TELNET} != "no" +FILESGROUPS+= TELNET +TELNET+= telnetd +TELNETDIR= ${FILESDIR} +TELNETMODE= ${FILESMODE} +.endif + +FILESMODE_README= 444 .include diff --git a/etc/syslog.conf b/etc/syslog.conf index e65db5347..e0df421b9 100644 --- a/etc/syslog.conf +++ b/etc/syslog.conf @@ -10,8 +10,6 @@ security.* /var/log/security auth.info;authpriv.info /var/log/auth.log mail.info /var/log/maillog -lpr.info /var/log/lpd-errs -ftp.info /var/log/xferlog cron.* /var/log/cron !-devd *.=debug /var/log/debug.log @@ -31,6 +29,6 @@ cron.* /var/log/cron # Uncomment this if you wish to see messages produced by devd # !devd # *.>=notice /var/log/devd.log -!ppp -*.* /var/log/ppp.log !* +include /etc/syslog.d +include /usr/local/etc/syslog.d diff --git a/etc/syslog.d/Makefile b/etc/syslog.d/Makefile new file mode 100644 index 000000000..315950221 --- /dev/null +++ b/etc/syslog.d/Makefile @@ -0,0 +1,19 @@ +# $FreeBSD$ + +.include + +.if ${MK_FTP} != "no" +FILES+= ftp.conf +.endif + +.if ${MK_LPR} != "no" +FILES+= lpr.conf +.endif + +.if ${MK_PPP} != "no" +FILES+= ppp.conf +.endif + +BINDIR= /etc/syslog.d + +.include diff --git a/etc/syslog.d/ftp.conf b/etc/syslog.d/ftp.conf new file mode 100644 index 000000000..d4d11cfb7 --- /dev/null +++ b/etc/syslog.d/ftp.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +ftp.info /var/log/xferlog diff --git a/etc/syslog.d/lpr.conf b/etc/syslog.d/lpr.conf new file mode 100644 index 000000000..0eb6eb06d --- /dev/null +++ b/etc/syslog.d/lpr.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +lpr.info /var/log/lpd-errs diff --git a/etc/syslog.d/ppp.conf b/etc/syslog.d/ppp.conf new file mode 100644 index 000000000..57ee868bd --- /dev/null +++ b/etc/syslog.d/ppp.conf @@ -0,0 +1,3 @@ +# $FreeBSD$ +!ppp +*.* /var/log/ppp.log diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 43bbff97d..3068ad9e8 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -56,6 +56,7 @@ OLD_FILES+=usr/share/man/man8/iasl.8.gz .if ${MK_AMD} == no OLD_FILES+=etc/amd.map +OLD_FILES+=etc/newsyslog.conf.d/amd.conf OLD_FILES+=etc/rc.d/amd OLD_FILES+=usr/bin/pawd OLD_FILES+=usr/sbin/amd @@ -1063,7 +1064,11 @@ OLD_FILES+=usr/share/man/man8/fmtree.8.gz .if ${MK_FTP} == no OLD_FILES+=etc/ftpusers +OLD_FILES+=etc/newsyslog.conf.d/ftp.conf +OLD_FILES+=etc/pam.d/ftp +OLD_FILES+=etc/pam.d/ftpd OLD_FILES+=etc/rc.d/ftpd +OLD_FILES+=etc/syslog.d/ftp.conf OLD_FILES+=usr/bin/ftp OLD_FILES+=usr/bin/gate-ftp OLD_FILES+=usr/bin/pftp @@ -3816,7 +3821,9 @@ OLD_FILES+=usr/share/man/man8/updatedb.8.gz .if ${MK_LPR} == no OLD_FILES+=etc/hosts.lpd OLD_FILES+=etc/printcap +OLD_FILES+=etc/newsyslog.conf.d/lpr.conf OLD_FILES+=etc/rc.d/lpd +OLD_FILES+=etc/syslog.d/lpr.conf OLD_FILES+=usr/bin/lp OLD_FILES+=usr/bin/lpq OLD_FILES+=usr/bin/lpr @@ -4192,6 +4199,7 @@ OLD_DIRS+=usr/share/examples/pc-sysinstall .endif .if ${MK_PF} == no +OLD_FILES+=etc/newsyslog.conf.d/pf.conf OLD_FILES+=etc/periodic/security/520.pfdenied OLD_FILES+=etc/pf.os OLD_FILES+=etc/rc.d/ftp-proxy @@ -4260,7 +4268,9 @@ OLD_FILES+=usr/share/man/man8/portsnap.8.gz .endif .if ${MK_PPP} == no +OLD_FILES+=etc/newsyslog.conf.d/ppp.conf OLD_FILES+=etc/ppp/ppp.conf +OLD_FILES+=etc/syslog.d/ppp.conf OLD_DIRS+=etc/ppp OLD_FILES+=usr/sbin/ppp OLD_FILES+=usr/sbin/pppctl @@ -4460,6 +4470,7 @@ OLD_FILES+=usr/share/man/man8/rtquery.8.gz .endif .if ${MK_SENDMAIL} == no +OLD_FILES+=etc/newsyslog.conf.d/sendmail.conf OLD_FILES+=etc/periodic/daily/150.clean-hoststat OLD_FILES+=etc/periodic/daily/440.status-mailq OLD_FILES+=etc/periodic/daily/460.status-mail-rejects @@ -4778,6 +4789,7 @@ OLD_FILES+=usr/share/nls/uk_UA.UTF-8/tcsh.cat .endif .if ${MK_TELNET} == no +OLD_FILES+=etc/pam.d/telnetd OLD_FILES+=usr/bin/telnet OLD_FILES+=usr/libexec/telnetd OLD_FILES+=usr/share/man/man1/telnet.1.gz diff --git a/usr.sbin/cron/cron/cron.8 b/usr.sbin/cron/cron/cron.8 index 5d5a8d9a9..d7f34cff8 100644 --- a/usr.sbin/cron/cron/cron.8 +++ b/usr.sbin/cron/cron/cron.8 @@ -17,7 +17,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 29, 2008 +.Dd October 31, 2016 .Dt CRON 8 .Os .Sh NAME @@ -52,7 +52,11 @@ The .Nm utility also searches for .Pa /etc/crontab -which is in a different format (see +and files in +.Pa /etc/cron.d +and +.Pa /usr/local/etc/cron.d +which are in a different format (see .Xr crontab 5 ) . .Pp The diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h index 60b2a9081..a6810be84 100644 --- a/usr.sbin/cron/cron/cron.h +++ b/usr.sbin/cron/cron/cron.h @@ -218,7 +218,7 @@ void set_cron_uid(void), unget_char(int, FILE *), free_entry(entry *), skip_comments(FILE *), - log_it(char *, int, char *, char *), + log_it(char *, int, char *, const char *), log_close(void); int job_runqueue(void), diff --git a/usr.sbin/cron/cron/database.c b/usr.sbin/cron/cron/database.c index 7a44d1429..2ac7113c1 100644 --- a/usr.sbin/cron/cron/database.c +++ b/usr.sbin/cron/cron/database.c @@ -45,9 +45,18 @@ load_database(old_db) DIR *dir; struct stat statbuf; struct stat syscron_stat; + time_t maxmtime; DIR_T *dp; cron_db new_db; user *u, *nu; + struct { + const char *name; + struct stat st; + } syscrontabs [] = { + { SYSCRONTABS }, + { LOCALSYSCRONTABS } + }; + int i; Debug(DLOAD, ("[%d] load_database()\n", getpid())) @@ -65,6 +74,16 @@ load_database(old_db) if (stat(SYSCRONTAB, &syscron_stat) < OK) syscron_stat.st_mtime = 0; + maxmtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + + for (i = 0; i < nitems(syscrontabs); i++) { + if (stat(syscrontabs[i].name, &syscrontabs[i].st) != -1) { + maxmtime = TMAX(syscrontabs[i].st.st_mtime, maxmtime); + } else { + syscrontabs[i].st.st_mtime = 0; + } + } + /* if spooldir's mtime has not changed, we don't need to fiddle with * the database. * @@ -72,7 +91,7 @@ load_database(old_db) * so is guaranteed to be different than the stat() mtime the first * time this function is called. */ - if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) { + if (old_db->mtime == maxmtime) { Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n", getpid())) return; @@ -83,7 +102,7 @@ load_database(old_db) * actually changed. Whatever is left in the old database when * we're done is chaff -- crontabs that disappeared. */ - new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + new_db.mtime = maxmtime; new_db.head = new_db.tail = NULL; if (syscron_stat.st_mtime) { @@ -92,6 +111,29 @@ load_database(old_db) &new_db, old_db); } + for (i = 0; i < nitems(syscrontabs); i++) { + char tabname[MAXPATHLEN]; + if (syscrontabs[i].st.st_mtime == 0) + continue; + if (!(dir = opendir(syscrontabs[i].name))) { + log_it("CRON", getpid(), "OPENDIR FAILED", + syscrontabs[i].name); + (void) exit(ERROR_EXIT); + } + + while (NULL != (dp = readdir(dir))) { + if (dp->d_name[0] == '.') + continue; + if (dp->d_type != DT_REG) + continue; + snprintf(tabname, sizeof(tabname), "%s/%s", + syscrontabs[i].name, dp->d_name); + process_crontab("root", SYS_NAME, tabname, + &syscrontabs[i].st, &new_db, old_db); + } + closedir(dir); + } + /* we used to keep this dir open all the time, for the sake of * efficiency. however, we need to close it in every fork, and * we fork a lot more often than the mtime of the dir changes. diff --git a/usr.sbin/cron/cron/pathnames.h b/usr.sbin/cron/cron/pathnames.h index ba91bfdc6..fe3ebf55d 100644 --- a/usr.sbin/cron/cron/pathnames.h +++ b/usr.sbin/cron/cron/pathnames.h @@ -62,6 +62,8 @@ /* 4.3BSD-style crontab */ #define SYSCRONTAB "/etc/crontab" +#define SYSCRONTABS "/etc/cron.d" +#define LOCALSYSCRONTABS "/usr/local/etc/cron.d" /* what editor to use if no EDITOR or VISUAL * environment variable specified. diff --git a/usr.sbin/cron/lib/misc.c b/usr.sbin/cron/lib/misc.c index afed07f3e..6a0b8acbd 100644 --- a/usr.sbin/cron/lib/misc.c +++ b/usr.sbin/cron/lib/misc.c @@ -385,11 +385,7 @@ out: if (allow) void -log_it(username, xpid, event, detail) - char *username; - int xpid; - char *event; - char *detail; +log_it(char *username, int xpid, char *event, const char *detail) { #if defined(LOG_FILE) || DEBUGGING PID_T pid = xpid; diff --git a/usr.sbin/syslogd/syslog.conf.5 b/usr.sbin/syslogd/syslog.conf.5 index 3378aa08c..94c1cd415 100644 --- a/usr.sbin/syslogd/syslog.conf.5 +++ b/usr.sbin/syslogd/syslog.conf.5 @@ -28,7 +28,7 @@ .\" @(#)syslog.conf.5 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd September 12, 2012 +.Dd November 1, 2016 .Dt SYSLOG.CONF 5 .Os .Sh NAME @@ -62,6 +62,12 @@ field is separated from the .Em action field by one or more tab characters or spaces. .Pp +A special +.Em include +keyword can be used to include all files with names ending in '.conf' and not +beginning with a '.' contained in the directory following the keyword. +This keyword can only be used in the first level configuration file. +.Pp Note that if you use spaces as separators, your .Nm might be incompatible with other Unices or Unix-like systems. diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 3d5429f9e..80d09bc97 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -97,6 +97,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -120,6 +121,8 @@ __FBSDID("$FreeBSD$"); const char *ConfFile = _PATH_LOGCONF; const char *PidFile = _PATH_LOGPID; const char ctty[] = _PATH_CONSOLE; +static const char include_str[] = "include"; +static const char include_ext[] = ".conf"; #define dprintf if (Debug) printf @@ -1548,96 +1551,46 @@ die(int signo) exit(1); } -/* - * INIT -- Initialize syslogd from configuration table - */ -static void -init(int signo) +static int +configfiles(const struct dirent *dp) { - int i; - FILE *cf; - struct filed *f, *next, **nextp; - char *p; - char cline[LINE_MAX]; - char prog[LINE_MAX]; - char host[MAXHOSTNAMELEN]; - char oldLocalHostName[MAXHOSTNAMELEN]; - char hostMsg[2*MAXHOSTNAMELEN+40]; - char bootfileMsg[LINE_MAX]; + const char *p; + size_t ext_len; - dprintf("init\n"); + if (dp->d_name[0] == '.') + return (0); - /* - * Load hostname (may have changed). - */ - if (signo != 0) - (void)strlcpy(oldLocalHostName, LocalHostName, - sizeof(oldLocalHostName)); - if (gethostname(LocalHostName, sizeof(LocalHostName))) - err(EX_OSERR, "gethostname() failed"); - if ((p = strchr(LocalHostName, '.')) != NULL) { - *p++ = '\0'; - LocalDomain = p; - } else { - LocalDomain = ""; - } + ext_len = sizeof(include_ext) -1; - /* - * Close all open log files. - */ - Initialized = 0; - for (f = Files; f != NULL; f = next) { - /* flush any pending output */ - if (f->f_prevcount) - fprintlog(f, 0, (char *)NULL); + if (dp->d_namlen <= ext_len) + return (0); - switch (f->f_type) { - case F_FILE: - case F_FORW: - case F_CONSOLE: - case F_TTY: - close_filed(f); - break; - case F_PIPE: - if (f->f_un.f_pipe.f_pid > 0) { - close_filed(f); - deadq_enter(f->f_un.f_pipe.f_pid, - f->f_un.f_pipe.f_pname); - } - f->f_un.f_pipe.f_pid = 0; - break; - } - next = f->f_next; - if (f->f_program) free(f->f_program); - if (f->f_host) free(f->f_host); - free((char *)f); - } - Files = NULL; - nextp = &Files; + p = &dp->d_name[dp->d_namlen - ext_len]; + if (strcmp(p, include_ext) != 0) + return (0); - /* open the configuration file */ - if ((cf = fopen(ConfFile, "r")) == NULL) { - dprintf("cannot open %s\n", ConfFile); - *nextp = (struct filed *)calloc(1, sizeof(*f)); - if (*nextp == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.ERR\t/dev/console", *nextp, "*", "*"); - (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)); - if ((*nextp)->f_next == NULL) { - logerror("calloc"); - exit(1); - } - cfline("*.PANIC\t*", (*nextp)->f_next, "*", "*"); - Initialized = 1; - return; - } + return (1); +} + +static void +readconfigfile(FILE *cf, struct filed **nextp, int allow_includes) +{ + FILE *cf2; + struct filed *f; + struct dirent **ent; + char cline[LINE_MAX]; + char host[MAXHOSTNAMELEN]; + char prog[LINE_MAX]; + char file[MAXPATHLEN]; + char *p, *tmp; + int i, nents; + size_t include_len; /* * 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)); while (fgets(cline, sizeof(cline), cf) != NULL) { @@ -1650,6 +1603,42 @@ init(int signo) continue; if (*p == 0) continue; + if (allow_includes && + strncmp(p, include_str, include_len) == 0 && + isspace(p[include_len])) { + p += include_len; + while (isspace(*p)) + p++; + tmp = p; + while (*tmp != '\0' && !isspace(*tmp)) + tmp++; + *tmp = '\0'; + dprintf("Trying to include files in '%s'\n", p); + nents = scandir(p, &ent, configfiles, alphasort); + if (nents == -1) { + dprintf("Unable to open '%s': %s\n", p, + strerror(errno)); + 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); + free(ent[i]); + continue; + } + free(ent[i]); + cf2 = fopen(file, "r"); + if (cf2 == NULL) + continue; + dprintf("reading %s\n", file); + readconfigfile(cf2, nextp, 0); + fclose(cf2); + } + free(ent); + continue; + } if (*p == '#') { p++; if (*p != '!' && *p != '+' && *p != '-') @@ -1711,6 +1700,91 @@ init(int signo) nextp = &f->f_next; cfline(cline, f, prog, host); } +} + +/* + * INIT -- Initialize syslogd from configuration table + */ +static void +init(int signo) +{ + int i; + FILE *cf; + struct filed *f, *next, **nextp; + char *p; + char oldLocalHostName[MAXHOSTNAMELEN]; + char hostMsg[2*MAXHOSTNAMELEN+40]; + char bootfileMsg[LINE_MAX]; + + dprintf("init\n"); + + /* + * Load hostname (may have changed). + */ + if (signo != 0) + (void)strlcpy(oldLocalHostName, LocalHostName, + sizeof(oldLocalHostName)); + if (gethostname(LocalHostName, sizeof(LocalHostName))) + err(EX_OSERR, "gethostname() failed"); + if ((p = strchr(LocalHostName, '.')) != NULL) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = ""; + } + + /* + * Close all open log files. + */ + Initialized = 0; + for (f = Files; f != NULL; f = next) { + /* flush any pending output */ + if (f->f_prevcount) + fprintlog(f, 0, (char *)NULL); + + switch (f->f_type) { + case F_FILE: + case F_FORW: + case F_CONSOLE: + case F_TTY: + close_filed(f); + break; + case F_PIPE: + if (f->f_un.f_pipe.f_pid > 0) { + close_filed(f); + deadq_enter(f->f_un.f_pipe.f_pid, + f->f_un.f_pipe.f_pname); + } + f->f_un.f_pipe.f_pid = 0; + break; + } + next = f->f_next; + if (f->f_program) free(f->f_program); + if (f->f_host) free(f->f_host); + free((char *)f); + } + Files = NULL; + + /* open the configuration file */ + if ((cf = fopen(ConfFile, "r")) == NULL) { + dprintf("cannot open %s\n", ConfFile); + *nextp = (struct filed *)calloc(1, sizeof(*f)); + if (*nextp == NULL) { + logerror("calloc"); + exit(1); + } + cfline("*.ERR\t/dev/console", *nextp, "*", "*"); + (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f)); + if ((*nextp)->f_next == NULL) { + logerror("calloc"); + exit(1); + } + cfline("*.PANIC\t*", (*nextp)->f_next, "*", "*"); + Initialized = 1; + return; + } + + readconfigfile(cf, &Files, 1); /* close the configuration file */ (void)fclose(cf); -- 2.42.0