Add support for multiple '*' in env_keep, env_check and env_delete
entries.
This commit is contained in:
3
MANIFEST
3
MANIFEST
@@ -264,6 +264,7 @@ plugins/sudoers/defaults.h
|
||||
plugins/sudoers/digestname.c
|
||||
plugins/sudoers/editor.c
|
||||
plugins/sudoers/env.c
|
||||
plugins/sudoers/env_pattern.c
|
||||
plugins/sudoers/filedigest.c
|
||||
plugins/sudoers/filedigest_gcrypt.c
|
||||
plugins/sudoers/filedigest_openssl.c
|
||||
@@ -370,6 +371,8 @@ plugins/sudoers/rcstr.c
|
||||
plugins/sudoers/redblack.c
|
||||
plugins/sudoers/redblack.h
|
||||
plugins/sudoers/regress/check_symbols/check_symbols.c
|
||||
plugins/sudoers/regress/env_match/check_env_pattern.c
|
||||
plugins/sudoers/regress/env_match/data
|
||||
plugins/sudoers/regress/iolog_path/check_iolog_path.c
|
||||
plugins/sudoers/regress/iolog_path/data
|
||||
plugins/sudoers/regress/logging/check_wrap.c
|
||||
|
@@ -143,6 +143,10 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
environment variables, use of the default _e_n_v___r_e_s_e_t behavior is
|
||||
encouraged.
|
||||
|
||||
Environment variables specified by _e_n_v___c_h_e_c_k, _e_n_v___d_e_l_e_t_e, or _e_n_v___k_e_e_p may
|
||||
include one or more `*' characters which will match zero or more
|
||||
characters. No other wildcard characters are supported.
|
||||
|
||||
By default, environment variables are matched by name. However, if the
|
||||
pattern includes an equal sign (`='), both the variables name and value
|
||||
must match. For example, an old-style (pre-shellshock) bbaasshh shell
|
||||
@@ -2813,4 +2817,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.20 May 8, 2017 Sudo 1.8.20
|
||||
Sudo 1.8.20 May 10, 2017 Sudo 1.8.20
|
||||
|
@@ -21,7 +21,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.TH "SUDOERS" "5" "May 8, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDOERS" "5" "May 10, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -354,6 +354,16 @@ of the default
|
||||
\fIenv_reset\fR
|
||||
behavior is encouraged.
|
||||
.PP
|
||||
Environment variables specified by
|
||||
\fIenv_check\fR,
|
||||
\fIenv_delete\fR,
|
||||
or
|
||||
\fIenv_keep\fR
|
||||
may include one or more
|
||||
\(oq*\(cq
|
||||
characters which will match zero or more characters.
|
||||
No other wildcard characters are supported.
|
||||
.PP
|
||||
By default, environment variables are matched by name.
|
||||
However, if the pattern includes an equal sign
|
||||
(\(oq=\&\(cq),
|
||||
|
@@ -19,7 +19,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd May 8, 2017
|
||||
.Dd May 10, 2017
|
||||
.Dt SUDOERS @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -343,6 +343,16 @@ of the default
|
||||
.Em env_reset
|
||||
behavior is encouraged.
|
||||
.Pp
|
||||
Environment variables specified by
|
||||
.Em env_check ,
|
||||
.Em env_delete ,
|
||||
or
|
||||
.Em env_keep
|
||||
may include one or more
|
||||
.Ql *
|
||||
characters which will match zero or more characters.
|
||||
No other wildcard characters are supported.
|
||||
.Pp
|
||||
By default, environment variables are matched by name.
|
||||
However, if the pattern includes an equal sign
|
||||
.Pq Ql =\& ,
|
||||
|
@@ -145,8 +145,9 @@ SHELL = @SHELL@
|
||||
|
||||
PROGS = sudoers.la visudo sudoreplay testsudoers
|
||||
|
||||
TEST_PROGS = check_iolog_path check_fill check_wrap check_addr check_base64 \
|
||||
check_gentime check_hexchar check_digest @SUDOERS_TEST_PROGS@
|
||||
TEST_PROGS = check_addr check_base64 check_digest check_env_pattern \
|
||||
check_fill check_gentime check_hexchar check_iolog_path \
|
||||
check_wrap @SUDOERS_TEST_PROGS@
|
||||
|
||||
AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
||||
|
||||
@@ -156,11 +157,11 @@ LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo digestname.lo \
|
||||
rcstr.lo redblack.lo sudoers_debug.lo timeout.lo \
|
||||
timestr.lo toke.lo toke_util.lo
|
||||
|
||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo find_path.lo \
|
||||
gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
||||
iolog_path.lo locale.lo logging.lo logwrap.lo mkdir_parents.lo \
|
||||
parse.lo policy.lo prompt.lo set_perms.lo sudo_nss.lo \
|
||||
sudoers.lo timestamp.lo @SUDOERS_OBJS@
|
||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo \
|
||||
env_pattern.lo find_path.lo gc.lo goodpath.lo group_plugin.lo \
|
||||
interfaces.lo iolog.lo iolog_path.lo locale.lo logging.lo \
|
||||
logwrap.lo mkdir_parents.lo parse.lo policy.lo prompt.lo \
|
||||
set_perms.lo sudo_nss.lo sudoers.lo timestamp.lo @SUDOERS_OBJS@
|
||||
|
||||
VISUDO_OBJS = editor.o find_path.o goodpath.o locale.o sudo_printf.o visudo.o \
|
||||
visudo_json.o
|
||||
@@ -177,6 +178,8 @@ CHECK_BASE64_OBJS = check_base64.o base64.o sudoers_debug.o
|
||||
|
||||
CHECK_DIGEST_OBJS = check_digest.o @FILEDIGEST@ digestname.o sudoers_debug.o
|
||||
|
||||
CHECK_ENV_MATCH_OBJS = check_env_pattern.o env_pattern.o sudoers_debug.o
|
||||
|
||||
CHECK_FILL_OBJS = check_fill.o hexchar.o toke_util.o sudoers_debug.o
|
||||
|
||||
CHECK_GENTIME_OBJS = check_gentime.o gentime.o gmtoff.o sudoers_debug.o
|
||||
@@ -248,6 +251,9 @@ check_base64: $(CHECK_BASE64_OBJS) $(LT_LIBS)
|
||||
check_digest: $(CHECK_DIGEST_OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_DIGEST_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @LIBMD@
|
||||
|
||||
check_env_pattern: $(CHECK_ENV_MATCH_OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_ENV_MATCH_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||
|
||||
check_fill: $(CHECK_FILL_OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_FILL_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||
|
||||
@@ -383,6 +389,7 @@ check: $(TEST_PROGS) visudo testsudoers
|
||||
./check_digest > regress/parser/check_digest.out; \
|
||||
diff regress/parser/check_digest.out $(srcdir)/regress/parser/check_digest.out.ok || rval=`expr $$rval + $$?`; \
|
||||
fi; \
|
||||
./check_env_pattern $(srcdir)/regress/env_match/data || rval=`expr $$rval + $$?`; \
|
||||
./check_fill || rval=`expr $$rval + $$?`; \
|
||||
./check_gentime || rval=`expr $$rval + $$?`; \
|
||||
./check_hexchar || rval=`expr $$rval + $$?`; \
|
||||
@@ -607,6 +614,17 @@ check_digest.o: $(srcdir)/regress/parser/check_digest.c \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_queue.h \
|
||||
$(srcdir)/parse.h $(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_digest.c
|
||||
check_env_pattern.o: $(srcdir)/regress/env_match/check_env_pattern.c \
|
||||
$(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/env_match/check_env_pattern.c
|
||||
check_fill.o: $(srcdir)/regress/parser/check_fill.c $(devdir)/gram.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
@@ -685,6 +703,17 @@ env.lo: $(srcdir)/env.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env.c
|
||||
env_pattern.lo: $(srcdir)/env_pattern.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env_pattern.c
|
||||
env_pattern.o: env_pattern.lo
|
||||
filedigest.lo: $(srcdir)/filedigest.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/sha2.h $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||
|
@@ -570,30 +570,13 @@ static bool
|
||||
matches_env_list(const char *var, struct list_members *list, bool *full_match)
|
||||
{
|
||||
struct list_member *cur;
|
||||
bool match = false;
|
||||
debug_decl(matches_env_list, SUDOERS_DEBUG_ENV)
|
||||
|
||||
SLIST_FOREACH(cur, list, entries) {
|
||||
size_t sep_pos, len = strlen(cur->value);
|
||||
bool iswild = false;
|
||||
|
||||
/* Locate position of the '=' separator in var=value. */
|
||||
sep_pos = strcspn(var, "=");
|
||||
|
||||
/* Deal with '*' wildcard at the end of the pattern. */
|
||||
if (cur->value[len - 1] == '*') {
|
||||
len--;
|
||||
iswild = true;
|
||||
}
|
||||
if (strncmp(cur->value, var, len) == 0 &&
|
||||
(iswild || len == sep_pos || var[len] == '\0')) {
|
||||
/* If we matched past the '=', count as a full match. */
|
||||
*full_match = len > sep_pos + 1;
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
if (matches_env_pattern(cur->value, var, full_match))
|
||||
debug_return_bool(true);
|
||||
}
|
||||
debug_return_bool(match);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
92
plugins/sudoers/env_pattern.c
Normal file
92
plugins/sudoers/env_pattern.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
|
||||
#include "sudoers.h"
|
||||
|
||||
/* extern for regress tests */
|
||||
bool
|
||||
matches_env_pattern(const char *pattern, const char *var, bool *full_match)
|
||||
{
|
||||
size_t len, sep_pos;
|
||||
bool iswild = false, match = false;
|
||||
bool saw_sep = false;
|
||||
const char *cp;
|
||||
debug_decl(matches_env_pattern, SUDOERS_DEBUG_ENV)
|
||||
|
||||
/* Locate position of the '=' separator in var=value. */
|
||||
sep_pos = strcspn(var, "=");
|
||||
|
||||
/* Locate '*' wildcard and compute len. */
|
||||
for (cp = pattern; *cp != '\0'; cp++) {
|
||||
if (*cp == '*') {
|
||||
iswild = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
len = (size_t)(cp - pattern);
|
||||
|
||||
if (iswild) {
|
||||
/* Match up to the '*' wildcard. */
|
||||
if (strncmp(pattern, var, len) == 0) {
|
||||
while (*cp != '\0') {
|
||||
if (*cp == '*') {
|
||||
/* Collapse sequential '*'s */
|
||||
do {
|
||||
cp++;
|
||||
} while (*cp == '*');
|
||||
/* A '*' at the end of a pattern matches anything. */
|
||||
if (*cp == '\0') {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
/* Keep track of whether we matched an equal sign. */
|
||||
if (*cp == '=')
|
||||
saw_sep = true;
|
||||
/* Look for first match of text after the '*' */
|
||||
while ((saw_sep || len != sep_pos) &&
|
||||
var[len] != '\0' && var[len] != *cp)
|
||||
len++;
|
||||
}
|
||||
if (var[len] != *cp)
|
||||
break;
|
||||
cp++;
|
||||
len++;
|
||||
}
|
||||
if (*cp == '\0' && (len == sep_pos || var[len] == '\0'))
|
||||
match = true;
|
||||
}
|
||||
} else {
|
||||
if (strncmp(pattern, var, len) == 0 &&
|
||||
(len == sep_pos || var[len] == '\0')) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (match)
|
||||
*full_match = len > sep_pos + 1;
|
||||
debug_return_bool(match);
|
||||
}
|
78
plugins/sudoers/regress/env_match/check_env_pattern.c
Normal file
78
plugins/sudoers/regress/env_match/check_env_pattern.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudoers.h"
|
||||
|
||||
__dso_public int main(int argc, char *argv[]);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp = stdin;
|
||||
char pattern[1024], string[1024];
|
||||
int errors = 0, tests = 0, got, want;
|
||||
|
||||
if (argc > 1) {
|
||||
if ((fp = fopen(argv[1], "r")) == NULL) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in test file, which is formatted thusly:
|
||||
*
|
||||
* pattern string 1/0
|
||||
*
|
||||
*/
|
||||
for (;;) {
|
||||
bool full_match = false;
|
||||
|
||||
got = fscanf(fp, "%s %s %d\n", pattern, string, &want);
|
||||
if (got == EOF)
|
||||
break;
|
||||
if (got == 3) {
|
||||
got = matches_env_pattern(pattern, string, &full_match);
|
||||
if (full_match)
|
||||
got++;
|
||||
if (got != want) {
|
||||
fprintf(stderr,
|
||||
"%s: %s %s: want %d, got %d\n",
|
||||
getprogname(), pattern, string, want, got);
|
||||
errors++;
|
||||
}
|
||||
tests++;
|
||||
}
|
||||
}
|
||||
if (tests != 0) {
|
||||
printf("%s: %d test%s run, %d errors, %d%% success rate\n",
|
||||
getprogname(), tests, tests == 1 ? "" : "s", errors,
|
||||
(tests - errors) * 100 / tests);
|
||||
}
|
||||
exit(errors);
|
||||
}
|
19
plugins/sudoers/regress/env_match/data
Normal file
19
plugins/sudoers/regress/env_match/data
Normal file
@@ -0,0 +1,19 @@
|
||||
foo=(){false;} foo=(){false;} 2
|
||||
foo foo=(){false;} 1
|
||||
foo= foo=(){false;} 0
|
||||
foo=* foo=(){false;} 1
|
||||
foo=(* foo=(){false;} 2
|
||||
foo=()* foo=(){false;} 2
|
||||
foo=*()* foo=(){false;} 2
|
||||
foo() foo()=a 1
|
||||
foo*() foo()=b 1
|
||||
foo*()* foo()= 1
|
||||
foo()* foo()= 1
|
||||
foo* foo()= 1
|
||||
fo*o*() foo()= 1
|
||||
fo*o*() fooo()== 1
|
||||
fo*o*() foooo()= 1
|
||||
fo*o*() foooo 0
|
||||
MYPATH=*:/mydir:* MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 2
|
||||
MYPATH=*:/mydir:** MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 2
|
||||
MYPATH=*:/mdir:* MYPATH=/dir1/subdir1:/mydir:/dir2:/dir3/subdir2 0
|
@@ -359,6 +359,9 @@ int sudoers_hook_putenv(char *string, void *closure);
|
||||
int sudoers_hook_setenv(const char *name, const char *value, int overwrite, void *closure);
|
||||
int sudoers_hook_unsetenv(const char *name, void *closure);
|
||||
|
||||
/* env_pattern.c */
|
||||
bool matches_env_pattern(const char *pattern, const char *var, bool *full_match);
|
||||
|
||||
/* sudoers.c */
|
||||
FILE *open_sudoers(const char *, bool, bool *);
|
||||
int sudoers_policy_init(void *info, char * const envp[]);
|
||||
|
Reference in New Issue
Block a user