Log run-time parsing errors now

Use getpwnam before getpwuid since two users with same uids can exists
(affects new login classes code only)

The same fixes as in inetd: by default run `system crontab things' with
daemon login class now, not restrict them to user class breaking
compatibility with old way (so-called nobody limits problem)

Implement user[:group][/login-class] syntax in system crontab
for more flexible control (the same as in inetd)
This commit is contained in:
Andrey A. Chernov 1997-11-02 17:22:20 +00:00
parent 12a5bd8bcf
commit 0435c15004
8 changed files with 88 additions and 16 deletions

View File

@ -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 <bsd.prog.mk>

View File

@ -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);

View File

@ -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..*/

View File

@ -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;

View File

@ -16,6 +16,9 @@ DPADD+= ${.CURDIR}/../lib/libcron.a
LDADD+= -lcron
LDADD+= -lutil
DPADD+= ${LIBUTIL}
BINOWN= root
BINMODE=4555
INSTALLFLAGS=-fschg

View File

@ -15,7 +15,7 @@
.\" * Paul Vixie <paul@vix.com> 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 ``:<group>'' and ``/<login-class>'' 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,

View File

@ -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

View File

@ -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 <grp.h>
#ifdef LOGIN_CAP
#include <login_cap.h>
#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) {