pid_t child; /* fork() baby */
int childstatus; /* wait() status */
- char **env_whitelist_names; /* environment whitelist */
- char **env_whitelist_vals;
+ struct ul_env_list *env_whitelist; /* environment whitelist */
struct sigaction oldact[SIGNALS_IDX_COUNT]; /* original sigactions indexed by SIG*_IDX */
#ifdef USE_PTY
exit(status);
}
-/* Adds @name from the current environment to the whitelist. If @name is not
- * set then nothing is added to the whitelist and returns 1.
- */
-static int env_whitelist_add(struct su_context *su, const char *name)
-{
- const char *env = getenv(name);
-
- if (!env)
- return 1;
- if (strv_extend(&su->env_whitelist_names, name))
- err_oom();
- if (strv_extend(&su->env_whitelist_vals, env))
- err_oom();
- return 0;
-}
-
-static int env_whitelist_setenv(struct su_context *su, int overwrite)
-{
- char **one;
- size_t i = 0;
- int rc;
-
- STRV_FOREACH(one, su->env_whitelist_names) {
- rc = setenv(*one, su->env_whitelist_vals[i], overwrite);
- if (rc)
- return rc;
- i++;
- }
-
- return 0;
-}
-
-/* Creates (add to) whitelist from comma delimited string */
-static int env_whitelist_from_string(struct su_context *su, const char *str)
-{
- char **all = strv_split(str, ",");
- char **one;
-
- if (!all) {
- if (errno == ENOMEM)
- err_oom();
- return -EINVAL;
- }
-
- STRV_FOREACH(one, all)
- env_whitelist_add(su, *one);
- strv_free(all);
- return 0;
-}
-
static void setenv_path(const struct passwd *pw)
{
int rc;
*/
if (su->simulate_login) {
/* leave TERM unchanged */
- env_whitelist_add(su, "TERM");
+ su->env_whitelist = env_list_add_getenv(su->env_whitelist, "TERM", NULL);
/* Note that original su(1) has allocated environ[] by malloc
* to the number of expected variables. This seems unnecessary
xsetenv("LOGNAME", pw->pw_name, 1);
/* apply all from whitelist, but no overwrite */
- env_whitelist_setenv(su, 0);
+ if (env_list_setenv(su->env_whitelist, 0) != 0)
+ err(EXIT_FAILURE, _("failed to set environment variables"));
/* Set HOME, SHELL, and (if not becoming a superuser) USER and LOGNAME.
*/
}
supam_export_environment(su);
+
+ env_list_free(su->env_whitelist);
+ su->env_whitelist = NULL;
}
static void init_groups(struct su_context *su, gid_t *groups, size_t ngroups)
break;
case 'w':
- env_whitelist_from_string(su, optarg);
+ su->env_whitelist = env_list_add_getenvs(su->env_whitelist, optarg);
break;
case 'P':