[RFC][PATCH 3/3] CAPP-compliant file system auditing

Timothy R. Chavez tinytim at us.ibm.com
Thu Mar 31 18:24:16 UTC 2005


:: Tools ::

To enable the kernel functionality one will need to download the audit-0.6.9 
source tree (http://people.redhat.com/sgrubb/audit/) and apply the attached 
patch.  Read the README-install file for installation instructions.  If the 
audit daemon is not running (also included in this package), then audit 
records will appear in /var/log/syslog rather then /var/log/audit.log.  Use 
the "auditctl" tool for inserting, removing, and listing watches.

Note:  At the time of writing this e-mail the user space / kernel space 
interaction is not yet complete.  For instance, I'd eventually like to add 
serialization routines to both spaces to pass "watch" structures more easily.  
There is also talk about another type of watch listing feature that can list 
all the watches present in memory.

++++

diff -Nurp audit-0.6.9/lib/libaudit.c audit-0.6.9~scratch/lib/libaudit.c
--- audit-0.6.9/lib/libaudit.c	2005-03-17 16:21:17.000000000 -0600
+++ audit-0.6.9~scratch/lib/libaudit.c	2005-03-29 23:33:51.000000000 -0600
@@ -220,6 +220,15 @@ int audit_remove_watch(int fd, struct au
 	return rc;
 }
 
+int audit_list_watches(int fd, char *path)
+{
+	int rc = audit_send(fd, AUDIT_WATCH_LIST, path, strlen(path)+1);
+	if (rc < 0)
+		msg(LOG_WARNING, "Error sending watch list request (%s)",
+			strerror(-rc));
+	return rc;
+}
+
 int audit_add_rule(int fd, struct audit_rule *rule, int flags, int action)
 {
 	int rc;
diff -Nurp audit-0.6.9/lib/libaudit.h audit-0.6.9~scratch/lib/libaudit.h
--- audit-0.6.9/lib/libaudit.h	2005-03-17 16:20:26.000000000 -0600
+++ audit-0.6.9~scratch/lib/libaudit.h	2005-03-29 23:39:42.000000000 -0600
@@ -38,11 +38,12 @@
 #ifndef AUDIT_WATCH_INS
 #define AUDIT_WATCH_INS		1007	/* Insert file/dir watch entry */
 #define AUDIT_WATCH_REM		1008	/* Remove file/dir watch entry */
+#define AUDIT_WATCH_LIST	1009	/* List watches on dir */
 struct audit_watch {
-	int     namelen;
-	int     fklen;
-	char    *name;
-	char    *filterkey;
+	uint32_t namelen;
+	uint32_t fklen;
+	char     *name;
+	char     *filterkey;
 	uint32_t perms;
 };
 /* 32 byte max key size */
@@ -62,7 +63,7 @@ struct audit_reply {
 	struct audit_login   *login;
 	const char           *message;
 	struct nlmsgerr      *error;
-	int                   watch;
+	const char 	     *watch;
 };
 
 struct auditd_reply_list {
@@ -119,6 +120,7 @@ extern int  audit_request_list(int fd);
 /* AUDIT_WATCH */
 extern int audit_insert_watch(int fd, struct audit_watch *req);
 extern int audit_remove_watch(int fd, struct audit_watch *req);
+extern int audit_list_watches(int fd, char *path);
 
 /* AUDIT_ADD */
 extern int  audit_add_rule(int fd, struct audit_rule *rule,
diff -Nurp audit-0.6.9/lib/netlink.c audit-0.6.9~scratch/lib/netlink.c
--- audit-0.6.9/lib/netlink.c	2005-03-17 16:25:21.000000000 -0600
+++ audit-0.6.9~scratch/lib/netlink.c	2005-03-29 23:33:57.000000000 -0600
@@ -132,7 +132,7 @@ static int adjust_reply(struct audit_rep
 	rep->rule    = NULL;
 	rep->message = NULL;
 	rep->error   = NULL;
-	rep->watch   = 0;
+	rep->watch   = NULL;
 	if (!NLMSG_OK(rep->nlh, (unsigned int)len))
 		return 0;
 	switch (rep->type) {
@@ -150,9 +150,8 @@ 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));
+		case AUDIT_WATCH_LIST:
+			rep->watch = NLMSG_DATA(rep->nlh);
 			break;
 	}
 	return len;
diff -Nurp audit-0.6.9/src/auditctl.c audit-0.6.9~scratch/src/auditctl.c
--- audit-0.6.9/src/auditctl.c	2005-03-17 16:24:50.000000000 -0600
+++ audit-0.6.9~scratch/src/auditctl.c	2005-03-29 23:44:10.000000000 -0600
@@ -71,7 +71,8 @@ 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 int ins = 0, rem = 0, list = 0;
+static char *path;
 static struct audit_rule  rule;
 static struct audit_watch watch;
 
@@ -122,10 +123,11 @@ static void usage(void)
      "       -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"
+     "       -p [rwea]    Set permissions filter on watch:\n"
      "                      r=read, w=write, e=execute, a=append\n"
      "       -k <key>     Set filterkey on watch\n"
+     "       -W <path>    Remove watch at <path>\n"
+     "       -L <path>    List all watches at <path>\n"
      );
 }
 
@@ -295,7 +297,7 @@ 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:w:W:k:p:")) != EOF &&
+			"hslDe:f:r:b:a:A:d:S:F:m:t:R:w:W:L:k:p:")) != EOF &&
 			retval != -1) {
         switch (c) {
         case 'h':
@@ -467,6 +469,16 @@ static int setopt(int count, char *vars[
 			retval = -1;
 		}
 		break;
+	case 'L':
+		if (optarg) {
+			list = 1;
+			path = optarg;
+			retval = audit_list_watches(fd, path);
+		} else {
+			fprintf(stderr, "watch option needs a path\n");
+			retval = -1;
+		}
+		break;
 	case 'k':
 		if (!ins) {
 			fprintf(stderr, 
@@ -646,13 +658,13 @@ int main(int argc, char *argv[])
 /*
  * This function is called after setopt to handle the return code.
  * status = 0 means just get the reply. Greater than 0 means we
- * are adding or deleting a rule. Less than 0 means an error occurred.
- * Even if there's an error, we need to call this routine to close up the 
- * audit fd.
+ * are adding or deleting a rule or watch. Less than 0 means an error
+ * occurred.  Even if there's an error, we need to call this routine
+ * to close up the audit fd.
  */
 static int handle_request(int status)
 {
-    if (status == 0)
+    if (list || status == 0)
 	get_reply();
     else if (status > 0) {
 	int rc;
@@ -669,20 +681,21 @@ static int handle_request(int status)
     		audit_close(fd);
 		exit(1);
     	}
-	if (rc > 0) {
-		if (audit_request_list(fd) > 0) {
-			list_requested = 1;
-			get_reply();
+	if (!ins && !rem) {
+		if (rc > 0) {
+			if (audit_request_list(fd) > 0) {
+				list_requested = 1;
+				get_reply();
+			} else {
+				fprintf(stderr, "Error requesting list\n");
+				status = -1;
+			}
 		} else {
-			fprintf(stderr, "Error requesting list\n");
+			fprintf(stderr, "Error sending rule to kernel\n");
 			status = -1;
-		}
-	} else {
-		fprintf(stderr, "Error sending rule to kernel\n");
-		status = -1;
+    		}
 	}
-    }
-    else {
+    } else {
 		status = -1;
     }
     audit_close(fd);
@@ -727,7 +740,7 @@ static int audit_print_reply(struct audi
     case NLMSG_NOOP:
 	return 1;
     case NLMSG_DONE:
-	if (list_requested)
+	if (list_requested && (!rem && !ins))
 		printf("No rules\n");
 	return 0;
     case NLMSG_ERROR: 
@@ -788,18 +801,16 @@ 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;
+    case AUDIT_WATCH_LIST: {
+    	if (rep->watch)
+		if (path[strlen(path)-1] == '/')
+			printf("AUDIT_WATCH: LIST: path=%s%s\n",
+		       		path, rep->watch);
+		else
+			printf("AUDIT_WATCH: LIST: path=%s/%s\n",
+				path, rep->watch);
+	return 1;
+    }
     default:
         printf("Unknown: type=%d, len=%d\n", rep->type, rep->nlh->nlmsg_len);
         return 0;

 
-tim




More information about the Linux-audit mailing list