mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Add NOTBEFORE and NOTAFTER command options similar to what is
already available in LDAP.
This commit is contained in:
parent
3b19d05fe9
commit
e5dee1557e
9
MANIFEST
9
MANIFEST
@ -264,9 +264,11 @@ plugins/sudoers/editor.c
|
||||
plugins/sudoers/env.c
|
||||
plugins/sudoers/find_path.c
|
||||
plugins/sudoers/gc.c
|
||||
plugins/sudoers/gentime.c
|
||||
plugins/sudoers/getdate.c
|
||||
plugins/sudoers/getdate.y
|
||||
plugins/sudoers/getspwuid.c
|
||||
plugins/sudoers/gmtoff.c
|
||||
plugins/sudoers/goodpath.c
|
||||
plugins/sudoers/gram.c
|
||||
plugins/sudoers/gram.h
|
||||
@ -374,6 +376,7 @@ plugins/sudoers/regress/parser/check_base64.c
|
||||
plugins/sudoers/regress/parser/check_digest.c
|
||||
plugins/sudoers/regress/parser/check_digest.out.ok
|
||||
plugins/sudoers/regress/parser/check_fill.c
|
||||
plugins/sudoers/regress/parser/check_gentime.c
|
||||
plugins/sudoers/regress/parser/check_hexchar.c
|
||||
plugins/sudoers/regress/sudoers/test1.in
|
||||
plugins/sudoers/regress/sudoers/test1.json.ok
|
||||
@ -415,6 +418,10 @@ plugins/sudoers/regress/sudoers/test18.in
|
||||
plugins/sudoers/regress/sudoers/test18.json.ok
|
||||
plugins/sudoers/regress/sudoers/test18.out.ok
|
||||
plugins/sudoers/regress/sudoers/test18.toke.ok
|
||||
plugins/sudoers/regress/sudoers/test19.in
|
||||
plugins/sudoers/regress/sudoers/test19.json.ok
|
||||
plugins/sudoers/regress/sudoers/test19.out.ok
|
||||
plugins/sudoers/regress/sudoers/test19.toke.ok
|
||||
plugins/sudoers/regress/sudoers/test2.in
|
||||
plugins/sudoers/regress/sudoers/test2.json.ok
|
||||
plugins/sudoers/regress/sudoers/test2.out.ok
|
||||
@ -465,6 +472,8 @@ plugins/sudoers/regress/testsudoers/test7.out.ok
|
||||
plugins/sudoers/regress/testsudoers/test7.sh
|
||||
plugins/sudoers/regress/visudo/test1.out.ok
|
||||
plugins/sudoers/regress/visudo/test1.sh
|
||||
plugins/sudoers/regress/visudo/test10.out.ok
|
||||
plugins/sudoers/regress/visudo/test10.sh
|
||||
plugins/sudoers/regress/visudo/test2.err.ok
|
||||
plugins/sudoers/regress/visudo/test2.out.ok
|
||||
plugins/sudoers/regress/visudo/test2.sh
|
||||
|
@ -711,6 +711,9 @@
|
||||
/* Define if your struct sockaddr has an sa_len field. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
|
||||
/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
|
||||
#undef HAVE_STRUCT_TM_TM_GMTOFF
|
||||
|
||||
/* Define to 1 if `ut_exit' is a member of `struct utmpx'. */
|
||||
#undef HAVE_STRUCT_UTMPX_UT_EXIT
|
||||
|
||||
@ -1050,6 +1053,9 @@
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#undef SIZEOF_TIME_T
|
||||
|
||||
/* Define to 1 to compile the sudoers plugin statically into the sudo binary.
|
||||
*/
|
||||
#undef STATIC_SUDOERS_PLUGIN
|
||||
|
47
configure
vendored
47
configure
vendored
@ -18262,6 +18262,39 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# The cast to long int works around a bug in the HP C Compiler
|
||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||
# This bug is HP SR number 8606223364.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
|
||||
$as_echo_n "checking size of time_t... " >&6; }
|
||||
if ${ac_cv_sizeof_time_t+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "$ac_includes_default"; then :
|
||||
|
||||
else
|
||||
if test "$ac_cv_type_time_t" = yes; then
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error 77 "cannot compute sizeof (time_t)
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
ac_cv_sizeof_time_t=0
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
|
||||
$as_echo "$ac_cv_sizeof_time_t" >&6; }
|
||||
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
|
||||
_ACEOF
|
||||
|
||||
|
||||
if test $ac_cv_header_utmpx_h = "yes"; then
|
||||
ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_id" "ac_cv_member_struct_utmpx_ut_id" "
|
||||
# include <sys/types.h>
|
||||
@ -20356,6 +20389,20 @@ esac
|
||||
"
|
||||
done
|
||||
|
||||
ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" "
|
||||
$ac_includes_default
|
||||
#include <errno.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes; then :
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_STRUCT_TM_TM_GMTOFF 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
|
||||
if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
|
||||
$as_echo "#define HAVE_ST_MTIM 1" >>confdefs.h
|
||||
|
@ -2348,6 +2348,7 @@ SUDO_SOCK_SA_LEN
|
||||
SUDO_SOCK_SIN_LEN
|
||||
AC_CHECK_SIZEOF([id_t])
|
||||
AC_CHECK_SIZEOF([long long])
|
||||
AC_CHECK_SIZEOF([time_t])
|
||||
dnl
|
||||
dnl Check for utmp/utmpx struct members.
|
||||
dnl We need to have already defined _GNU_SOURCE on glibc which only has
|
||||
@ -2665,6 +2666,10 @@ fi
|
||||
AC_CHECK_FUNCS([strtonum])
|
||||
AC_LIBOBJ(strtonum)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_strtonum)
|
||||
AC_CHECK_MEMBERS([struct tm.tm_gmtoff], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#include <errno.h>
|
||||
])
|
||||
AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)]
|
||||
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
|
||||
[AC_CHECK_MEMBER([struct stat.st_mtimespec], AC_DEFINE([HAVE_ST_MTIMESPEC]))])
|
||||
|
@ -478,12 +478,14 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
|
||||
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
|
||||
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Timeout_Spec)
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
|
||||
|
||||
SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
|
||||
|
||||
Timeout_Spec ::= 'TIMEOUT=timeout'
|
||||
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
@ -608,6 +610,24 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
|
||||
Privileges can be excluded from a set by prefixing the privilege name
|
||||
with either an `!' or `-' character.
|
||||
|
||||
DDaattee__SSppeecc
|
||||
ssuuddooeerrss rules can be specified with a start and end date via the
|
||||
NOTBEFORE and NOTAFTER settings. The time stamp must be specified in
|
||||
_G_e_n_e_r_a_l_i_z_e_d _T_i_m_e as defined by RFC 4517. The format is effectively
|
||||
yyyymmddHHMMSSZ where the minutes and seconds are optional. The `Z'
|
||||
suffix indicates that the time stamp is in Coordinated Universal Time
|
||||
(UTC). It is also possible to specify a timezone offset from UTC in
|
||||
hours and minutes instead of a `Z'. For example, `-0500' would
|
||||
correspond to Eastern Standard time in the US. As an extension, if no
|
||||
`Z' or timezone offset is specified, local time will be used.
|
||||
|
||||
The following are all valid time stamps:
|
||||
|
||||
20170214083000Z
|
||||
2017021408Z
|
||||
20160315220000-0500
|
||||
20151201235900
|
||||
|
||||
TTiimmeeoouutt__SSppeecc
|
||||
A command may have a timeout associated with it. If the timeout expires
|
||||
before the command has exited, the command will be terminated. The
|
||||
|
@ -986,12 +986,14 @@ Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
|
||||
|
||||
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
|
||||
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Timeout_Spec)
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
|
||||
|
||||
SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
|
||||
|
||||
Timeout_Spec ::= 'TIMEOUT=timeout'
|
||||
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
@ -1257,6 +1259,42 @@ name with either an
|
||||
or
|
||||
\(oq\-\(cq
|
||||
character.
|
||||
.SS "Date_Spec"
|
||||
\fBsudoers\fR
|
||||
rules can be specified with a start and end date via the
|
||||
\fRNOTBEFORE\fR
|
||||
and
|
||||
\fRNOTAFTER\fR
|
||||
settings.
|
||||
The time stamp must be specified in
|
||||
\fIGeneralized Time\fR
|
||||
as defined by RFC 4517.
|
||||
The format is effectively
|
||||
\fRyyyymmddHHMMSSZ\fR
|
||||
where the minutes and seconds are optional.
|
||||
The
|
||||
\(oqZ\(cq
|
||||
suffix indicates that the time stamp is in Coordinated Universal Time (UTC).
|
||||
It is also possible to specify a timezone offset from UTC in hours
|
||||
and minutes instead of a
|
||||
\(oqZ\(cq.
|
||||
For example,
|
||||
\(oq-0500\(cq
|
||||
would correspond to Eastern Standard time in the US.
|
||||
As an extension, if no
|
||||
\(oqZ\(cq
|
||||
or timezone offset is specified, local time will be used.
|
||||
.PP
|
||||
The following are all valid time stamps:
|
||||
.nf
|
||||
.sp
|
||||
.RS 4n
|
||||
20170214083000Z
|
||||
2017021408Z
|
||||
20160315220000-0500
|
||||
20151201235900
|
||||
.RE
|
||||
.fi
|
||||
.SS "Timeout_Spec"
|
||||
A command may have a timeout associated with it.
|
||||
If the timeout expires before the command has exited, the
|
||||
|
@ -939,12 +939,14 @@ Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
|
||||
|
||||
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
|
||||
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Timeout_Spec)
|
||||
Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)
|
||||
|
||||
SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
|
||||
|
||||
Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
|
||||
|
||||
Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')
|
||||
|
||||
Timeout_Spec ::= 'TIMEOUT=timeout'
|
||||
|
||||
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
|
||||
@ -1180,6 +1182,39 @@ name with either an
|
||||
or
|
||||
.Ql \-
|
||||
character.
|
||||
.Ss Date_Spec
|
||||
.Nm sudoers
|
||||
rules can be specified with a start and end date via the
|
||||
.Li NOTBEFORE
|
||||
and
|
||||
.Li NOTAFTER
|
||||
settings.
|
||||
The time stamp must be specified in
|
||||
.Em Generalized Time
|
||||
as defined by RFC 4517.
|
||||
The format is effectively
|
||||
.Li yyyymmddHHMMSSZ
|
||||
where the minutes and seconds are optional.
|
||||
The
|
||||
.Ql Z
|
||||
suffix indicates that the time stamp is in Coordinated Universal Time (UTC).
|
||||
It is also possible to specify a timezone offset from UTC in hours
|
||||
and minutes instead of a
|
||||
.Ql Z .
|
||||
For example,
|
||||
.Ql -0500
|
||||
would correspond to Eastern Standard time in the US.
|
||||
As an extension, if no
|
||||
.Ql Z
|
||||
or timezone offset is specified, local time will be used.
|
||||
.Pp
|
||||
The following are all valid time stamps:
|
||||
.Bd -literal -offset 4n
|
||||
20170214083000Z
|
||||
2017021408Z
|
||||
20160315220000-0500
|
||||
20151201235900
|
||||
.Ed
|
||||
.Ss Timeout_Spec
|
||||
A command may have a timeout associated with it.
|
||||
If the timeout expires before the command has exited, the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2011-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
|
||||
@ -156,6 +156,14 @@ struct sudo_conf_debug_file_list;
|
||||
return sudo_debug_ret; \
|
||||
} while (0)
|
||||
|
||||
#define debug_return_time_t(ret) \
|
||||
do { \
|
||||
time_t sudo_debug_ret = (ret); \
|
||||
sudo_debug_exit_time_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\
|
||||
sudo_debug_ret); \
|
||||
return sudo_debug_ret; \
|
||||
} while (0)
|
||||
|
||||
#define debug_return_long(ret) \
|
||||
do { \
|
||||
long sudo_debug_ret = (ret); \
|
||||
@ -247,6 +255,7 @@ __dso_public void sudo_debug_exit_size_t_v1(const char *func, const char *file,
|
||||
__dso_public void sudo_debug_exit_ssize_t_v1(const char *func, const char *file, int line, int subsys, ssize_t ret);
|
||||
__dso_public void sudo_debug_exit_str_v1(const char *func, const char *file, int line, int subsys, const char *ret);
|
||||
__dso_public void sudo_debug_exit_str_masked_v1(const char *func, const char *file, int line, int subsys, const char *ret);
|
||||
__dso_public void sudo_debug_exit_time_t_v1(const char *func, const char *file, int line, int subsys, time_t ret);
|
||||
__dso_public pid_t sudo_debug_fork_v1(void);
|
||||
__dso_public int sudo_debug_get_active_instance_v1(void);
|
||||
__dso_public int sudo_debug_get_fds_v1(unsigned char **fds);
|
||||
@ -272,6 +281,7 @@ __dso_public void sudo_debug_write2_v1(int fd, const char *func, const char *fil
|
||||
#define sudo_debug_exit_ssize_t(_a, _b, _c, _d, _e) sudo_debug_exit_ssize_t_v1((_a), (_b), (_c), (_d), (_e))
|
||||
#define sudo_debug_exit_str(_a, _b, _c, _d, _e) sudo_debug_exit_str_v1((_a), (_b), (_c), (_d), (_e))
|
||||
#define sudo_debug_exit_str_masked(_a, _b, _c, _d, _e) sudo_debug_exit_str_masked_v1((_a), (_b), (_c), (_d), (_e))
|
||||
#define sudo_debug_exit_time_t(_a, _b, _c, _d, _e) sudo_debug_exit_time_t_v1((_a), (_b), (_c), (_d), (_e))
|
||||
#define sudo_debug_fork() sudo_debug_fork_v1()
|
||||
#define sudo_debug_get_active_instance() sudo_debug_get_active_instance_v1()
|
||||
#define sudo_debug_get_fds(_a) sudo_debug_get_fds_v1((_a))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2011-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
|
||||
@ -481,6 +481,19 @@ sudo_debug_exit_ssize_t_v1(const char *func, const char *file, int line,
|
||||
"<- %s @ %s:%d := %zd", func, file, line, ret);
|
||||
}
|
||||
|
||||
void
|
||||
sudo_debug_exit_time_t_v1(const char *func, const char *file, int line,
|
||||
int subsys, time_t ret)
|
||||
{
|
||||
#if SIZEOF_TIME_T == 8
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d := %lld", func, file, line, (long long)ret);
|
||||
#else
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d := %d", func, file, line, (int)ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
sudo_debug_exit_bool_v1(const char *func, const char *file, int line,
|
||||
int subsys, bool ret)
|
||||
|
@ -25,6 +25,7 @@ sudo_debug_exit_size_t_v1
|
||||
sudo_debug_exit_ssize_t_v1
|
||||
sudo_debug_exit_str_v1
|
||||
sudo_debug_exit_str_masked_v1
|
||||
sudo_debug_exit_time_t_v1
|
||||
sudo_debug_fork_v1
|
||||
sudo_debug_get_active_instance_v1
|
||||
sudo_debug_get_fds_v1
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1996, 1998-2005, 2007-2015
|
||||
# Copyright (c) 1996, 1998-2005, 2007-2017
|
||||
# Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
@ -146,14 +146,15 @@ SHELL = @SHELL@
|
||||
PROGS = sudoers.la visudo sudoreplay testsudoers
|
||||
|
||||
TEST_PROGS = check_iolog_path check_fill check_wrap check_addr check_digest \
|
||||
check_base64 check_hexchar @SUDOERS_TEST_PROGS@
|
||||
check_base64 check_gentime check_hexchar @SUDOERS_TEST_PROGS@
|
||||
|
||||
AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
||||
|
||||
LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \
|
||||
gram.lo match.lo match_addr.lo pwutil.lo pwutil_impl.lo \
|
||||
rcstr.lo redblack.lo sudoers_debug.lo timeout.lo \
|
||||
timestr.lo toke.lo toke_util.lo
|
||||
LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo gentime.lo \
|
||||
hexchar.lo gmtoff.lo gram.lo match.lo match_addr.lo \
|
||||
pwutil.lo pwutil_impl.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 \
|
||||
@ -178,6 +179,8 @@ CHECK_DIGEST_OBJS = check_digest.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
|
||||
|
||||
CHECK_HEXCHAR_OBJS = check_hexchar.o hexchar.o sudoers_debug.o
|
||||
|
||||
CHECK_IOLOG_PATH_OBJS = check_iolog_path.o iolog_path.o locale.o \
|
||||
@ -248,6 +251,9 @@ check_digest: $(CHECK_DIGEST_OBJS) $(LT_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)
|
||||
|
||||
check_gentime: $(CHECK_GENTIME_OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_GENTIME_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||
|
||||
check_hexchar: $(CHECK_HEXCHAR_OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_HEXCHAR_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||
|
||||
@ -374,6 +380,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 + $$?`; \
|
||||
./check_fill || rval=`expr $$rval + $$?`; \
|
||||
./check_gentime || rval=`expr $$rval + $$?`; \
|
||||
./check_hexchar || rval=`expr $$rval + $$?`; \
|
||||
./check_iolog_path $(srcdir)/regress/iolog_path/data || rval=`expr $$rval + $$?`; \
|
||||
case "$(TEST_PROGS)" in \
|
||||
@ -601,6 +608,12 @@ check_fill.o: $(srcdir)/regress/parser/check_fill.c $(devdir)/gram.h \
|
||||
$(incdir)/sudo_util.h $(srcdir)/parse.h $(srcdir)/toke.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_fill.c
|
||||
check_gentime.o: $(srcdir)/regress/parser/check_gentime.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
|
||||
$(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_gentime.c
|
||||
check_hexchar.o: $(srcdir)/regress/parser/check_hexchar.c \
|
||||
$(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/parser/check_hexchar.c
|
||||
@ -688,6 +701,12 @@ gc.lo: $(srcdir)/gc.c $(devdir)/def_data.h $(incdir)/compat/stdbool.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)/gc.c
|
||||
gentime.lo: $(srcdir)/gentime.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gentime.c
|
||||
gentime.o: gentime.lo
|
||||
getdate.o: $(devdir)/getdate.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(devdir)/getdate.c
|
||||
getspwuid.lo: $(srcdir)/getspwuid.c $(devdir)/def_data.h \
|
||||
@ -700,6 +719,12 @@ getspwuid.lo: $(srcdir)/getspwuid.c $(devdir)/def_data.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)/getspwuid.c
|
||||
gmtoff.lo: $(srcdir)/gmtoff.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_queue.h $(srcdir)/parse.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/gmtoff.c
|
||||
gmtoff.o: gmtoff.lo
|
||||
goodpath.lo: $(srcdir)/goodpath.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||
@ -892,8 +917,8 @@ policy.lo: $(srcdir)/policy.c $(devdir)/def_data.h $(incdir)/compat/stdbool.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)/interfaces.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(srcdir)/interfaces.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(srcdir)/sudoers_version.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/policy.c
|
||||
|
158
plugins/sudoers/gentime.c
Normal file
158
plugins/sudoers/gentime.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# include "compat/stdbool.h"
|
||||
#endif /* HAVE_STDBOOL_H */
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudoers_debug.h"
|
||||
#include "parse.h"
|
||||
|
||||
/*
|
||||
* Parse a timestamp in Generalized Time format as per RFC4517.
|
||||
* E.g. yyyymmddHHMMSS.FZ or yyyymmddHHMMSS.F[+-]TZOFF
|
||||
* where minutes, seconds and fraction are optional.
|
||||
* Returns the time in Unix time format or -1 on error.
|
||||
*/
|
||||
time_t
|
||||
parse_gentime(const char *timestr)
|
||||
{
|
||||
char tcopy[sizeof("yyyymmddHHMMSS.F")];
|
||||
const char *cp;
|
||||
time_t result;
|
||||
struct tm tm;
|
||||
size_t len;
|
||||
int items, tzoff = 0;
|
||||
bool islocal = false;
|
||||
debug_decl(parse_gentime, SUDOERS_DEBUG_PARSER)
|
||||
|
||||
/* Make a copy of the time without time zone for easy parsing. */
|
||||
len = strspn(timestr, "0123456789.,");
|
||||
if (len >= sizeof(tcopy)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to parse general time string %s", timestr);
|
||||
debug_return_time_t(-1);
|
||||
}
|
||||
memcpy(tcopy, timestr, len);
|
||||
tcopy[len] = '\0';
|
||||
|
||||
/* Parse general time, ignoring the timezone for now. */
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
items = sscanf(tcopy, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon,
|
||||
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
|
||||
if (items == EOF || items < 4) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"only parsed %d items in general time string %s", items, timestr);
|
||||
debug_return_time_t(-1);
|
||||
}
|
||||
cp = timestr + ((items + 1) * 2);
|
||||
|
||||
/* Parse optional fractional hours/minute/second if present. */
|
||||
if ((cp[0] == '.' || cp[0] == ',') && isdigit((unsigned char)cp[1])) {
|
||||
int frac = cp[1] - '0';
|
||||
switch (items) {
|
||||
case 4:
|
||||
/* convert fractional hour -> minutes */
|
||||
tm.tm_min += 60 / 10 * frac;
|
||||
break;
|
||||
case 5:
|
||||
/* convert fractional minute -> seconds */
|
||||
tm.tm_sec += 60 / 10 * frac;
|
||||
break;
|
||||
case 6:
|
||||
/* ignore fractional second */
|
||||
break;
|
||||
}
|
||||
cp += 2; /* skip over radix and fraction */
|
||||
}
|
||||
|
||||
switch (*cp) {
|
||||
case '-':
|
||||
case '+': {
|
||||
int hour = 0, min = 0;
|
||||
|
||||
/* No DST */
|
||||
tm.tm_isdst = 0;
|
||||
/* parse time zone offset */
|
||||
items = sscanf(cp + 1, "%2d%2d", &hour, &min);
|
||||
if (items == EOF || items < 1) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to parse time zone offset in %s, items %d",
|
||||
timestr, items);
|
||||
debug_return_time_t(-1);
|
||||
}
|
||||
if (*cp == '-')
|
||||
tzoff = -((hour * 60) + min) * 60;
|
||||
else
|
||||
tzoff = ((hour * 60) + min) * 60;
|
||||
cp += 1 + (items * 2);
|
||||
break;
|
||||
}
|
||||
case 'Z':
|
||||
/* GMT/UTC, no DST */
|
||||
tm.tm_isdst = 0;
|
||||
cp++;
|
||||
break;
|
||||
case '\0':
|
||||
/* no zone specified, use local time */
|
||||
tm.tm_isdst = -1;
|
||||
islocal = true;
|
||||
break;
|
||||
default:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to parse general time string %s", timestr);
|
||||
debug_return_time_t(-1);
|
||||
}
|
||||
if (*cp != '\0') {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"trailing garbage in general time string %s", timestr);
|
||||
debug_return_time_t(-1);
|
||||
}
|
||||
|
||||
/* Adjust from Generalized Time to struct tm */
|
||||
tm.tm_year -= 1900;
|
||||
tm.tm_mon--;
|
||||
|
||||
result = mktime(&tm);
|
||||
if (result != -1) {
|
||||
if (!islocal) {
|
||||
/* Not local time, convert to GMT */
|
||||
result += get_gmtoff(&result);
|
||||
/* Adjust time based on supplied GMT offset. */
|
||||
result -= tzoff;
|
||||
}
|
||||
}
|
||||
|
||||
debug_return_time_t(result);
|
||||
}
|
67
plugins/sudoers/gmtoff.c
Normal file
67
plugins/sudoers/gmtoff.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <time.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudoers_debug.h"
|
||||
#include "parse.h"
|
||||
|
||||
/*
|
||||
* Returns the offset from GMT in seconds (algorithm taken from sendmail).
|
||||
* Warning: clobbers the static storage used by localtime() and gmtime().
|
||||
*/
|
||||
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
||||
long
|
||||
get_gmtoff(time_t *clock)
|
||||
{
|
||||
struct tm *local;
|
||||
|
||||
local = localtime(clock);
|
||||
return local->tm_gmtoff;
|
||||
}
|
||||
#else
|
||||
long
|
||||
get_gmtoff(time_t *clock)
|
||||
{
|
||||
struct tm gmt, *local;
|
||||
long offset;
|
||||
|
||||
gmt = *gmtime(clock);
|
||||
local = localtime(clock);
|
||||
|
||||
offset = (local->tm_sec - gmt.tm_sec) +
|
||||
((local->tm_min - gmt.tm_min) * 60) +
|
||||
((local->tm_hour - gmt.tm_hour) * 3600);
|
||||
|
||||
/* Timezone may cause year rollover to happen on a different day. */
|
||||
if (local->tm_year < gmt.tm_year)
|
||||
offset -= 24 * 3600;
|
||||
else if (local->tm_year > gmt.tm_year)
|
||||
offset -= 24 * 3600;
|
||||
else if (local->tm_yday < gmt.tm_yday)
|
||||
offset -= 24 * 3600;
|
||||
else if (local->tm_yday > gmt.tm_yday)
|
||||
offset += 24 * 3600;
|
||||
|
||||
return offset;
|
||||
}
|
||||
#endif /* HAVE_TM_GMTOFF */
|
File diff suppressed because it is too large
Load Diff
@ -37,11 +37,13 @@
|
||||
#define PRIVS 293
|
||||
#define LIMITPRIVS 294
|
||||
#define CMND_TIMEOUT 295
|
||||
#define MYSELF 296
|
||||
#define SHA224_TOK 297
|
||||
#define SHA256_TOK 298
|
||||
#define SHA384_TOK 299
|
||||
#define SHA512_TOK 300
|
||||
#define NOTBEFORE 296
|
||||
#define NOTAFTER 297
|
||||
#define MYSELF 298
|
||||
#define SHA224_TOK 299
|
||||
#define SHA256_TOK 300
|
||||
#define SHA384_TOK 301
|
||||
#define SHA512_TOK 302
|
||||
#ifndef YYSTYPE_DEFINED
|
||||
#define YYSTYPE_DEFINED
|
||||
typedef union {
|
||||
|
@ -130,6 +130,8 @@ static struct sudo_digest *new_digest(int, char *);
|
||||
%token <tok> PRIVS /* Solaris privileges */
|
||||
%token <tok> LIMITPRIVS /* Solaris limit privileges */
|
||||
%token <tok> CMND_TIMEOUT /* command timeout */
|
||||
%token <tok> NOTBEFORE /* time restriction */
|
||||
%token <tok> NOTAFTER /* time restriction */
|
||||
%token <tok> MYSELF /* run as myself, not another user */
|
||||
%token <tok> SHA224_TOK /* sha224 token */
|
||||
%token <tok> SHA256_TOK /* sha256 token */
|
||||
@ -164,6 +166,8 @@ static struct sudo_digest *new_digest(int, char *);
|
||||
%type <string> privsspec
|
||||
%type <string> limitprivsspec
|
||||
%type <string> timeoutspec
|
||||
%type <string> notbeforespec
|
||||
%type <string> notafterspec
|
||||
%type <digest> digest
|
||||
%type <options> options
|
||||
|
||||
@ -353,6 +357,11 @@ cmndspeclist : cmndspec
|
||||
$3->limitprivs = prev->limitprivs;
|
||||
}
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
/* propagate command time restrictions */
|
||||
if ($3->notbefore == UNSPEC)
|
||||
$3->notbefore = prev->notbefore;
|
||||
if ($3->notafter == UNSPEC)
|
||||
$3->notafter = prev->notafter;
|
||||
/* propagate command timeout */
|
||||
if ($3->timeout == UNSPEC)
|
||||
$3->timeout = prev->timeout;
|
||||
@ -420,6 +429,8 @@ cmndspec : runasspec options cmndtag digcmnd {
|
||||
cs->privs = $2.privs;
|
||||
cs->limitprivs = $2.limitprivs;
|
||||
#endif
|
||||
cs->notbefore = $2.notbefore;
|
||||
cs->notafter = $2.notafter;
|
||||
cs->timeout = $2.timeout;
|
||||
cs->tags = $3;
|
||||
cs->cmnd = $4;
|
||||
@ -491,6 +502,15 @@ timeoutspec : CMND_TIMEOUT '=' WORD {
|
||||
}
|
||||
;
|
||||
|
||||
notbeforespec : NOTBEFORE '=' WORD {
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
notafterspec : NOTAFTER '=' WORD {
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
rolespec : ROLE '=' WORD {
|
||||
$$ = $3;
|
||||
}
|
||||
@ -580,6 +600,22 @@ runaslist : /* empty */ {
|
||||
options : /* empty */ {
|
||||
init_options(&$$);
|
||||
}
|
||||
| options notbeforespec {
|
||||
$$.notbefore = parse_gentime($2);
|
||||
free($2);
|
||||
if ($$.notbefore == -1) {
|
||||
sudoerserror(N_("invalid notbefore value"));
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| options notafterspec {
|
||||
$$.notafter = parse_gentime($2);
|
||||
free($2);
|
||||
if ($$.notafter == -1) {
|
||||
sudoerserror(N_("invalid notafter value"));
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| options timeoutspec {
|
||||
$$.timeout = parse_timeout($2);
|
||||
free($2);
|
||||
@ -1185,6 +1221,8 @@ init_parser(const char *path, bool quiet)
|
||||
static void
|
||||
init_options(struct command_options *opts)
|
||||
{
|
||||
opts->notbefore = UNSPEC;
|
||||
opts->notafter = UNSPEC;
|
||||
opts->timeout = UNSPEC;
|
||||
#ifdef HAVE_SELINUX
|
||||
opts->role = NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005, 2007-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2004-2005, 2007-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
|
||||
@ -29,8 +29,9 @@
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sudoers.h"
|
||||
#include "parse.h"
|
||||
@ -151,6 +152,7 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
struct privilege *priv;
|
||||
struct userspec *us;
|
||||
struct member *matching_user;
|
||||
time_t now;
|
||||
debug_decl(sudo_file_lookup, SUDOERS_DEBUG_NSS)
|
||||
|
||||
if (nss->handle == NULL)
|
||||
@ -207,6 +209,7 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
if (!set_perms(PERM_RUNAS))
|
||||
debug_return_int(validated);
|
||||
|
||||
time(&now);
|
||||
match = UNSPEC;
|
||||
TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
|
||||
if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
|
||||
@ -219,6 +222,14 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
else
|
||||
continue;
|
||||
TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
|
||||
if (cs->notbefore != UNSPEC) {
|
||||
if (now < cs->notbefore)
|
||||
continue;
|
||||
}
|
||||
if (cs->notafter != UNSPEC) {
|
||||
if (now > cs->notafter)
|
||||
continue;
|
||||
}
|
||||
matching_user = NULL;
|
||||
runas_match = runaslist_matches(cs->runasuserlist,
|
||||
cs->runasgrouplist, &matching_user, NULL);
|
||||
@ -378,6 +389,22 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
|
||||
snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
|
||||
sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
|
||||
}
|
||||
if (cs->notbefore != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
struct tm *tm = gmtime(&cs->notbefore);
|
||||
snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
|
||||
}
|
||||
if (cs->notafter != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
struct tm *tm = gmtime(&cs->notafter);
|
||||
snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
|
||||
}
|
||||
if (TAG_CHANGED(setenv)) {
|
||||
tags->setenv = cs->tags.setenv;
|
||||
sudo_lbuf_append(lbuf, tags->setenv ? "SETENV: " : "NOSETENV: ");
|
||||
@ -568,6 +595,22 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
|
||||
snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
|
||||
sudo_lbuf_append(lbuf, " Timeout: %s\n", numbuf);
|
||||
}
|
||||
if (cs->notbefore != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
struct tm *tm = gmtime(&cs->notbefore);
|
||||
snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
sudo_lbuf_append(lbuf, " NotBefore: %s\n", buf);
|
||||
}
|
||||
if (cs->notafter != UNSPEC) {
|
||||
char buf[sizeof("CCYYMMDDHHMMSSZ")];
|
||||
struct tm *tm = gmtime(&cs->notafter);
|
||||
snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
sudo_lbuf_append(lbuf, " NotAfter: %s\n", buf);
|
||||
}
|
||||
sudo_lbuf_append(lbuf, _(" Commands:\n"));
|
||||
}
|
||||
sudo_lbuf_append(lbuf, "\t");
|
||||
|
@ -113,6 +113,8 @@ struct cmndtag {
|
||||
* Per-command option container struct.
|
||||
*/
|
||||
struct command_options {
|
||||
time_t notbefore; /* time restriction */
|
||||
time_t notafter; /* time restriction */
|
||||
int timeout; /* command timeout */
|
||||
#ifdef HAVE_SELINUX
|
||||
char *role, *type; /* SELinux role and type */
|
||||
@ -176,6 +178,8 @@ struct cmndspec {
|
||||
struct member_list *runasgrouplist; /* list of runas groups */
|
||||
struct member *cmnd; /* command to allow/deny */
|
||||
struct cmndtag tags; /* tag specificaion */
|
||||
time_t notbefore; /* time restriction */
|
||||
time_t notafter; /* time restriction */
|
||||
int timeout; /* command timeout */
|
||||
#ifdef HAVE_SELINUX
|
||||
char *role, *type; /* SELinux role and type */
|
||||
@ -280,4 +284,10 @@ size_t base64_decode(const char *str, unsigned char *dst, size_t dsize);
|
||||
/* timeout.c */
|
||||
int parse_timeout(const char *timestr);
|
||||
|
||||
/* gmtoff.c */
|
||||
long get_gmtoff(time_t *clock);
|
||||
|
||||
/* gentime.c */
|
||||
time_t parse_gentime(const char *expstr);
|
||||
|
||||
#endif /* SUDOERS_PARSE_H */
|
||||
|
84
plugins/sudoers/regress/parser/check_gentime.c
Normal file
84
plugins/sudoers/regress/parser/check_gentime.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 <time.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudoers_debug.h"
|
||||
#include "parse.h"
|
||||
|
||||
__dso_public int main(int argc, char *argv[]);
|
||||
|
||||
struct gentime_test {
|
||||
char *gentime;
|
||||
time_t unixtime;
|
||||
} tests[] = {
|
||||
{ "199412161032ZZ", -1 },
|
||||
{ "199412161032Z", 787573920 },
|
||||
{ "199412160532-0500", 787573920 },
|
||||
{ "199412160532-05000", -1 },
|
||||
{ "199412160532", 787573920 }, /* local time is EST */
|
||||
{ "20170214083000-0500", 1487079000 },
|
||||
{ "201702140830-0500", 1487079000 },
|
||||
{ "201702140830", 1487079000 }, /* local time is EST */
|
||||
{ "201702140830.3-0500", 1487079018 },
|
||||
{ "201702140830,3-0500", 1487079018 },
|
||||
{ "20170214083000.5Z", 1487061000 },
|
||||
{ "20170214083000,5Z", 1487061000 },
|
||||
{ "201702142359.4Z", 1487116764 },
|
||||
{ "201702142359,4Z", 1487116764 },
|
||||
{ "2017021408.5Z", 1487061000 },
|
||||
{ "2017021408,5Z", 1487061000 },
|
||||
{ "20170214Z", -1 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ntests, errors = 0;
|
||||
time_t result;
|
||||
|
||||
/* Do local time tests in Eastern Standard Time. */
|
||||
putenv("TZ=EST5EST5");
|
||||
tzset();
|
||||
|
||||
for (ntests = 0; tests[ntests].gentime != NULL; ntests++) {
|
||||
result = parse_gentime(tests[ntests].gentime);
|
||||
if (result != tests[ntests].unixtime) {
|
||||
fprintf(stderr, "check_gentime[%d]: %s: expected %lld, got %lld\n",
|
||||
ntests, tests[ntests].gentime,
|
||||
(long long)tests[ntests].unixtime, (long long)result);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
printf("check_gentime: %d tests run, %d errors, %d%% success rate\n",
|
||||
ntests, errors, (ntests - errors) * 100 / ntests);
|
||||
exit(errors);
|
||||
}
|
12
plugins/sudoers/regress/sudoers/test19.in
Normal file
12
plugins/sudoers/regress/sudoers/test19.in
Normal file
@ -0,0 +1,12 @@
|
||||
# Test parsing of NOTBEFORE and NOTAFTER syntax
|
||||
# Local time zone parsing is checked in visudo/test10.sh
|
||||
user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, /bin/ls
|
||||
user1 ALL = NOTBEFORE=201702140830Z /usr/bin/id, NOTAFTER=20170301083000Z /bin/ls
|
||||
user2 ALL = NOTBEFORE=201702140830.3Z /usr/bin/id
|
||||
user3 ALL = NOTBEFORE=2017021408Z /usr/bin/id
|
||||
user4 ALL = NOTBEFORE=2017021408.4Z /usr/bin/id
|
||||
user5 ALL = NOTBEFORE=20170214083000.5Z /usr/bin/id
|
||||
user6 ALL = NOTBEFORE=20170214083000\,5Z /usr/bin/id
|
||||
user7 ALL = NOTBEFORE=20170214033000-0500 /usr/bin/id
|
||||
user8 ALL = NOTBEFORE=20170214033000.0-0500 /usr/bin/id
|
||||
user9 ALL = NOTBEFORE=20170214033000\,0-0500 /usr/bin/id
|
156
plugins/sudoers/regress/sudoers/test19.json.ok
Normal file
156
plugins/sudoers/regress/sudoers/test19.json.ok
Normal file
@ -0,0 +1,156 @@
|
||||
{
|
||||
"User_Specs": [
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user0" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" },
|
||||
{ "command": "/bin/ls" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user1" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" },
|
||||
{ "command": "/bin/ls" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user2" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user3" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user4" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user5" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user6" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user7" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user8" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "user9" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostalias": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"Commands": [
|
||||
{ "command": "/usr/bin/id" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
14
plugins/sudoers/regress/sudoers/test19.out.ok
Normal file
14
plugins/sudoers/regress/sudoers/test19.out.ok
Normal file
@ -0,0 +1,14 @@
|
||||
Parses OK.
|
||||
|
||||
|
||||
|
||||
user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /bin/ls
|
||||
user1 ALL = NOTBEFORE=20170214083000Z /usr/bin/id, NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /bin/ls
|
||||
user2 ALL = NOTBEFORE=20170214083018Z /usr/bin/id
|
||||
user3 ALL = NOTBEFORE=20170214080000Z /usr/bin/id
|
||||
user4 ALL = NOTBEFORE=20170214082400Z /usr/bin/id
|
||||
user5 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
|
||||
user6 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
|
||||
user7 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
|
||||
user8 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
|
||||
user9 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
|
12
plugins/sudoers/regress/sudoers/test19.toke.ok
Normal file
12
plugins/sudoers/regress/sudoers/test19.toke.ok
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
#
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) NOTAFTER = WORD(5) COMMAND , COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND , NOTAFTER = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
||||
WORD(5) ALL = NOTBEFORE = WORD(5) COMMAND
|
1
plugins/sudoers/regress/visudo/test10.out.ok
Normal file
1
plugins/sudoers/regress/visudo/test10.out.ok
Normal file
@ -0,0 +1 @@
|
||||
stdin: parsed OK
|
11
plugins/sudoers/regress/visudo/test10.sh
Executable file
11
plugins/sudoers/regress/visudo/test10.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Test parsing of NOTBEFORE/NOTAFTER using local time zone
|
||||
#
|
||||
|
||||
./visudo -cf - <<-EOF
|
||||
user1 ALL = NOTBEFORE=20151201235900 /usr/bin/id
|
||||
user2 ALL = NOTBEFORE=20151201235900.2 /usr/bin/id
|
||||
user3 ALL = NOTBEFORE=20151201235900\,2 /usr/bin/id
|
||||
user4 ALL = NOTBEFORE=2015120123 /usr/bin/id
|
||||
EOF
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2011-2013, 2015, 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
|
||||
@ -17,7 +18,6 @@
|
||||
/*
|
||||
* Major sudoers grammar changes are documented here.
|
||||
* Note that minor changes such as added Defaults options are not listed here.
|
||||
* This file placed in the public domain by Todd C. Miller on Apr 5, 2011.
|
||||
*
|
||||
* 1 sudo 1.1
|
||||
* 2 sudo 1.3, adds support specifying a directory instead of a command.
|
||||
@ -64,11 +64,12 @@
|
||||
* 43 sudo 1.8.7, Support for specifying a digest along with the command.
|
||||
* 44 sudo 1.8.13, added MAIL/NOMAIL tags.
|
||||
* 45 sudo 1.8.15, added FOLLOW/NOFOLLOW tags as well as sudoedit_follow and sudoedit_checkdir Defaults.
|
||||
*/
|
||||
* 46 sudo 1.8.20, added TIMEOUT, NOTBEFORE and NOTAFTER options.
|
||||
*/
|
||||
|
||||
#ifndef SUDOERS_VERSION_H
|
||||
#define SUDOERS_VERSION_H
|
||||
|
||||
#define SUDOERS_GRAMMAR_VERSION 45
|
||||
#define SUDOERS_GRAMMAR_VERSION 46
|
||||
|
||||
#endif /* SUDOERS_VERSION_H */
|
||||
|
@ -38,6 +38,7 @@
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
# include <netgroup.h>
|
||||
#endif /* HAVE_NETGROUP_H */
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
@ -636,6 +637,18 @@ print_privilege(struct privilege *priv)
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (cs->timeout > 0)
|
||||
printf("TIMEOUT=%d ", cs->timeout);
|
||||
if (cs->notbefore != UNSPEC) {
|
||||
struct tm *tm = gmtime(&cs->notbefore);
|
||||
printf("NOTBEFORE=%04d%02d%02d%02d%02d%02dZ ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
if (cs->notafter != UNSPEC) {
|
||||
struct tm *tm = gmtime(&cs->notafter);
|
||||
printf("NOTAFTER=%04d%02d%02d%02d%02d%02dZ ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
if (TAG_CHANGED(follow))
|
||||
printf("%sFOLLOW: ", cs->tags.follow ? "" : "NO");
|
||||
if (TAG_CHANGED(log_input))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1996, 1998-2005, 2007-2016
|
||||
* Copyright (c) 1996, 1998-2005, 2007-2017
|
||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -535,6 +535,16 @@ ALL {
|
||||
LEXRETURN(CMND_TIMEOUT);
|
||||
}
|
||||
|
||||
<INITIAL>NOTBEFORE {
|
||||
LEXTRACE("NOTBEFORE ");
|
||||
LEXRETURN(NOTBEFORE);
|
||||
}
|
||||
|
||||
<INITIAL>NOTAFTER {
|
||||
LEXTRACE("NOTAFTER ");
|
||||
LEXRETURN(NOTAFTER);
|
||||
}
|
||||
|
||||
<INITIAL>ROLE {
|
||||
#ifdef HAVE_SELINUX
|
||||
LEXTRACE("ROLE ");
|
||||
|
Loading…
x
Reference in New Issue
Block a user