Bring back boot time checking code and zero out time stamp files
that predate the boot time. This should help systems w/o /var/run where the admin has setup rc.d to clear the timestamp directory.
This commit is contained in:
1
MANIFEST
1
MANIFEST
@@ -201,6 +201,7 @@ plugins/sudoers/auth/sia.c
|
||||
plugins/sudoers/auth/sudo_auth.c
|
||||
plugins/sudoers/auth/sudo_auth.h
|
||||
plugins/sudoers/base64.c
|
||||
plugins/sudoers/boottime.c
|
||||
plugins/sudoers/bsm_audit.c
|
||||
plugins/sudoers/bsm_audit.h
|
||||
plugins/sudoers/check.c
|
||||
|
@@ -2203,6 +2203,11 @@ SSEECCUURRIITTYY NNOOTTEESS
|
||||
themselves on systems that allow unprivileged users to change the
|
||||
ownership of files they create.
|
||||
|
||||
While the time stamp directory _s_h_o_u_l_d be cleared at reboot time, not all
|
||||
systems contain a _/_v_a_r_/_r_u_n directory. To avoid potential problems,
|
||||
_s_u_d_o_e_r_s will ignore time stamp files that date from before the machine
|
||||
booted on systems where the boot time is available.
|
||||
|
||||
Some systems with graphical desktop environments allow unprivileged users
|
||||
to change the system clock. Since _s_u_d_o_e_r_s relies on the system clock for
|
||||
time stamp validation, it may be possible on such systems for a user to
|
||||
@@ -2317,4 +2322,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or http://www.sudo.ws/sudo/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.10 February 1, 2014 Sudo 1.8.10
|
||||
Sudo 1.8.10 February 3, 2014 Sudo 1.8.10
|
||||
|
@@ -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" "@mansectsu@" "February 1, 2014" "Sudo @PACKAGE_VERSION@" "Programmer's Manual"
|
||||
.TH "SUDOERS" "@mansectsu@" "February 3, 2014" "Sudo @PACKAGE_VERSION@" "Programmer's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -4488,6 +4488,16 @@ this is no longer recommended as it may be possible for a user
|
||||
to create the time stamp themselves on systems that allow
|
||||
unprivileged users to change the ownership of files they create.
|
||||
.PP
|
||||
While the time stamp directory
|
||||
\fIshould\fR
|
||||
be cleared at reboot time, not all systems contain a
|
||||
\fI/var/run\fR
|
||||
directory.
|
||||
To avoid potential problems,
|
||||
\fIsudoers\fR
|
||||
will ignore time stamp files that date from before the machine booted
|
||||
on systems where the boot time is available.
|
||||
.PP
|
||||
Some systems with graphical desktop environments allow unprivileged
|
||||
users to change the system clock.
|
||||
Since
|
||||
|
@@ -19,7 +19,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd February 1, 2014
|
||||
.Dd February 3, 2014
|
||||
.Dt SUDOERS @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -4128,6 +4128,16 @@ this is no longer recommended as it may be possible for a user
|
||||
to create the time stamp themselves on systems that allow
|
||||
unprivileged users to change the ownership of files they create.
|
||||
.Pp
|
||||
While the time stamp directory
|
||||
.Em should
|
||||
be cleared at reboot time, not all systems contain a
|
||||
.Pa /var/run
|
||||
directory.
|
||||
To avoid potential problems,
|
||||
.Em sudoers
|
||||
will ignore time stamp files that date from before the machine booted
|
||||
on systems where the boot time is available.
|
||||
.Pp
|
||||
Some systems with graphical desktop environments allow unprivileged
|
||||
users to change the system clock.
|
||||
Since
|
||||
|
156
plugins/sudoers/boottime.c
Normal file
156
plugins/sudoers/boottime.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 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 <sys/time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif /* STDC_HEADERS */
|
||||
#ifdef HAVE_STRING_H
|
||||
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#include <limits.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <time.h>
|
||||
#endif
|
||||
#ifndef __linux__
|
||||
# if defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
|
||||
# include <sys/sysctl.h>
|
||||
# elif defined(HAVE_GETUTXID)
|
||||
# include <utmpx.h>
|
||||
# elif defined(HAVE_GETUTID)
|
||||
# include <utmp.h>
|
||||
# endif
|
||||
#endif /* !__linux__ */
|
||||
|
||||
#include "missing.h"
|
||||
#include "sudo_debug.h"
|
||||
|
||||
/*
|
||||
* Fill in a struct timeval with the time the system booted.
|
||||
* Returns 1 on success and 0 on failure.
|
||||
*/
|
||||
|
||||
#if defined(__linux__)
|
||||
int
|
||||
get_boottime(struct timeval *tv)
|
||||
{
|
||||
char *ep, *line = NULL;
|
||||
size_t linesize = 0;
|
||||
ssize_t len;
|
||||
FILE * fp;
|
||||
debug_decl(get_boottime, SUDO_DEBUG_UTIL)
|
||||
|
||||
/* 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) {
|
||||
long long llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
|
||||
if (llval > 0) {
|
||||
tv->tv_sec = (time_t)llval;
|
||||
tv->tv_usec = 0;
|
||||
debug_return_bool(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
free(line);
|
||||
}
|
||||
|
||||
debug_return_bool(0);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
|
||||
|
||||
int
|
||||
get_boottime(struct timeval *tv)
|
||||
{
|
||||
size_t size;
|
||||
int mib[2];
|
||||
debug_decl(get_boottime, SUDO_DEBUG_UTIL)
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_BOOTTIME;
|
||||
size = sizeof(*tv);
|
||||
if (sysctl(mib, 2, tv, &size, NULL, 0) != -1)
|
||||
debug_return_bool(1);
|
||||
|
||||
debug_return_bool(0);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_GETUTXID)
|
||||
|
||||
int
|
||||
get_boottime(struct timeval *tv)
|
||||
{
|
||||
struct utmpx *ut, key;
|
||||
debug_decl(get_boottime, SUDO_DEBUG_UTIL)
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.ut_type = BOOT_TIME;
|
||||
setutxent();
|
||||
if ((ut = getutxid(&key)) != NULL) {
|
||||
tv->tv_sec = ut->ut_tv.tv_sec;
|
||||
tv->tv_usec = ut->ut_tv.tv_usec;
|
||||
}
|
||||
endutxent();
|
||||
debug_return_bool(ut != NULL);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_GETUTID)
|
||||
|
||||
int
|
||||
get_boottime(struct timeval *tv)
|
||||
{
|
||||
struct utmp *ut, key;
|
||||
debug_decl(get_boottime, SUDO_DEBUG_UTIL)
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.ut_type = BOOT_TIME;
|
||||
setutent();
|
||||
if ((ut = getutid(&key)) != NULL) {
|
||||
tv->tv_sec = ut->ut_time;
|
||||
tv->tv_usec = 0;
|
||||
}
|
||||
endutent();
|
||||
debug_return_bool(ut != NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
get_boottime(struct timeval *tv)
|
||||
{
|
||||
debug_decl(get_boottime, SUDO_DEBUG_UTIL)
|
||||
debug_return_bool(0);
|
||||
}
|
||||
#endif
|
@@ -325,6 +325,9 @@ void sudo_setspent(void);
|
||||
/* timestr.c */
|
||||
char *get_timestr(time_t, int);
|
||||
|
||||
/* boottime.c */
|
||||
int get_boottime(struct timeval *);
|
||||
|
||||
/* iolog.c */
|
||||
int io_set_max_sessid(const char *sessid);
|
||||
void io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]);
|
||||
|
@@ -359,6 +359,7 @@ timestamp_status(struct passwd *pw)
|
||||
struct timestamp_entry entry;
|
||||
struct timespec diff, timeout;
|
||||
int status = TS_ERROR; /* assume the worst */
|
||||
struct stat sb;
|
||||
int fd = -1;
|
||||
debug_decl(timestamp_status, SUDO_DEBUG_AUTH)
|
||||
|
||||
@@ -395,7 +396,6 @@ timestamp_status(struct passwd *pw)
|
||||
}
|
||||
timestamp_key.sid = user_sid;
|
||||
if (def_timestampdir) {
|
||||
struct stat sb;
|
||||
if (user_ttypath != NULL && stat(user_ttypath, &sb) == 0) {
|
||||
/* tty-based time stamp */
|
||||
timestamp_key.type = TS_TTY;
|
||||
@@ -415,16 +415,28 @@ timestamp_status(struct passwd *pw)
|
||||
/* Open time stamp file and lock it for exclusive access. */
|
||||
if (timestamp_uid != 0)
|
||||
set_perms(PERM_TIMESTAMP);
|
||||
fd = open(timestamp_file, O_RDONLY);
|
||||
fd = open(timestamp_file, O_RDWR);
|
||||
if (timestamp_uid != 0)
|
||||
restore_perms();
|
||||
if (fd == -1) {
|
||||
status = TS_MISSING;
|
||||
goto done;
|
||||
}
|
||||
lock_file(fd, SUDO_LOCK);
|
||||
|
||||
/* Ignore and clear time stamp file if mtime predates boot time. */
|
||||
if (fstat(fd, &sb) == 0) {
|
||||
struct timeval boottime, mtime;
|
||||
|
||||
mtim_get(&sb, &mtime);
|
||||
if (get_boottime(&boottime) && sudo_timevalcmp(&mtime, &boottime, <)) {
|
||||
ignore_result(ftruncate(fd, (off_t)0));
|
||||
status = TS_MISSING;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read existing record, if any. */
|
||||
lock_file(fd, SUDO_LOCK);
|
||||
if (!ts_find_record(fd, ×tamp_key, &entry)) {
|
||||
status = TS_MISSING;
|
||||
goto done;
|
||||
|
Reference in New Issue
Block a user