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 /miscutils | |
| 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>
Diffstat (limited to 'miscutils')
| -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(); |
