Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.busybox.net/busybox.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Fox <pgf@foxharp.boston.ma.us>2022-03-07 19:35:28 +0300
committerDenys Vlasenko <vda.linux@googlemail.com>2022-05-02 13:28:48 +0300
commit52a7bf6fa677abdb80f8e484f6ba77ed3d34e444 (patch)
treed0368c0da65170757e7c9db43d18abfdfa34add1 /miscutils
parent9b6f44e0403f9214343bdafd054a628aa1506630 (diff)
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>
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/crond.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 1965af656..bd43c6b68 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -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();