diff options
Diffstat (limited to 'usr.sbin/cron/database.c')
-rw-r--r-- | usr.sbin/cron/database.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/usr.sbin/cron/database.c b/usr.sbin/cron/database.c index 6fe1a0d2ee3..950c9713d91 100644 --- a/usr.sbin/cron/database.c +++ b/usr.sbin/cron/database.c @@ -1,4 +1,4 @@ -/* $OpenBSD: database.c,v 1.34 2016/01/11 14:23:50 millert Exp $ */ +/* $OpenBSD: database.c,v 1.35 2017/06/07 23:36:43 millert Exp $ */ /* Copyright 1988,1990,1993,1994 by Paul Vixie * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") @@ -34,6 +34,7 @@ #include <unistd.h> #include "pathnames.h" +#include "globals.h" #include "macros.h" #include "structs.h" #include "funcs.h" @@ -170,7 +171,8 @@ process_crontab(int dfd, const char *uname, const char *fname, { struct passwd *pw = NULL; int crontab_fd = -1; - user *u; + user *u, *new_u; + mode_t tabmask, tabperm; /* Note: pw must remain NULL for system crontab (see below). */ if (fname[0] != '/' && (pw = getpwnam(uname)) == NULL) { @@ -196,19 +198,22 @@ process_crontab(int dfd, const char *uname, const char *fname, syslog(LOG_WARNING, "(%s) NOT REGULAR (%s)", uname, fname); goto next_crontab; } - if (pw != NULL) { - /* Looser permissions on system crontab. */ - if ((statbuf->st_mode & 077) != 0) { - syslog(LOG_WARNING, "(%s) BAD FILE MODE (%s)", - uname, fname); - goto next_crontab; - } + /* Looser permissions on system crontab. */ + tabmask = pw ? ALLPERMS : (ALLPERMS & ~(S_IWUSR|S_IRGRP|S_IROTH)); + tabperm = pw ? (S_IRUSR|S_IWUSR) : S_IRUSR; + if ((statbuf->st_mode & tabmask) != tabperm) { + syslog(LOG_WARNING, "(%s) BAD FILE MODE (%s)", uname, fname); + goto next_crontab; } if (statbuf->st_uid != 0 && (pw == NULL || statbuf->st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) { syslog(LOG_WARNING, "(%s) WRONG FILE OWNER (%s)", uname, fname); goto next_crontab; } + if (pw != NULL && statbuf->st_gid != cron_gid) { + syslog(LOG_WARNING, "(%s) WRONG FILE GROUP (%s)", uname, fname); + goto next_crontab; + } if (pw != NULL && statbuf->st_nlink != 1) { syslog(LOG_WARNING, "(%s) BAD LINK COUNT (%s)", uname, fname); goto next_crontab; @@ -224,21 +229,21 @@ process_crontab(int dfd, const char *uname, const char *fname, TAILQ_INSERT_TAIL(&new_db->users, u, entries); goto next_crontab; } - - /* before we fall through to the code that will reload - * the user, let's deallocate and unlink the user in - * the old database. This is more a point of memory - * efficiency than anything else, since all leftover - * users will be deleted from the old database when - * we finish with the crontab... - */ - TAILQ_REMOVE(&old_db->users, u, entries); - free_user(u); syslog(LOG_INFO, "(%s) RELOAD (%s)", uname, fname); } - u = load_user(crontab_fd, pw, fname); - if (u != NULL) { - u->mtime = statbuf->st_mtim; + + new_u = load_user(crontab_fd, pw, fname); + if (new_u != NULL) { + /* Insert user into the new database and remove from old. */ + new_u->mtime = statbuf->st_mtim; + TAILQ_INSERT_TAIL(&new_db->users, new_u, entries); + if (u != NULL) { + TAILQ_REMOVE(&old_db->users, u, entries); + free_user(u); + } + } else if (u != NULL) { + /* New user crontab failed to load, preserve the old one. */ + TAILQ_REMOVE(&old_db->users, u, entries); TAILQ_INSERT_TAIL(&new_db->users, u, entries); } |