From f8e5c55a036f0e2e2a958e30456270f3f9eba933 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 14:52:13 +0200 Subject: Adding upstream version 1.9.5p2. Signed-off-by: Daniel Baumann --- plugins/sudoers/boottime.c | 167 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 plugins/sudoers/boottime.c (limited to 'plugins/sudoers/boottime.c') diff --git a/plugins/sudoers/boottime.c b/plugins/sudoers/boottime.c new file mode 100644 index 0000000..78f3279 --- /dev/null +++ b/plugins/sudoers/boottime.c @@ -0,0 +1,167 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2009-2015, 2018 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. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#include /* for size_t, ssize_t */ +#include + +#include +#include +#include +#include +#include +#include +#ifndef __linux__ +# if defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME) +# include +# elif defined(HAVE_GETUTXID) +# include +# elif defined(HAVE_GETUTID) +# include +# endif +#endif /* !__linux__ */ + +#include "sudoers.h" + +/* + * Fill in a struct timespec with the time the system booted. + * Returns 1 on success and 0 on failure. + */ + +#if defined(__linux__) +bool +get_boottime(struct timespec *ts) +{ + char *line = NULL; + size_t linesize = 0; + bool found = false; + long long llval; + ssize_t len; + FILE *fp; + debug_decl(get_boottime, SUDOERS_DEBUG_UTIL); + + /* read btime from /proc/stat */ + fp = fopen("/proc/stat", "r"); + if (fp != NULL) { + while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) { + if (strncmp(line, "btime ", 6) == 0) { + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + llval = sudo_strtonum(line + 6, 1, LLONG_MAX, NULL); + if (llval > 0) { + ts->tv_sec = (time_t)llval; + ts->tv_nsec = 0; + found = true; + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "found btime in /proc/stat: %lld", llval); + break; + } else { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "invalid btime in /proc/stat: %s", line); + } + } + } + fclose(fp); + free(line); + } + + debug_return_bool(found); +} + +#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME) + +bool +get_boottime(struct timespec *ts) +{ + size_t size; + int mib[2]; + struct timeval tv; + debug_decl(get_boottime, SUDOERS_DEBUG_UTIL); + + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + size = sizeof(tv); + if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "KERN_BOOTTIME: %lld, %ld", (long long)tv.tv_sec, (long)tv.tv_usec); + TIMEVAL_TO_TIMESPEC(&tv, ts); + debug_return_bool(true); + } + + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "KERN_BOOTTIME: %s", strerror(errno)); + debug_return_bool(false); +} + +#elif defined(HAVE_GETUTXID) + +bool +get_boottime(struct timespec *ts) +{ + struct utmpx *ut, key; + debug_decl(get_boottime, SUDOERS_DEBUG_UTIL); + + memset(&key, 0, sizeof(key)); + key.ut_type = BOOT_TIME; + setutxent(); + if ((ut = getutxid(&key)) != NULL) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "BOOT_TIME: %lld, %ld", (long long)ut->ut_tv.tv_sec, + (long)ut->ut_tv.tv_usec); + TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts); + } + endutxent(); + debug_return_bool(ut != NULL); +} + +#elif defined(HAVE_GETUTID) + +bool +get_boottime(struct timespec *ts) +{ + struct utmp *ut, key; + debug_decl(get_boottime, SUDOERS_DEBUG_UTIL); + + memset(&key, 0, sizeof(key)); + key.ut_type = BOOT_TIME; + setutent(); + if ((ut = getutid(&key)) != NULL) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "BOOT_TIME: %lld", (long long)ut->ut_time); + ts->tv_sec = ut->ut_time; + ts->tv_nsec = 0; + } + endutent(); + debug_return_bool(ut != NULL); +} + +#else + +bool +get_boottime(struct timespec *ts) +{ + debug_decl(get_boottime, SUDOERS_DEBUG_UTIL); + debug_return_bool(false); +} +#endif -- cgit v1.2.3