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.
|
the time stamp to commands run by the same process, usually the shell.
|
||||||
Bug #793
|
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
|
What's new in Sudo 1.8.20p2
|
||||||
|
|
||||||
* Fixed a bug parsing /proc/pid/stat on Linux when the process
|
* 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
|
policy may return an error if the user does not have
|
||||||
permission to preserve the environment.
|
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
|
--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
|
of a path name, the string "sudoedit" is used when consulting
|
||||||
the security policy. If the user is authorized by the
|
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
|
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||||
complete details.
|
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
|
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
.\" 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
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@@ -260,6 +260,13 @@ preserve their existing environment variables.
|
|||||||
The security policy may return an error if the user does not have
|
The security policy may return an error if the user does not have
|
||||||
permission to preserve the environment.
|
permission to preserve the environment.
|
||||||
.TP 12n
|
.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
|
\fB\-e\fR, \fB\--edit\fR
|
||||||
Edit one or more files instead of running a command.
|
Edit one or more files instead of running a command.
|
||||||
In lieu of a path name, the string "sudoedit" is used when consulting
|
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
|
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||||
.\"
|
.\"
|
||||||
.Dd July 21, 2017
|
.Dd Auguest 2, 2017
|
||||||
.Dt SUDO @mansectsu@
|
.Dt SUDO @mansectsu@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -236,6 +236,12 @@ Indicates to the security policy that the user wishes to
|
|||||||
preserve their existing environment variables.
|
preserve their existing environment variables.
|
||||||
The security policy may return an error if the user does not have
|
The security policy may return an error if the user does not have
|
||||||
permission to preserve the environment.
|
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
|
.It Fl e , -edit
|
||||||
Edit one or more files instead of running a command.
|
Edit one or more files instead of running a command.
|
||||||
In lieu of a path name, the string "sudoedit" is used when consulting
|
In lieu of a path name, the string "sudoedit" is used when consulting
|
||||||
|
120
src/parse_args.c
120
src/parse_args.c
@@ -107,6 +107,12 @@ static struct sudo_settings sudo_settings[] = {
|
|||||||
{ NULL }
|
{ 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.
|
* Default flags allowed when running a command.
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +133,7 @@ static struct option long_opts[] = {
|
|||||||
{ "background", no_argument, NULL, 'b' },
|
{ "background", no_argument, NULL, 'b' },
|
||||||
{ "close-from", required_argument, NULL, 'C' },
|
{ "close-from", required_argument, NULL, 'C' },
|
||||||
{ "login-class", 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' },
|
{ "edit", no_argument, NULL, 'e' },
|
||||||
{ "group", required_argument, NULL, 'g' },
|
{ "group", required_argument, NULL, 'g' },
|
||||||
{ "set-home", no_argument, NULL, 'H' },
|
{ "set-home", no_argument, NULL, 'H' },
|
||||||
@@ -152,6 +158,73 @@ static struct option long_opts[] = {
|
|||||||
{ NULL, no_argument, NULL, '\0' },
|
{ 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.
|
* Command line argument parsing.
|
||||||
* Sets nargc and nargv which corresponds to the argc/argv we'll use
|
* 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,
|
parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
||||||
struct sudo_settings **settingsp, char ***env_addp)
|
struct sudo_settings **settingsp, char ***env_addp)
|
||||||
{
|
{
|
||||||
|
struct environment extra_env;
|
||||||
int mode = 0; /* what mode is sudo to be run in? */
|
int mode = 0; /* what mode is sudo to be run in? */
|
||||||
int flags = 0; /* mode flags */
|
int flags = 0; /* mode flags */
|
||||||
int valid_flags = DEFAULT_VALID_FLAGS;
|
int valid_flags = DEFAULT_VALID_FLAGS;
|
||||||
int ch, i;
|
int ch, i;
|
||||||
char *cp, **env_add;
|
char *cp;
|
||||||
const char *runas_user = NULL;
|
const char *runas_user = NULL;
|
||||||
const char *runas_group = NULL;
|
const char *runas_group = NULL;
|
||||||
const char *progname;
|
const char *progname;
|
||||||
int proglen;
|
int proglen;
|
||||||
int nenv = 0;
|
|
||||||
int env_size = 32;
|
|
||||||
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
||||||
|
|
||||||
/* Is someone trying something funny? */
|
/* Is someone trying something funny? */
|
||||||
if (argc <= 0)
|
if (argc <= 0)
|
||||||
usage(1);
|
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() */
|
/* Pass progname to plugin so it can call initprogname() */
|
||||||
progname = getprogname();
|
progname = getprogname();
|
||||||
sudo_settings[ARG_PROGNAME].value = progname;
|
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] != '/' && \
|
#define is_envar (optind < argc && argv[optind][0] != '/' && \
|
||||||
strchr(argv[optind], '=') != NULL)
|
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 */
|
/* XXX - should fill in settings at the end to avoid dupes */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/*
|
/*
|
||||||
@@ -253,7 +324,15 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
|||||||
/* Ignored for backwards compatibility. */
|
/* Ignored for backwards compatibility. */
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
|
/*
|
||||||
|
* 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;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (mode && mode != MODE_EDIT)
|
if (mode && mode != MODE_EDIT)
|
||||||
@@ -368,25 +447,14 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
|||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
} else if (!got_end_of_args && is_envar) {
|
} else if (!got_end_of_args && is_envar) {
|
||||||
if (nenv == env_size - 2) {
|
/* Insert key=value pair, crank optind and resume getopt. */
|
||||||
char **tmp;
|
env_insert(&extra_env, argv[optind]);
|
||||||
|
|
||||||
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. */
|
|
||||||
optind++;
|
optind++;
|
||||||
} else {
|
} else {
|
||||||
/* Not an option or an environment variable -- we're done. */
|
/* Not an option or an environment variable -- we're done. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
env_add[nenv] = NULL;
|
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
@@ -421,10 +489,10 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
|||||||
if ((flags & valid_flags) != flags)
|
if ((flags & valid_flags) != flags)
|
||||||
usage(1);
|
usage(1);
|
||||||
if (mode == MODE_EDIT &&
|
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))
|
if (ISSET(mode, MODE_PRESERVE_ENV))
|
||||||
sudo_warnx(U_("the `-E' option is not valid in edit mode"));
|
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"));
|
sudo_warnx(U_("you may not specify environment variables in edit mode"));
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
@@ -518,7 +586,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*settingsp = sudo_settings;
|
*settingsp = sudo_settings;
|
||||||
*env_addp = env_add;
|
*env_addp = extra_env.envp;
|
||||||
*nargc = argc;
|
*nargc = argc;
|
||||||
*nargv = argv;
|
*nargv = argv;
|
||||||
debug_return_int(mode | flags);
|
debug_return_int(mode | flags);
|
||||||
@@ -624,6 +692,8 @@ help(void)
|
|||||||
#endif
|
#endif
|
||||||
sudo_lbuf_append(&lbuf, " -E, --preserve-env %s\n",
|
sudo_lbuf_append(&lbuf, " -E, --preserve-env %s\n",
|
||||||
_("preserve user environment when running command"));
|
_("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",
|
sudo_lbuf_append(&lbuf, " -e, --edit %s\n",
|
||||||
_("edit files instead of running a command"));
|
_("edit files instead of running a command"));
|
||||||
sudo_lbuf_append(&lbuf, " -g, --group=group %s\n",
|
sudo_lbuf_append(&lbuf, " -g, --group=group %s\n",
|
||||||
|
Reference in New Issue
Block a user