crond: implement support for setting PATH in crontab files
It's very inconvenient for a cron user not to be able to set a "personal" PATH for their cron jobs, as is possible with other crons function old new delta load_crontab 868 942 +74 .rodata 104878 104884 +6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 80/0) Total: 80 bytes Signed-off-by: Paul Fox <pgf@foxharp.boston.ma.us> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
9b6f44e040
commit
52a7bf6fa6
@ -125,6 +125,7 @@ typedef struct CronLine {
|
||||
char *cl_mailto; /* whom to mail results, may be NULL */
|
||||
#endif
|
||||
char *cl_shell;
|
||||
char *cl_path;
|
||||
/* ordered by size, not in natural order. makes code smaller: */
|
||||
char cl_Dow[7]; /* 0-6, beginning sunday */
|
||||
char cl_Mons[12]; /* 0-11 */
|
||||
@ -421,6 +422,7 @@ static void load_crontab(const char *fileName)
|
||||
char *mailTo = NULL;
|
||||
#endif
|
||||
char *shell = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
delete_cronfile(fileName);
|
||||
|
||||
@ -470,7 +472,12 @@ static void load_crontab(const char *fileName)
|
||||
shell = xstrdup(&tokens[0][6]);
|
||||
continue;
|
||||
}
|
||||
//TODO: handle HOME= too? "man crontab" says:
|
||||
if (is_prefixed_with(tokens[0], "PATH=")) {
|
||||
free(path);
|
||||
path = xstrdup(&tokens[0][5]);
|
||||
continue;
|
||||
}
|
||||
//TODO: handle HOME= too? Better yet, handle arbitrary ENVVARs? "man crontab" says:
|
||||
//name = value
|
||||
//
|
||||
//where the spaces around the equal-sign (=) are optional, and any subsequent
|
||||
@ -480,8 +487,8 @@ static void load_crontab(const char *fileName)
|
||||
//
|
||||
//Several environment variables are set up automatically by the cron(8) daemon.
|
||||
//SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd
|
||||
//line of the crontab's owner. HOME and SHELL may be overridden by settings
|
||||
//in the crontab; LOGNAME may not.
|
||||
//line of the crontab's owner. HOME, SHELL, and PATH may be overridden by
|
||||
//settings in the crontab; LOGNAME may not.
|
||||
|
||||
#if ENABLE_FEATURE_CROND_SPECIAL_TIMES
|
||||
if (tokens[0][0] == '@') {
|
||||
@ -567,6 +574,7 @@ static void load_crontab(const char *fileName)
|
||||
line->cl_mailto = xstrdup(mailTo);
|
||||
#endif
|
||||
line->cl_shell = xstrdup(shell);
|
||||
line->cl_path = xstrdup(path);
|
||||
/* copy command */
|
||||
line->cl_cmd = xstrdup(tokens[5]);
|
||||
pline = &line->cl_next;
|
||||
@ -653,21 +661,22 @@ static void safe_setenv(char **pvar_val, const char *var, const char *val)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_env_vars(struct passwd *pas, const char *shell)
|
||||
static void set_env_vars(struct passwd *pas, const char *shell, const char *path)
|
||||
{
|
||||
/* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL.
|
||||
* We assume crond inherited suitable PATH.
|
||||
*/
|
||||
#if SETENV_LEAKS
|
||||
safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name);
|
||||
safe_setenv(&G.env_var_user, "USER", pas->pw_name);
|
||||
safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
|
||||
safe_setenv(&G.env_var_shell, "SHELL", shell);
|
||||
if (path) safe_setenv(&G.env_var_shell, "PATH", path);
|
||||
#else
|
||||
xsetenv("LOGNAME", pas->pw_name);
|
||||
xsetenv("USER", pas->pw_name);
|
||||
xsetenv("HOME", pas->pw_dir);
|
||||
xsetenv("SHELL", shell);
|
||||
if (path) xsetenv("PATH", path);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -701,7 +710,7 @@ fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail)
|
||||
shell = line->cl_shell ? line->cl_shell : G.default_shell;
|
||||
prog = run_sendmail ? SENDMAIL : shell;
|
||||
|
||||
set_env_vars(pas, shell);
|
||||
set_env_vars(pas, shell, NULL); /* don't use crontab's PATH for sendmail */
|
||||
|
||||
sv_logmode = logmode;
|
||||
pid = vfork();
|
||||
@ -845,7 +854,7 @@ static pid_t start_one_job(const char *user, CronLine *line)
|
||||
|
||||
/* Prepare things before vfork */
|
||||
shell = line->cl_shell ? line->cl_shell : G.default_shell;
|
||||
set_env_vars(pas, shell);
|
||||
set_env_vars(pas, shell, line->cl_path);
|
||||
|
||||
/* Fork as the user in question and run program */
|
||||
pid = vfork();
|
||||
|
Loading…
Reference in New Issue
Block a user