]> err.no Git - util-linux/commitdiff
hwclock: add support for audit system
authorKarel Zak <kzak@redhat.com>
Wed, 21 Mar 2007 13:12:05 +0000 (14:12 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 21 Mar 2007 13:12:05 +0000 (14:12 +0100)
If you compile --with-audit the hwclock tool reports changes in sys/hw clock to
audit system. The real long-term and final solution is probably add hooks for
/dev/rtc to kernel, but it's not implemented yet.

Signed-off-by: Steve Grubb <sgrubb@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
hwclock/Makefile.am
hwclock/clock.h
hwclock/hwclock.c
hwclock/kd.c
hwclock/rtc.c

index d2de98229701e860f768b637590bc2ea2f4859ff..80207d0d4aea261f17cb99a896753f6807f93626 100644 (file)
@@ -5,5 +5,10 @@ man_MANS = hwclock.8
 sbin_PROGRAMS = hwclock
 
 hwclock_SOURCES = hwclock.c cmos.c rtc.c kd.c clock.h
+hwclock_LDADD =
+
+if HAVE_AUDIT
+hwclock_LDADD += -laudit
+endif
 
 EXTRA_DIST = README.* clock-ppc.c
index f1d00e49381f0b16d0d66c1711b69dbc0ee25bc0..39971f7217b8df2af8430f65b88d124f6bacd342 100644 (file)
@@ -34,3 +34,10 @@ extern void set_cmos_access(int Jensen, int funky_toy);
 extern int get_epoch_rtc(unsigned long *epoch, int silent);
 extern int set_epoch_rtc(unsigned long epoch);
 extern char *rtc_dev_name;
+
+#ifdef HAVE_LIBAUDIT
+extern void hwaudit_exit(int status);
+# define hwclock_exit(_status) hwaudit_exit(_status)
+#else
+# define hwclock_exit(_status) exit(_status)
+#endif
index 820c388d45ff8b6ea8a38e9fa0337864ee507126..7cb0ca27d7943fd1bba4f92a344c8a2684f79147 100644 (file)
 #include "clock.h"
 #include "nls.h"
 
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+static int hwaudit_fd = -1;
+static int hwaudit_on;
+#endif
+
 #define MYNAME "hwclock"
 
 char *progname = MYNAME;
@@ -1240,7 +1246,7 @@ usage( const char *fmt, ... ) {
     va_end(ap);
   }
  
-  exit(fmt ? EX_USAGE : 0);
+  hwclock_exit(fmt ? EX_USAGE : 0);
 }
 
 static const struct option longopts[] = {
@@ -1305,6 +1311,17 @@ main(int argc, char **argv) {
        /* Remember what time we were invoked */
        gettimeofday(&startup_time, NULL);
 
+#ifdef HAVE_LIBAUDIT
+       hwaudit_fd = audit_open();
+       if (hwaudit_fd < 0 && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
+                               errno == EAFNOSUPPORT)) {
+               /* You get these error codes only when the kernel doesn't have
+                * audit compiled in. */
+               fprintf(stderr, _("%s: Unable to connect to audit system\n"),
+                               MYNAME);
+               return EX_NOPERM;
+       }
+#endif
        setlocale(LC_ALL, "");
 #ifdef LC_NUMERIC
        /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
@@ -1403,6 +1420,14 @@ main(int argc, char **argv) {
        argc -= optind;
        argv += optind;
 
+#ifdef HAVE_LIBAUDIT
+       if (testing != TRUE) {
+               if (adjust == TRUE || hctosys == TRUE || systohc == TRUE ||
+                                       set == TRUE || setepoch == TRUE) {
+                       hwaudit_on = TRUE;
+               }
+       }
+#endif
        if (argc > 0) {
                usage(_("%s takes no non-option arguments.  "
                        "You supplied %d.\n"),
@@ -1413,27 +1438,27 @@ main(int argc, char **argv) {
                fprintf(stderr, _("You have specified multiple functions.\n"
                                  "You can only perform one function "
                                  "at a time.\n"));
-               exit(EX_USAGE);
+               hwclock_exit(EX_USAGE);
        }
 
        if (utc && local_opt) {
                fprintf(stderr, _("%s: The --utc and --localtime options "
                                  "are mutually exclusive.  You specified "
                                  "both.\n"), MYNAME);
-               exit(EX_USAGE);
+               hwclock_exit(EX_USAGE);
        }
 
        if (adjust && noadjfile) {
                fprintf(stderr, _("%s: The --adjust and --noadjfile options "
                                  "are mutually exclusive.  You specified "
                                  "both.\n"), MYNAME);
-               exit(EX_USAGE);
+               hwclock_exit(EX_USAGE);
        }
 
        if (noadjfile && !(utc || local_opt)) {
                fprintf(stderr, _("%s: With --noadjfile, you must specify "
                                  "either --utc or --localtime\n"), MYNAME);
-               exit(EX_USAGE);
+               hwclock_exit(EX_USAGE);
        }
 
 #ifdef __alpha__
@@ -1447,7 +1472,7 @@ main(int argc, char **argv) {
                if (rc != 0) {
                        fprintf(stderr, _("No usable set-to time.  "
                                          "Cannot set clock.\n"));
-                       exit(EX_USAGE);
+                       hwclock_exit(EX_USAGE);
                }
        }
 
@@ -1479,11 +1504,11 @@ main(int argc, char **argv) {
        }
 
        if (!permitted)
-               exit(EX_NOPERM);
+               hwclock_exit(EX_NOPERM);
 
        if (getepoch || setepoch) {
                manipulate_epoch(getepoch, setepoch, epoch_option, testing);
-               return 0;
+               hwclock_exit(0);
        }
 
        if (debug)
@@ -1497,12 +1522,14 @@ main(int argc, char **argv) {
                        fprintf(stderr,
                                _("Use the --debug option to see the details "
                                  "of our search for an access method.\n"));
-               exit(1);
+               hwclock_exit(1);
        }
 
-       return manipulate_clock(show, adjust, noadjfile, set, set_time,
+       rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
                                hctosys, systohc, startup_time, utc,
                                local_opt, testing);
+       hwclock_exit(rc);
+       return rc;      /* Not reached */
 }
 
 /* A single routine for greater uniformity */
@@ -1519,6 +1546,20 @@ outsyserr(char *msg, ...) {
                errsv, strerror(errsv));
 }
 
+
+#ifdef HAVE_LIBAUDIT
+void
+hwaudit_exit(int status)
+{
+       if (hwaudit_on) {
+               audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
+                       "changing system time", NULL, NULL, NULL, status ? 0 : 1);
+               close(hwaudit_fd);
+       }
+       exit(status);
+}
+#endif
+
 /****************************************************************************
 
   History of this program:
index 2c10342fdbc5e05506d7542767ffd78c0614ee0d..b9f8d74d573c47b12854db14c7590044d0191b5e 100644 (file)
@@ -103,7 +103,7 @@ read_hardware_clock_kd(struct tm *tm) {
 
   if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
     outsyserr(_("ioctl() failed to read time from %s"), con_fd_filename);
-    exit(EX_IOERR);
+    hwclock_exit(EX_IOERR);
   }
 
   tm->tm_sec  = t.sec;
@@ -139,7 +139,7 @@ set_hardware_clock_kd(const struct tm *new_broken_time) {
 
   if (ioctl(con_fd, KDSHWCLK, &t ) == -1) {
     outsyserr(_("ioctl KDSHWCLK failed"));
-    exit(1);
+    hwclock_exit(1);
   }
   return 0;
 }
index 33be42bbecf2e9bb42ee8dce08c5e7b402520e38..dddb1e372dbc98ac76076af3b81739b669e032e4 100644 (file)
@@ -131,7 +131,7 @@ open_rtc_or_exit(void) {
 
        if (rtc_fd < 0) {
                outsyserr(_("open() of %s failed"), rtc_dev_name);
-               exit(EX_OSFILE);
+               hwclock_exit(EX_OSFILE);
        }
        return rtc_fd;
 }
@@ -166,7 +166,7 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
                perror(ioctlname);
                fprintf(stderr, _("ioctl() to %s to read the time failed.\n"),
                        rtc_dev_name);
-               exit(EX_IOERR);
+               hwclock_exit(EX_IOERR);
        }
 
        tm->tm_isdst = -1;          /* don't know whether it's dst */
@@ -346,7 +346,7 @@ set_hardware_clock_rtc(const struct tm *new_broken_time) {
                perror(ioctlname);
                fprintf(stderr, _("ioctl() to %s to set the time failed.\n"),
                        rtc_dev_name);
-               exit(EX_IOERR);
+               hwclock_exit(EX_IOERR);
        }
 
        if (debug)