Imported Upstream version 2.4.3
[platform/upstream/audit.git] / contrib / skeleton.c
1 /* skeleton.c --
2  * 
3  * This is a sample program that you can customize to create your own audit
4  * event handler. It will be started by auditd via the dispatcher option in
5  * /etc/audit/auditd.conf. This program can be built as follows:
6  *
7  * gcc skeleton.c -o skeleton -laudit
8  */
9
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 #include <fcntl.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <locale.h>
20 #include "libaudit.h"
21
22
23 // Local data
24 static volatile int signaled = 0;
25 static int pipe_fd;
26 static const char *pgm = "skeleton";
27
28 // Local functions
29 static int event_loop(void);
30
31 // SIGTERM handler
32 static void term_handler( int sig )
33 {
34         signaled = 1;
35 }
36
37
38 /*
39  * main is started by auditd. See dispatcher in auditd.conf
40  */
41 int main(int argc, char *argv[])
42 {
43         struct sigaction sa;
44
45         setlocale (LC_ALL, "");
46         openlog(pgm, LOG_PID, LOG_DAEMON);
47         syslog(LOG_NOTICE, "starting...");
48
49 #ifndef DEBUG
50         // Make sure we are root
51         if (getuid() != 0) {
52                 syslog(LOG_ERR, "You must be root to run this program.");
53                 return 4;
54         }
55 #endif
56
57         // register sighandlers
58         sa.sa_flags = 0 ;
59         sa.sa_handler = term_handler;
60         sigemptyset( &sa.sa_mask ) ;
61         sigaction( SIGTERM, &sa, NULL );
62         sa.sa_handler = term_handler;
63         sigemptyset( &sa.sa_mask ) ;
64         sigaction( SIGCHLD, &sa, NULL );
65         sa.sa_handler = SIG_IGN;
66         sigaction( SIGHUP, &sa, NULL );
67         (void)chdir("/");
68
69         // change over to pipe_fd
70         pipe_fd = dup(0);
71         close(0);
72         open("/dev/null", O_RDONLY);
73         fcntl(pipe_fd, F_SETFD, FD_CLOEXEC);
74
75         // Start the program
76         return event_loop();
77 }
78
79 static int event_loop(void)
80 {
81         void *data;
82         struct iovec vec[2];
83         struct audit_dispatcher_header hdr;
84
85         // allocate data structures
86         data = malloc(MAX_AUDIT_MESSAGE_LENGTH);
87         if (data == NULL) {
88                 syslog(LOG_ERR, "Cannot allocate buffer");
89                 return 1;
90         }
91         memset(data, 0, MAX_AUDIT_MESSAGE_LENGTH);
92         memset(&hdr, 0, sizeof(hdr));
93
94         do {
95                 int rc;
96                 struct timeval tv;
97                 fd_set fd;
98
99                 tv.tv_sec = 1;
100                 tv.tv_usec = 0;
101                 FD_ZERO(&fd);
102                 FD_SET(pipe_fd, &fd);
103                 rc = select(pipe_fd+1, &fd, NULL, NULL, &tv);
104                 if (rc == 0) 
105                         continue;
106                  else if (rc == -1)
107                         break;
108
109                 /* Get header first. it is fixed size */
110                 vec[0].iov_base = (void*)&hdr;
111                 vec[0].iov_len = sizeof(hdr);
112                 do {
113                         rc = readv(fd, &vec[0], 1);
114                 } while (rc < 0 && errno == EINTR);
115
116                 if (rc > 0) {
117                         // Next payload 
118                         vec[1].iov_base = data;
119                         vec[1].iov_len = hdr.size; 
120                         do {
121                                 rc = readv(fd, &vec[1], 1);
122                         } while (rc < 0 && errno == EINTR);
123                 }
124                 if (rc <= 0) {
125                         syslog(LOG_ERR, "rc == %d(%s)", rc, strerror(errno));
126                         continue;
127                 }
128
129                 // Handle events here. Just for illustration, we print
130                 // to syslog, but you will want to do something else.
131                 syslog(LOG_NOTICE,"type=%d, payload size=%d", 
132                         hdr.type, hdr.size);
133                 syslog(LOG_NOTICE,"data=\"%.*s\"", hdr.size,
134                         (char *)data);
135
136         } while(!signaled);
137
138         return 0;
139 }
140