summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/at/Makefile10
-rw-r--r--usr.bin/at/at.c365
-rw-r--r--usr.bin/at/at.h6
-rw-r--r--usr.bin/at/panic.c114
-rw-r--r--usr.bin/at/panic.h32
-rw-r--r--usr.bin/at/parsetime.c122
-rw-r--r--usr.bin/at/parsetime.h30
-rw-r--r--usr.bin/at/perm.c108
-rw-r--r--usr.bin/at/perm.h28
-rw-r--r--usr.bin/at/privs.h44
-rw-r--r--usr.sbin/cron/atrun.c91
-rw-r--r--usr.sbin/cron/config.h23
-rw-r--r--usr.sbin/cron/cron.834
-rw-r--r--usr.sbin/cron/cron.c45
-rw-r--r--usr.sbin/cron/crontab.14
-rw-r--r--usr.sbin/cron/crontab.54
-rw-r--r--usr.sbin/cron/crontab.c44
-rw-r--r--usr.sbin/cron/database.c7
-rw-r--r--usr.sbin/cron/do_command.c23
-rw-r--r--usr.sbin/cron/entry.c17
-rw-r--r--usr.sbin/cron/env.c5
-rw-r--r--usr.sbin/cron/externs.h17
-rw-r--r--usr.sbin/cron/funcs.h3
-rw-r--r--usr.sbin/cron/globals.h4
-rw-r--r--usr.sbin/cron/job.c5
-rw-r--r--usr.sbin/cron/macros.h16
-rw-r--r--usr.sbin/cron/misc.c114
-rw-r--r--usr.sbin/cron/pathnames.h58
-rw-r--r--usr.sbin/cron/popen.c26
-rw-r--r--usr.sbin/cron/user.c5
30 files changed, 646 insertions, 758 deletions
diff --git a/usr.bin/at/Makefile b/usr.bin/at/Makefile
index f5d9c51e621..a56c946054a 100644
--- a/usr.bin/at/Makefile
+++ b/usr.bin/at/Makefile
@@ -1,15 +1,17 @@
-# $OpenBSD: Makefile,v 1.7 2002/07/15 19:13:29 millert Exp $
+# $OpenBSD: Makefile,v 1.8 2003/02/20 20:38:08 millert Exp $
PROG= at
-SRCS= at.c panic.c parsetime.c perm.c
-CFLAGS+=-I${.CURDIR}/../../usr.sbin/cron
+SRCS= at.c misc.c parsetime.c
+CRONDIR=${.CURDIR}/../../usr.sbin/cron
+CFLAGS+=-I${CRONDIR} -DDEBUGGING=0
MAN= at.1 atrm.1 atq.1
LINKS= ${BINDIR}/at ${BINDIR}/atq \
${BINDIR}/at ${BINDIR}/atrm \
${BINDIR}/at ${BINDIR}/batch
MLINKS= at.1 batch.1
-
BINGRP= crontab
BINMODE= 2555
+.PATH: ${CRONDIR}
+
.include <bsd.prog.mk>
diff --git a/usr.bin/at/at.c b/usr.bin/at/at.c
index 7764db9154d..13e026e2afd 100644
--- a/usr.bin/at/at.c
+++ b/usr.bin/at/at.c
@@ -1,5 +1,4 @@
-/* $OpenBSD: at.c,v 1.34 2003/02/18 02:25:39 millert Exp $ */
-/* $NetBSD: at.c,v 1.4 1995/03/25 18:13:31 glass Exp $ */
+/* $OpenBSD: at.c,v 1.35 2003/02/20 20:38:08 millert Exp $ */
/*
* at.c : Put file into atrun queue
@@ -9,7 +8,7 @@
* Copyright (C) 1993 David Parsons
*
* Traditional BSD behavior and other significant modifications
- * Copyright (C) 2002 Todd C. Miller
+ * Copyright (C) 2002-2003 Todd C. Miller
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,49 +31,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/un.h>
-
-#include <ctype.h>
-#include <dirent.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <locale.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <utime.h>
-#include <utmp.h>
-
-#if (MAXLOGNAME-1) > UT_NAMESIZE
-#define LOGNAMESIZE UT_NAMESIZE
-#else
-#define LOGNAMESIZE (MAXLOGNAME-1)
-#endif
+#define MAIN_PROGRAM
+#include "cron.h"
#include "at.h"
-#include "panic.h"
-#include "parsetime.h"
-#include "perm.h"
-#include "pathnames.h"
-#define MAIN
#include "privs.h"
+#include <limits.h>
#define ALARMC 10 /* Number of seconds to wait for timeout */
#define TIMESIZE 50 /* Size of buffer passed to strftime() */
#ifndef lint
-static const char rcsid[] = "$OpenBSD: at.c,v 1.34 2003/02/18 02:25:39 millert Exp $";
+static const char rcsid[] = "$OpenBSD: at.c,v 1.35 2003/02/20 20:38:08 millert Exp $";
#endif
/* Variables to remove from the job's environment. */
@@ -85,7 +53,7 @@ char *no_export[] =
};
int program = AT; /* default program mode */
-char atfile[PATH_MAX]; /* path to the at spool file */
+char atfile[MAX_FNAME]; /* path to the at spool file */
int fcreated; /* whether or not we created the file yet */
char *atinput = NULL; /* where to get input from */
char atqueue = 0; /* which queue to examine for jobs (atq) */
@@ -96,39 +64,93 @@ static int send_mail = 0; /* whether we are sending mail */
static void sigc(int);
static void alarmc(int);
-static void writefile(time_t, char);
+static void writefile(const char *, time_t, char);
static void list_jobs(int, char **, int, int);
-static void poke_daemon(void);
static time_t ttime(const char *);
+static int check_permission(void);
+static void panic(const char *);
+static void perr(const char *);
+static void perr2(const char *, const char *);
+static void usage(void);
+time_t parsetime(int, char **);
-static void
-sigc(int signo)
+/*
+ * Something fatal has happened, print error message and exit.
+ */
+static __dead void
+panic(const char *a)
{
- /* If the user presses ^C, remove the spool file and exit. */
+ (void)fprintf(stderr, "%s: %s\n", ProgramName, a);
if (fcreated) {
PRIV_START;
- (void)unlink(atfile);
+ unlink(atfile);
PRIV_END;
}
- _exit(EXIT_FAILURE);
+ exit(ERROR_EXIT);
}
-static void
-alarmc(int signo)
+/*
+ * Two-parameter version of panic().
+ */
+static __dead void
+panic2(const char *a, const char *b)
{
- char buf[1024];
+ (void)fprintf(stderr, "%s: %s%s\n", ProgramName, a, b);
+ if (fcreated) {
+ PRIV_START;
+ unlink(atfile);
+ PRIV_END;
+ }
+
+ exit(ERROR_EXIT);
+}
- /* Time out after some seconds. */
- strlcpy(buf, __progname, sizeof(buf));
- strlcat(buf, ": File locking timed out\n", sizeof(buf));
- write(STDERR_FILENO, buf, strlen(buf));
+/*
+ * Some operating system error; print error message and exit.
+ */
+static __dead void
+perr(const char *a)
+{
+ if (!force)
+ perror(a);
if (fcreated) {
PRIV_START;
unlink(atfile);
PRIV_END;
}
- _exit(EXIT_FAILURE);
+
+ exit(ERROR_EXIT);
+}
+
+/*
+ * Two-parameter version of perr().
+ */
+static __dead void
+perr2(const char *a, const char *b)
+{
+ if (!force)
+ (void)fputs(a, stderr);
+ perr(b);
+}
+
+static void
+sigc(int signo)
+{
+ /* If the user presses ^C, remove the spool file and exit. */
+ if (fcreated) {
+ PRIV_START;
+ (void)unlink(atfile);
+ PRIV_END;
+ }
+
+ _exit(ERROR_EXIT);
+}
+
+static void
+alarmc(int signo)
+{
+ /* just return */
}
static int
@@ -142,8 +164,8 @@ newjob(time_t runtimer, int queue)
* queues instead...
*/
for (i = 0; i < 120; i++) {
- snprintf(atfile, sizeof(atfile), "%s/%ld.%c",
- _PATH_ATJOBS, (long)runtimer, queue);
+ snprintf(atfile, sizeof(atfile), "%s/%ld.%c", AT_DIR,
+ (long)runtimer, queue);
fd = open(atfile, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
if (fd >= 0)
return (fd);
@@ -157,11 +179,11 @@ newjob(time_t runtimer, int queue)
* writing a job.
*/
static void
-writefile(time_t runtimer, char queue)
+writefile(const char *cwd, time_t runtimer, char queue)
{
- char *ap, *mailname, *shell;
+ const char *ap;
+ char *mailname, *shell;
char timestr[TIMESIZE];
- char path[PATH_MAX];
struct passwd *pass_entry;
struct tm runtime;
int fdes, lockdes, fd2;
@@ -178,7 +200,7 @@ writefile(time_t runtimer, char queue)
* Install the signal handler for SIGINT; terminate after removing the
* spool file if necessary
*/
- memset(&act, 0, sizeof act);
+ bzero(&act, sizeof act);
act.sa_handler = sigc;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
@@ -186,23 +208,27 @@ writefile(time_t runtimer, char queue)
PRIV_START;
+ if ((lockdes = open(AT_DIR, O_RDONLY, 0)) < 0)
+ perr("Cannot open jobs dir");
+
/*
* Lock the jobs dir so we don't have to worry about someone
* else grabbing a file name out from under us.
* Set an alarm so we don't sleep forever waiting on the lock.
* If we don't succeed with ALARMC seconds, something is wrong...
*/
- memset(&act, 0, sizeof act);
+ bzero(&act, sizeof act);
act.sa_handler = alarmc;
sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
+#ifdef SA_INTERRUPT
+ act.sa_flags = SA_INTERRUPT;
+#endif
sigaction(SIGALRM, &act, NULL);
alarm(ALARMC);
- lockdes = open(_PATH_ATJOBS, O_RDONLY|O_EXLOCK, 0);
+ ch = flock(lockdes, LOCK_EX);
alarm(0);
-
- if (lockdes < 0)
- perr("Cannot lock jobs dir");
+ if (ch != 0)
+ panic("Unable to lock jobs dir");
/*
* Create the file. The x bit is only going to be set after it has
@@ -243,7 +269,7 @@ writefile(time_t runtimer, char queue)
mailname = getenv("USER");
if ((mailname == NULL) || (mailname[0] == '\0') ||
- (strlen(mailname) > LOGNAMESIZE) || (getpwnam(mailname) == NULL)) {
+ (strlen(mailname) > MAX_UNAME) || (getpwnam(mailname) == NULL)) {
pass_entry = getpwuid(real_uid);
if (pass_entry != NULL)
mailname = pass_entry->pw_name;
@@ -268,7 +294,7 @@ writefile(time_t runtimer, char queue)
perr("Cannot open input file");
}
(void)fprintf(fp, "#!/bin/sh\n# atrun uid=%ld gid=%ld\n# mail %*s %d\n",
- (long)real_uid, (long)real_gid, LOGNAMESIZE, mailname, send_mail);
+ (long)real_uid, (long)real_gid, MAX_UNAME, mailname, send_mail);
/* Write out the umask at the time of invocation */
(void)fprintf(fp, "umask %o\n", cmask);
@@ -329,10 +355,8 @@ writefile(time_t runtimer, char queue)
* Cd to the directory at the time and write out all the
* commands the user supplies from stdin.
*/
- if ((ap = getcwd(path, sizeof(path))) == NULL)
- perr("Cannot get current working directory");
(void)fputs("cd ", fp);
- for (; *ap != '\0'; ap++) {
+ for (ap = cwd; *ap != '\0'; ap++) {
if (*ap == '\n')
fprintf(fp, "\"\n\"");
else {
@@ -377,12 +401,14 @@ writefile(time_t runtimer, char queue)
(void)close(fd2);
/* Poke cron so it knows to reload the at spool. */
- poke_daemon();
+ PRIV_START;
+ poke_daemon(AT_DIR, RELOAD_AT);
+ PRIV_END;
runtime = *localtime(&runtimer);
strftime(timestr, TIMESIZE, "%a %b %e %T %Y", &runtime);
(void)fprintf(stderr, "commands will be executed using %s\n", shell);
- (void)fprintf(stderr, "job %s at %s\n", &atfile[sizeof(_PATH_ATJOBS)],
+ (void)fprintf(stderr, "job %s at %s\n", &atfile[sizeof(AT_DIR)],
timestr);
}
@@ -440,7 +466,7 @@ print_job(struct atjob *job, int n, struct stat *st, int shortformat)
/*
* List all of a user's jobs in the queue, by looping through
- * _PATH_ATJOBS, or all jobs if we are root. If argc is > 0, argv
+ * AT_DIR, or all jobs if we are root. If argc is > 0, argv
* contains the list of users whose jobs shall be displayed. By
* default, the list is sorted by execution date and queue. If
* csort is non-zero jobs will be sorted by creation/submission date.
@@ -461,34 +487,32 @@ list_jobs(int argc, char **argv, int count_only, int csort)
if (argc) {
if ((uids = malloc(sizeof(uid_t) * argc)) == NULL)
- err(EXIT_FAILURE, "malloc");
+ panic("Insufficient virtual memory");
for (i = 0; i < argc; i++) {
if ((pw = getpwnam(argv[i])) == NULL)
- errx(EXIT_FAILURE,
- "%s: invalid user name", argv[i]);
+ panic2(argv[i], ": invalid user name");
if (pw->pw_uid != real_uid && real_uid != 0)
- errx(EXIT_FAILURE, "Only the superuser may "
- "display other users' jobs");
+ panic("Only the superuser may display other users' jobs");
uids[i] = pw->pw_uid;
}
} else
uids = NULL;
- shortformat = strcmp(__progname, "at") == 0;
+ shortformat = strcmp(ProgramName, "at") == 0;
PRIV_START;
- if (chdir(_PATH_ATJOBS) != 0)
- perr2("Cannot change to ", _PATH_ATJOBS);
+ if (chdir(AT_DIR) != 0)
+ perr2("Cannot change to ", AT_DIR);
if ((spool = opendir(".")) == NULL)
- perr2("Cannot open ", _PATH_ATJOBS);
+ perr2("Cannot open ", AT_DIR);
PRIV_END;
- if (fstat(dirfd(spool), &stbuf) != 0)
- perr2("Cannot stat ", _PATH_ATJOBS);
+ if (fstat(spool->dd_fd, &stbuf) != 0)
+ perr2("Cannot stat ", AT_DIR);
/*
* The directory's link count should give us a good idea
@@ -499,14 +523,14 @@ list_jobs(int argc, char **argv, int count_only, int csort)
maxjobs = stbuf.st_nlink + 4;
atjobs = (struct atjob **)malloc(maxjobs * sizeof(struct atjob *));
if (atjobs == NULL)
- err(EXIT_FAILURE, "malloc");
+ panic("Insufficient virtual memory");
/* Loop over every file in the directory. */
while ((dirent = readdir(spool)) != NULL) {
PRIV_START;
if (stat(dirent->d_name, &stbuf) != 0)
- perr2("Cannot stat in ", _PATH_ATJOBS);
+ perr2("Cannot stat in ", AT_DIR);
PRIV_END;
@@ -546,15 +570,15 @@ list_jobs(int argc, char **argv, int count_only, int csort)
job = (struct atjob *)malloc(sizeof(struct atjob));
if (job == NULL)
- err(EXIT_FAILURE, "malloc");
+ panic("Insufficient virtual memory");
job->runtimer = runtimer;
job->ctime = stbuf.st_ctime;
job->queue = queue;
if (numjobs == maxjobs) {
- maxjobs *= 2;
- atjobs = realloc(atjobs, maxjobs * sizeof(struct atjob *));
- if (atjobs == NULL)
- err(EXIT_FAILURE, "realloc");
+ maxjobs *= 2;
+ atjobs = realloc(atjobs, maxjobs * sizeof(job));
+ if (atjobs == NULL)
+ panic("Insufficient virtual memory");
}
atjobs[numjobs++] = job;
}
@@ -597,7 +621,7 @@ rmok(int job)
}
/*
- * Loop through all jobs in _PATH_ATJOBS and display or delete ones
+ * Loop through all jobs in AT_DIR and display or delete ones
* that match argv (may be job or username), or all if argc == 0.
* Only the superuser may display/delete other people's jobs.
*/
@@ -618,11 +642,11 @@ process_jobs(int argc, char **argv, int what)
PRIV_START;
- if (chdir(_PATH_ATJOBS) != 0)
- perr2("Cannot change to ", _PATH_ATJOBS);
+ if (chdir(AT_DIR) != 0)
+ perr2("Cannot change to ", AT_DIR);
if ((spool = opendir(".")) == NULL)
- perr2("Cannot open ", _PATH_ATJOBS);
+ perr2("Cannot open ", AT_DIR);
PRIV_END;
@@ -633,7 +657,7 @@ process_jobs(int argc, char **argv, int what)
if (argc > 0) {
if ((jobs = malloc(sizeof(char *) * argc)) == NULL ||
(uids = malloc(sizeof(uid_t) * argc)) == NULL)
- err(EXIT_FAILURE, "malloc");
+ panic("Insufficient virtual memory");
for (i = 0; i < argc; i++) {
l = strtol(argv[i], &ep, 10);
@@ -641,15 +665,16 @@ process_jobs(int argc, char **argv, int what)
*(ep + 2) == '\0' && l > 0 && l < INT_MAX)
jobs[jobs_len++] = argv[i];
else if ((pw = getpwnam(argv[i])) != NULL) {
- if (real_uid != pw->pw_uid && real_uid != 0)
- errx(EXIT_FAILURE,
- "Only the superuser may %s"
- " other users' jobs", what == ATRM
- ? "remove" : "print");
+ if (real_uid != pw->pw_uid && real_uid != 0) {
+ fprintf(stderr, "%s: Only the superuser"
+ " may %s other users' jobs",
+ ProgramName, what == ATRM
+ ? "remove" : "view");
+ exit(ERROR_EXIT);
+ }
uids[uids_len++] = pw->pw_uid;
} else
- errx(EXIT_FAILURE,
- "%s: invalid user name", argv[i]);
+ panic2(argv[i], ": invalid user name");
}
}
@@ -659,7 +684,7 @@ process_jobs(int argc, char **argv, int what)
PRIV_START;
if (stat(dirent->d_name, &stbuf) != 0)
- perr2("Cannot stat in ", _PATH_ATJOBS);
+ perr2("Cannot stat in ", AT_DIR);
PRIV_END;
if (stbuf.st_uid != real_uid && real_uid != 0)
@@ -676,8 +701,7 @@ process_jobs(int argc, char **argv, int what)
job_matches = (argc == 0) ? 1 : 0;
if (!job_matches) {
for (i = 0; i < jobs_len; i++) {
- if (jobs[i] != NULL &&
- strcmp(dirent->d_name, jobs[i]) == 0) {
+ if (strcmp(dirent->d_name, jobs[i]) == 0) {
jobs[i] = NULL;
job_matches = 1;
break;
@@ -730,9 +754,7 @@ process_jobs(int argc, char **argv, int what)
break;
default:
- errx(EXIT_FAILURE,
- "Internal error, process_jobs = %d",
- what);
+ panic("Internal error");
break;
}
}
@@ -740,7 +762,8 @@ process_jobs(int argc, char **argv, int what)
for (error = 0, i = 0; i < jobs_len; i++) {
if (jobs[i] != NULL) {
if (!force)
- warnx("%s: no such job", jobs[i]);
+ fprintf(stderr, "%s: %s: no such job",
+ ProgramName, jobs[i]);
error++;
}
}
@@ -748,8 +771,14 @@ process_jobs(int argc, char **argv, int what)
free(uids);
/* If we modied the spool, poke cron so it knows to reload. */
- if (changed)
- poke_daemon();
+ if (changed) {
+ PRIV_START;
+ if (chdir(CRONDIR) != 0)
+ perror(CRONDIR);
+ else
+ poke_daemon(AT_DIR, RELOAD_AT);
+ PRIV_END;
+ }
return (error);
}
@@ -823,39 +852,55 @@ ttime(const char *arg)
"[[CC]YY]MMDDhhmm[.SS]");
}
-#define RELOAD_AT 0x4 /* XXX - from cron's macros.h */
+static int
+check_permission(void)
+{
+ int ok;
+ uid_t uid = geteuid();
+ struct passwd *pw;
-/* XXX - share with crontab */
-static void
-poke_daemon() {
- int sock, flags;
- unsigned char poke;
- struct sockaddr_un sun;
+ if ((pw = getpwuid(uid)) == NULL) {
+ perror("Cannot access password database");
+ exit(ERROR_EXIT);
+ }
PRIV_START;
- if (utime(_PATH_ATJOBS, NULL) < 0) {
- warn("can't update mtime on %s", _PATH_ATJOBS);
- PRIV_END;
- return;
- }
-
- /* Failure to poke the daemon socket is not a fatal error. */
- (void) signal(SIGPIPE, SIG_IGN);
- strlcpy(sun.sun_path, CRONDIR "/" SPOOL_DIR "/" CRONSOCK,
- sizeof(sun.sun_path));
- sun.sun_family = AF_UNIX;
- sun.sun_len = SUN_LEN(&sun);
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
- connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- poke = RELOAD_AT;
- write(sock, &poke, 1);
- close(sock);
- } else
- fprintf(stderr, "Warning, cron does not appear to be running.\n");
- (void) signal(SIGPIPE, SIG_DFL);
+ ok = allowed(pw->pw_name, AT_ALLOW, AT_DENY);
PRIV_END;
+
+ return (ok);
+}
+
+static void
+usage(void)
+{
+ /* Print usage and exit. */
+ switch (program) {
+ case AT:
+ case CAT:
+ (void)fprintf(stderr,
+ "usage: at [-bm] [-f file] [-q queue] -t time_arg\n"
+ " at [-bm] [-f file] [-q queue] timespec\n"
+ " at -c job [job ...]\n"
+ " at -l [-q queue] [job ...]\n"
+ " at -r job [job ...]\n");
+ break;
+ case ATQ:
+ (void)fprintf(stderr,
+ "usage: atq [-cnv] [-q queue] [name...]\n");
+ break;
+ case ATRM:
+ (void)fprintf(stderr,
+ "usage: atrm [-afi] [[job] [name] ...]\n");
+ break;
+ case BATCH:
+ (void)fprintf(stderr,
+ "usage: batch [-m] [-f file] [-q queue] [timespec]\n");
+ break;
+ }
+ exit(ERROR_EXIT);
}
int
@@ -865,21 +910,27 @@ main(int argc, char **argv)
char queue = DEFAULT_AT_QUEUE;
char queue_set = 0;
char *options = "q:f:t:bcdlmrv"; /* default options for at */
+ char cwd[MAX_FNAME];
int ch;
int aflag = 0;
int cflag = 0;
int nflag = 0;
+ if ((ProgramName = strrchr(argv[0], '/')) != NULL)
+ ProgramName++;
+ else
+ ProgramName = argv[0];
+
RELINQUISH_PRIVS;
/* find out what this program is supposed to do */
- if (strcmp(__progname, "atq") == 0) {
+ if (strcmp(ProgramName, "atq") == 0) {
program = ATQ;
options = "cnvq:";
- } else if (strcmp(__progname, "atrm") == 0) {
+ } else if (strcmp(ProgramName, "atrm") == 0) {
program = ATRM;
options = "afi";
- } else if (strcmp(__progname, "batch") == 0) {
+ } else if (strcmp(ProgramName, "batch") == 0) {
program = BATCH;
options = "f:q:mv";
}
@@ -969,9 +1020,13 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ perr("Cannot get current working directory");
+
+ set_cron_cwd();
+
if (!check_permission())
- errx(EXIT_FAILURE, "You do not have permission to use %s.",
- __progname);
+ panic("You do not have permission to use at.");
/* select our program */
switch (program) {
@@ -988,9 +1043,13 @@ main(int argc, char **argv)
case AT:
/* Time may have been specified via the -t flag. */
- if (timer == -1)
- timer = parsetime(argc, argv);
- writefile(timer, queue);
+ if (timer == -1) {
+ if (argc == 0)
+ usage();
+ else if ((timer = parsetime(argc, argv)) == -1)
+ exit(ERROR_EXIT);
+ }
+ writefile(cwd, timer, queue);
break;
case BATCH:
@@ -999,17 +1058,17 @@ main(int argc, char **argv)
else
queue = DEFAULT_BATCH_QUEUE;
- if (argc > 0)
- timer = parsetime(argc, argv);
- else
+ if (argc == 0)
timer = time(NULL);
+ else if ((timer = parsetime(argc, argv)) == -1)
+ exit(ERROR_EXIT);
- writefile(timer, queue);
+ writefile(cwd, timer, queue);
break;
default:
panic("Internal error");
break;
}
- exit(EXIT_SUCCESS);
+ exit(OK_EXIT);
}
diff --git a/usr.bin/at/at.h b/usr.bin/at/at.h
index 121157ac42b..80b8bd82257 100644
--- a/usr.bin/at/at.h
+++ b/usr.bin/at/at.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: at.h,v 1.7 2002/05/14 18:05:39 millert Exp $ */
-/* $NetBSD: at.h,v 1.2 1995/03/25 18:13:32 glass Exp $ */
+/* $OpenBSD: at.h,v 1.8 2003/02/20 20:38:08 millert Exp $ */
/*
* at.h - header for at(1)
@@ -27,7 +26,6 @@
*/
extern int fcreated;
-extern char *__progname;
extern int program;
extern char atfile[];
extern char vflag;
@@ -42,7 +40,5 @@ struct atjob {
char queue;
};
-#define AT_MAXJOBS 255 /* max jobs outstanding per user */
-
#define DEFAULT_BATCH_QUEUE 'E'
#define DEFAULT_AT_QUEUE 'c'
diff --git a/usr.bin/at/panic.c b/usr.bin/at/panic.c
deleted file mode 100644
index e9e2c635b17..00000000000
--- a/usr.bin/at/panic.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $OpenBSD: panic.c,v 1.10 2002/05/14 18:05:39 millert Exp $ */
-/* $NetBSD: panic.c,v 1.2 1995/03/25 18:13:33 glass Exp $ */
-
-/*
- * panic.c - terminate fast in case of error
- * Copyright (c) 1993 by Thomas Koenig
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author(s) may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "at.h"
-#include "panic.h"
-#include "privs.h"
-
-#ifndef lint
-static const char rcsid[] = "$OpenBSD: panic.c,v 1.10 2002/05/14 18:05:39 millert Exp $";
-#endif
-
-/*
- * Something fatal has happened, print error message and exit.
- */
-__dead void
-panic(const char *a)
-{
- (void)fprintf(stderr, "%s: %s\n", __progname, a);
- if (fcreated) {
- PRIV_START;
- unlink(atfile);
- PRIV_END;
- }
-
- exit(EXIT_FAILURE);
-}
-
-/*
- * Some operating system error; print error message and exit.
- */
-__dead void
-perr(const char *a)
-{
- if (!force)
- perror(a);
- if (fcreated) {
- PRIV_START;
- unlink(atfile);
- PRIV_END;
- }
-
- exit(EXIT_FAILURE);
-}
-
-/*
- * Two-parameter version of perr().
- */
-__dead void
-perr2(const char *a, const char *b)
-{
- if (!force)
- (void)fputs(a, stderr);
- perr(b);
-}
-
-__dead void
-usage(void)
-{
- /* Print usage and exit. */
- switch (program) {
- case AT:
- case CAT:
- (void)fprintf(stderr,
- "usage: at [-bm] [-f file] [-q queue] -t time_arg\n"
- " at [-bm] [-f file] [-q queue] timespec\n"
- " at -c job [job ...]\n"
- " at -l [-q queue] [job ...]\n"
- " at -r job [job ...]\n");
- break;
- case ATQ:
- (void)fprintf(stderr,
- "usage: atq [-cnv] [-q queue] [name...]\n");
- break;
- case ATRM:
- (void)fprintf(stderr,
- "usage: atrm [-afi] [[job] [name] ...]\n");
- break;
- case BATCH:
- (void)fprintf(stderr,
- "usage: batch [-m] [-f file] [-q queue] [timespec]\n");
- break;
- }
- exit(EXIT_FAILURE);
-}
diff --git a/usr.bin/at/panic.h b/usr.bin/at/panic.h
deleted file mode 100644
index 725f0feaea5..00000000000
--- a/usr.bin/at/panic.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $OpenBSD: panic.h,v 1.6 2002/05/11 23:16:44 millert Exp $ */
-/* $NetBSD: panic.h,v 1.2 1995/03/25 18:13:35 glass Exp $ */
-
-/*
- * panic.h - header for at(1)
- * Copyright (c) 1993 Thomas Koenig
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author(s) may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-__dead void panic(const char *);
-__dead void perr(const char *);
-__dead void perr2(const char *, const char *);
-__dead void usage(void);
diff --git a/usr.bin/at/parsetime.c b/usr.bin/at/parsetime.c
index f2d734666bd..0ef2db668fa 100644
--- a/usr.bin/at/parsetime.c
+++ b/usr.bin/at/parsetime.c
@@ -1,5 +1,4 @@
-/* $OpenBSD: parsetime.c,v 1.12 2002/06/14 21:35:00 todd Exp $ */
-/* $NetBSD: parsetime.c,v 1.3 1995/03/25 18:13:36 glass Exp $ */
+/* $OpenBSD: parsetime.c,v 1.13 2003/02/20 20:38:08 millert Exp $ */
/*
* parsetime.c - parse time for at(1)
@@ -37,7 +36,6 @@
*/
#include <sys/types.h>
-#include <err.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
@@ -47,9 +45,8 @@
#include <tzfile.h>
#include <unistd.h>
+#include "globals.h"
#include "at.h"
-#include "panic.h"
-
/* Structures and unions */
@@ -144,7 +141,7 @@ static int sc_tokid; /* scanner - token id */
static int sc_tokplur; /* scanner - is token plural? */
#ifndef lint
-static const char rcsid[] = "$OpenBSD: parsetime.c,v 1.12 2002/06/14 21:35:00 todd Exp $";
+static const char rcsid[] = "$OpenBSD: parsetime.c,v 1.13 2003/02/20 20:38:08 millert Exp $";
#endif
/*
@@ -170,7 +167,7 @@ parse_token(char *arg)
/*
* init_scanner() sets up the scanner to eat arguments
*/
-static void
+static int
init_scanner(int argc, char **argv)
{
scp = argv;
@@ -180,8 +177,12 @@ init_scanner(int argc, char **argv)
while (argc-- > 0)
sc_len += strlen(*argv++);
- if ((sc_token = (char *) malloc(sc_len)) == NULL)
- panic("Insufficient virtual memory");
+ if ((sc_token = (char *) malloc(sc_len)) == NULL) {
+ fprintf(stderr, "%s: Insufficient virtual memory\n",
+ ProgramName);
+ return (-1);
+ }
+ return (0);
}
/*
@@ -193,7 +194,7 @@ token(void)
int idx;
for (;;) {
- (void)memset(sc_token, 0, sc_len);
+ bzero(sc_token, sc_len);
sc_tokid = EOF;
sc_tokplur = 0;
idx = 0;
@@ -260,18 +261,22 @@ token(void)
static void
plonk(int tok)
{
- panic((tok == EOF) ? "incomplete time" : "garbled time");
+ fprintf(stderr, "%s: %s time\n", ProgramName,
+ (tok == EOF) ? "incomplete" : "garbled");
}
/*
- * expect() gets a token and dies most horribly if it's not the token we want
+ * expect() gets a token and returns -1 if it's not the token we want
*/
-static void
+static int
expect(int desired)
{
- if (token() != desired)
- plonk(sc_tokid); /* and we die here... */
+ if (token() != desired) {
+ plonk(sc_tokid);
+ return (-1);
+ }
+ return (0);
}
@@ -321,13 +326,14 @@ dateadd(int minutes, struct tm *tm)
* at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS]
*
*/
-static void
+static int
plus(struct tm *tm)
{
int delay;
int expectplur;
- expect(NUMBER);
+ if (expect(NUMBER) != 0)
+ return (-1);
delay = atoi(sc_token);
expectplur = (delay != 1) ? 1 : 0;
@@ -341,12 +347,14 @@ plus(struct tm *tm)
delay *= 60;
case MINUTES:
if (expectplur != sc_tokplur)
- warnx("pluralization is wrong");
+ fprintf(stderr, "%s: pluralization is wrong\n",
+ ProgramName);
dateadd(delay, tm);
- return;
+ return (0);
}
plonk(sc_tokid);
+ return (-1);
}
@@ -354,7 +362,7 @@ plus(struct tm *tm)
* tod() computes the time of day
* [NUMBER [DOT NUMBER] [AM|PM]]
*/
-static void
+static int
tod(struct tm *tm)
{
int hour, minute = 0;
@@ -368,15 +376,16 @@ tod(struct tm *tm)
* a HHMM time, otherwise it's HH DOT MM time
*/
if (token() == DOT) {
- expect(NUMBER);
+ if (expect(NUMBER) != 0)
+ return (-1);
minute = atoi(sc_token);
if (minute > 59)
- panic("garbled time");
+ goto bad;
token();
} else if (tlen == 4) {
minute = hour % 100;
if (minute > 59)
- panic("garbled time");
+ goto bad;
hour = hour / 100;
}
@@ -385,7 +394,7 @@ tod(struct tm *tm)
*/
if (sc_tokid == AM || sc_tokid == PM) {
if (hour > 12)
- panic("garbled time");
+ goto bad;
if (sc_tokid == PM) {
if (hour != 12) /* 12:xx PM is 12:xx, not 24:xx */
@@ -396,7 +405,7 @@ tod(struct tm *tm)
}
token();
} else if (hour > 23)
- panic("garbled time");
+ goto bad;
/*
* if we specify an absolute time, we don't want to bump the day even
@@ -414,6 +423,10 @@ tod(struct tm *tm)
tm->tm_hour = 0;
tm->tm_mday++;
}
+ return (0);
+bad:
+ fprintf(stderr, "%s: garbled time\n", ProgramName);
+ return (-1);
}
@@ -463,7 +476,7 @@ assign_date(struct tm *tm, int mday, int mon, int year)
* |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
* \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
*/
-static void
+static int
month(struct tm *tm)
{
int year = (-1);
@@ -472,7 +485,8 @@ month(struct tm *tm)
switch (sc_tokid) {
case PLUS:
- plus(tm);
+ if (plus(tm) != 0)
+ return (-1);
break;
case TOMORROW:
@@ -490,7 +504,8 @@ month(struct tm *tm)
* do month mday [year]
*/
mon = sc_tokid - JAN;
- expect(NUMBER);
+ if (expect(NUMBER) != 0)
+ return (-1);
mday = atoi(sc_token);
if (token() == NUMBER) {
year = atoi(sc_token);
@@ -530,10 +545,12 @@ month(struct tm *tm)
int sep;
sep = sc_tokid;
- expect(NUMBER);
+ if (expect(NUMBER) != 0)
+ return (-1);
mday = atoi(sc_token);
if (token() == sep) {
- expect(NUMBER);
+ if (expect(NUMBER) != 0)
+ return (-1);
year = atoi(sc_token);
token();
}
@@ -557,15 +574,19 @@ month(struct tm *tm)
mday = mon % 100;
mon /= 100;
} else
- panic("garbled time");
+ goto bad;
mon--;
if (mon < 0 || mon > 11 || mday < 1 || mday > 31)
- panic("garbled time");
+ goto bad;
assign_date(tm, mday, mon, year);
break;
- } /* case */
+ }
+ return (0);
+bad:
+ fprintf(stderr, "%s: garbled time\n", ProgramName);
+ return (-1);
}
@@ -581,6 +602,9 @@ parsetime(int argc, char **argv)
int hr = 0;
/* this MUST be initialized to zero for midnight/noon/teatime */
+ if (argc == 0)
+ return (-1);
+
nowtimer = time(NULL);
nowtime = *localtime(&nowtimer);
@@ -588,10 +612,8 @@ parsetime(int argc, char **argv)
runtime.tm_sec = 0;
runtime.tm_isdst = 0;
- if (argc == 0)
- usage();
-
- init_scanner(argc, argv);
+ if (init_scanner(argc, argv) == -1)
+ return (-1);
switch (token()) {
case NOW: /* now is optional prefix for PLUS tree */
@@ -603,12 +625,13 @@ parsetime(int argc, char **argv)
else if (sc_tokid != PLUS)
plonk(sc_tokid);
case PLUS:
- plus(&runtime);
+ if (plus(&runtime) != 0)
+ return (-1);
break;
case NUMBER:
- tod(&runtime);
- month(&runtime);
+ if (tod(&runtime) != 0 || month(&runtime) != 0)
+ return (-1);
break;
/*
@@ -633,10 +656,12 @@ parsetime(int argc, char **argv)
token();
/* fall through to month setting */
default:
- month(&runtime);
+ if (month(&runtime) != 0)
+ return (-1);
break;
} /* ugly case statement */
- expect(EOF);
+ if (expect(EOF) != 0)
+ return (-1);
/*
* adjust for daylight savings time
@@ -648,11 +673,16 @@ parsetime(int argc, char **argv)
runtimer = mktime(&runtime);
}
- if (runtimer < 0)
- panic("garbled time");
+ if (runtimer < 0) {
+ fprintf(stderr, "%s: garbled time\n", ProgramName);
+ return (-1);
+ }
- if (nowtimer > runtimer)
- panic("Trying to travel back in time");
+ if (nowtimer > runtimer) {
+ fprintf(stderr, "%s: Trying to travel back in time\n",
+ ProgramName);
+ return (-1);
+ }
return (runtimer);
}
diff --git a/usr.bin/at/parsetime.h b/usr.bin/at/parsetime.h
deleted file mode 100644
index bca21610240..00000000000
--- a/usr.bin/at/parsetime.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $OpenBSD: parsetime.h,v 1.4 2002/02/16 21:27:44 millert Exp $ */
-/* $NetBSD: parsetime.h,v 1.2 1995/03/25 18:13:37 glass Exp $ */
-
-/*
- * parsetime.h - header for at(1)
- * Copyright (c) 1993 Thomas Koenig
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author(s) may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-time_t parsetime(int, char **);
diff --git a/usr.bin/at/perm.c b/usr.bin/at/perm.c
deleted file mode 100644
index 6ff4eabfe5a..00000000000
--- a/usr.bin/at/perm.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $OpenBSD: perm.c,v 1.4 2002/05/14 18:05:39 millert Exp $ */
-
-/*
- * perm.c - check user permission for at(1)
- * Copyright (C) 1994 Thomas Koenig
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author(s) may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <pwd.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "at.h"
-#include "panic.h"
-#include "pathnames.h"
-#include "privs.h"
-
-#ifndef lint
-static const char rcsid[] = "$OpenBSD: perm.c,v 1.4 2002/05/14 18:05:39 millert Exp $";
-#endif
-
-static int check_for_user(FILE *, const char *);
-
-
-static int
-check_for_user(FILE *fp, const char *name)
-{
- char *buffer;
- size_t len;
- int found = 0;
-
- len = strlen(name);
- if ((buffer = malloc(len + 2)) == NULL)
- panic("Insufficient virtual memory");
-
- while (fgets(buffer, len + 2, fp) != NULL) {
- if (strncmp(name, buffer, len) == 0 && buffer[len] == '\n') {
- found = 1;
- break;
- }
- }
- (void)fclose(fp);
- free(buffer);
- return (found);
-}
-
-
-int
-check_permission(void)
-{
- FILE *fp;
- uid_t uid = geteuid();
- struct passwd *pentry;
-
- if (uid==0)
- return 1;
-
- if ((pentry = getpwuid(uid)) == NULL) {
- perror("Cannot access password database");
- exit(EXIT_FAILURE);
- }
-
- PRIV_START;
-
- fp = fopen(_PATH_AT_ALLOW, "r");
-
- PRIV_END;
-
- if (fp != NULL) {
- return (check_for_user(fp, pentry->pw_name));
- } else {
- PRIV_START;
-
- fp = fopen(_PATH_AT_DENY, "r");
-
- PRIV_END;
-
- if (fp != NULL)
- return (!check_for_user(fp, pentry->pw_name));
- else
- perror(_PATH_AT_DENY);
- }
- return (0);
-}
diff --git a/usr.bin/at/perm.h b/usr.bin/at/perm.h
deleted file mode 100644
index 3b0f76fe566..00000000000
--- a/usr.bin/at/perm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $OpenBSD: perm.h,v 1.3 2002/02/16 21:27:44 millert Exp $ */
-
-/*
- * perm.h - header for at(1)
- * Copyright (C) 1994 Thomas Koenig
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author(s) may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-int check_permission(void);
diff --git a/usr.bin/at/privs.h b/usr.bin/at/privs.h
index 2485e244cd2..ee3612c9507 100644
--- a/usr.bin/at/privs.h
+++ b/usr.bin/at/privs.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: privs.h,v 1.6 2002/06/04 00:13:54 deraadt Exp $ */
-/* $NetBSD: privs.h,v 1.3 1995/03/25 18:13:41 glass Exp $ */
+/* $OpenBSD: privs.h,v 1.7 2003/02/20 20:38:08 millert Exp $ */
/*
* privs.h - header for privileged operations
@@ -33,7 +32,8 @@
/* Relinquish privileges temporarily for a setuid or setgid program
* with the option of getting them back later. This is done by
- * utilizing POSIX saved user and groups ids. Call RELINQUISH_PRIVS once
+ * utilizing POSIX saved user and groups ids (or setreuid amd setregid if
+ * POSIX saved ids are not available). Call RELINQUISH_PRIVS once
* at the beginning of the main program. This will cause all operatons
* to be executed with the real userid. When you need the privileges
* of the setuid/setgid invocation, call PRIV_START; when you no longer
@@ -56,16 +56,18 @@
* to the real userid before calling any of them.
*/
-#ifndef MAIN
+#ifndef MAIN_PROGRAM
extern
#endif
uid_t real_uid, effective_uid;
-#ifndef MAIN
+#ifndef MAIN_PROGRAM
extern
#endif
gid_t real_gid, effective_gid;
+#ifdef HAVE_SAVED_UIDS
+
#define RELINQUISH_PRIVS do { \
real_uid = getuid(); \
effective_uid = geteuid(); \
@@ -94,4 +96,36 @@ gid_t real_gid, effective_gid;
seteuid(real_uid); \
} while (0)
+#else /* HAVE_SAVED_UIDS */
+
+#define RELINQUISH_PRIVS do { \
+ real_uid = getuid(); \
+ effective_uid = geteuid(); \
+ real_gid = getgid(); \
+ effective_gid = getegid(); \
+ setregid(effective_gid, real_gid); \
+ setreuid(effective_uid, real_uid); \
+} while (0)
+
+#define RELINQUISH_PRIVS_ROOT(a, b) do { \
+ real_uid = (a); \
+ effective_uid = geteuid(); \
+ real_gid = (b); \
+ effective_gid = getegid(); \
+ setregid(effective_gid, real_gid); \
+ setreuid(effective_uid, real_uid); \
+} while (0)
+
+#define PRIV_START do { \
+ setreuid(real_uid, effective_uid); \
+ setregid(real_gid, effective_gid); \
+} while (0)
+
+#define PRIV_END do { \
+ setregid(effective_gid, real_gid); \
+ setreuid(effective_uid, real_uid); \
+} while (0)
+
+#endif /* HAVE_SAVED_UIDS */
+
#endif /* _PRIVS_H */
diff --git a/usr.sbin/cron/atrun.c b/usr.sbin/cron/atrun.c
index 0af77580d1b..a3d4cdb3770 100644
--- a/usr.sbin/cron/atrun.c
+++ b/usr.sbin/cron/atrun.c
@@ -1,42 +1,39 @@
-/* $OpenBSD: atrun.c,v 1.5 2002/08/10 20:28:51 millert Exp $ */
+/* $OpenBSD: atrun.c,v 1.6 2003/02/20 20:38:08 millert Exp $ */
/*
- * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
+ * Copyright (c) 2002-2003 Todd C. Miller <Todd.Miller@courtesan.com>
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static const char rcsid[] = "$OpenBSD: atrun.c,v 1.5 2002/08/10 20:28:51 millert Exp $";
+static const char rcsid[] = "$OpenBSD: atrun.c,v 1.6 2003/02/20 20:38:08 millert Exp $";
#endif
#include "cron.h"
+#include <limits.h>
#include <sys/resource.h>
static void unlink_job(at_db *, atjob *);
static void run_job(atjob *, char *);
+#ifndef UID_MAX
+#define UID_MAX INT_MAX
+#endif
+#ifndef GID_MAX
+#define GID_MAX INT_MAX
+#endif
+
/*
* Scan the at jobs dir and build up a list of jobs found.
*/
@@ -55,8 +52,8 @@ scan_atjobs(at_db *old_db, struct timeval *tv)
Debug(DLOAD, ("[%ld] scan_atjobs()\n", (long)getpid()))
- if (stat(_PATH_ATJOBS, &statbuf) != 0) {
- log_it("CRON", getpid(), "CAN'T STAT", _PATH_ATJOBS);
+ if (stat(AT_DIR, &statbuf) != 0) {
+ log_it("CRON", getpid(), "CAN'T STAT", AT_DIR);
return (0);
}
@@ -72,13 +69,11 @@ scan_atjobs(at_db *old_db, struct timeval *tv)
return (0);
}
- if (chdir(_PATH_ATJOBS) != 0 || (atdir = opendir(".")) == NULL) {
+ if (chdir(AT_DIR) != 0 || (atdir = opendir(".")) == NULL) {
if (atdir == NULL)
- log_it("CRON", getpid(), "OPENDIR FAILED",
- _PATH_ATJOBS);
+ log_it("CRON", getpid(), "OPENDIR FAILED", AT_DIR);
else
- log_it("CRON", getpid(), "CHDIR FAILED",
- _PATH_ATJOBS);
+ log_it("CRON", getpid(), "CHDIR FAILED", AT_DIR);
fchdir(cwd);
close(cwd);
return (0);
@@ -99,10 +94,11 @@ scan_atjobs(at_db *old_db, struct timeval *tv)
* QUEUE is a letter that designates the job's queue
*/
l = strtol(file->d_name, &ep, 10);
- if (*ep != '.' || !isalpha(*(ep + 1)) || l < 0 || l >= INT_MAX)
+ if (ep[0] != '.' || !isalpha((unsigned char)ep[1]) || l < 0 ||
+ l >= INT_MAX)
continue;
run_time = (TIME_T)l;
- queue = *(ep + 1);
+ queue = ep[1];
if (!isalpha(queue))
continue;
@@ -157,7 +153,7 @@ scan_atjobs(at_db *old_db, struct timeval *tv)
void
atrun(at_db *db, double batch_maxload, TIME_T now)
{
- char atfile[PATH_MAX];
+ char atfile[MAX_FNAME];
struct stat statbuf;
double la;
atjob *job, *batch;
@@ -169,7 +165,7 @@ atrun(at_db *db, double batch_maxload, TIME_T now)
if (job->run_time > now)
continue;
- snprintf(atfile, sizeof(atfile), "%s/%ld.%c", _PATH_ATJOBS,
+ snprintf(atfile, sizeof(atfile), "%s/%ld.%c", AT_DIR,
(long)job->run_time, job->queue);
if (stat(atfile, &statbuf) != 0)
@@ -197,9 +193,13 @@ atrun(at_db *db, double batch_maxload, TIME_T now)
}
/* Run a single batch job if there is one pending. */
- if (batch != NULL && (batch_maxload == 0.0 ||
- ((getloadavg(&la, 1) == 1) && la <= batch_maxload))) {
- snprintf(atfile, sizeof(atfile), "%s/%ld.%c", _PATH_ATJOBS,
+ if (batch != NULL
+#ifdef HAVE_GETLOADAVG
+ && (batch_maxload == 0.0 ||
+ ((getloadavg(&la, 1) == 1) && la <= batch_maxload))
+#endif
+ ) {
+ snprintf(atfile, sizeof(atfile), "%s/%ld.%c", AT_DIR,
(long)batch->run_time, batch->queue);
run_job(batch, atfile);
unlink_job(db, batch);
@@ -280,12 +280,13 @@ run_job(atjob *job, char *atfile)
log_it("CRON", getpid(), "ORPHANED JOB", atfile);
_exit(ERROR_EXIT);
}
- /* XXX - is this needed now that we do auth_approval? */
+#if (defined(BSD)) && (BSD >= 199103)
if (pw->pw_expire && time(NULL) >= pw->pw_expire) {
log_it(pw->pw_name, getpid(), "ACCOUNT EXPIRED, JOB ABORTED",
atfile);
_exit(ERROR_EXIT);
}
+#endif
/* Sanity checks */
if (fstat(fd, &statbuf) < OK) {
@@ -349,16 +350,16 @@ run_job(atjob *job, char *atfile)
strncmp(buf, "# mail ", 7) != 0)
goto bad_file;
cp = buf + 7;
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
ep = cp;
- while (!isspace(*ep) && *ep != '\0')
+ while (!isspace((unsigned char)*ep) && *ep != '\0')
ep++;
if (*ep == '\0' || *ep != ' ' || ep - cp >= sizeof(mailto))
goto bad_file;
memcpy(mailto, cp, ep - cp);
mailto[ep - cp] = '\0';
- always_mail = *(ep + 1) == '1';
+ always_mail = ep[1] == '1';
(void)fclose(fp);
if (!safe_p(pw->pw_name, mailto))
@@ -461,7 +462,9 @@ run_job(atjob *job, char *atfile)
#else
setgid(pw->pw_gid);
initgroups(pw->pw_name, pw->pw_gid);
+#if (defined(BSD)) && (BSD >= 199103)
setlogin(pw->pw_name);
+#endif
setuid(pw->pw_uid);
#endif /* LOGIN_CAP */
@@ -539,8 +542,8 @@ run_job(atjob *job, char *atfile)
#ifdef MAIL_DATE
fprintf(mail, "Date: %s\n", arpadate(&StartTime));
#endif /*MAIL_DATE*/
- fprintf(mail, "\nYour \"at\" job on %s\n\"%s\"\n",
- hostname, atfile);
+ fprintf(mail, "\nYour \"at\" job on %s\n\"%s/%s\"\n",
+ hostname, CRONDIR, atfile);
fprintf(mail, "\nproduced the following output:\n\n");
/* Pipe the job's output to sendmail. */
diff --git a/usr.sbin/cron/config.h b/usr.sbin/cron/config.h
index 33944a2ed24..74a30b3b62d 100644
--- a/usr.sbin/cron/config.h
+++ b/usr.sbin/cron/config.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.h,v 1.14 2003/02/20 19:12:16 millert Exp $ */
+/* $OpenBSD: config.h,v 1.15 2003/02/20 20:38:08 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
@@ -21,7 +21,7 @@
* SOFTWARE.
*/
-/* config.h - configurables for ISC cron
+/* config.h - configurables for ISC Cron
*/
/*
@@ -80,8 +80,14 @@
*/
#define SYSLOG /*-*/
+ /* if you want cron to capitalize its name in ps
+ * when running a job. Does not work on SYSV.
+ */
#define CAPITALIZE_FOR_PS /*-*/
+ /* if you have a tm_gmtoff member in struct tm.
+ * If not, we will have to compute the value ourselves.
+ */
#define HAVE_TM_GMTOFF /*-*/
/* if your OS supports a BSD-style login.conf file */
@@ -90,5 +96,16 @@
/* if your OS supports BSD authentication */
#define BSD_AUTH /*-*/
+ /* if your OS has a getloadavg() function */
+#define HAVE_GETLOADAVG /*-*/
+
/* maximum load at which batch jobs will still run */
-#define BATCH_MAXLOAD 1.5
+#define BATCH_MAXLOAD 1.5 /*-*/
+
+ /* Define this to run crontab setgid instead of
+ * setuid root. Group access will be used to read
+ * the tabs/atjobs dirs and the allow/deny files.
+ * If this is not defined then crontab and at
+ * must be setuid root.
+ */
+#define CRON_GROUP "crontab" /*-*/
diff --git a/usr.sbin/cron/cron.8 b/usr.sbin/cron/cron.8
index 515e306da2c..c4dc4ad023d 100644
--- a/usr.sbin/cron/cron.8
+++ b/usr.sbin/cron/cron.8
@@ -1,30 +1,20 @@
.\"
-.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+.\" Copyright (c) 2002-2003 Todd C. Miller <Todd.Miller@courtesan.com>
.\" All rights reserved.
.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
.\"
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+.\" FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+.\" OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+.\" CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $OpenBSD: cron.8,v 1.20 2003/02/19 23:45:46 millert Exp $
+.\" $OpenBSD: cron.8,v 1.21 2003/02/20 20:38:08 millert Exp $
.\"
.Dd July 6, 2002
.Dt CRON 8
diff --git a/usr.sbin/cron/cron.c b/usr.sbin/cron/cron.c
index 56ecef1c5a1..47ef4dc5f2f 100644
--- a/usr.sbin/cron/cron.c
+++ b/usr.sbin/cron/cron.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: cron.c,v 1.30 2003/02/18 02:43:06 millert Exp $ */
+/* $OpenBSD: cron.c,v 1.31 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,14 +22,12 @@
*/
#if !defined(lint) && !defined(LINT)
-static const char rcsid[] = "$OpenBSD: cron.c,v 1.30 2003/02/18 02:43:06 millert Exp $";
+static const char rcsid[] = "$OpenBSD: cron.c,v 1.31 2003/02/20 20:38:08 millert Exp $";
#endif
#define MAIN_PROGRAM
#include "cron.h"
-#include <sys/socket.h>
-#include <sys/un.h>
enum timejump { negative, small, medium, large };
@@ -88,19 +87,19 @@ 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 */
sact.sa_handler = quit;
(void) sigaction(SIGINT, &sact, NULL);
(void) sigaction(SIGTERM, &sact, NULL);
+ sact.sa_handler = SIG_IGN;
+ (void) sigaction(SIGPIPE, &sact, NULL);
+ (void) sigaction(SIGUSR1, &sact, NULL); /* XXX */
acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();
- if (putenv("PATH="_PATH_DEFPATH) == -1) {
- log_it("CRON",getpid(),"DEATH","can't malloc");
+ if (putenv("PATH="_PATH_DEFPATH) < 0) {
+ log_it("CRON", getpid(), "DEATH", "can't malloc");
exit(1);
}
@@ -144,7 +143,7 @@ main(int argc, char *argv[]) {
at_database.tail = NULL;
at_database.mtime = (time_t) 0;
scan_atjobs(&at_database, NULL);
- set_time(1);
+ set_time(TRUE);
run_reboot_jobs(&database);
timeRunning = virtualTime = clockTime;
@@ -165,7 +164,7 @@ main(int argc, char *argv[]) {
/* ... wait for the time (in minutes) to change ... */
do {
cron_sleep(timeRunning + 1);
- set_time(0);
+ set_time(FALSE);
} while (clockTime == timeRunning);
timeRunning = clockTime;
@@ -232,7 +231,7 @@ main(int argc, char *argv[]) {
virtualTime++;
find_jobs(virtualTime, &database,
FALSE, TRUE);
- set_time(0);
+ set_time(FALSE);
} while (virtualTime< timeRunning &&
clockTime == timeRunning);
break;
@@ -326,8 +325,8 @@ find_jobs(int vtime, cron_db *db, int doWild, int doNonWild) {
for (u = db->head; u != NULL; u = u->next) {
for (e = u->crontab; e != NULL; e = e->next) {
Debug(DSCH|DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n",
- e->pwd->pw_name, (long)e->pwd->pw_uid,
- (long)e->pwd->pw_gid, e->cmd))
+ e->pwd->pw_name, (long)e->pwd->pw_uid,
+ (long)e->pwd->pw_gid, e->cmd))
if (bit_test(e->minute, minute) &&
bit_test(e->hour, hour) &&
bit_test(e->month, month) &&
@@ -352,16 +351,18 @@ find_jobs(int vtime, cron_db *db, int doWild, int doNonWild) {
*/
static void
set_time(int initialize) {
- struct tm *tm;
+ struct tm tm;
static int isdst;
StartTime = time(NULL);
/* We adjust the time to GMT so we can catch DST changes. */
- tm = localtime(&StartTime);
- if (initialize || tm->tm_isdst != isdst) {
- isdst = tm->tm_isdst;
- GMToff = get_gmtoff(&StartTime, tm);
+ tm = *localtime(&StartTime);
+ if (initialize || tm.tm_isdst != isdst) {
+ isdst = tm.tm_isdst;
+ GMToff = get_gmtoff(&StartTime, &tm);
+ Debug(DSCH, ("[%ld] GMToff=%ld\n",
+ (long)getpid(), (long)GMToff))
}
clockTime = (StartTime + GMToff) / (time_t)SECONDS_PER_MINUTE;
}
@@ -374,7 +375,7 @@ cron_sleep(int target) {
int fd, nfds;
unsigned char poke;
struct timeval t1, t2, tv;
- struct sockaddr_un sun;
+ struct sockaddr_un s_un;
socklen_t sunlen;
static fd_set *fdsr;
@@ -404,7 +405,7 @@ cron_sleep(int target) {
if (nfds > 0) {
Debug(DSCH, ("[%ld] Got a poke on the socket\n",
(long)getpid()))
- fd = accept(cronSock, (struct sockaddr *)&sun, &sunlen);
+ fd = accept(cronSock, (struct sockaddr *)&s_un, &sunlen);
if (fd >= 0) {
(void) read(fd, &poke, 1);
close(fd);
@@ -464,7 +465,7 @@ quit(int x) {
}
static void
-sigchld_reaper() {
+sigchld_reaper(void) {
WAIT_T waiter;
PID_T pid;
diff --git a/usr.sbin/cron/crontab.1 b/usr.sbin/cron/crontab.1
index 50b3616f262..be73a0b7c32 100644
--- a/usr.sbin/cron/crontab.1
+++ b/usr.sbin/cron/crontab.1
@@ -2,6 +2,8 @@
.\" * All rights reserved
.\" */
.\"
+.\" Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
@@ -15,7 +17,7 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE.
.\"
-.\" $OpenBSD: crontab.1,v 1.18 2003/02/20 19:12:16 millert Exp $
+.\" $OpenBSD: crontab.1,v 1.19 2003/02/20 20:38:08 millert Exp $
.\"
.Dd June 8, 1999
.Dt CRONTAB 1
diff --git a/usr.sbin/cron/crontab.5 b/usr.sbin/cron/crontab.5
index 089c68e9fa3..2eeb0653bf1 100644
--- a/usr.sbin/cron/crontab.5
+++ b/usr.sbin/cron/crontab.5
@@ -2,6 +2,8 @@
.\" * All rights reserved
.\" */
.\"
+.\" Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
@@ -15,7 +17,7 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE.
.\"
-.\" $OpenBSD: crontab.5,v 1.17 2002/07/08 18:11:02 millert Exp $
+.\" $OpenBSD: crontab.5,v 1.18 2003/02/20 20:38:08 millert Exp $
.\"
.Dd June 8, 1999
.Dt CRONTAB 5
diff --git a/usr.sbin/cron/crontab.c b/usr.sbin/cron/crontab.c
index 9accc8d24d9..151c418004a 100644
--- a/usr.sbin/cron/crontab.c
+++ b/usr.sbin/cron/crontab.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: crontab.c,v 1.39 2003/02/20 19:12:16 millert Exp $ */
+/* $OpenBSD: crontab.c,v 1.40 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: crontab.c,v 1.39 2003/02/20 19:12:16 millert Exp $";
+static char const rcsid[] = "$OpenBSD: crontab.c,v 1.40 2003/02/20 20:38:08 millert Exp $";
#endif
/* crontab - install and manage per-user crontab files
@@ -32,8 +33,6 @@ static char const rcsid[] = "$OpenBSD: crontab.c,v 1.39 2003/02/20 19:12:16 mill
#define MAIN_PROGRAM
#include "cron.h"
-#include <sys/socket.h>
-#include <sys/un.h>
#define NHEADER_LINES 3
@@ -56,7 +55,6 @@ static struct passwd *pw;
static void list_cmd(void),
delete_cmd(void),
edit_cmd(void),
- poke_daemon(void),
check_error(const char *),
parse_args(int c, char *v[]),
die(int);
@@ -88,7 +86,7 @@ main(int argc, char *argv[]) {
#endif
parse_args(argc, argv); /* sets many globals, opens a file */
set_cron_cwd();
- if (!allowed(RealUser, ALLOW_FILE, DENY_FILE)) {
+ if (!allowed(RealUser, CRON_ALLOW, CRON_DENY)) {
fprintf(stderr,
"You (%s) are not allowed to use this program (%s)\n",
User, ProgramName);
@@ -273,7 +271,7 @@ delete_cmd(void) {
perror(n);
exit(ERROR_EXIT);
}
- poke_daemon();
+ poke_daemon(SPOOL_DIR, RELOAD_CRON);
}
static void
@@ -624,7 +622,7 @@ replace_cmd(void) {
TempFilename[0] = '\0';
log_it(RealUser, Pid, "REPLACE", User);
- poke_daemon();
+ poke_daemon(SPOOL_DIR, RELOAD_CRON);
done:
(void) signal(SIGHUP, SIG_DFL);
@@ -638,36 +636,6 @@ done:
}
static void
-poke_daemon() {
- int sock, flags;
- unsigned char poke;
- struct sockaddr_un sun;
-
- if (utime(SPOOL_DIR, NULL) < OK) {
- fprintf(stderr, "crontab: can't update mtime on spooldir\n");
- perror(SPOOL_DIR);
- return;
- }
-
- /* 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 = SUN_LEN(&sun);
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
- connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == 0) {
- poke = RELOAD_CRON;
- write(sock, &poke, 1);
- close(sock);
- } else
- fprintf(stderr, "Warning, cron does not appear to be running.\n");
-
- }
- (void) signal(SIGPIPE, SIG_DFL);
-}
-
-static void
die(int x) {
if (TempFilename[0])
(void) unlink(TempFilename);
diff --git a/usr.sbin/cron/database.c b/usr.sbin/cron/database.c
index ff5ad462c50..52668b2ba63 100644
--- a/usr.sbin/cron/database.c
+++ b/usr.sbin/cron/database.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: database.c,v 1.11 2002/08/10 20:28:51 millert Exp $ */
+/* $OpenBSD: database.c,v 1.12 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: database.c,v 1.11 2002/08/10 20:28:51 millert Exp $";
+static char const rcsid[] = "$OpenBSD: database.c,v 1.12 2003/02/20 20:38:08 millert Exp $";
#endif
/* vix 26jan87 [RCS has the log]
@@ -212,7 +213,7 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
log_it(fname, getpid(), "BAD FILE MODE", tabname);
goto next_crontab;
}
- if (statbuf->st_uid != 0 && (pw == NULL ||
+ if (statbuf->st_uid != ROOT_UID && (pw == NULL ||
statbuf->st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) {
log_it(fname, getpid(), "WRONG FILE OWNER", tabname);
goto next_crontab;
diff --git a/usr.sbin/cron/do_command.c b/usr.sbin/cron/do_command.c
index 6eb2c5388a2..05363d67b95 100644
--- a/usr.sbin/cron/do_command.c
+++ b/usr.sbin/cron/do_command.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: do_command.c,v 1.22 2002/08/08 18:17:50 millert Exp $ */
+/* $OpenBSD: do_command.c,v 1.23 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: do_command.c,v 1.22 2002/08/08 18:17:50 millert Exp $";
+static char const rcsid[] = "$OpenBSD: do_command.c,v 1.23 2003/02/20 20:38:08 millert Exp $";
#endif
#include "cron.h"
@@ -63,8 +64,7 @@ do_command(entry *e, user *u) {
static void
child_process(entry *e, user *u) {
int stdin_pipe[2], stdout_pipe[2];
- char *usernm;
- char *input_data, *mailto;
+ char *input_data, *usernm, *mailto;
int children = 0;
Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd))
@@ -208,7 +208,9 @@ child_process(entry *e, user *u) {
_exit(ERROR_EXIT);
}
if (setusercontext(lc, e->pwd, e->pwd->pw_uid, LOGIN_SETALL) < 0) {
- fprintf(stderr, "setusercontext failed for %s\n", e->pwd->pw_name);
+ fprintf(stderr,
+ "setusercontext failed for %s\n",
+ e->pwd->pw_name);
_exit(ERROR_EXIT);
}
#ifdef BSD_AUTH
@@ -242,7 +244,9 @@ child_process(entry *e, user *u) {
#else
setgid(e->pwd->pw_gid);
initgroups(usernm, e->pwd->pw_gid);
+#if (defined(BSD)) && (BSD >= 199103)
setlogin(usernm);
+#endif /* BSD */
setuid(e->pwd->pw_uid); /* we aren't root after this... */
#endif /* LOGIN_CAP */
@@ -380,7 +384,7 @@ child_process(entry *e, user *u) {
/* get name of recipient. this is MAILTO if set to a
* valid local username; USER otherwise.
*/
- if (mailto && safe_p(usernm, mailto)) {
+ if (mailto) {
/* MAILTO was present in the environment
*/
if (!*mailto) {
@@ -399,7 +403,7 @@ child_process(entry *e, user *u) {
* up the mail command and subjects and stuff...
*/
- if (mailto) {
+ if (mailto && safe_p(usernm, mailto)) {
char **env;
char mailcmd[MAX_COMMAND];
char hostname[MAXHOSTNAMELEN];
@@ -490,10 +494,9 @@ child_process(entry *e, user *u) {
Debug(DPROC, ("[%ld] waiting for grandchild #%d to finish\n",
(long)getpid(), children))
- pid = wait(&waiter);
+ while ((pid = wait(&waiter)) < OK && errno == EINTR)
+ ;
if (pid < OK) {
- if (errno == EINTR)
- continue;
Debug(DPROC,
("[%ld] no more grandchildren--mail written?\n",
(long)getpid()))
diff --git a/usr.sbin/cron/entry.c b/usr.sbin/cron/entry.c
index 32d96d4577f..6a6863f3e53 100644
--- a/usr.sbin/cron/entry.c
+++ b/usr.sbin/cron/entry.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: entry.c,v 1.15 2002/08/10 20:28:51 millert Exp $ */
+/* $OpenBSD: entry.c,v 1.16 2003/02/20 20:38:08 millert Exp $ */
+
/*
* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
@@ -22,7 +23,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: entry.c,v 1.15 2002/08/10 20:28:51 millert Exp $";
+static char const rcsid[] = "$OpenBSD: entry.c,v 1.16 2003/02/20 20:38:08 millert Exp $";
#endif
/* vix 26jan87 [RCS'd; rest of log is in RCS file]
@@ -248,7 +249,8 @@ load_entry(FILE *file, void (*error_func)(), struct passwd *pw, char **envp) {
goto eof;
}
- if ((pw = getpwnam(username)) == NULL) {
+ pw = getpwnam(username);
+ if (pw == NULL) {
ecode = e_username;
goto eof;
}
@@ -294,7 +296,8 @@ load_entry(FILE *file, void (*error_func)(), struct passwd *pw, char **envp) {
} else
log_it("CRON", getpid(), "error", "can't set HOME");
}
-#ifdef LOGIN_CAP
+#ifndef LOGIN_CAP
+ /* If login.conf is in use we will get the default PATH later. */
if (!env_get("PATH", e->envp)) {
if (glue_strings(envstr, sizeof envstr, "PATH",
_PATH_DEFPATH, '=')) {
@@ -316,7 +319,7 @@ load_entry(FILE *file, void (*error_func)(), struct passwd *pw, char **envp) {
e->envp = tenvp;
} else
log_it("CRON", getpid(), "error", "can't set LOGNAME");
-#if defined(BSD)
+#if defined(BSD) || defined(__linux)
if (glue_strings(envstr, sizeof envstr, "USER",
pw->pw_name, '=')) {
if ((tenvp = env_set(e->envp, envstr)) == NULL) {
@@ -519,13 +522,13 @@ get_number(int *numptr, int low, const char *names[], char ch, FILE *file) {
pc = temp;
len = 0;
all_digits = TRUE;
- while (isalnum(ch)) {
+ while (isalnum((unsigned char)ch)) {
if (++len >= MAX_TEMPSTR)
return (EOF);
*pc++ = ch;
- if (!isdigit(ch))
+ if (!isdigit((unsigned char)ch))
all_digits = FALSE;
ch = get_char(file);
diff --git a/usr.sbin/cron/env.c b/usr.sbin/cron/env.c
index 51070680e14..6599c5d0d5d 100644
--- a/usr.sbin/cron/env.c
+++ b/usr.sbin/cron/env.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 millert Exp $ */
+/* $OpenBSD: env.c,v 1.14 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 millert Exp $";
+static char const rcsid[] = "$OpenBSD: env.c,v 1.14 2003/02/20 20:38:08 millert Exp $";
#endif
#include "cron.h"
diff --git a/usr.sbin/cron/externs.h b/usr.sbin/cron/externs.h
index 9ede7f9644b..d8d1268e430 100644
--- a/usr.sbin/cron/externs.h
+++ b/usr.sbin/cron/externs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: externs.h,v 1.8 2002/07/17 22:10:56 millert Exp $ */
+/* $OpenBSD: externs.h,v 1.9 2003/02/20 20:38:08 millert Exp $ */
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
@@ -25,13 +25,13 @@
#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>
#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <bitstring.h>
#include <ctype.h>
@@ -42,7 +42,6 @@
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
-#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <signal.h>
@@ -59,11 +58,11 @@
#endif
#if defined(LOGIN_CAP)
-#include <login_cap.h>
+# include <login_cap.h>
#endif /*LOGIN_CAP*/
#if defined(BSD_AUTH)
-#include <bsd_auth.h>
+# include <bsd_auth.h>
#endif /*BSD_AUTH*/
#define DIR_T struct dirent
@@ -77,13 +76,13 @@ extern char *tzname[2];
#endif
#define TZONE(tm) tzname[(tm).tm_isdst]
-#if (BSD >= 198606)
+#if (defined(BSD)) && (BSD >= 198606) || defined(__linux)
# define HAVE_FCHOWN
# define HAVE_FCHMOD
#endif
-#if (BSD >= 199103)
-# define HAVE_SAVED_GIDS
+#if (defined(BSD)) && (BSD >= 199103) || defined(__linux)
+# define HAVE_SAVED_UIDS
#endif
#define MY_UID(pw) getuid()
diff --git a/usr.sbin/cron/funcs.h b/usr.sbin/cron/funcs.h
index e7dc347d500..63c71ee0f46 100644
--- a/usr.sbin/cron/funcs.h
+++ b/usr.sbin/cron/funcs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: funcs.h,v 1.9 2003/02/20 19:12:16 millert Exp $ */
+/* $OpenBSD: funcs.h,v 1.10 2003/02/20 20:38:08 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -39,6 +39,7 @@ void set_cron_uid(void),
skip_comments(FILE *),
log_it(const char *, int, const char *, const char *),
log_close(void),
+ poke_daemon(const char *, unsigned char),
atrun(at_db *, double, time_t);
int job_runqueue(void),
diff --git a/usr.sbin/cron/globals.h b/usr.sbin/cron/globals.h
index edd3d4a82d7..9ea6ad7558a 100644
--- a/usr.sbin/cron/globals.h
+++ b/usr.sbin/cron/globals.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: globals.h,v 1.5 2003/02/17 18:40:11 millert Exp $ */
+/* $OpenBSD: globals.h,v 1.6 2003/02/20 20:38:08 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -70,5 +70,5 @@ XTRN const char *DebugFlagNames[]
#endif
;
#else
-#define DebugFlags 0
+#define DebugFlags 0
#endif /* DEBUGGING */
diff --git a/usr.sbin/cron/job.c b/usr.sbin/cron/job.c
index 9e8a15fdb50..e5ddc7d9101 100644
--- a/usr.sbin/cron/job.c
+++ b/usr.sbin/cron/job.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: job.c,v 1.5 2002/07/11 20:15:40 millert Exp $ */
+/* $OpenBSD: job.c,v 1.6 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: job.c,v 1.5 2002/07/11 20:15:40 millert Exp $";
+static char const rcsid[] = "$OpenBSD: job.c,v 1.6 2003/02/20 20:38:08 millert Exp $";
#endif
#include "cron.h"
diff --git a/usr.sbin/cron/macros.h b/usr.sbin/cron/macros.h
index 452334c0ec2..959a6d3cffc 100644
--- a/usr.sbin/cron/macros.h
+++ b/usr.sbin/cron/macros.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: macros.h,v 1.3 2002/07/15 19:13:29 millert Exp $ */
+/* $OpenBSD: macros.h,v 1.4 2003/02/20 20:38:08 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -94,14 +94,14 @@
}
/* Data values used on cron socket */
-#define RELOAD_CRON 0x2
-#define RELOAD_AT 0x4
+#define RELOAD_CRON 0x2
+#define RELOAD_AT 0x4
#ifdef HAVE_TM_GMTOFF
-#define get_gmtoff(c, t) (t->tm_gmtoff)
+#define get_gmtoff(c, t) ((t)->tm_gmtoff)
#endif
-#define SECONDS_PER_MINUTE 60
+#define SECONDS_PER_MINUTE 60
#define FIRST_MINUTE 0
#define LAST_MINUTE 59
@@ -123,9 +123,3 @@
#define FIRST_DOW 0
#define LAST_DOW 7
#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1)
-
- /* each user's crontab will be held as a list of
- * the following structure.
- *
- * These are the cron commands.
- */
diff --git a/usr.sbin/cron/misc.c b/usr.sbin/cron/misc.c
index b234f1cabeb..0cad49f7a82 100644
--- a/usr.sbin/cron/misc.c
+++ b/usr.sbin/cron/misc.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: misc.c,v 1.25 2003/02/20 19:12:16 millert Exp $ */
+/* $OpenBSD: misc.c,v 1.26 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char const rcsid[] = "$OpenBSD: misc.c,v 1.25 2003/02/20 19:12:16 millert Exp $";
+static char const rcsid[] = "$OpenBSD: misc.c,v 1.26 2003/02/20 20:38:08 millert Exp $";
#endif
/* vix 26jan87 [RCS has the rest of the log]
@@ -29,8 +30,7 @@ static char const rcsid[] = "$OpenBSD: misc.c,v 1.25 2003/02/20 19:12:16 millert
*/
#include "cron.h"
-#include <sys/socket.h>
-#include <sys/un.h>
+#include <limits.h>
#if defined(SYSLOG) && defined(LOG_FILE)
# undef LOG_FILE
@@ -114,7 +114,7 @@ strdtb(char *s) {
* or the last non-blank in the string, whichever comes first.
*/
do {x--;}
- while (x >= s && isspace(*x));
+ while (x >= s && isspace((unsigned char)*x));
/* one character beyond where we stopped above is where the null
* goes.
@@ -208,12 +208,16 @@ set_cron_uid(void) {
void
set_cron_cwd(void) {
struct stat sb;
+ struct group *grp = NULL;
+#ifdef CRON_GROUP
+ grp = getgrnam(CRON_GROUP);
+#endif
/* first check for CRONDIR ("/var/cron" or some such)
*/
if (stat(CRONDIR, &sb) < OK && errno == ENOENT) {
perror(CRONDIR);
- if (OK == mkdir(CRONDIR, 0700)) {
+ if (OK == mkdir(CRONDIR, 0710)) {
fprintf(stderr, "%s: created\n", CRONDIR);
stat(CRONDIR, &sb);
} else {
@@ -222,7 +226,7 @@ set_cron_cwd(void) {
exit(ERROR_EXIT);
}
}
- if ((sb.st_mode & S_IFDIR) == 0) {
+ if (!S_ISDIR(sb.st_mode)) {
fprintf(stderr, "'%s' is not a directory, bailing out.\n",
CRONDIR);
exit(ERROR_EXIT);
@@ -246,11 +250,42 @@ set_cron_cwd(void) {
exit(ERROR_EXIT);
}
}
- if ((sb.st_mode & S_IFDIR) == 0) {
+ if (!S_ISDIR(sb.st_mode)) {
fprintf(stderr, "'%s' is not a directory, bailing out.\n",
SPOOL_DIR);
exit(ERROR_EXIT);
}
+ if (grp != NULL) {
+ if (sb.st_gid != grp->gr_gid)
+ chown(SPOOL_DIR, -1, grp->gr_gid);
+ if (sb.st_mode != 01730)
+ chmod(SPOOL_DIR, 01730);
+ }
+
+ /* finally, look at AT_DIR ("atjobs" or some such)
+ */
+ if (stat(AT_DIR, &sb) < OK && errno == ENOENT) {
+ perror(AT_DIR);
+ if (OK == mkdir(AT_DIR, 0700)) {
+ fprintf(stderr, "%s: created\n", AT_DIR);
+ stat(AT_DIR, &sb);
+ } else {
+ fprintf(stderr, "%s: ", AT_DIR);
+ perror("mkdir");
+ exit(ERROR_EXIT);
+ }
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ fprintf(stderr, "'%s' is not a directory, bailing out.\n",
+ AT_DIR);
+ exit(ERROR_EXIT);
+ }
+ if (grp != NULL) {
+ if (sb.st_gid != grp->gr_gid)
+ chown(AT_DIR, -1, grp->gr_gid);
+ if (sb.st_mode != 01770)
+ chmod(AT_DIR, 01770);
+ }
}
/* acquire_daemonlock() - write our PID into /etc/cron.pid, unless
@@ -423,9 +458,9 @@ in_file(const char *string, FILE *file, int error)
if (*endp != '\n')
return (error);
*endp = '\0';
+ if (0 == strcmp(line, string))
+ return (TRUE);
}
- if (0 == strcmp(line, string))
- return (TRUE);
}
if (ferror(file))
return (error);
@@ -662,16 +697,21 @@ arpadate(clock)
}
#endif /*MAIL_DATE*/
-#ifdef HAVE_SAVED_GIDS
+#ifdef HAVE_SAVED_UIDS
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*/
+#else /*HAVE_SAVED_UIDS*/
int swap_gids() { return (setregid(getegid(), getgid())); }
int swap_gids_back() { return (swap_gids()); }
-#endif /*HAVE_SAVED_GIDS*/
+#endif /*HAVE_SAVED_UIDS*/
-/* Return the offset from GMT in seconds (algorithm taken from sendmail). */
+/* Return the offset from GMT in seconds (algorithm taken from sendmail).
+ *
+ * warning:
+ * clobbers the static storage space used by localtime() and gmtime().
+ * If the local pointer is non-NULL it *must* point to a local copy.
+ */
#ifndef HAVE_TM_GMTOFF
long get_gmtoff(time_t *clock, struct tm *local)
{
@@ -708,7 +748,7 @@ open_socket()
{
int sock;
mode_t omask;
- struct sockaddr_un sun;
+ struct sockaddr_un s_un;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
@@ -717,18 +757,20 @@ open_socket()
log_it("CRON", getpid(), "DEATH", "can't create socket");
exit(ERROR_EXIT);
}
- if (!glue_strings(sun.sun_path, sizeof sun.sun_path, SPOOL_DIR,
+ if (!glue_strings(s_un.sun_path, sizeof s_un.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_family = AF_UNIX;
- sun.sun_len = SUN_LEN(&sun);
+ unlink(s_un.sun_path);
+ s_un.sun_family = AF_UNIX;
+#ifdef SUN_LEN
+ s_un.sun_len = SUN_LEN(&s_un);
+#endif
omask = umask(007);
- if (bind(sock, (struct sockaddr *)&sun, sizeof(sun))) {
+ if (bind(sock, (struct sockaddr *)&s_un, sizeof(s_un))) {
fprintf(stderr, "%s: can't bind socket: %s\n",
ProgramName, strerror(errno));
log_it("CRON", getpid(), "DEATH", "can't bind socket");
@@ -740,8 +782,38 @@ open_socket()
log_it("CRON", getpid(), "DEATH", "can't listen on socket");
exit(ERROR_EXIT);
}
- chmod(sun.sun_path, 0660);
+ chmod(s_un.sun_path, 0660);
umask(omask);
return(sock);
}
+
+void
+poke_daemon(const char *spool_dir, unsigned char cookie) {
+ int sock = -1;
+ struct sockaddr_un s_un;
+
+ if (utime(spool_dir, NULL) < 0) {
+ fprintf(stderr, "%s: unable to update mtime on %s\n",
+ ProgramName, spool_dir);
+ return;
+ }
+
+ if (glue_strings(s_un.sun_path, sizeof s_un.sun_path, SPOOL_DIR,
+ CRONSOCK, '/')) {
+ s_un.sun_family = AF_UNIX;
+#ifdef SUN_LEN
+ s_un.sun_len = SUN_LEN(&s_un);
+#endif
+ (void) signal(SIGPIPE, SIG_IGN);
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 &&
+ connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == 0)
+ write(sock, &cookie, 1);
+ else
+ fprintf(stderr, "%s: warning, cron does not appear to be "
+ "running.\n", ProgramName);
+ if (sock >= 0)
+ close(sock);
+ (void) signal(SIGPIPE, SIG_DFL);
+ }
+}
diff --git a/usr.sbin/cron/pathnames.h b/usr.sbin/cron/pathnames.h
index 2164d99fd53..e1a2ce1be7b 100644
--- a/usr.sbin/cron/pathnames.h
+++ b/usr.sbin/cron/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.9 2003/02/19 22:11:42 millert Exp $ */
+/* $OpenBSD: pathnames.h,v 1.10 2003/02/20 20:38:08 millert Exp $ */
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
@@ -27,10 +27,10 @@
#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX)
# include <paths.h>
#endif /*BSD*/
-
+
#ifndef CRONDIR
/* CRONDIR is where cron(8) and crontab(1) both chdir
- * to; SPOOL_DIR, ALLOW_FILE, DENY_FILE, and LOG_FILE
+ * to; SPOOL_DIR, CRON_ALLOW, CRON_DENY, and LOG_FILE
* are all relative to this directory.
*/
#define CRONDIR "/var/cron"
@@ -46,22 +46,39 @@
*/
#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.
+ /* ATDIR is where the at jobs live (relative to CRONDIR)
+ * This directory will have its modtime updated
+ * whenever at(1) changes a crontab; this is
+ * the signal for cron(8) to look for changes in the
+ * jobs directory (new, changed or jobs).
+ */
+#define AT_DIR "atjobs"
+
+ /* CRONSOCK is the name of the socket used by at and
+ * crontab to poke cron to re-read the at and cron
+ * spool files while cron is asleep.
+ * It lives in the spool directory.
+ */
+#define CRONSOCK ".sock"
+
+ /* cron allow/deny file. At least cron.deny must
+ * exist for ordinary users to run crontab.
+ */
+#define CRON_ALLOW "cron.allow"
+#define CRON_DENY "cron.deny"
+
+ /* at allow/deny file. At least at.deny must
+ * exist for ordinary users to run at.
*/
-#define CRONSOCK ".sock"
+#define AT_ALLOW "at.allow"
+#define AT_DENY "at.deny"
- /* 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
- * LOG_FILE or SYSLOG is defined, we don't log. If
- * both are defined, we log both ways. Note that if
+ /* undefining this turns off logging to a file. If
+ * neither LOG_FILE or SYSLOG is defined, we don't log.
+ * If both are defined, we log both ways. Note that if
* LOG_CRON is defined by <syslog.h>, LOG_FILE will not
* be used.
*/
-#define ALLOW_FILE "cron.allow"
-#define DENY_FILE "cron.deny"
#define LOG_FILE "log"
/* where should the daemon stick its PID?
@@ -87,6 +104,10 @@
# define EDITOR "/usr/ucb/vi"
#endif
+#ifndef _PATH_SENDMAIL
+# define _PATH_SENDMAIL "/usr/lib/sendmail"
+#endif
+
#ifndef _PATH_BSHELL
# define _PATH_BSHELL "/bin/sh"
#endif
@@ -103,13 +124,4 @@
# define _PATH_DEVNULL "/dev/null"
#endif
-#if !defined(_PATH_SENDMAIL)
-# define _PATH_SENDMAIL "/usr/lib/sendmail"
-#endif /*SENDMAIL*/
-
-/* XXX */
-#define _PATH_ATJOBS "/var/cron/atjobs"
-#define _PATH_AT_ALLOW "/var/cron/at.allow"
-#define _PATH_AT_DENY "/var/cron/at.deny"
-
#endif /* _PATHNAMES_H_ */
diff --git a/usr.sbin/cron/popen.c b/usr.sbin/cron/popen.c
index e8f5cfdd3c1..7baf392127f 100644
--- a/usr.sbin/cron/popen.c
+++ b/usr.sbin/cron/popen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: popen.c,v 1.17 2002/07/15 19:13:29 millert Exp $ */
+/* $OpenBSD: popen.c,v 1.18 2003/02/20 20:38:08 millert Exp $ */
/*
* Copyright (c) 1988, 1993, 1994
@@ -42,7 +42,7 @@
#if 0
static const sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
#else
-static const char rcsid[] = "$OpenBSD: popen.c,v 1.17 2002/07/15 19:13:29 millert Exp $";
+static const char rcsid[] = "$OpenBSD: popen.c,v 1.18 2003/02/20 20:38:08 millert Exp $";
#endif
#endif /* not lint */
@@ -94,7 +94,7 @@ cron_popen(char *program, char *type, struct passwd *pw) {
/* NOTREACHED */
case 0: /* child */
if (pw) {
-#if defined(LOGIN_CAP)
+#ifdef LOGIN_CAP
if (setusercontext(0, pw, pw->pw_uid, LOGIN_SETALL) < 0) {
fprintf(stderr,
"setusercontext failed for %s\n",
@@ -102,14 +102,22 @@ cron_popen(char *program, char *type, struct passwd *pw) {
_exit(ERROR_EXIT);
}
#else
- if (setgid(pw->pw_gid) ||
- setgroups(0, NULL) ||
- initgroups(pw->pw_name, pw->pw_gid))
- _exit(1);
+ if (setgid(pw->pw_gid) < 0 ||
+ initgroups(pw->pw_name, pw->pw_gid) < 0) {
+ fprintf(stderr,
+ "unable to set groups for %s\n",
+ pw->pw_name);
+ _exit(1);
+ }
+#if (defined(BSD)) && (BSD >= 199103)
setlogin(pw->pw_name);
- if (setuid(pw->pw_uid))
+#endif /* BSD */
+ if (setuid(pw->pw_uid)) {
+ fprintf(stderr,
+ "unable to set uid for %s\n",
+ pw->pw_name);
_exit(1);
- chdir(pw->pw_dir);
+ }
#endif /* LOGIN_CAP */
}
if (*type == 'r') {
diff --git a/usr.sbin/cron/user.c b/usr.sbin/cron/user.c
index de60ed83eb6..f7a7806c254 100644
--- a/usr.sbin/cron/user.c
+++ b/usr.sbin/cron/user.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: user.c,v 1.5 2002/07/11 20:15:40 millert Exp $ */
+/* $OpenBSD: user.c,v 1.6 2003/02/20 20:38:08 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +22,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static const char rcsid[] = "$OpenBSD: user.c,v 1.5 2002/07/11 20:15:40 millert Exp $";
+static const char rcsid[] = "$OpenBSD: user.c,v 1.6 2003/02/20 20:38:08 millert Exp $";
#endif
/* vix 26jan87 [log is in RCS file]