[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[RFC][PATCH] auditfs userspace



Here's the userspace patch for audit-0.6.5 -- It doesn't work as is.  

To get this working I had to make a directory audit-0.6.5/linux and cp
/ ln -s audit.h into it.  The patch should do this for you.  However,
you will have to 'install -m 0644 lib/libaudit.h audit-0.6.5/'
yourself.

cd audit-0.6.5/
autoreconf -fv --install
./configure --sbindir=/path/to/sbin --libdir=/lib --with-pam=yes/no
install -m 0644 lib/libaudit.h .
make

It's probably just best to not "make install" and just cd src/ and run
auditctl from there for testing the auditfs kernel piece.  I'm hoping
that some form of this code will eventually be integrated into the
userspace tool.

So please break..er test my code :)

-- 
- Timothy R. Chavez
diff -Nurp audit-0.6.5/lib/libaudit.c audit-0.6.5-scratch/lib/libaudit.c
--- audit-0.6.5/lib/libaudit.c	2005-03-03 15:52:55.000000000 -0600
+++ audit-0.6.5-scratch/lib/libaudit.c	2005-03-07 15:48:15.000000000 -0600
@@ -96,6 +96,16 @@ int audit_is_enabled(int fd)
 	return -1;
 }
 
+int audit_set_fsenabled(int fd, int enabled)
+{
+    struct audit_status s;
+
+    memset(&s, 0, sizeof(s));
+    s.mask	= AUDIT_STATUS_FSENABLED;
+    s.fs_enabled= enabled;
+    return audit_send(fd, AUDIT_SET, &s, sizeof(s));
+}
+
 int audit_set_failure(int fd, int failure)
 {
     struct audit_status s;
@@ -196,6 +206,17 @@ uid_t audit_getloginuid(void)
 		return uid;
 }
 
+/* req->namelen is used for kernel->user traffic only */
+int audit_insert_watch(int fd, struct audit_watch *req)
+{
+    return audit_send(fd, AUDIT_WATCH_INS, req, sizeof(*req));
+}
+
+int audit_remove_watch(int fd, struct audit_watch *req)
+{
+    return audit_send(fd, AUDIT_WATCH_REM, req, sizeof(*req));
+}
+
 int audit_send_message(int fd, const char *message)
 {
     if (fd >= 0) {
diff -Nurp audit-0.6.5/lib/libaudit.h audit-0.6.5-scratch/lib/libaudit.h
--- audit-0.6.5/lib/libaudit.h	2005-02-26 11:13:30.000000000 -0600
+++ audit-0.6.5-scratch/lib/libaudit.h	2005-03-07 15:52:00.000000000 -0600
@@ -44,6 +44,7 @@ struct audit_reply {
     struct audit_status  *status;
     struct audit_rule    *rule;
     struct audit_login   *login;
+    int			watch;
     const char           *message;
     struct nlmsgerr      *error;
 };
@@ -89,6 +90,7 @@ extern int audit_is_enabled(int fd);
 
 /* AUDIT_SET */
 extern int  audit_set_enabled(int fd, int enabled);
+extern int  audit_set_fsenabled(int fs, int enabled);
 extern int  audit_set_failure(int fd, int failure);
 extern int  audit_set_pid(int fd, int pid);
 extern int  audit_set_rate_limit(int fd, int limit);
@@ -118,6 +120,11 @@ extern int  audit_set_loginuid(uid_t uid
 extern int  audit_login_message(int fd, const char *arg);
 extern int  audit_logout_message(int fd, const char *arg);
 
+/* INSERT WATCH */
+extern int audit_insert_watch(int fd, struct audit_watch *req);
+/* REMOVE WATCH */
+extern int audit_remove_watch(int fd, struct audit_watch *req);
+
 /* Rule-building helper functions */
 extern struct audit_rule *audit_rule_alloc(void);
 extern int  audit_rule_syscall(struct audit_rule *rule, int syscall);
diff -Nurp audit-0.6.5/lib/netlink.c audit-0.6.5-scratch/lib/netlink.c
--- audit-0.6.5/lib/netlink.c	2005-03-03 15:33:59.000000000 -0600
+++ audit-0.6.5-scratch/lib/netlink.c	2005-03-07 15:55:34.000000000 -0600
@@ -124,6 +124,7 @@ static int adjust_reply(struct audit_rep
     rep->type    = rep->msg.nlh.nlmsg_type;
     rep->len     = rep->msg.nlh.nlmsg_len;
     rep->nlh     = &rep->msg.nlh;
+    rep->watch		= 0;
     rep->status  = NULL;
     rep->rule    = NULL;
     rep->message = NULL;
@@ -146,6 +147,10 @@ static int adjust_reply(struct audit_rep
     case AUDIT_USER:  
 	rep->message = NLMSG_DATA(rep->nlh); 
 	break;
+    case AUDIT_WATCH_INS:
+    case AUDIT_WATCH_REM:
+	memcpy(&rep->watch, NLMSG_DATA(rep->nlh), sizeof(int));
+	break;
     }
     return len;
 }
diff -Nurp audit-0.6.5/linux/audit.h audit-0.6.5-scratch/linux/audit.h
--- audit-0.6.5/linux/audit.h	1969-12-31 17:00:00.000000000 -0700
+++ audit-0.6.5-scratch/linux/audit.h	2005-03-07 15:48:44.000000000 -0600
@@ -0,0 +1,259 @@
+/* audit.h -- Auditing support -*- linux-c -*-
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Written by Rickard E. (Rik) Faith <faith redhat com>
+ *
+ */
+
+#ifndef _LINUX_AUDIT_H_
+#define _LINUX_AUDIT_H_
+
+/* Request and reply types */
+#define AUDIT_GET      	1000	/* Get status */
+#define AUDIT_SET      	1001	/* Set status (enable/disable/auditd) */
+#define AUDIT_LIST     	1002	/* List filtering rules */
+#define AUDIT_ADD      	1003	/* Add filtering rule */
+#define AUDIT_DEL      	1004	/* Delete filtering rule */
+#define AUDIT_USER     	1005	/* Send a message from user-space */
+#define AUDIT_LOGIN    	1006    /* Define the login id and information */
+#define AUDIT_WATCH_INS	1007    /* Insert file/dir watch entry */
+#define AUDIT_WATCH_REM	1008	/* Remove file/dir watch entry */
+#define AUDIT_KERNEL   	2000	/* Asynchronous audit record. NOT A REQUEST. */
+
+/* Rule flags */
+#define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
+#define AUDIT_AT_ENTRY 0x02	/* Apply rule at syscall entry */
+#define AUDIT_AT_EXIT  0x04	/* Apply rule at syscall exit */
+#define AUDIT_PREPEND  0x10	/* Prepend to front of list */
+
+/* Rule actions */
+#define AUDIT_NEVER    0	/* Do not build context if rule matches */
+#define AUDIT_POSSIBLE 1	/* Build context if rule matches  */
+#define AUDIT_ALWAYS   2	/* Generate audit record if rule matches */
+
+/* Rule structure sizes -- if these change, different AUDIT_ADD and
+ * AUDIT_LIST commands must be implemented. */
+#define AUDIT_MAX_FIELDS   64
+#define AUDIT_BITMASK_SIZE 64
+#define AUDIT_WORD(nr) ((__u32)((nr)/32))
+#define AUDIT_BIT(nr)  (1 << ((nr) - AUDIT_WORD(nr)*32))
+
+/* Rule fields */
+				/* These are useful when checking the
+				 * task structure at task creation time
+				 * (AUDIT_PER_TASK).  */
+#define AUDIT_PID	0
+#define AUDIT_UID	1
+#define AUDIT_EUID	2
+#define AUDIT_SUID	3
+#define AUDIT_FSUID	4
+#define AUDIT_GID	5
+#define AUDIT_EGID	6
+#define AUDIT_SGID	7
+#define AUDIT_FSGID	8
+#define AUDIT_LOGINUID	9
+#define AUDIT_PERS	10
+
+				/* These are ONLY useful when checking
+				 * at syscall exit time (AUDIT_AT_EXIT). */
+#define AUDIT_DEVMAJOR	100
+#define AUDIT_DEVMINOR	101
+#define AUDIT_INODE	102
+#define AUDIT_EXIT	103
+#define AUDIT_SUCCESS   104	/* exit >= 0; value ignored */
+
+#define AUDIT_ARG0      200
+#define AUDIT_ARG1      (AUDIT_ARG0+1)
+#define AUDIT_ARG2      (AUDIT_ARG0+2)
+#define AUDIT_ARG3      (AUDIT_ARG0+3)
+
+#define AUDIT_NEGATE    0x80000000
+
+
+/* Status symbols */
+				/* Mask values */
+#define AUDIT_STATUS_ENABLED		0x0001
+#define AUDIT_STATUS_FAILURE		0x0002
+#define AUDIT_STATUS_PID		0x0004
+#define AUDIT_STATUS_RATE_LIMIT		0x0008
+#define AUDIT_STATUS_BACKLOG_LIMIT	0x0010
+#define AUDIT_STATUS_FSENABLED		0x0020
+				/* Failure-to-log actions */
+#define AUDIT_FAIL_SILENT	0
+#define AUDIT_FAIL_PRINTK	1
+#define AUDIT_FAIL_PANIC	2
+
+/* 32 byte max key size */
+#define AUDIT_FILTERKEY_MAX	32
+
+#ifndef __KERNEL__
+struct audit_message {
+	struct nlmsghdr nlh;
+	char		data[1200];
+};
+#endif
+
+struct audit_status {
+	__u32		mask;		/* Bit mask for valid entries */
+	__u32		enabled;	/* 1 = enabled, 0 = disbaled */
+	__u32		fs_enabled;	/* 1 = fs auditing on, 0 = off */ 
+	__u32		failure;	/* Failure-to-log action */
+	__u32		pid;		/* pid of auditd process */
+	__u32		rate_limit;	/* messages rate limit (per second) */
+	__u32		backlog_limit;	/* waiting messages limit */
+	__u32		lost;		/* messages lost */
+	__u32		backlog;	/* messages waiting in queue */
+};
+
+struct audit_rule {		/* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
+	__u32		flags;	/* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
+	__u32		action;	/* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
+	__u32		field_count;
+	__u32		mask[AUDIT_BITMASK_SIZE];
+	__u32		fields[AUDIT_MAX_FIELDS];
+	__u32		values[AUDIT_MAX_FIELDS];
+};
+
+struct audit_watch {
+	int	namelen;
+	int 	fklen;
+	char	*name;
+	char	*filterkey;
+	__u32	perms;
+};
+
+#ifdef __KERNEL__
+
+struct audit_data {
+	struct audit_wentry	*wentry;
+	struct list_head 	watchlist;
+	rwlock_t 		watchlist_lock;
+	atomic_t		count;
+};
+
+struct audit_wentry {
+	struct list_head 	w_list;
+	atomic_t 		w_count;
+	struct audit_data 	*w_data;
+	struct audit_watch	*w_watch;
+	int			w_valid;
+};
+
+#ifdef CONFIG_AUDIT
+struct audit_buffer;
+struct audit_context;
+#endif
+
+#ifdef CONFIG_AUDITSYSCALL
+struct inode;
+/* These are defined in auditsc.c */
+				/* Public API */
+extern int  audit_alloc(struct task_struct *task);
+extern void audit_free(struct task_struct *task);
+extern void audit_syscall_entry(struct task_struct *task,
+				int major, unsigned long a0, unsigned long a1,
+				unsigned long a2, unsigned long a3);
+extern void audit_syscall_exit(struct task_struct *task, int return_code);
+extern void audit_getname(const char *name);
+extern void audit_putname(const char *name);
+extern void audit_inode(const char *name, unsigned long ino, dev_t rdev);
+
+				/* Private API (for audit.c only) */
+extern int  audit_receive_filter(int type, int pid, int uid, int seq,
+				 void *data);
+extern void audit_get_stamp(struct audit_context *ctx,
+			    struct timespec *t, int *serial);
+extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+extern uid_t audit_get_loginuid(struct audit_context *ctx);
+extern int audit_notify_watch(struct inode *inode, int mask);
+#else
+#define audit_alloc(t) ({ 0; })
+#define audit_free(t) do { ; } while (0)
+#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0)
+#define audit_syscall_exit(t,r) do { ; } while (0)
+#define audit_getname(n) do { ; } while (0)
+#define audit_putname(n) do { ; } while (0)
+#define audit_inode(n,i,d) do { ; } while (0)
+#define audit_get_loginuid(c) ({ -1; })
+#define audit_notify_watch(i,m) ({ 0; })
+#endif
+
+#ifdef CONFIG_AUDITFILESYSTEM
+extern void audit_receive_watch(int type, int pid, int uid, int seq, 
+			       struct audit_watch *req);
+extern void audit_filesystem_init(void);
+extern void audit_inode_alloc(struct inode *inode);
+extern void audit_inode_free(struct inode *inode);
+extern void audit_watch(struct dentry *dentry, int drain);
+extern void audit_wentry_put(struct audit_wentry *wentry);
+extern struct audit_wentry *audit_wentry_get(struct audit_wentry *wentry);
+#else
+#define audit_receive_watch(t,p,u,s,r) do { ; } while(0)
+#define audit_filesystem_init() do { ; } while(0)
+#define audit_inode_alloc(i) do { ; } while(0)
+#define audit_inode_free(i) do { ; } while(0)
+#define audit_watch(dt,d) do { ; } while (0)
+#define audit_watch_put(w) do { ; } while(0)
+#define audit_watch_get(w) ({ 0; })
+#endif 
+
+#ifdef CONFIG_AUDIT
+/* These are defined in audit.c */
+				/* Public API */
+extern void		    audit_log(struct audit_context *ctx,
+				      const char *fmt, ...)
+			    __attribute__((format(printf,2,3)));
+
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern void		    audit_log_format(struct audit_buffer *ab,
+					     const char *fmt, ...)
+			    __attribute__((format(printf,2,3)));
+extern void		    audit_log_end(struct audit_buffer *ab);
+extern void		    audit_log_end_fast(struct audit_buffer *ab);
+extern void		    audit_log_end_irq(struct audit_buffer *ab);
+extern void		    audit_log_d_path(struct audit_buffer *ab,
+					     const char *prefix,
+					     struct dentry *dentry,
+					     struct vfsmount *vfsmnt);
+extern int		    audit_set_rate_limit(int limit);
+extern int		    audit_set_backlog_limit(int limit);
+extern int		    audit_set_enabled(int state);
+extern int		    audit_set_failure(int state);
+
+				/* Private API (for auditsc.c only) */
+extern void		    audit_send_reply(int pid, int seq, int type,
+					     int done, int multi,
+					     void *payload, int size);
+extern void		    audit_log_lost(const char *message);
+#else
+#define audit_log(t,f,...) do { ; } while (0)
+#define audit_log_start(t) ({ NULL; })
+#define audit_log_vformat(b,f,a) do { ; } while (0)
+#define audit_log_format(b,f,...) do { ; } while (0)
+#define audit_log_end(b) do { ; } while (0)
+#define audit_log_end_fast(b) do { ; } while (0)
+#define audit_log_end_irq(b) do { ; } while (0)
+#define audit_log_d_path(b,p,d,v) do { ; } while (0)
+#define audit_set_rate_limit(l) do { ; } while (0)
+#define audit_set_backlog_limit(l) do { ; } while (0)
+#define audit_set_enabled(s) do { ; } while (0)
+#define audit_set_failure(s) do { ; } while (0)
+#endif
+#endif
+#endif
diff -Nurp audit-0.6.5/src/auditctl.c audit-0.6.5-scratch/src/auditctl.c
--- audit-0.6.5/src/auditctl.c	2005-03-03 10:11:00.000000000 -0600
+++ audit-0.6.5-scratch/src/auditctl.c	2005-03-07 15:56:19.000000000 -0600
@@ -49,6 +49,14 @@
  */
 #define LINE_SIZE 1600
 
+#define WATCH_MAY_EXEC		1
+#define WATCH_MAY_WRITE		2
+#define WATCH_MAY_READ		4
+#define WATCH_MAY_APPEND	8
+
+#define WATCH_NAME		1
+#define WATCH_FILTERKEY		2
+#define WATCH_PERMS		3
 
 /* Global functions */
 static int handle_request(int status);
@@ -61,7 +69,9 @@ static int fd = -1;
 static int list_requested = 0;
 static int syscalladded = 0;
 static int add = 0, del = 0, action = 0;
+static int ins = 0, rem = 0;
 static struct audit_rule  rule;
+static struct audit_watch watch;
 
 /*
  * This function will reset everything used for each loop when loading 
@@ -73,8 +83,11 @@ static int reset_vars(void)
 	syscalladded = 0;
 	add = 0;
 	del = 0;
+	ins = 0;
+	rem = 0;
 	action = 0;
 	memset(&rule, 0, sizeof(rule));
+	memset(&watch, 0, sizeof(watch));
 	if ((fd = audit_open()) < 0) {
 		fprintf(stderr, "Cannot open netlink audit socket\n");
 		return 1;
@@ -93,6 +106,7 @@ static void usage(void)
      "                    l=task,entry,exit a=never,possible,always\n"
      "       -D           Delete all rules\n"
      "       -e [0|1]     Set enabled flag\n"
+     "       -E [0|1]     Enable filesystem auditing\n"
      "       -f [0..2]    Set failure flag\n"
      "                    0=silent 1=printk 2=panic\n"
      "       -F f=v       Build rule: field name, value\n"
@@ -104,6 +118,11 @@ static void usage(void)
      "       -s           Report status\n"
      "       -S syscall   Build rule: syscall name or number\n"
      "       -t <syscall> Translate syscall number to syscall name\n"
+     "       -w <path>    Insert watch at <path>\n"
+     "       -W <path>    Remove watch at <path>\n"
+     "       -p [r|w|e|a] Set permissions filter on watch:\n"
+     "                      r=read, w=write, e=execute, a=append\n"
+     "       -k <key>     Set filterkey on watch\n"
      );
 }
 
@@ -128,6 +147,84 @@ static int audit_rule_setup(const char *
     return 0;
 }
 
+/* Setup a watch.  The "name" of the watch in userspace will be the <path> to
+ * the watch.  When this potential watch reaches the kernel, it will resolve
+ * down to <name> (of terminating file or directory).
+ */ 
+static int audit_watch_setup(int type, struct audit_watch *req,
+			     const char *opt)
+{
+	int i;
+	int ret = 0;
+	
+	if (!opt)
+		goto audit_watch_setup_exit;
+
+	switch (type) {
+		case WATCH_NAME:
+			if (!req->name && opt) {
+				req->namelen = strlen(opt) + 1;
+	    			req->name = (char *) malloc(req->namelen);
+	    			if (!req->name)
+	    				goto audit_watch_setup_exit;
+	    			strcpy(req->name, opt);
+	    			ret = 1;
+			}
+		break;
+    		case WATCH_FILTERKEY:
+			if (!req->filterkey && opt) {
+	    			req->fklen = strlen(opt) + 1;
+	    			req->filterkey = (char *) malloc(req->fklen);
+	    			if (!req->filterkey)
+	    				goto audit_watch_setup_exit;
+	    			strcpy(req->filterkey, opt);
+	    			ret = 1;
+			}
+		break;
+		case WATCH_PERMS:
+			if (strlen(opt) > 4)
+				goto audit_watch_setup_exit;
+		
+			for (i = 0; i < strlen(opt); i++) {
+			switch (opt[i]) {
+				case 'r':
+					if (!(req->perms & WATCH_MAY_READ))
+						req->perms |= WATCH_MAY_READ;
+					else 
+						goto audit_watch_setup_exit;
+					break;
+	    			case 'w':
+					if (!(req->perms & WATCH_MAY_WRITE))
+					req->perms |= WATCH_MAY_WRITE;
+					else
+						goto audit_watch_setup_exit;
+					break;
+				case 'e':
+					if (!(req->perms & WATCH_MAY_EXEC))
+						req->perms |= WATCH_MAY_EXEC;
+					else
+						goto audit_watch_setup_exit;
+					break;
+	    			case 'a':
+					if (!(req->perms & WATCH_MAY_APPEND))
+						req->perms |= WATCH_MAY_APPEND;
+					else
+						goto audit_watch_setup_exit;
+					break;
+	    			default:
+					goto audit_watch_setup_exit;
+			}
+		}
+		
+		ret = 1;
+    		
+		default:
+			break;
+	}
+audit_watch_setup_exit:
+	return ret;
+}
+
 /*
  * returns: < 0 error - noreply, 0 success - reply, > 0 success - rule
  */
@@ -138,8 +235,8 @@ static int setopt(int count, char *vars[
 
     optind = 0;
     opterr = 0;
-    while ((c = getopt(count, vars, "hslDe:f:r:b:a:A:d:S:F:m:t:R:")) != EOF &&
-		retval != -1) {
+    while ((c = getopt(count, vars, "hslDf:e:E:r:b:a:A:d:S:F:m:t:R:W:w:k:p:")) 
+    		!= EOF && retval != -1) {
         switch (c) {
         case 'h':
 		usage();
@@ -162,6 +259,15 @@ static int setopt(int count, char *vars[
 			retval = -1;
 		}
 		break;
+	case 'E':
+		if (optarg && ((optarg[0] == '0') || (optarg[0] == '1'))) {
+		   audit_set_fsenabled(fd, strtol(optarg, NULL, 0));
+		   audit_request_status(fd);
+		} else {
+		   printf("Enable must be 0 or 1 was %s\n", optarg);
+		   retval = -1;
+		}
+		break;
         case 'f':
 		if (optarg && ((optarg[0] == '0')||(optarg[0] == '1')||
 				(optarg[0] == '2'))) {
@@ -291,6 +397,38 @@ static int setopt(int count, char *vars[
 	case 'D':
 		retval = delete_all_rules();
 		break;
+	case 'W':
+		if (audit_watch_setup(WATCH_NAME, &watch, optarg))
+			rem = retval = 1;
+		else {
+			usage();
+			retval = -1;
+		}
+		break;
+	case 'w':
+		if (audit_watch_setup(WATCH_NAME, &watch, optarg))
+			ins = retval = 1;
+		else {
+			usage();
+			retval = -1;
+		}
+		break;
+	case 'k':
+		if (ins && audit_watch_setup(WATCH_FILTERKEY, &watch, optarg))
+			retval = 1;
+		else {
+			usage();
+			retval = -1;
+		}
+		break;
+	case 'p':
+		if (ins && audit_watch_setup(WATCH_PERMS, &watch, optarg))
+			retval = 1;
+		else {
+			usage();
+			retval = -1;
+		}
+		break;
         default: 
 		usage();
 		retval = -1;
@@ -458,6 +596,10 @@ static int handle_request(int status)
 		rc = audit_add_rule(fd, &rule, add, action);
 	else if (del & 0x07) 
 		rc = audit_delete_rule(fd, &rule, del, action);
+	else if (ins && !rem)
+		rc = audit_insert_watch(fd, &watch);
+	else if (rem && !ins)
+		rc = audit_remove_watch(fd, &watch);
 	else {
         	usage();
     		audit_close(fd);
@@ -520,14 +662,14 @@ static int audit_print_reply(struct audi
 		printf("No rules\n");
 	return 0;
     case NLMSG_ERROR: 
-        printf("NLMSG_ERROR %d (%s) type=%d seq=%d\n", rep->error->error,
-               strerror(rep->error->error), rep->type, rep->nlh->nlmsg_seq);
+        printf("NLMSG_ERROR %d (%s) type=%d seq=%d\n", -rep->error->error,
+               strerror(-rep->error->error), rep->type, rep->nlh->nlmsg_seq);
         return 0;
     case AUDIT_GET:
-        printf("AUDIT_STATUS: enabled=%d flag=%d pid=%d"
+        printf("AUDIT_STATUS: enabled=%d fs_enabled=%d flag=%d pid=%d"
                " rate_limit=%d backlog_limit=%d lost=%d backlog=%d\n",
-               rep->status->enabled, rep->status->failure,
-               rep->status->pid, rep->status->rate_limit,
+               rep->status->enabled, rep->status->fs_enabled,
+	       rep->status->failure, rep->status->pid, rep->status->rate_limit,
                rep->status->backlog_limit, rep->status->lost,
                rep->status->backlog);
         return 0;
@@ -577,6 +719,18 @@ static int audit_print_reply(struct audi
         }
         printf("\n");
         return 1;               /* get more messages, until NLMSG_DONE */
+   case AUDIT_WATCH_INS:
+   	if (rep->watch < 0)
+		printf("AUDIT_WATCH : INSERT : %s\n", strerror(-(rep->watch)));
+	else
+		printf("AUDIT_WATCH : INSERT : SUCCESS\n");
+	return 0;
+    case AUDIT_WATCH_REM:
+    	if (rep->watch < 0)
+		printf("AUDIT_WATCH : REMOVE : %s\n", strerror(-(rep->watch)));
+	else
+		printf("AUDIT_WATCH : REMOVE : SUCCESS\n");
+	return 0;
     default:
         printf("Unknown: type=%d, len=%d\n", rep->type, rep->nlh->nlmsg_len);
         return 0;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]