Allow the user to specify a list of environment variables to preserve.
This adds an option paramter to the --preserve-env option, a comma-separated list of variable names.
This commit is contained in:
3
NEWS
3
NEWS
@@ -56,6 +56,9 @@ What's new in Sudo 1.8.21
|
||||
the time stamp to commands run by the same process, usually the shell.
|
||||
Bug #793
|
||||
|
||||
* The --preserve-env command line option has been extended to accept
|
||||
a comma-separated list of environment variables to preserve.
|
||||
|
||||
What's new in Sudo 1.8.20p2
|
||||
|
||||
* Fixed a bug parsing /proc/pid/stat on Linux when the process
|
||||
|
@@ -107,6 +107,13 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
policy may return an error if the user does not have
|
||||
permission to preserve the environment.
|
||||
|
||||
----pprreesseerrvvee--eennvv==lliisstt
|
||||
Indicates to the security policy that the user wishes to add
|
||||
the comma-separated list of environment variables to those
|
||||
preserved from the user's environment. The security policy
|
||||
may return an error if the user does not have permission to
|
||||
preserve the environment.
|
||||
|
||||
--ee, ----eeddiitt Edit one or more files instead of running a command. In lieu
|
||||
of a path name, the string "sudoedit" is used when consulting
|
||||
the security policy. If the user is authorized by the
|
||||
@@ -631,4 +638,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.21 July 21, 2017 Sudo 1.8.21
|
||||
Sudo 1.8.21 Auguest 2, 2017 Sudo 1.8.21
|
||||
|
@@ -21,7 +21,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.TH "SUDO" "8" "July 21, 2017" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.TH "SUDO" "8" "Auguest 2, 2017" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -260,6 +260,13 @@ preserve their existing environment variables.
|
||||
The security policy may return an error if the user does not have
|
||||
permission to preserve the environment.
|
||||
.TP 12n
|
||||
\fB\--preserve-env=list\fR
|
||||
Indicates to the security policy that the user wishes to add the
|
||||
comma-separated list of environment variables to those preserved
|
||||
from the user's environment.
|
||||
The security policy may return an error if the user does not have
|
||||
permission to preserve the environment.
|
||||
.TP 12n
|
||||
\fB\-e\fR, \fB\--edit\fR
|
||||
Edit one or more files instead of running a command.
|
||||
In lieu of a path name, the string "sudoedit" is used when consulting
|
||||
|
@@ -19,7 +19,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd July 21, 2017
|
||||
.Dd Auguest 2, 2017
|
||||
.Dt SUDO @mansectsu@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -236,6 +236,12 @@ Indicates to the security policy that the user wishes to
|
||||
preserve their existing environment variables.
|
||||
The security policy may return an error if the user does not have
|
||||
permission to preserve the environment.
|
||||
.It Fl -preserve-env=list
|
||||
Indicates to the security policy that the user wishes to add the
|
||||
comma-separated list of environment variables to those preserved
|
||||
from the user's environment.
|
||||
The security policy may return an error if the user does not have
|
||||
permission to preserve the environment.
|
||||
.It Fl e , -edit
|
||||
Edit one or more files instead of running a command.
|
||||
In lieu of a path name, the string "sudoedit" is used when consulting
|
||||
|
118
src/parse_args.c
118
src/parse_args.c
@@ -107,6 +107,12 @@ static struct sudo_settings sudo_settings[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
struct environment {
|
||||
char **envp; /* pointer to the new environment */
|
||||
size_t env_size; /* size of new_environ in char **'s */
|
||||
size_t env_len; /* number of slots used, not counting NULL */
|
||||
};
|
||||
|
||||
/*
|
||||
* Default flags allowed when running a command.
|
||||
*/
|
||||
@@ -127,7 +133,7 @@ static struct option long_opts[] = {
|
||||
{ "background", no_argument, NULL, 'b' },
|
||||
{ "close-from", required_argument, NULL, 'C' },
|
||||
{ "login-class", required_argument, NULL, 'c' },
|
||||
{ "preserve-env", no_argument, NULL, 'E' },
|
||||
{ "preserve-env", optional_argument, NULL, 'E' },
|
||||
{ "edit", no_argument, NULL, 'e' },
|
||||
{ "group", required_argument, NULL, 'g' },
|
||||
{ "set-home", no_argument, NULL, 'H' },
|
||||
@@ -152,6 +158,73 @@ static struct option long_opts[] = {
|
||||
{ NULL, no_argument, NULL, '\0' },
|
||||
};
|
||||
|
||||
/*
|
||||
* Insert a key=value pair into the specified environment.
|
||||
*/
|
||||
static void
|
||||
env_insert(struct environment *e, char *pair)
|
||||
{
|
||||
debug_decl(env_insert, SUDO_DEBUG_ARGS)
|
||||
|
||||
/* Make sure we have at least two slots free (one for NULL). */
|
||||
if (e->env_len + 1 >= e->env_size) {
|
||||
char **tmp;
|
||||
|
||||
if (e->env_size == 0)
|
||||
e->env_size = 16;
|
||||
tmp = reallocarray(e->envp, e->env_size, 2 * sizeof(char *));
|
||||
if (tmp == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
e->envp = tmp;
|
||||
e->env_size *= 2;
|
||||
}
|
||||
e->envp[e->env_len++] = pair;
|
||||
e->envp[e->env_len] = NULL;
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Format as var=val and insert into the specified environment.
|
||||
*/
|
||||
static void
|
||||
env_set(struct environment *e, char *var, char *val)
|
||||
{
|
||||
char *pair;
|
||||
debug_decl(env_set, SUDO_DEBUG_ARGS)
|
||||
|
||||
pair = sudo_new_key_val(var, val);
|
||||
if (pair == NULL) {
|
||||
sudo_fatalx(U_("%s: %s"),
|
||||
__func__, U_("unable to allocate memory"));
|
||||
}
|
||||
env_insert(e, pair);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a comma-separated list of env vars and add to the
|
||||
* specified environment.
|
||||
*/
|
||||
static void
|
||||
parse_env_list(struct environment *e, char *list)
|
||||
{
|
||||
char *cp, *last, *val;
|
||||
debug_decl(parse_env_list, SUDO_DEBUG_ARGS)
|
||||
|
||||
for ((cp = strtok_r(list, ",", &last)); cp != NULL;
|
||||
(cp = strtok_r(NULL, ",", &last))) {
|
||||
if (strchr(cp, '=') != NULL) {
|
||||
sudo_warnx(U_("invalid environment variable name: %s"), cp);
|
||||
usage(1);
|
||||
}
|
||||
if ((val = getenv(cp)) != NULL)
|
||||
env_set(e, cp, val);
|
||||
}
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Command line argument parsing.
|
||||
* Sets nargc and nargv which corresponds to the argc/argv we'll use
|
||||
@@ -161,27 +234,22 @@ int
|
||||
parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
struct sudo_settings **settingsp, char ***env_addp)
|
||||
{
|
||||
struct environment extra_env;
|
||||
int mode = 0; /* what mode is sudo to be run in? */
|
||||
int flags = 0; /* mode flags */
|
||||
int valid_flags = DEFAULT_VALID_FLAGS;
|
||||
int ch, i;
|
||||
char *cp, **env_add;
|
||||
char *cp;
|
||||
const char *runas_user = NULL;
|
||||
const char *runas_group = NULL;
|
||||
const char *progname;
|
||||
int proglen;
|
||||
int nenv = 0;
|
||||
int env_size = 32;
|
||||
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
||||
|
||||
/* Is someone trying something funny? */
|
||||
if (argc <= 0)
|
||||
usage(1);
|
||||
|
||||
env_add = reallocarray(NULL, env_size, sizeof(char *));
|
||||
if (env_add == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
|
||||
/* Pass progname to plugin so it can call initprogname() */
|
||||
progname = getprogname();
|
||||
sudo_settings[ARG_PROGNAME].value = progname;
|
||||
@@ -218,6 +286,9 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
#define is_envar (optind < argc && argv[optind][0] != '/' && \
|
||||
strchr(argv[optind], '=') != NULL)
|
||||
|
||||
/* Space for environment variables is lazy allocated. */
|
||||
memset(&extra_env, 0, sizeof(extra_env));
|
||||
|
||||
/* XXX - should fill in settings at the end to avoid dupes */
|
||||
for (;;) {
|
||||
/*
|
||||
@@ -253,7 +324,15 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
/* Ignored for backwards compatibility. */
|
||||
break;
|
||||
case 'E':
|
||||
/*
|
||||
* Optional argument is a comma-separated list of
|
||||
* environment variables to preserve. If not present,
|
||||
* preserve everything.
|
||||
*/
|
||||
if (optarg == NULL)
|
||||
sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
|
||||
else
|
||||
parse_env_list(&extra_env, optarg);
|
||||
break;
|
||||
case 'e':
|
||||
if (mode && mode != MODE_EDIT)
|
||||
@@ -368,25 +447,14 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
usage(1);
|
||||
}
|
||||
} else if (!got_end_of_args && is_envar) {
|
||||
if (nenv == env_size - 2) {
|
||||
char **tmp;
|
||||
|
||||
tmp = reallocarray(env_add, env_size, 2 * sizeof(char *));
|
||||
if (tmp == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
env_add = tmp;
|
||||
env_size *= 2;
|
||||
}
|
||||
env_add[nenv++] = argv[optind];
|
||||
|
||||
/* Crank optind and resume getopt. */
|
||||
/* Insert key=value pair, crank optind and resume getopt. */
|
||||
env_insert(&extra_env, argv[optind]);
|
||||
optind++;
|
||||
} else {
|
||||
/* Not an option or an environment variable -- we're done. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
env_add[nenv] = NULL;
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
@@ -421,10 +489,10 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
if ((flags & valid_flags) != flags)
|
||||
usage(1);
|
||||
if (mode == MODE_EDIT &&
|
||||
(ISSET(flags, MODE_PRESERVE_ENV) || env_add[0] != NULL)) {
|
||||
(ISSET(flags, MODE_PRESERVE_ENV) || extra_env.env_len != 0)) {
|
||||
if (ISSET(mode, MODE_PRESERVE_ENV))
|
||||
sudo_warnx(U_("the `-E' option is not valid in edit mode"));
|
||||
if (env_add[0] != NULL)
|
||||
if (extra_env.env_len != 0)
|
||||
sudo_warnx(U_("you may not specify environment variables in edit mode"));
|
||||
usage(1);
|
||||
}
|
||||
@@ -518,7 +586,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||
}
|
||||
|
||||
*settingsp = sudo_settings;
|
||||
*env_addp = env_add;
|
||||
*env_addp = extra_env.envp;
|
||||
*nargc = argc;
|
||||
*nargv = argv;
|
||||
debug_return_int(mode | flags);
|
||||
@@ -624,6 +692,8 @@ help(void)
|
||||
#endif
|
||||
sudo_lbuf_append(&lbuf, " -E, --preserve-env %s\n",
|
||||
_("preserve user environment when running command"));
|
||||
sudo_lbuf_append(&lbuf, " --preserve-env=list %s\n",
|
||||
_("preserve specific environment variables"));
|
||||
sudo_lbuf_append(&lbuf, " -e, --edit %s\n",
|
||||
_("edit files instead of running a command"));
|
||||
sudo_lbuf_append(&lbuf, " -g, --group=group %s\n",
|
||||
|
Reference in New Issue
Block a user