parse_gentime: use timegm() to generate time since the epoch
The timegm() function is non-standard but widely available. Provide an implementation for those systems that lack it. Bug #1006
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -215,6 +215,7 @@ lib/util/getusershell.c
|
||||
lib/util/gidlist.c
|
||||
lib/util/glob.c
|
||||
lib/util/gmtime_r.c
|
||||
lib/util/timegm.c
|
||||
lib/util/inet_ntop.c
|
||||
lib/util/inet_pton.c
|
||||
lib/util/isblank.c
|
||||
@@ -571,7 +572,6 @@ 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
|
||||
|
@@ -964,6 +964,9 @@
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the `timegm' function. */
|
||||
#undef HAVE_TIMEGM
|
||||
|
||||
/* Define to 1 if you have the `TLS_method' function. */
|
||||
#undef HAVE_TLS_METHOD
|
||||
|
||||
|
26
configure
vendored
26
configure
vendored
@@ -21189,6 +21189,32 @@ esac
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in timegm
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm"
|
||||
if test "x$ac_cv_func_timegm" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h
|
||||
|
||||
else $as_nop
|
||||
|
||||
case " $LIBOBJS " in
|
||||
*" timegm.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS timegm.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
for _sym in sudo_timegm; do
|
||||
COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
"
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
@@ -2591,6 +2591,10 @@ AC_CHECK_FUNCS([gmtime_r], [], [
|
||||
AC_LIBOBJ(gmtime_r)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_gmtime_r)
|
||||
])
|
||||
AC_CHECK_FUNCS([timegm], [], [
|
||||
AC_LIBOBJ(timegm)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_timegm)
|
||||
])
|
||||
AC_CHECK_FUNCS([getgrouplist], [], [
|
||||
case "$host_os" in
|
||||
aix*)
|
||||
|
@@ -467,6 +467,9 @@ sudo_dso_public struct tm *sudo_localtime_r(const time_t *, struct tm *);
|
||||
# undef localtime_r
|
||||
# define localtime_r(_a, _b) sudo_localtime_r((_a), (_b))
|
||||
#endif /* HAVE_LOCALTIME_R */
|
||||
#ifndef HAVE_TIMEGM
|
||||
sudo_dso_public time_t sudo_timegm(struct tm *);
|
||||
#endif /* HAVE_TIMEGM */
|
||||
#ifndef HAVE_UTIMENSAT
|
||||
sudo_dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
|
||||
# undef utimensat
|
||||
|
@@ -23,61 +23,76 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudoers_debug.h"
|
||||
#include "parse.h"
|
||||
#include "sudo_debug.h"
|
||||
|
||||
/*
|
||||
* Returns the offset from GMT in seconds (algorithm taken from sendmail).
|
||||
*/
|
||||
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
||||
long
|
||||
static long
|
||||
get_gmtoff(time_t *when)
|
||||
{
|
||||
struct tm local;
|
||||
struct tm local;
|
||||
|
||||
if (localtime_r(when, &local) == NULL)
|
||||
return 0;
|
||||
if (localtime_r(when, &local) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Adjust for DST. */
|
||||
if (local.tm_isdst != 0)
|
||||
local.tm_gmtoff -= local.tm_isdst * 3600;
|
||||
/* Adjust for DST. */
|
||||
if (local.tm_isdst != 0)
|
||||
local.tm_gmtoff -= local.tm_isdst * 3600;
|
||||
|
||||
return local.tm_gmtoff;
|
||||
return local.tm_gmtoff;
|
||||
}
|
||||
#else
|
||||
long
|
||||
static long
|
||||
get_gmtoff(time_t *when)
|
||||
{
|
||||
struct tm gmt, local;
|
||||
long offset;
|
||||
struct tm gmt, local;
|
||||
long offset;
|
||||
|
||||
if (gmtime_r(when, &gmt) == NULL)
|
||||
return 0;
|
||||
if (localtime_r(when, &local) == NULL)
|
||||
return 0;
|
||||
if (gmtime_r(when, &gmt) == NULL)
|
||||
return 0;
|
||||
if (localtime_r(when, &local) == NULL)
|
||||
return 0;
|
||||
|
||||
offset = (local.tm_sec - gmt.tm_sec) +
|
||||
((local.tm_min - gmt.tm_min) * 60) +
|
||||
((local.tm_hour - gmt.tm_hour) * 3600);
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
/* Adjust for DST. */
|
||||
if (local.tm_isdst != 0)
|
||||
offset -= local.tm_isdst * 3600;
|
||||
/* Adjust for DST. */
|
||||
if (local.tm_isdst != 0)
|
||||
offset -= local.tm_isdst * 3600;
|
||||
|
||||
return offset;
|
||||
return offset;
|
||||
}
|
||||
#endif /* HAVE_TM_GMTOFF */
|
||||
|
||||
time_t
|
||||
sudo_timegm(struct tm *tm)
|
||||
{
|
||||
time_t result;
|
||||
|
||||
result = mktime(tm);
|
||||
if (result != -1)
|
||||
result += get_gmtoff(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_TIMEGM */
|
@@ -172,7 +172,7 @@ FUZZ_RUNS = 8192
|
||||
AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
||||
|
||||
LIBPARSESUDOERS_OBJS = alias.lo b64_decode.lo defaults.lo digestname.lo \
|
||||
exptilde.lo filedigest.lo gentime.lo gmtoff.lo gram.lo \
|
||||
exptilde.lo filedigest.lo gentime.lo gram.lo \
|
||||
hexchar.lo match.lo match_addr.lo match_command.lo \
|
||||
match_digest.lo pwutil.lo pwutil_impl.lo \
|
||||
redblack.lo strlist.lo sudoers_debug.lo timeout.lo \
|
||||
@@ -233,7 +233,7 @@ CHECK_EXPTILDE_OBJS = check_exptilde.o exptilde.lo pwutil.lo pwutil_impl.lo redb
|
||||
|
||||
CHECK_FILL_OBJS = check_fill.o hexchar.lo toke_util.lo sudoers_debug.lo
|
||||
|
||||
CHECK_GENTIME_OBJS = check_gentime.o gentime.lo gmtoff.lo sudoers_debug.lo
|
||||
CHECK_GENTIME_OBJS = check_gentime.o gentime.lo sudoers_debug.lo
|
||||
|
||||
CHECK_HEXCHAR_OBJS = check_hexchar.o hexchar.lo sudoers_debug.lo
|
||||
|
||||
@@ -1901,18 +1901,6 @@ getspwuid.i: $(srcdir)/getspwuid.c $(devdir)/def_data.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
getspwuid.plog: getspwuid.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getspwuid.c --i-file $< --output-file $@
|
||||
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.i: $(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
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
gmtoff.plog: gmtoff.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gmtoff.c --i-file $< --output-file $@
|
||||
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 \
|
||||
|
@@ -38,6 +38,11 @@
|
||||
#include "sudoers_debug.h"
|
||||
#include "parse.h"
|
||||
|
||||
/* Since timegm() is only used in one place we keep the macro local. */
|
||||
#ifndef HAVE_TIMEGM
|
||||
# define timegm(_t) sudo_timegm(_t)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parse a timestamp in Generalized Time format as per RFC4517.
|
||||
* E.g. yyyymmddHHMMSS.FZ or yyyymmddHHMMSS.F[+-]TZOFF
|
||||
@@ -152,11 +157,11 @@ parse_gentime(const char *timestr)
|
||||
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);
|
||||
if (islocal) {
|
||||
result = mktime(&tm);
|
||||
} else {
|
||||
result = timegm(&tm);
|
||||
if (result != -1) {
|
||||
/* Adjust time based on supplied GMT offset. */
|
||||
result -= tzoff;
|
||||
}
|
||||
|
@@ -411,9 +411,6 @@ size_t base64_encode(const unsigned char *in, size_t in_len, char *out, size_t o
|
||||
/* 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);
|
||||
|
||||
|
@@ -116,7 +116,7 @@ sub mkdep {
|
||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||
$makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_buf.lo arc4random_uniform.lo cfmakeraw.lo closefrom.lo dup3.lo explicit_bzero.lo fchmodat.lo freezero.lo fstatat.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo getusershell.lo glob.lo gmtime_r.lo inet_ntop_lo inet_pton.lo isblank.lo localtime_r.lo memrchr.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo openat.lo pipe2.lo pread.lo pwrite.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo unlinkat.lo utimens.lo:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_buf.lo arc4random_uniform.lo cfmakeraw.lo closefrom.lo dup3.lo explicit_bzero.lo fchmodat.lo freezero.lo fstatat.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo getusershell.lo glob.lo gmtime_r.lo inet_ntop_lo inet_pton.lo isblank.lo localtime_r.lo memrchr.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo openat.lo pipe2.lo pread.lo pwrite.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo timegm.lo unlinkat.lo utimens.lo:;
|
||||
|
||||
# Parse OBJS lines
|
||||
my %objs;
|
||||
|
Reference in New Issue
Block a user