diff --git a/usr.sbin/cron/cron/Makefile b/usr.sbin/cron/cron/Makefile index e98f183324e..ddb06a88e68 100644 --- a/usr.sbin/cron/cron/Makefile +++ b/usr.sbin/cron/cron/Makefile @@ -5,8 +5,6 @@ SRCS= cron.c database.c do_command.c job.c user.c popen.c MAN8= cron.8 CFLAGS+=-DLOGIN_CAP -LDADD+= -lutil -DPADD+= ${LIBUTIL} .if exists(${.OBJDIR}/../lib) LDDESTDIR+= -L${.OBJDIR}/../lib @@ -18,4 +16,7 @@ DPADD+= ${.CURDIR}/../lib/libcron.a LDADD+= -lcron +LDADD+= -lutil +DPADD+= ${LIBUTIL} + .include diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h index 884984e0d91..95132714a9b 100644 --- a/usr.sbin/cron/cron/cron.h +++ b/usr.sbin/cron/cron/cron.h @@ -17,7 +17,7 @@ /* cron.h - header for vixie's cron * - * $Id: cron.h,v 1.6 1997/02/22 16:04:41 peter Exp $ + * $Id: cron.h,v 1.7 1997/09/15 06:39:04 charnier Exp $ * * vix 14nov88 [rest of log is in RCS] * vix 14jan87 [0 or 7 can be sunday; thanks, mwm@berkeley] @@ -143,6 +143,11 @@ #define LAST_DOW 7 #define DOW_COUNT (LAST_DOW - FIRST_DOW + 1) +#ifdef LOGIN_CAP +/* see init.c */ +#define RESOURCE_RC "daemon" +#endif + /* each user's crontab will be held as a list of * the following structure. * @@ -153,6 +158,9 @@ typedef struct _entry { struct _entry *next; uid_t uid; gid_t gid; +#ifdef LOGIN_CAP + char *class; +#endif char **envp; char *cmd; bitstr_t bit_decl(minute, MINUTE_COUNT); diff --git a/usr.sbin/cron/cron/do_command.c b/usr.sbin/cron/cron/do_command.c index 7faebdf9eb1..03236f4eaf3 100644 --- a/usr.sbin/cron/cron/do_command.c +++ b/usr.sbin/cron/cron/do_command.c @@ -17,7 +17,7 @@ #if !defined(lint) && !defined(LINT) static const char rcsid[] = - "$Id: do_command.c,v 1.12 1997/03/14 14:45:30 peter Exp $"; + "$Id: do_command.c,v 1.13 1997/09/15 06:39:06 charnier Exp $"; #endif @@ -83,6 +83,7 @@ child_process(e, u) int children = 0; # if defined(LOGIN_CAP) struct passwd *pwd; + login_cap_t *lc; # endif Debug(DPROC, ("[%d] child_process('%s')\n", getpid(), e->cmd)) @@ -223,9 +224,16 @@ child_process(e, u) /* Set user's entire context, but skip the environment * as cron provides a separate interface for this */ - pwd = getpwuid(e->uid); + if ((pwd = getpwnam(usernm)) == NULL) + pwd = getpwuid(e->uid); + lc = NULL; + if (pwd != NULL) { + pwd->pw_gid = e->gid; + if (e->class != NULL) + lc = login_getclass(e->class); + } if (pwd && - setusercontext(NULL, pwd, e->uid, + setusercontext(lc, pwd, e->uid, LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETENV)) == 0) (void) endpwent(); else { @@ -237,7 +245,7 @@ child_process(e, u) */ setgid(e->gid); # if defined(BSD) - initgroups(env_get("LOGNAME", e->envp), e->gid); + initgroups(usernm, e->gid); # endif setlogin(usernm); setuid(e->uid); /* we aren't root after this..*/ diff --git a/usr.sbin/cron/cron/user.c b/usr.sbin/cron/cron/user.c index 8004c14b343..d5833612535 100644 --- a/usr.sbin/cron/cron/user.c +++ b/usr.sbin/cron/cron/user.c @@ -17,7 +17,7 @@ #if !defined(lint) && !defined(LINT) static const char rcsid[] = - "$Id: user.c,v 1.5 1997/02/22 16:04:47 peter Exp $"; + "$Id: user.c,v 1.6 1997/09/15 06:39:07 charnier Exp $"; #endif /* vix 26jan87 [log is in RCS file] @@ -26,6 +26,7 @@ static const char rcsid[] = #include "cron.h" +static char *User_name; void free_user(u) @@ -41,6 +42,12 @@ free_user(u) free(u); } +static void +log_error(msg) + char *msg; +{ + log_it(User_name, getpid(), "PARSE", msg); +} user * load_user(crontab_fd, pw, name) @@ -94,7 +101,8 @@ load_user(crontab_fd, pw, name) u = NULL; goto done; case FALSE: - e = load_entry(file, NULL, pw, envp); + User_name = u->name; /* for log_error */ + e = load_entry(file, log_error, pw, envp); if (e) { e->next = u->crontab; u->crontab = e; diff --git a/usr.sbin/cron/crontab/Makefile b/usr.sbin/cron/crontab/Makefile index cce341db6ca..1c9a4866d3a 100644 --- a/usr.sbin/cron/crontab/Makefile +++ b/usr.sbin/cron/crontab/Makefile @@ -16,6 +16,9 @@ DPADD+= ${.CURDIR}/../lib/libcron.a LDADD+= -lcron +LDADD+= -lutil +DPADD+= ${LIBUTIL} + BINOWN= root BINMODE=4555 INSTALLFLAGS=-fschg diff --git a/usr.sbin/cron/crontab/crontab.5 b/usr.sbin/cron/crontab/crontab.5 index cf43525801d..c9d5bb5169f 100644 --- a/usr.sbin/cron/crontab/crontab.5 +++ b/usr.sbin/cron/crontab/crontab.5 @@ -15,7 +15,7 @@ .\" * Paul Vixie uunet!decwrl!vixie!paul .\" */ .\" -.\" $Id: crontab.5,v 1.5 1997/09/15 06:39:14 charnier Exp $ +.\" $Id: crontab.5,v 1.6 1997/09/29 19:11:36 wosch Exp $ .\" .Dd January 24, 1994 .Dt CRONTAB 5 @@ -114,7 +114,9 @@ usually doesn't read its mail. .Pp The format of a cron command is very much the V7 standard, with a number of upward-compatible extensions. Each line has five time and date fields, -followed by a user name if this is the system crontab file, +followed by a user name +(with optional ``:'' and ``/'' suffixes) +if this is the system crontab file, followed by a command. Commands are executed by .Xr cron 8 when the minute, hour, and month of year fields match the current time, diff --git a/usr.sbin/cron/lib/Makefile b/usr.sbin/cron/lib/Makefile index 5c6106568c1..52701315fe3 100644 --- a/usr.sbin/cron/lib/Makefile +++ b/usr.sbin/cron/lib/Makefile @@ -1,7 +1,8 @@ LIB= cron SRCS= entry.c env.c misc.c -CFLAGS+= -I${.CURDIR}/../cron +CFLAGS+=-I${.CURDIR}/../cron +CFLAGS+=-DLOGIN_CAP NOPIC= yes NOPROFILE= yes diff --git a/usr.sbin/cron/lib/entry.c b/usr.sbin/cron/lib/entry.c index 39ff0df052f..b7dba593001 100644 --- a/usr.sbin/cron/lib/entry.c +++ b/usr.sbin/cron/lib/entry.c @@ -17,7 +17,7 @@ #if !defined(lint) && !defined(LINT) static const char rcsid[] = - "$Id: entry.c,v 1.6 1997/02/22 16:05:06 peter Exp $"; + "$Id: entry.c,v 1.7 1997/09/15 06:39:21 charnier Exp $"; #endif /* vix 26jan87 [RCS'd; rest of log is in RCS file] @@ -28,11 +28,17 @@ static const char rcsid[] = #include "cron.h" - +#include +#ifdef LOGIN_CAP +#include +#endif typedef enum ecode { e_none, e_minute, e_hour, e_dom, e_month, e_dow, - e_cmd, e_timespec, e_username + e_cmd, e_timespec, e_username, e_group +#ifdef LOGIN_CAP + , e_class +#endif } ecode_e; static char get_list __P((bitstr_t *, int, int, char *[], int, FILE *)), @@ -51,6 +57,10 @@ static char *ecodes[] = "bad command", "bad time specifier", "bad username", + "bad group name", +#ifdef LOGIN_CAP + "bad class name", +#endif }; @@ -58,6 +68,10 @@ void free_entry(e) entry *e; { +#ifdef LOGIN_CAP + if (e->class != NULL) + free(e->class); +#endif free(e->cmd); env_free(e->envp); free(e); @@ -224,6 +238,8 @@ load_entry(file, error_func, pw, envp) if (!pw) { char *username = cmd; /* temp buffer */ + char *s, *group; + struct group *grp; Debug(DPARS, ("load_entry()...about to parse username\n")) ch = get_string(username, MAX_COMMAND, file, " \t"); @@ -234,12 +250,37 @@ load_entry(file, error_func, pw, envp) goto eof; } +#ifdef LOGIN_CAP + if ((s = strrchr(username, '/')) != NULL) { + *s = '\0'; + e->class = strdup(s + 1); + } else + e->class = strdup(RESOURCE_RC); + if (login_getclass(e->class) == NULL) { + ecode = e_class; + goto eof; + } +#endif + grp = NULL; + if ((s = strrchr(username, ':')) != NULL) { + *s = '\0'; + if ((grp = getgrnam(s + 1)) == NULL) { + ecode = e_group; + goto eof; + } + } + pw = getpwnam(username); if (pw == NULL) { ecode = e_username; goto eof; } - Debug(DPARS, ("load_entry()...uid %d, gid %d\n",e->uid,e->gid)) + if (grp != NULL) + pw->pw_gid = grp->gr_gid; + Debug(DPARS, ("load_entry()...uid %d, gid %d\n",pw->pw_uid,pw->pw_gid)) +#ifdef LOGIN_CAP + Debug(DPARS, ("load_entry()...class %s\n",e->class)) +#endif } if (pw->pw_expire && time(NULL) >= pw->pw_expire) {