From 1cb7491a3f49f671e368efa50c2466ce75899cbd Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 12 Apr 2018 13:52:55 +0000 Subject: [PATCH] cron(8): Reload database if an existing job in cron.d changed as well Directory mtime will only change if a file is added or removed, not modified. For /var/cron/tabs, this is fine because of how crontab(1) manages it using temp files so all crontab(1) changes will trigger a reload of the database. For /etc/cron.d and /usr/local/etc/cron.d, this is not necessarily the case. Instead of checking their mtime, we should descend into them and check mtime on all jobs also. Reported by: des Reviewed by: bapt MFC after: 1 week --- usr.sbin/cron/cron/database.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/usr.sbin/cron/cron/database.c b/usr.sbin/cron/cron/database.c index 2b0c67b9c02d..6665d87ea482 100644 --- a/usr.sbin/cron/cron/database.c +++ b/usr.sbin/cron/cron/database.c @@ -56,7 +56,7 @@ load_database(old_db) { SYSCRONTABS }, { LOCALSYSCRONTABS } }; - int i; + int i, ret; Debug(DLOAD, ("[%d] load_database()\n", getpid())) @@ -79,6 +79,18 @@ load_database(old_db) for (i = 0; i < nitems(syscrontabs); i++) { if (stat(syscrontabs[i].name, &syscrontabs[i].st) != -1) { maxmtime = TMAX(syscrontabs[i].st.st_mtime, maxmtime); + /* Traverse into directory */ + if (!(dir = opendir(syscrontabs[i].name))) + continue; + while (NULL != (dp = readdir(dir))) { + if (dp->d_name[0] == '.') + continue; + ret = fstatat(dirfd(dir), dp->d_name, &st, 0); + if (ret == 0 && !S_ISREG(st.st_mode)) + continue; + maxmtime = TMAX(st.st_mtime, maxmtime); + } + closedir(dir); } else { syscrontabs[i].st.st_mtime = 0; }