aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Fox <pgf@foxharp.boston.ma.us>2022-03-07 11:35:28 -0500
committerDenys Vlasenko <vda.linux@googlemail.com>2022-05-02 12:28:48 +0200
commit52a7bf6fa677abdb80f8e484f6ba77ed3d34e444 (patch)
treed0368c0da65170757e7c9db43d18abfdfa34add1
parent9b6f44e0403f9214343bdafd054a628aa1506630 (diff)
downloadbusybox-w32-52a7bf6fa677abdb80f8e484f6ba77ed3d34e444.tar.gz
busybox-w32-52a7bf6fa677abdb80f8e484f6ba77ed3d34e444.tar.bz2
busybox-w32-52a7bf6fa677abdb80f8e484f6ba77ed3d34e444.zip
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>
-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 {
125 char *cl_mailto; /* whom to mail results, may be NULL */ 125 char *cl_mailto; /* whom to mail results, may be NULL */
126#endif 126#endif
127 char *cl_shell; 127 char *cl_shell;
128 char *cl_path;
128 /* ordered by size, not in natural order. makes code smaller: */ 129 /* ordered by size, not in natural order. makes code smaller: */
129 char cl_Dow[7]; /* 0-6, beginning sunday */ 130 char cl_Dow[7]; /* 0-6, beginning sunday */
130 char cl_Mons[12]; /* 0-11 */ 131 char cl_Mons[12]; /* 0-11 */
@@ -421,6 +422,7 @@ static void load_crontab(const char *fileName)
421 char *mailTo = NULL; 422 char *mailTo = NULL;
422#endif 423#endif
423 char *shell = NULL; 424 char *shell = NULL;
425 char *path = NULL;
424 426
425 delete_cronfile(fileName); 427 delete_cronfile(fileName);
426 428
@@ -470,7 +472,12 @@ static void load_crontab(const char *fileName)
470 shell = xstrdup(&tokens[0][6]); 472 shell = xstrdup(&tokens[0][6]);
471 continue; 473 continue;
472 } 474 }
473//TODO: handle HOME= too? "man crontab" says: 475 if (is_prefixed_with(tokens[0], "PATH=")) {
476 free(path);
477 path = xstrdup(&tokens[0][5]);
478 continue;
479 }
480//TODO: handle HOME= too? Better yet, handle arbitrary ENVVARs? "man crontab" says:
474//name = value 481//name = value
475// 482//
476//where the spaces around the equal-sign (=) are optional, and any subsequent 483//where the spaces around the equal-sign (=) are optional, and any subsequent
@@ -480,8 +487,8 @@ static void load_crontab(const char *fileName)
480// 487//
481//Several environment variables are set up automatically by the cron(8) daemon. 488//Several environment variables are set up automatically by the cron(8) daemon.
482//SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd 489//SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd
483//line of the crontab's owner. HOME and SHELL may be overridden by settings 490//line of the crontab's owner. HOME, SHELL, and PATH may be overridden by
484//in the crontab; LOGNAME may not. 491//settings in the crontab; LOGNAME may not.
485 492
486#if ENABLE_FEATURE_CROND_SPECIAL_TIMES 493#if ENABLE_FEATURE_CROND_SPECIAL_TIMES
487 if (tokens[0][0] == '@') { 494 if (tokens[0][0] == '@') {
@@ -567,6 +574,7 @@ static void load_crontab(const char *fileName)
567 line->cl_mailto = xstrdup(mailTo); 574 line->cl_mailto = xstrdup(mailTo);
568#endif 575#endif
569 line->cl_shell = xstrdup(shell); 576 line->cl_shell = xstrdup(shell);
577 line->cl_path = xstrdup(path);
570 /* copy command */ 578 /* copy command */
571 line->cl_cmd = xstrdup(tokens[5]); 579 line->cl_cmd = xstrdup(tokens[5]);
572 pline = &line->cl_next; 580 pline = &line->cl_next;
@@ -653,21 +661,22 @@ static void safe_setenv(char **pvar_val, const char *var, const char *val)
653} 661}
654#endif 662#endif
655 663
656static void set_env_vars(struct passwd *pas, const char *shell) 664static void set_env_vars(struct passwd *pas, const char *shell, const char *path)
657{ 665{
658 /* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL. 666 /* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL.
659 * We assume crond inherited suitable PATH.
660 */ 667 */
661#if SETENV_LEAKS 668#if SETENV_LEAKS
662 safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name); 669 safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name);
663 safe_setenv(&G.env_var_user, "USER", pas->pw_name); 670 safe_setenv(&G.env_var_user, "USER", pas->pw_name);
664 safe_setenv(&G.env_var_home, "HOME", pas->pw_dir); 671 safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
665 safe_setenv(&G.env_var_shell, "SHELL", shell); 672 safe_setenv(&G.env_var_shell, "SHELL", shell);
673 if (path) safe_setenv(&G.env_var_shell, "PATH", path);
666#else 674#else
667 xsetenv("LOGNAME", pas->pw_name); 675 xsetenv("LOGNAME", pas->pw_name);
668 xsetenv("USER", pas->pw_name); 676 xsetenv("USER", pas->pw_name);
669 xsetenv("HOME", pas->pw_dir); 677 xsetenv("HOME", pas->pw_dir);
670 xsetenv("SHELL", shell); 678 xsetenv("SHELL", shell);
679 if (path) xsetenv("PATH", path);
671#endif 680#endif
672} 681}
673 682
@@ -701,7 +710,7 @@ fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail)
701 shell = line->cl_shell ? line->cl_shell : G.default_shell; 710 shell = line->cl_shell ? line->cl_shell : G.default_shell;
702 prog = run_sendmail ? SENDMAIL : shell; 711 prog = run_sendmail ? SENDMAIL : shell;
703 712
704 set_env_vars(pas, shell); 713 set_env_vars(pas, shell, NULL); /* don't use crontab's PATH for sendmail */
705 714
706 sv_logmode = logmode; 715 sv_logmode = logmode;
707 pid = vfork(); 716 pid = vfork();
@@ -845,7 +854,7 @@ static pid_t start_one_job(const char *user, CronLine *line)
845 854
846 /* Prepare things before vfork */ 855 /* Prepare things before vfork */
847 shell = line->cl_shell ? line->cl_shell : G.default_shell; 856 shell = line->cl_shell ? line->cl_shell : G.default_shell;
848 set_env_vars(pas, shell); 857 set_env_vars(pas, shell, line->cl_path);
849 858
850 /* Fork as the user in question and run program */ 859 /* Fork as the user in question and run program */
851 pid = vfork(); 860 pid = vfork();