crond: implement support for setting PATH in crontab files
No binary (build failed)
—
(log yok)
| @@ -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(); | |