From 88058a71e27a5b4ded2879b774aaf1c1a15944ca Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 21 Mar 2007 14:12:05 +0100 Subject: [PATCH] hwclock: add support for audit system 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 Signed-off-by: Karel Zak --- hwclock/Makefile.am | 5 ++++ hwclock/clock.h | 7 ++++++ hwclock/hwclock.c | 61 +++++++++++++++++++++++++++++++++++++-------- hwclock/kd.c | 4 +-- hwclock/rtc.c | 6 ++--- 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/hwclock/Makefile.am b/hwclock/Makefile.am index d2de98229..80207d0d4 100644 --- a/hwclock/Makefile.am +++ b/hwclock/Makefile.am @@ -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 diff --git a/hwclock/clock.h b/hwclock/clock.h index f1d00e493..39971f721 100644 --- a/hwclock/clock.h +++ b/hwclock/clock.h @@ -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 diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c index 820c388d4..7cb0ca27d 100644 --- a/hwclock/hwclock.c +++ b/hwclock/hwclock.c @@ -85,6 +85,12 @@ #include "clock.h" #include "nls.h" +#ifdef HAVE_LIBAUDIT +#include +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: diff --git a/hwclock/kd.c b/hwclock/kd.c index 2c10342fd..b9f8d74d5 100644 --- a/hwclock/kd.c +++ b/hwclock/kd.c @@ -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; } diff --git a/hwclock/rtc.c b/hwclock/rtc.c index 33be42bbe..dddb1e372 100644 --- a/hwclock/rtc.c +++ b/hwclock/rtc.c @@ -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)