aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/audit/contrib/skeleton.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/audit/contrib/skeleton.c')
-rw-r--r--framework/src/audit/contrib/skeleton.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/framework/src/audit/contrib/skeleton.c b/framework/src/audit/contrib/skeleton.c
new file mode 100644
index 00000000..7e041042
--- /dev/null
+++ b/framework/src/audit/contrib/skeleton.c
@@ -0,0 +1,140 @@
+/* skeleton.c --
+ *
+ * This is a sample program that you can customize to create your own audit
+ * event handler. It will be started by auditd via the dispatcher option in
+ * /etc/audit/auditd.conf. This program can be built as follows:
+ *
+ * gcc skeleton.c -o skeleton -laudit
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <locale.h>
+#include "libaudit.h"
+
+
+// Local data
+static volatile int signaled = 0;
+static int pipe_fd;
+static const char *pgm = "skeleton";
+
+// Local functions
+static int event_loop(void);
+
+// SIGTERM handler
+static void term_handler( int sig )
+{
+ signaled = 1;
+}
+
+
+/*
+ * main is started by auditd. See dispatcher in auditd.conf
+ */
+int main(int argc, char *argv[])
+{
+ struct sigaction sa;
+
+ setlocale (LC_ALL, "");
+ openlog(pgm, LOG_PID, LOG_DAEMON);
+ syslog(LOG_NOTICE, "starting...");
+
+#ifndef DEBUG
+ // Make sure we are root
+ if (getuid() != 0) {
+ syslog(LOG_ERR, "You must be root to run this program.");
+ return 4;
+ }
+#endif
+
+ // register sighandlers
+ sa.sa_flags = 0 ;
+ sa.sa_handler = term_handler;
+ sigemptyset( &sa.sa_mask ) ;
+ sigaction( SIGTERM, &sa, NULL );
+ sa.sa_handler = term_handler;
+ sigemptyset( &sa.sa_mask ) ;
+ sigaction( SIGCHLD, &sa, NULL );
+ sa.sa_handler = SIG_IGN;
+ sigaction( SIGHUP, &sa, NULL );
+ (void)chdir("/");
+
+ // change over to pipe_fd
+ pipe_fd = dup(0);
+ close(0);
+ open("/dev/null", O_RDONLY);
+ fcntl(pipe_fd, F_SETFD, FD_CLOEXEC);
+
+ // Start the program
+ return event_loop();
+}
+
+static int event_loop(void)
+{
+ void *data;
+ struct iovec vec[2];
+ struct audit_dispatcher_header hdr;
+
+ // allocate data structures
+ data = malloc(MAX_AUDIT_MESSAGE_LENGTH);
+ if (data == NULL) {
+ syslog(LOG_ERR, "Cannot allocate buffer");
+ return 1;
+ }
+ memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
+ memset(&hdr, 0, sizeof(hdr));
+
+ do {
+ int rc;
+ struct timeval tv;
+ fd_set fd;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ FD_ZERO(&fd);
+ FD_SET(pipe_fd, &fd);
+ rc = select(pipe_fd+1, &fd, NULL, NULL, &tv);
+ if (rc == 0)
+ continue;
+ else if (rc == -1)
+ break;
+
+ /* Get header first. it is fixed size */
+ vec[0].iov_base = (void*)&hdr;
+ vec[0].iov_len = sizeof(hdr);
+ do {
+ rc = readv(fd, &vec[0], 1);
+ } while (rc < 0 && errno == EINTR);
+
+ if (rc > 0) {
+ // Next payload
+ vec[1].iov_base = data;
+ vec[1].iov_len = hdr.size;
+ do {
+ rc = readv(fd, &vec[1], 1);
+ } while (rc < 0 && errno == EINTR);
+ }
+ if (rc <= 0) {
+ syslog(LOG_ERR, "rc == %d(%s)", rc, strerror(errno));
+ continue;
+ }
+
+ // Handle events here. Just for illustration, we print
+ // to syslog, but you will want to do something else.
+ syslog(LOG_NOTICE,"type=%d, payload size=%d",
+ hdr.type, hdr.size);
+ syslog(LOG_NOTICE,"data=\"%.*s\"", hdr.size,
+ (char *)data);
+
+ } while(!signaled);
+
+ return 0;
+}
+