diff options
author | Paul Fox <pgf@foxharp.boston.ma.us> | 2022-03-07 11:35:28 -0500 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2022-05-02 12:28:48 +0200 |
commit | 52a7bf6fa677abdb80f8e484f6ba77ed3d34e444 (patch) | |
tree | d0368c0da65170757e7c9db43d18abfdfa34add1 | |
parent | 9b6f44e0403f9214343bdafd054a628aa1506630 (diff) | |
download | busybox-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.c | 23 |
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 | ||
656 | static void set_env_vars(struct passwd *pas, const char *shell) | 664 | static 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(); |