diff -up cronie-1.4.10/src/env.c.copy-env cronie-1.4.10/src/env.c --- cronie-1.4.10/src/env.c.copy-env 2012-11-27 08:32:13.000000000 +0100 +++ cronie-1.4.10/src/env.c 2013-06-11 17:41:08.533094913 +0200 @@ -25,6 +25,7 @@ #include #include #include +#include #include "globals.h" #include "funcs.h" @@ -67,7 +68,7 @@ char **env_copy(char **envp) { return (p); } -char **env_set(char **envp, char *envstr) { +char **env_set(char **envp, const char *envstr) { int count, found; char **p, *envtmp; @@ -112,6 +113,47 @@ char **env_set(char **envp, char *envstr return (p); } +int env_set_from_environ(char ***envpp) { + static const char *names[] = { + "LANG", + "LC_CTYPE", + "LC_NUMERIC", + "LC_TIME", + "LC_COLLATE", + "LC_MONETARY", + "LC_MESSAGES", + "LC_PAPER", + "LC_NAME", + "LC_ADDRESS", + "LC_TELEPHONE", + "LC_MEASUREMENT", + "LC_IDENTIFICATION", + "LC_ALL", + "LANGUAGE", + NULL + }; + const char **name; + char **procenv; + + for (procenv = environ; *procenv != NULL; ++procenv) { + for (name = names; *name != NULL; ++name) { + size_t namelen; + + namelen = strlen(*name); + if (strncmp(*name, *procenv, namelen) == 0 + && (*procenv)[namelen] == '=') { + char **tmpenv; + + tmpenv = env_set(*envpp, *procenv); + if (tmpenv == NULL) + return FALSE; + *envpp = tmpenv; + } + } + } + return TRUE; +} + /* The following states are used by load_env(), traversed in order: */ enum env_state { NAMEI, /* First char of NAME, may be quote */ diff -up cronie-1.4.10/src/funcs.h.copy-env cronie-1.4.10/src/funcs.h --- cronie-1.4.10/src/funcs.h.copy-env 2012-11-27 10:22:14.000000000 +0100 +++ cronie-1.4.10/src/funcs.h 2013-06-11 17:08:36.462019472 +0200 @@ -67,6 +67,7 @@ int load_database(cron_db *), swap_uids(void), swap_uids_back(void), load_env(char *, FILE *), + env_set_from_environ(char ***envpp), cron_pclose(FILE *), glue_strings(char *, size_t, const char *, const char *, char), strcmp_until(const char *, const char *, char), @@ -81,7 +82,7 @@ char *env_get(const char *, char **), *first_word(const char *, const char *), **env_init(void), **env_copy(char **), - **env_set(char **, char *); + **env_set(char **, const char *); user *load_user(int, struct passwd *, const char *, const char *, const char *), *find_user(cron_db *, const char *, const char *); diff -up cronie-1.4.10/src/user.c.copy-env cronie-1.4.10/src/user.c --- cronie-1.4.10/src/user.c.copy-env 2012-11-27 08:32:13.000000000 +0100 +++ cronie-1.4.10/src/user.c 2013-06-11 17:34:51.000000000 +0200 @@ -63,7 +63,7 @@ load_user (int crontab_fd, struct passwd FILE *file; user *u; entry *e; - int status, save_errno = errno; + int status = TRUE, save_errno = 0; char **envp = NULL, **tenvp; if (!(file = fdopen(crontab_fd, "r"))) { @@ -84,26 +84,24 @@ load_user (int crontab_fd, struct passwd if (((u->name = strdup(fname)) == NULL) || ((u->tabname = strdup(tabname)) == NULL)) { save_errno = errno; - free_user(u); - u = NULL; goto done; } - /* init environment. this will be copied/augmented for each entry. */ if ((envp = env_init()) == NULL) { save_errno = errno; - free_user(u); - u = NULL; + goto done; + } + + if (env_set_from_environ(&envp) == FALSE) { + save_errno = errno; goto done; } #ifdef WITH_SELINUX if (get_security_context(pw == NULL ? NULL : uname, crontab_fd, &u->scontext, tabname) != 0) { - free_user (u); - u = NULL; goto done; } #endif @@ -111,15 +109,10 @@ load_user (int crontab_fd, struct passwd */ while ((status = load_env (envstr, file)) >= OK) { switch (status) { - case ERR: - save_errno = errno; - free_user(u); - u = NULL; - goto done; case FALSE: FileName = tabname; e = load_entry(file, log_error, pw, envp); - if (e) { + if (e) { e->next = u->crontab; u->crontab = e; } @@ -127,16 +120,18 @@ load_user (int crontab_fd, struct passwd case TRUE: if ((tenvp = env_set (envp, envstr)) == NULL) { save_errno = errno; - free_user(u); - u = NULL; goto done; } - envp = tenvp; - break; + envp = tenvp; + break; } } done: + if (status == TRUE) { + free_user(u); + u = NULL; + } if (envp) env_free(envp); fclose(file);