summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-05-09 21:22:02 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-05-09 21:22:02 +0000
commit124d0347b10f2c64912889fab1379f308b796911 (patch)
tree1f009cb40f170648cc70571d89992e375b0fbf94
parent0fcf09b27f6901580349da84181cdf8f92d74a8c (diff)
crontab is no longer setuid root, it is now setgid crontab.
These changes were modelled after the Owl version of vixie-cron, but developed independently. Our crontab used to send cron SIGUSR1 to tell cron to reread the spool dir. Now that crontab is not setuid root this doesn't work. Instead, crontab pokes cron via a Unix domain socket located in the tabs dir. Please note, after these changes, the owner on user crontab files will have to be changed manually from root to the uid of the corresponding user for crontab to be usable. cron itself will accept tab files owned by either root or the user. Also, any /var/cron/{allow,deny} files must be readable by group crontab.
-rw-r--r--etc/mtree/4.4BSD.dist4
-rw-r--r--etc/mtree/special4
-rw-r--r--usr.bin/crontab/Makefile6
-rw-r--r--usr.sbin/cron/cron.819
-rw-r--r--usr.sbin/cron/cron.c97
-rw-r--r--usr.sbin/cron/crontab.14
-rw-r--r--usr.sbin/cron/crontab.c79
-rw-r--r--usr.sbin/cron/database.c22
-rw-r--r--usr.sbin/cron/externs.h12
-rw-r--r--usr.sbin/cron/funcs.h6
-rw-r--r--usr.sbin/cron/misc.c90
-rw-r--r--usr.sbin/cron/pathnames.h8
12 files changed, 205 insertions, 146 deletions
diff --git a/etc/mtree/4.4BSD.dist b/etc/mtree/4.4BSD.dist
index 97cfbc3b372..39737099263 100644
--- a/etc/mtree/4.4BSD.dist
+++ b/etc/mtree/4.4BSD.dist
@@ -1,4 +1,4 @@
-# $OpenBSD: 4.4BSD.dist,v 1.123 2002/04/24 22:19:19 espie Exp $
+# $OpenBSD: 4.4BSD.dist,v 1.124 2002/05/09 21:22:01 millert Exp $
/set type=dir uname=root gname=wheel mode=0755
# .
@@ -1871,7 +1871,7 @@ crash mode=770
cron mode=0555
# ./var/cron/tabs
-tabs mode=0700
+tabs gname=crontab mode=1730
# ./var/cron/tabs
..
diff --git a/etc/mtree/special b/etc/mtree/special
index a29d4863909..ac49d57db86 100644
--- a/etc/mtree/special
+++ b/etc/mtree/special
@@ -1,4 +1,4 @@
-# $OpenBSD: special,v 1.40 2002/02/13 04:53:54 marc Exp $
+# $OpenBSD: special,v 1.41 2002/05/09 21:22:01 millert Exp $
# $NetBSD: special,v 1.4 1996/05/08 21:30:18 pk Exp $
# @(#)special 8.2 (Berkeley) 1/23/94
#
@@ -142,7 +142,7 @@ backups type=dir mode=0700 uname=root gname=wheel ignore
.. #var/backups
cron type=dir mode=0555 uname=root gname=wheel
log type=file mode=0600 uname=root gname=wheel
-tabs type=dir mode=0700 uname=root gname=wheel ignore
+tabs type=dir mode=1730 uname=root gname=crontab ignore
.. #var/cron/tabs
.. #var/cron
db type=dir mode=0755 uname=root gname=wheel
diff --git a/usr.bin/crontab/Makefile b/usr.bin/crontab/Makefile
index bfd1f7e4cd7..752de1e7f5e 100644
--- a/usr.bin/crontab/Makefile
+++ b/usr.bin/crontab/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.3 1998/07/12 08:23:49 deraadt Exp $
+# $OpenBSD: Makefile,v 1.4 2002/05/09 21:22:01 millert Exp $
PROG= crontab
SRCS= crontab.c misc.c entry.c env.c
CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../usr.sbin/cron -DDEBUGGING=0
-BINOWN =root
-BINMODE=4555
+BINGRP =crontab
+BINMODE=2555
MAN= crontab.1 crontab.5
.PATH: ${.CURDIR}/../../usr.sbin/cron
diff --git a/usr.sbin/cron/cron.8 b/usr.sbin/cron/cron.8
index 04b06575cfb..cb7c60a2696 100644
--- a/usr.sbin/cron/cron.8
+++ b/usr.sbin/cron/cron.8
@@ -17,7 +17,7 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE.
.\"
-.\" $OpenBSD: cron.8,v 1.13 2001/12/20 23:27:47 millert Exp $
+.\" $OpenBSD: cron.8,v 1.14 2002/05/09 21:22:01 millert Exp $
.\"
.Dd June 6, 1999
.Dt CRON 8
@@ -109,12 +109,19 @@ this has no effect because
.Nm cron
logs via
.Xr syslog 3 .
-.It Dv SIGUSR1
-causes
+.El
+.Sh FILES
+.Bl -tag -width "/var/cron/tabs/.sock" -compact
+.It Pa /var/cron/log
+cron's log file
+.It Pa /var/cron/tabs
+directory of individual crontabs
+.It Pa /var/cron/tabs/.sock
+used by
+.Xr crontab 1
+to tell
.Nm
-to check its spool directory's modtime (and the modtime of
-.Pa /etc/crontab )
-at the next possible moment instead of waiting until the next minute.
+to check for crontab changes immediately
.El
.Sh SEE ALSO
.Xr crontab 1 ,
diff --git a/usr.sbin/cron/cron.c b/usr.sbin/cron/cron.c
index fb3f44cd202..d7a9febf5bb 100644
--- a/usr.sbin/cron/cron.c
+++ b/usr.sbin/cron/cron.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cron.c,v 1.19 2002/02/16 21:28:01 millert Exp $ */
+/* $OpenBSD: cron.c,v 1.20 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,12 +21,14 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: cron.c,v 1.19 2002/02/16 21:28:01 millert Exp $";
+static char rcsid[] = "$OpenBSD: cron.c,v 1.20 2002/05/09 21:22:01 millert Exp $";
#endif
#define MAIN_PROGRAM
#include "cron.h"
+#include <sys/socket.h>
+#include <sys/un.h>
static void usage(void),
run_reboot_jobs(cron_db *),
@@ -35,13 +37,12 @@ static void usage(void),
cron_sleep(int),
sigchld_handler(int),
sighup_handler(int),
- sigusr1_handler(int),
sigchld_reaper(void),
check_sigs(int),
parse_args(int c, char *v[]);
-static volatile sig_atomic_t got_sighup, got_sigchld, got_sigusr1;
-static int timeRunning, virtualTime, clockTime;
+static volatile sig_atomic_t got_sighup, got_sigchld;
+static int timeRunning, virtualTime, clockTime, cronSock;
static long GMToff;
static cron_db database;
@@ -82,6 +83,9 @@ main(int argc, char *argv[]) {
(void) sigaction(SIGCHLD, &sact, NULL);
sact.sa_handler = sighup_handler;
(void) sigaction(SIGHUP, &sact, NULL);
+ sact.sa_handler = SIG_IGN;
+ (void) sigaction(SIGPIPE, &sact, NULL);
+ (void) sigaction(SIGUSR1, &sact, NULL); /* XXX */
acquire_daemonlock(0);
set_cron_uid();
@@ -123,6 +127,7 @@ main(int argc, char *argv[]) {
}
acquire_daemonlock(0);
+ cronSock = open_socket();
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
@@ -338,40 +343,55 @@ set_time(int initialize) {
*/
static void
cron_sleep(int target) {
- time_t t1, t2;
- int seconds_to_wait;
- struct sigaction sact;
-
- bzero((char *)&sact, sizeof sact);
- sigemptyset(&sact.sa_mask);
- sact.sa_flags = 0;
-#ifdef SA_RESTART
- sact.sa_flags |= SA_RESTART;
-#endif
- sact.sa_handler = sigusr1_handler;
- (void) sigaction(SIGUSR1, &sact, NULL);
-
- t1 = time(NULL) + GMToff;
- seconds_to_wait = (int)(target * SECONDS_PER_MINUTE - t1) + 1;
- Debug(DSCH, ("[%ld] Target time=%ld, sec-to-wait=%d\n",
- (long)getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
+ char c;
+ int fd, nfds;
+ struct timeval t1, t2, tv;
+ struct sockaddr_un sun;
+ socklen_t sunlen;
+ static fd_set *fdsr;
+
+ gettimeofday(&t1, NULL);
+ t1.tv_sec += GMToff;
+ tv.tv_sec = (target * SECONDS_PER_MINUTE - t1.tv_sec) + 1;
+ tv.tv_usec = 0;
+ Debug(DSCH, ("[%ld] Target time=%ld, sec-to-wait=%ld\n",
+ (long)getpid(), (long)target*SECONDS_PER_MINUTE, tv.tv_sec))
+
+ if (fdsr == NULL) {
+ fdsr = (fd_set *)calloc(howmany(cronSock + 1, NFDBITS),
+ sizeof(fd_mask));
+ }
- while (seconds_to_wait > 0 && seconds_to_wait < 65) {
- sleep((unsigned int) seconds_to_wait);
+ while (timerisset(&tv) && tv.tv_sec < 65) {
+ if (fdsr)
+ FD_SET(cronSock, fdsr);
+ /* Sleep until we time out, get a crontab poke, or signal. */
+ nfds = select(cronSock + 1, fdsr, NULL, NULL, &tv);
+ if (nfds == 0)
+ break; /* timer expired */
+ if (nfds > 0) {
+ Debug(DSCH, ("[%ld] Got a poke on the socket\n",
+ (long)getpid()))
+ fd = accept(cronSock, (struct sockaddr *)&sun, &sunlen);
+ if (fd >= 0) {
+ while (read(fd, &c, sizeof c) > 0)
+ ; /* suck up anything in the socket */
+ close(fd);
+ }
+ }
/*
- * Check to see if we were interrupted by a signal.
- * If so, service the signal(s) then continue sleeping
- * where we left off.
+ * Check to see if we were interrupted by a signal or a poke
+ * on the socket. If so, service the signal/poke, adjust tv
+ * and continue the select() where we left off.
*/
- check_sigs(FALSE);
- t2 = time(NULL) + GMToff;
- seconds_to_wait -= (int)(t2 - t1);
- t1 = t2;
+ check_sigs(nfds > 0);
+ gettimeofday(&t2, NULL);
+ t2.tv_sec += GMToff;
+ timersub(&t2, &t1, &t1);
+ timersub(&tv, &t1, &tv);
+ memcpy(&t1, &t2, sizeof(t1));
}
-
- sact.sa_handler = SIG_DFL;
- (void) sigaction(SIGUSR1, &sact, NULL);
}
static void
@@ -385,11 +405,6 @@ sigchld_handler(int x) {
}
static void
-sigusr1_handler(int x) {
- got_sigusr1 = 1;
-}
-
-static void
sigchld_reaper() {
WAIT_T waiter;
PID_T pid;
@@ -427,10 +442,8 @@ check_sigs(int force_dbload) {
got_sigchld = 0;
sigchld_reaper();
}
- if (got_sigusr1 || force_dbload) {
- got_sigusr1 = 0;
+ if (force_dbload)
load_database(&database);
- }
}
static void
diff --git a/usr.sbin/cron/crontab.1 b/usr.sbin/cron/crontab.1
index 1da796bf3b2..407ec7a4973 100644
--- a/usr.sbin/cron/crontab.1
+++ b/usr.sbin/cron/crontab.1
@@ -15,14 +15,14 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE.
.\"
-.\" $OpenBSD: crontab.1,v 1.10 2001/08/02 18:37:34 mpech Exp $
+.\" $OpenBSD: crontab.1,v 1.11 2002/05/09 21:22:01 millert Exp $
.\"
.Dd June 8, 1999
.Dt CRONTAB 1
.Os
.Sh NAME
.Nm crontab
-.Nd maintain crontab files for individual users (V3)
+.Nd maintain crontab files for individual users
.Sh SYNOPSIS
.Nm crontab
.Op Fl u Ar user
diff --git a/usr.sbin/cron/crontab.c b/usr.sbin/cron/crontab.c
index f3d1c9a44ad..22a5e6dc716 100644
--- a/usr.sbin/cron/crontab.c
+++ b/usr.sbin/cron/crontab.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crontab.c,v 1.28 2002/05/08 22:57:58 millert Exp $ */
+/* $OpenBSD: crontab.c,v 1.29 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: crontab.c,v 1.28 2002/05/08 22:57:58 millert Exp $";
+static char rcsid[] = "$OpenBSD: crontab.c,v 1.29 2002/05/09 21:22:01 millert Exp $";
#endif
/* crontab - install and manage per-user crontab files
@@ -32,6 +32,8 @@ static char rcsid[] = "$OpenBSD: crontab.c,v 1.28 2002/05/08 22:57:58 millert Ex
#define MAIN_PROGRAM
#include "cron.h"
+#include <sys/socket.h>
+#include <sys/un.h>
#define NHEADER_LINES 3
@@ -85,7 +87,6 @@ main(int argc, char *argv[]) {
setlinebuf(stderr);
#endif
parse_args(argc, argv); /* sets many globals, opens a file */
- set_cron_uid();
set_cron_cwd();
if (!allowed(User)) {
fprintf(stderr,
@@ -201,7 +202,7 @@ parse_args(int argc, char *argv[]) {
if (!strcmp(Filename, "-"))
NewCrontab = stdin;
else {
- /* relinquish the setuid status of the binary during
+ /* relinquish the setgid status of the binary during
* the open, lest nonroot users read files they should
* not be able to read. we can't use access() here
* since there's a race condition. thanks go out to
@@ -209,16 +210,16 @@ parse_args(int argc, char *argv[]) {
* the race.
*/
- if (swap_uids() < OK) {
- perror("swapping uids");
+ if (swap_gids() < OK) {
+ perror("swapping gids");
exit(ERROR_EXIT);
}
if (!(NewCrontab = fopen(Filename, "r"))) {
perror(Filename);
exit(ERROR_EXIT);
}
- if (swap_uids_back() < OK) {
- perror("swapping uids back");
+ if (swap_gids_back() < OK) {
+ perror("swapping gids back");
exit(ERROR_EXIT);
}
}
@@ -334,17 +335,6 @@ edit_cmd(void) {
perror(Filename);
goto fatal;
}
-#ifdef HAVE_FCHOWN
- if (fchown(t, MY_UID(pw), MY_GID(pw)) < 0) {
- perror("fchown");
- goto fatal;
- }
-#else
- if (chown(Filename, MY_UID(pw), MY_GID(pw)) < 0) {
- perror("chown");
- goto fatal;
- }
-#endif
if (!(NewCrontab = fdopen(t, "r+"))) {
perror("fdopen");
goto fatal;
@@ -413,10 +403,6 @@ edit_cmd(void) {
perror("setgid(getgid())");
exit(ERROR_EXIT);
}
- if (setuid(MY_UID(pw)) < 0) {
- perror("setuid(getuid())");
- exit(ERROR_EXIT);
- }
if (chdir(_PATH_TMP) < 0) {
perror(_PATH_TMP);
exit(ERROR_EXIT);
@@ -524,7 +510,6 @@ replace_cmd(void) {
entry *e;
time_t now = time(NULL);
char **envp = env_init();
- struct stat sb;
if (envp == NULL) {
fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
@@ -606,18 +591,15 @@ replace_cmd(void) {
goto done;
}
- if (fstat(fileno(tmp), &sb))
- sb.st_gid = -1;
-
#ifdef HAVE_FCHOWN
- if (fchown(fileno(tmp), ROOT_UID, sb.st_gid) < OK) {
+ if (fchown(fileno(tmp), pw->pw_uid, -1) < OK) {
perror("fchown");
fclose(tmp);
error = -2;
goto done;
}
#else
- if (chown(TempFilename, ROOT_UID, sb.st_gid) < OK) {
+ if (chown(TempFilename, pw->pw_uid, -1) < OK) {
perror("chown");
fclose(tmp);
error = -2;
@@ -625,22 +607,6 @@ replace_cmd(void) {
}
#endif
-#ifdef HAVE_FCHMOD
- if (fchmod(fileno(tmp), 0600) < OK) {
- perror("fchmod");
- fclose(tmp);
- error = -2;
- goto done;
- }
-#else
- if (chmod(TempFilename, 0600) < OK) {
- perror("chmod");
- fclose(tmp);
- error = -2;
- goto done;
- }
-#endif
-
if (fclose(tmp) == EOF) {
perror("fclose");
error = -2;
@@ -677,8 +643,8 @@ done:
static void
poke_daemon() {
- char pidfile[MAX_FNAME];
- PID_T pid;
+ int sock, flags;
+ struct sockaddr_un sun;
FILE *fp;
if (utime(SPOOL_DIR, NULL) < OK) {
@@ -686,11 +652,22 @@ poke_daemon() {
perror(SPOOL_DIR);
return;
}
- if (glue_strings(pidfile, sizeof pidfile, PIDDIR, PIDFILE, '/')) {
- if ((fp = fopen(pidfile, "r")) &&
- fscanf(fp, "%d", &pid) == 1)
- kill(pid, SIGUSR1);
+
+ /* Failure to poke the daemon socket is not a fatal error. */
+ (void) signal(SIGPIPE, SIG_IGN);
+ if (glue_strings(sun.sun_path, sizeof sun.sun_path, SPOOL_DIR,
+ CRONSOCK, '/')) {
+ sun.sun_family = AF_UNIX;
+ sun.sun_len = strlen(sun.sun_path);
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
+ (flags = fcntl(sock, F_GETFL)) >= 0 &&
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK) >= 0 &&
+ connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
+ write(sock, "!", 1);
+ close(sock);
+ }
}
+ (void) signal(SIGPIPE, SIG_DFL);
}
static void
diff --git a/usr.sbin/cron/database.c b/usr.sbin/cron/database.c
index 7fec60661c5..d575465ddc6 100644
--- a/usr.sbin/cron/database.c
+++ b/usr.sbin/cron/database.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: database.c,v 1.5 2001/02/18 19:48:33 millert Exp $ */
+/* $OpenBSD: database.c,v 1.6 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: database.c,v 1.5 2001/02/18 19:48:33 millert Exp $";
+static char rcsid[] = "$OpenBSD: database.c,v 1.6 2002/05/09 21:22:01 millert Exp $";
#endif
/* vix 26jan87 [RCS has the log]
@@ -190,7 +190,7 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
goto next_crontab;
}
- if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) {
+ if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < OK) {
/* crontab not accessible?
*/
log_it(fname, getpid(), "CAN'T OPEN", tabname);
@@ -201,6 +201,22 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
log_it(fname, getpid(), "FSTAT FAILED", tabname);
goto next_crontab;
}
+ if (!S_ISREG(statbuf->st_mode)) {
+ log_it(fname, getpid(), "NOT REGULAR", tabname);
+ goto next_crontab;
+ }
+ if ((statbuf->st_mode & 07777) != 0600) {
+ log_it(fname, getpid(), "BAD FILE MODE", tabname);
+ goto next_crontab;
+ }
+ if (statbuf->st_uid != 0 && pw && statbuf->st_uid != pw->pw_uid) {
+ log_it(fname, getpid(), "WRONG FILE OWNER", tabname);
+ goto next_crontab;
+ }
+ if (statbuf->st_nlink != 1) {
+ log_it(fname, getpid(), "BAD LINK COUNT", tabname);
+ goto next_crontab;
+ }
Debug(DLOAD, ("\t%s:", fname))
u = find_user(old_db, fname);
diff --git a/usr.sbin/cron/externs.h b/usr.sbin/cron/externs.h
index 11b3e7c6cec..4d3c0625ca8 100644
--- a/usr.sbin/cron/externs.h
+++ b/usr.sbin/cron/externs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: externs.h,v 1.3 2001/02/18 19:48:34 millert Exp $ */
+/* $OpenBSD: externs.h,v 1.4 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
@@ -24,7 +24,9 @@
#include <sys/param.h>
#include <sys/types.h>
+#if !defined(AIX) && !defined(UNICOS)
#include <sys/time.h>
+#endif
#include <sys/wait.h>
#include <sys/fcntl.h>
#include <sys/file.h>
@@ -84,18 +86,12 @@ extern char *tzname[2];
#endif
#if (BSD >= 199103)
-# define HAVE_SAVED_UIDS
+# define HAVE_SAVED_GIDS
#endif
#define MY_UID(pw) getuid()
#define MY_GID(pw) getgid()
-#if !defined(AIX) && !defined(UNICOS)
-# define SYS_TIME_H 1
-#else
-# define SYS_TIME_H 0
-#endif
-
/* getopt() isn't part of POSIX. some systems define it in <stdlib.h> anyway.
* of those that do, some complain that our definition is different and some
* do not. to add to the misery and confusion, some systems define getopt()
diff --git a/usr.sbin/cron/funcs.h b/usr.sbin/cron/funcs.h
index 680f1301ca6..5199dd44042 100644
--- a/usr.sbin/cron/funcs.h
+++ b/usr.sbin/cron/funcs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: funcs.h,v 1.4 2002/02/16 21:28:01 millert Exp $ */
+/* $OpenBSD: funcs.h,v 1.5 2002/05/09 21:22:01 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -44,8 +44,8 @@ int job_runqueue(void),
set_debug_flags(char *),
get_char(FILE *),
get_string(char *, int, FILE *, char *),
- swap_uids(void),
- swap_uids_back(void),
+ swap_gids(void),
+ swap_gids_back(void),
load_env(char *, FILE *),
cron_pclose(FILE *),
glue_strings(char *, int, char *, char *, int),
diff --git a/usr.sbin/cron/misc.c b/usr.sbin/cron/misc.c
index 3362f812a4a..883c505df6d 100644
--- a/usr.sbin/cron/misc.c
+++ b/usr.sbin/cron/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.11 2001/12/12 19:02:50 millert Exp $ */
+/* $OpenBSD: misc.c,v 1.12 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: misc.c,v 1.11 2001/12/12 19:02:50 millert Exp $";
+static char rcsid[] = "$OpenBSD: misc.c,v 1.12 2002/05/09 21:22:01 millert Exp $";
#endif
/* vix 26jan87 [RCS has the rest of the log]
@@ -30,18 +30,8 @@ static char rcsid[] = "$OpenBSD: misc.c,v 1.11 2001/12/12 19:02:50 millert Exp $
#include "cron.h"
-#if SYS_TIME_H
-# include <sys/time.h>
-#else
-# include <time.h>
-#endif
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#if defined(SYSLOG)
-# include <syslog.h>
-#endif
+#include <sys/socket.h>
+#include <sys/un.h>
#if defined(LOG_CRON) && defined(LOG_FILE)
@@ -302,7 +292,7 @@ acquire_daemonlock(closeflag)
if (!fp) {
if (!glue_strings(pidfile, sizeof pidfile, PIDDIR,
PIDFILE, '/')) {
- fprintf(stderr, "%s%s: path too long\n",
+ fprintf(stderr, "%s/%s: path too long\n",
PIDDIR, PIDFILE);
log_it("CRON", getpid(), "DEATH", "path too long");
exit(ERROR_EXIT);
@@ -720,14 +710,14 @@ arpadate(clock)
}
#endif /*MAIL_DATE*/
-#ifdef HAVE_SAVED_UIDS
-static uid_t save_euid;
-int swap_uids() { save_euid = geteuid(); return (seteuid(getuid())); }
-int swap_uids_back() { return (seteuid(save_euid)); }
-#else /*HAVE_SAVED_UIDS*/
-int swap_uids() { return (setreuid(geteuid(), getuid())); }
-int swap_uids_back() { return (swap_uids()); }
-#endif /*HAVE_SAVED_UIDS*/
+#ifdef HAVE_SAVED_GIDS
+static gid_t save_egid;
+int swap_gids() { save_egid = getegid(); return (setegid(getgid())); }
+int swap_gids_back() { return (setegid(save_egid)); }
+#else /*HAVE_SAVED_GIDS*/
+int swap_gids() { return (setregid(getegid(), getgid())); }
+int swap_gids_back() { return (swap_gids()); }
+#endif /*HAVE_SAVED_GIDS*/
/* Return the offset from GMT in seconds (algorithm taken from sendmail). */
#ifndef HAVE_TM_GMTOFF
@@ -757,3 +747,57 @@ long get_gmtoff(time_t *clock, struct tm *local)
return (offset);
}
#endif /* HAVE_TM_GMTOFF */
+
+/* void open_socket(void)
+ * opens a UNIX domain socket that crontab uses to poke cron.
+ */
+int
+open_socket()
+{
+ int sock, flags;
+ mode_t omask;
+ struct sockaddr_un sun;
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock == -1) {
+ fprintf(stderr, "%s: can't create socket: %s\n",
+ ProgramName, strerror(errno));
+ log_it("CRON", getpid(), "DEATH", "can't create socket");
+ exit(ERROR_EXIT);
+ }
+ if ((flags = fcntl(sock, F_GETFL)) == -1 ||
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
+ fprintf(stderr, "%s: can't set non-block: %s\n",
+ ProgramName, strerror(errno));
+ log_it("CRON", getpid(), "DEATH", "can't set non-block");
+ exit(ERROR_EXIT);
+ }
+
+ if (!glue_strings(sun.sun_path, sizeof sun.sun_path, SPOOL_DIR,
+ CRONSOCK, '/')) {
+ fprintf(stderr, "%s/%s: path too long\n", SPOOL_DIR, CRONSOCK);
+ log_it("CRON", getpid(), "DEATH", "path too long");
+ exit(ERROR_EXIT);
+ }
+ unlink(sun.sun_path);
+ sun.sun_len = strlen(sun.sun_path);
+ sun.sun_family = AF_UNIX;
+
+ omask = umask(007);
+ if (bind(sock, (struct sockaddr *)&sun, sizeof(sun))) {
+ fprintf(stderr, "%s: can't bind socket: %s\n",
+ ProgramName, strerror(errno));
+ log_it("CRON", getpid(), "DEATH", "can't bind socket");
+ exit(ERROR_EXIT);
+ }
+ if (listen(sock, SOMAXCONN)) {
+ fprintf(stderr, "%s: can't listen on socket: %s\n",
+ ProgramName, strerror(errno));
+ log_it("CRON", getpid(), "DEATH", "can't listen on socket");
+ exit(ERROR_EXIT);
+ }
+ chmod(sun.sun_path, 0660);
+ umask(omask);
+
+ return(sock);
+}
diff --git a/usr.sbin/cron/pathnames.h b/usr.sbin/cron/pathnames.h
index ed727d6cf5d..aaeed25c41f 100644
--- a/usr.sbin/cron/pathnames.h
+++ b/usr.sbin/cron/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.4 2001/10/24 17:28:16 millert Exp $ */
+/* $OpenBSD: pathnames.h,v 1.5 2002/05/09 21:22:01 millert Exp $ */
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
@@ -38,6 +38,12 @@
*/
#define SPOOL_DIR "tabs"
+ /* CRONSOCK is the name of the socket used by crontab
+ * to poke cron while it is sleeping to re-read the
+ * cron spool files. It lives in the spool directory.
+ */
+#define CRONSOCK ".sock"
+
/* undefining these turns off their features. note
* that ALLOW_FILE and DENY_FILE must both be defined
* in order to enable the allow/deny code. If neither