From 600ce3dfa67d42cffe266b3df33c0e0a542d3ed6 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 10 Dec 2009 16:59:27 +0000 Subject: [PATCH] Treat timestamp files from before we booted as old. Idea from and Apple patch. --- Makefile.in | 25 +++++----- boottime.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ check.c | 8 ++- config.h.in | 9 ++++ configure | 115 +++++++++++++++++++++++++++++++++++++++---- configure.in | 4 +- sudo.h | 1 + 7 files changed, 274 insertions(+), 23 deletions(-) create mode 100644 boottime.c diff --git a/Makefile.in b/Makefile.in index 184b7a325..582894840 100644 --- a/Makefile.in +++ b/Makefile.in @@ -104,16 +104,17 @@ SHELL = /bin/sh PROGS = @PROGS@ -SRCS = aix.c alias.c alloc.c audit.c bsm_audit.c check.c closefrom.c \ - def_data.c defaults.c env.c error.c fileops.c find_path.c fnmatch.c \ - getcwd.c getprogname.c getspwuid.c gettime.c glob.c goodpath.c gram.c \ - gram.y interfaces.c isblank.c lbuf.c ldap.c list.c logging.c match.c \ - mkstemp.c memrchr.c nanosleep.c parse.c pwutil.c pty.c script.c \ - set_perms.c sigaction.c snprintf.c strcasecmp.c strerror.c strlcat.c \ - strlcpy.c strsignal.c sudo.c sudo_noexec.c sudo_edit.c sudo_nss.c \ - term.c testsudoers.c tgetpass.c toke.c toke.l tsgetgrpw.c utimes.c \ - vasgroups.c visudo.c zero_bytes.c redblack.c selinux.c sesh.c \ - sudoreplay.c getdate.c getdate.y getline.c timestr.c $(AUTH_SRCS) +SRCS = aix.c alias.c alloc.c audit.c boottime.c bsm_audit.c check.c \ + closefrom.c def_data.c defaults.c env.c error.c fileops.c find_path.c \ + fnmatch.c getcwd.c getprogname.c getspwuid.c gettime.c glob.c \ + goodpath.c gram.c gram.y interfaces.c isblank.c lbuf.c ldap.c list.c \ + logging.c match.c mkstemp.c memrchr.c nanosleep.c parse.c pwutil.c \ + pty.c script.c set_perms.c sigaction.c snprintf.c strcasecmp.c \ + strerror.c strlcat.c strlcpy.c strsignal.c sudo.c sudo_noexec.c \ + sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \ + tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c redblack.c \ + selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \ + timestr.c $(AUTH_SRCS) AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \ auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ @@ -132,7 +133,7 @@ COMMON_OBJS = alias.o alloc.o defaults.o error.o getline.o gram.o \ list.o match.o pwutil.o timestr.o toke.o redblack.o \ term.o zero_bytes.o @NONUNIX_GROUPS_IMPL@ -SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o check.o \ +SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o boottime.o check.o \ env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ interfaces.o lbuf.o logging.o parse.o set_perms.o sudo.o \ sudo_edit.o sudo_nss.o tgetpass.o @@ -250,6 +251,8 @@ alloc.o: $(srcdir)/alloc.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alloc.c audit.o: $(srcdir)/audit.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/audit.c +boottime.o: $(srcdir)/boottime.c config.h + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/boottime.c bsm_audit.o: $(srcdir)/bsm_audit.c $(SUDODEP) bsm_audit.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/bsm_audit.c check.o: $(srcdir)/check.c $(SUDODEP) diff --git a/boottime.c b/boottime.c new file mode 100644 index 000000000..6789b9a13 --- /dev/null +++ b/boottime.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2009 Todd C. Miller + * + * 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 + +#include +#include + +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ +#include + +#ifdef HAVE_SYSCTL +# include +#endif + +#include "compat.h" +#include "missing.h" + +#if defined(__linux__) +time_t +get_boottime() +{ + time_t boottime = 0; + char *line = NULL; + size_t linesize = 0; + ssize_t len; + FILE * fp; + + /* read btime from /proc/stat */ + fp = fopen("/proc/stat", "r"); + if (fp != NULL) { + while ((len = getline(&line, &linesize, fp)) != -1) { + if (strncmp(line, "btime ", 6) == 0) { + boottime = atoi(line + 6); + break; + } + } + fclose(fp); + free(line); + } + + return(boottime); +} + +#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME) + +time_t +get_boottime() +{ + struct timeval tv; + time_t boottime = 0; + size_t size; + int mib[2]; + + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + size = sizeof(tv); + if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1) + boottime = tv.tv_sec; + + return(boottime); +} + +#elif defined(HAVE_GETUTXID) + +#include +time_t +get_boottime() +{ + time_t boottime = 0; + struct utmpx *ut, key; + + zero_bytes(&key, sizeof(key)); + key.ut_type = BOOT_TIME; + if ((ut = getutxid(&key)) != NULL) { + boottime = ut->ut_tv.tv_sec; + endutxent(); + } + return(boottime); +} + +#elif defined(HAVE_GETUTID) + +#include +time_t +get_boottime() +{ + time_t boottime = 0; + struct utmp *ut, key; + + zero_bytes(&key, sizeof(key)); + key.ut_type = BOOT_TIME; + if ((ut = getutid(&key)) != NULL) { + boottime = ut->ut_time; + endutent(); + } + return(boottime); +} + +#else + +time_t +get_boottime() +{ + return(0); +} +#endif diff --git a/check.c b/check.c index d75c8c590..d8132a6ba 100644 --- a/check.c +++ b/check.c @@ -410,7 +410,7 @@ timestamp_status(timestampdir, timestampfile, user, flags) int flags; { struct stat sb; - time_t now; + time_t boottime, now; char *dirparent = def_timestampdir; int status = TS_ERROR; /* assume the worst */ @@ -552,6 +552,7 @@ timestamp_status(timestampdir, timestampfile, user, flags) else { /* XXX - should use timespec here */ now = time(NULL); + boottime = get_boottime(); if (def_timestamp_timeout && now - sb.st_mtime < 60 * def_timestamp_timeout) { /* @@ -567,8 +568,11 @@ timestamp_status(timestampdir, timestampfile, user, flags) else (void) rmdir(timestampdir); status = TS_MISSING; - } else + } else if (sb.st_mtime < boottime) { + status = TS_OLD; + } else { status = TS_CURRENT; + } } } } diff --git a/config.h.in b/config.h.in index cf307302a..9275d53ef 100644 --- a/config.h.in +++ b/config.h.in @@ -184,6 +184,12 @@ /* Define to 1 if you have the `getuserattr' function. */ #undef HAVE_GETUSERATTR +/* Define to 1 if you have the `getutid' function. */ +#undef HAVE_GETUTID + +/* Define to 1 if you have the `getutxid' function. */ +#undef HAVE_GETUTXID + /* Define to 1 if you have the `glob' function. */ #undef HAVE_GLOB @@ -471,6 +477,9 @@ /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF +/* Define to 1 if you have the `sysctl' function. */ +#undef HAVE_SYSCTL + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTYPES_H diff --git a/configure b/configure index e5938c5b9..d68088732 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for sudo 1.7.3. +# Generated by GNU Autoconf 2.61 for sudo 1.7.3b1. # # Report bugs to . # @@ -724,8 +724,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sudo' PACKAGE_TARNAME='sudo' -PACKAGE_VERSION='1.7.3' -PACKAGE_STRING='sudo 1.7.3' +PACKAGE_VERSION='1.7.3b1' +PACKAGE_STRING='sudo 1.7.3b1' PACKAGE_BUGREPORT='http://www.sudo.ws/bugs/' # Factoring default headers for most tests. @@ -1418,7 +1418,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sudo 1.7.3 to adapt to many kinds of systems. +\`configure' configures sudo 1.7.3b1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1483,7 +1483,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sudo 1.7.3:";; + short | recursive ) echo "Configuration of sudo 1.7.3b1:";; esac cat <<\_ACEOF @@ -1688,7 +1688,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sudo configure 1.7.3 +sudo configure 1.7.3b1 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1702,7 +1702,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sudo $as_me 1.7.3, which was +It was created by sudo $as_me 1.7.3b1, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -16332,6 +16332,103 @@ done + + +for ac_func in sysctl getutid getutxid +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + + for ac_func in openpty do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -26480,7 +26577,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sudo $as_me 1.7.3, which was +This file was extended by sudo $as_me 1.7.3b1, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -26529,7 +26626,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -sudo config.status 1.7.3 +sudo config.status 1.7.3b1 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.in b/configure.in index 0d9ebd917..183783f57 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl $Sudo$ dnl dnl Copyright (c) 1994-1996,1998-2009 Todd C. Miller dnl -AC_INIT([sudo], [1.7.3], [http://www.sudo.ws/bugs/], [sudo]) +AC_INIT([sudo], [1.7.3b1], [http://www.sudo.ws/bugs/], [sudo]) AC_CONFIG_HEADER(config.h pathnames.h) dnl dnl This won't work before AC_INIT @@ -1854,6 +1854,8 @@ AC_CHECK_FUNCS(getline, [], [ AC_CHECK_FUNCS(fgetln) ]) +AC_CHECK_FUNCS(sysctl getutid getutxid, [break]) + AC_CHECK_FUNCS(openpty, [AC_CHECK_HEADERS(util.h pty.h, [break])], [ AC_CHECK_LIB(util, openpty, [ AC_CHECK_HEADERS(util.h pty.h, [break]) diff --git a/sudo.h b/sudo.h index ab3c039be..2daa313dc 100644 --- a/sudo.h +++ b/sudo.h @@ -278,6 +278,7 @@ int term_noecho __P((int)); int term_raw __P((int, int, int)); int term_restore __P((int, int)); char *get_timestr __P((time_t, int)); +time_t get_boottime __P((void)); YY_DECL; /* Only provide extern declarations outside of sudo.c. */ -- 2.40.0