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 */
|
char *cl_mailto; /* whom to mail results, may be NULL */
|
||||||
#endif
|
#endif
|
||||||
char *cl_shell;
|
char *cl_shell;
|
||||||
|
char *cl_path;
|
||||||
/* ordered by size, not in natural order. makes code smaller: */
|
/* ordered by size, not in natural order. makes code smaller: */
|
||||||
char cl_Dow[7]; /* 0-6, beginning sunday */
|
char cl_Dow[7]; /* 0-6, beginning sunday */
|
||||||
char cl_Mons[12]; /* 0-11 */
|
char cl_Mons[12]; /* 0-11 */
|
||||||
@ -421,6 +422,7 @@ static void load_crontab(const char *fileName)
|
|||||||
char *mailTo = NULL;
|
char *mailTo = NULL;
|
||||||
#endif
|
#endif
|
||||||
char *shell = NULL;
|
char *shell = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
delete_cronfile(fileName);
|
delete_cronfile(fileName);
|
||||||
|
|
||||||
@ -470,7 +472,12 @@ static void load_crontab(const char *fileName)
|
|||||||
shell = xstrdup(&tokens[0][6]);
|
shell = xstrdup(&tokens[0][6]);
|
||||||
continue;
|
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
|
//name = value
|
||||||
//
|
//
|
||||||
//where the spaces around the equal-sign (=) are optional, and any subsequent
|
//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.
|
//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
|
//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
|
//line of the crontab's owner. HOME, SHELL, and PATH may be overridden by
|
||||||
//in the crontab; LOGNAME may not.
|
//settings in the crontab; LOGNAME may not.
|
||||||
|
|
||||||
#if ENABLE_FEATURE_CROND_SPECIAL_TIMES
|
#if ENABLE_FEATURE_CROND_SPECIAL_TIMES
|
||||||
if (tokens[0][0] == '@') {
|
if (tokens[0][0] == '@') {
|
||||||
@ -567,6 +574,7 @@ static void load_crontab(const char *fileName)
|
|||||||
line->cl_mailto = xstrdup(mailTo);
|
line->cl_mailto = xstrdup(mailTo);
|
||||||
#endif
|
#endif
|
||||||
line->cl_shell = xstrdup(shell);
|
line->cl_shell = xstrdup(shell);
|
||||||
|
line->cl_path = xstrdup(path);
|
||||||
/* copy command */
|
/* copy command */
|
||||||
line->cl_cmd = xstrdup(tokens[5]);
|
line->cl_cmd = xstrdup(tokens[5]);
|
||||||
pline = &line->cl_next;
|
pline = &line->cl_next;
|
||||||
@ -653,21 +661,22 @@ static void safe_setenv(char **pvar_val, const char *var, const char *val)
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
/* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL.
|
||||||
* We assume crond inherited suitable PATH.
|
|
||||||
*/
|
*/
|
||||||
#if SETENV_LEAKS
|
#if SETENV_LEAKS
|
||||||
safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name);
|
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_user, "USER", pas->pw_name);
|
||||||
safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
|
safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
|
||||||
safe_setenv(&G.env_var_shell, "SHELL", shell);
|
safe_setenv(&G.env_var_shell, "SHELL", shell);
|
||||||
|
if (path) safe_setenv(&G.env_var_shell, "PATH", path);
|
||||||
#else
|
#else
|
||||||
xsetenv("LOGNAME", pas->pw_name);
|
xsetenv("LOGNAME", pas->pw_name);
|
||||||
xsetenv("USER", pas->pw_name);
|
xsetenv("USER", pas->pw_name);
|
||||||
xsetenv("HOME", pas->pw_dir);
|
xsetenv("HOME", pas->pw_dir);
|
||||||
xsetenv("SHELL", shell);
|
xsetenv("SHELL", shell);
|
||||||
|
if (path) xsetenv("PATH", path);
|
||||||
#endif
|
#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;
|
shell = line->cl_shell ? line->cl_shell : G.default_shell;
|
||||||
prog = run_sendmail ? SENDMAIL : 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;
|
sv_logmode = logmode;
|
||||||
pid = vfork();
|
pid = vfork();
|
||||||
@ -845,7 +854,7 @@ static pid_t start_one_job(const char *user, CronLine *line)
|
|||||||
|
|
||||||
/* Prepare things before vfork */
|
/* Prepare things before vfork */
|
||||||
shell = line->cl_shell ? line->cl_shell : G.default_shell;
|
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 */
|
/* Fork as the user in question and run program */
|
||||||
pid = vfork();
|
pid = vfork();
|
||||||
|
Loading…
Reference in New Issue
Block a user