]> granicus.if.org Git - sudo/commitdiff
Convert from mono time to real time before displaying time stamps.
authorTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 12 Jan 2018 18:03:22 +0000 (11:03 -0700)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 12 Jan 2018 18:03:22 +0000 (11:03 -0700)
plugins/sudoers/tsdump.c

index 4cac78ce1bdc79c4265893f8fbfbe0a0b0d99251..45d5ebd566e74dd820fa0eab8c6e7de36b5d195d 100644 (file)
@@ -53,8 +53,9 @@ union timestamp_entry_storage {
 __dso_public int main(int argc, char *argv[]);
 
 static void usage(void) __attribute__((__noreturn__));
-static void dump_entry(union timestamp_entry_storage *u, off_t pos);
+static void dump_entry(struct timestamp_entry *entry, off_t pos);
 static bool valid_entry(union timestamp_entry_storage *u, off_t pos);
+static bool convert_entry(union timestamp_entry_storage *record, struct timespec *off);
 
 /*
  * tsdump: a simple utility to dump the contents of a time stamp file.
@@ -68,6 +69,7 @@ main(int argc, char *argv[])
     const char *user = NULL;
     char *fname = NULL;
     union timestamp_entry_storage cur;
+    struct timespec now, timediff;
     debug_decl(main, SUDOERS_DEBUG_MAIN)
 
 #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
@@ -104,6 +106,13 @@ main(int argc, char *argv[])
        usage();
     }
 
+    /* Calculate the difference between real time and mono time. */
+    if (sudo_gettime_real(&now) == -1)
+       sudo_fatal("unable to get current time");
+    if (sudo_gettime_mono(&timediff) == -1)
+       sudo_fatal("unable to read the clock");
+    sudo_timespecsub(&now, &timediff, &timediff);
+
     if (fname == NULL) {
        struct passwd *pw;
 
@@ -136,8 +145,12 @@ main(int argc, char *argv[])
            if (lseek(fd, offset, SEEK_CUR) == -1)
                sudo_fatal("unable to seek %d bytes", (int)offset);
        }
-       if (valid)
-           dump_entry(&cur, pos);
+       if (valid) {
+           /* Convert entry to latest version as needed. */
+           if (!convert_entry(&cur, &timediff))
+               continue;
+           dump_entry(&cur.v2, pos);
+       }
     }
 
     return 0;
@@ -220,46 +233,52 @@ print_flags(int flags)
 
 /*
  * Convert an older entry to current.
+ * Also adjusts time stamps on Linux to be wallclock time.
  */
 static bool
-convert_entry(union timestamp_entry_storage *record)
+convert_entry(union timestamp_entry_storage *record, struct timespec *off)
 {
     union timestamp_entry_storage orig;
     debug_decl(convert_entry, SUDOERS_DEBUG_UTIL)
 
-    if (record->common.version != 1) {
-       sudo_warnx("unexpected record version %hu", record->common.version);
-       debug_return_bool(false);
+    if (record->common.version != TS_VERSION) {
+       if (record->common.version != 1) {
+           sudo_warnx("unexpected record version %hu", record->common.version);
+           debug_return_bool(false);
+       }
+
+       /* The first four fields are the same regardless of version. */
+       memcpy(&orig, record, sizeof(union timestamp_entry_storage));
+       record->v2.auth_uid = orig.v1.auth_uid;
+       record->v2.sid = orig.v1.sid;
+       sudo_timespecclear(&record->v2.start_time);
+       record->v2.ts = orig.v1.ts;
+       if (record->common.type == TS_TTY)
+           record->v2.u.ttydev = orig.v1.u.ttydev;
+       else if (record->common.type == TS_PPID)
+           record->v2.u.ppid = orig.v1.u.ppid;
+       else
+           memset(&record->v2.u, 0, sizeof(record->v2.u));
     }
 
-    /* The first four fields are the same regardless of version. */
-    memcpy(&orig, record, sizeof(union timestamp_entry_storage));
-    record->v2.auth_uid = orig.v1.auth_uid;
-    record->v2.sid = orig.v1.sid;
-    sudo_timespecclear(&record->v2.start_time);
-    record->v2.ts = orig.v1.ts;
-    if (record->common.type == TS_TTY)
-       record->v2.u.ttydev = orig.v1.u.ttydev;
-    else if (record->common.type == TS_PPID)
-       record->v2.u.ppid = orig.v1.u.ppid;
-    else
-       memset(&record->v2.u, 0, sizeof(record->v2.u));
+    /* On Linux, start time is relative to boot time, adjust to real time. */
+#ifdef __linux__
+    if (sudo_timespecisset(&record->v2.start_time))
+       sudo_timespecadd(&record->v2.start_time, off, &record->v2.start_time);
+#endif
+
+    /* Adjust time stamp from mono time to real time. */
+    if (sudo_timespecisset(&record->v2.ts))
+       sudo_timespecadd(&record->v2.ts, off, &record->v2.ts);
 
     debug_return_bool(true);
 }
 
 static void
-dump_entry(union timestamp_entry_storage *u, off_t pos)
+dump_entry(struct timestamp_entry *entry, off_t pos)
 {
-    struct timestamp_entry *entry = (struct timestamp_entry *)u;
     debug_decl(dump_entry, SUDOERS_DEBUG_UTIL)
 
-    /* Convert to latest version as needed. */
-    if (u->common.version != TS_VERSION) {
-       if (!convert_entry(u))
-           debug_return;
-    }
-
     printf("position: %lld\n", (long long)pos);
     printf("version: %hu\n", entry->version);
     printf("size: %hu\n", entry->size);