From bc705d128cc209c55b374746f8f0e49d2723738d Mon Sep 17 00:00:00 2001 From: Holger Hetterich Date: Sat, 20 Feb 2010 18:32:59 +0100 Subject: [PATCH] s3: vfs_full_audit.c: Allow negated ops, allow opclass definitions. Part of BSO#4025 --- docs-xml/manpages-3/vfs_full_audit.8.xml | 36 +++++++- source3/modules/vfs_full_audit.c | 138 ++++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 12 deletions(-) diff --git a/docs-xml/manpages-3/vfs_full_audit.8.xml b/docs-xml/manpages-3/vfs_full_audit.8.xml index 1d519e2..6a8c24b 100644 --- a/docs-xml/manpages-3/vfs_full_audit.8.xml +++ b/docs-xml/manpages-3/vfs_full_audit.8.xml @@ -180,11 +180,37 @@ + vfs_full_audit:classes = LIST + + LIST is a list of VFS operation classes the user + may define. A class can include other classes. The user + provides a definition of the class with + vfs_full_audit:$CLASSNAME = LIST. The classes + can be used with vfs_full_audit:success or + vfs_full_audit:failure. + + + + + vfs_full_audit:$CLASSNAME = LIST + + LIST is a list of VFS operations that should be + recorded. Operations are specified using + the names listed above. Operations can be unset by prefixing + the names with "!". The list is stored in the operation + class $CLASSNAME and can be used from vfs_full_audit:success + or vfs_full_audit:failure. + + + + + vfs_full_audit:success = LIST LIST is a list of VFS operations that should be recorded if they succeed. Operations are specified using - the names listed above. + the names listed above. Operations can be unset by prefixing + the names with "!". @@ -195,7 +221,8 @@ LIST is a list of VFS operations that should be recorded if they failed. Operations are specified using - the names listed above. + the names listed above. Operations can be unset by prefixing + the names with "!". @@ -232,7 +259,8 @@ Log file and directory open operations on the [records] share using the LOCAL7 facility and ALERT priority, including - the username and IP address: + the username and IP address. Logging excludes the open VFS function + on failures: @@ -240,7 +268,7 @@ full_audit %u|%I open opendir - all + all !open LOCAL7 ALERT diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 19ac7ad..021f363 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -431,13 +431,105 @@ static bool log_failure(vfs_handle_struct *handle, vfs_op_type op) return bitmap_query(pd->failure_ops, op); } -static void init_bitmap(struct bitmap **bm, const char **ops) +/** + * recursivly parse operation classes + * const char *class The class we are working on + * struct bitmap **bm The bitmap to set/unset + * vfs_handle_struct *handle The vfs handle + * bool mode Apply the class as is(true), or negated(false) + * recursion_count Counter to check the recursion level + */ +static void audit_apply_opclass(const char *class, + struct bitmap **bm, vfs_handle_struct *handle, bool mode, + int *recursion_count) { + int i; bool log_all = False; + const char **classlist; + const char **ops = + lp_parm_string_list(SNUM(handle->conn), + "full_audit", + class, + NULL); + + if (*ops == NULL) { + debug(0,("full_audit: ERROR: No operation class definition " + " '%s' exists, check your configuration!\n",class)); + return; + } - if (*bm != NULL) + /* + * should the class definition of the user contain classes + * that repeat each other, we will break out after a maximum + * of 20 recursions, and log this as a warning. + */ + if (*recursion_count == 20) { + DEBUG(0,("full_audit: WARNING: giving up parsing your class " + "definition, it likely leads to endless " + "recursion.\n")); return; + } + *recursion_count = *recursion_count +1; + while (*ops != NULL) { + bool found = False; + for (i=0; iconn), + "full_audit", + "classes", + NULL); + + while (*classlist != NULL) { + if (strequal(*ops, *classlist)) { + audit_apply_opclass(*classlist, + bm, + handle, + True, + recursion_count); + found = True; + } else if ( *(*ops) =='!' && strequal(*ops+1,*classlist)) { + audit_apply_opclass(*classlist, + bm, + handle, + False, + recursion_count); + found = True; + } + classlist += 1; + } + if (!found) { + DEBUG(0,("full_audit: unkown identifier '%s' in your " + "class definition '%s'\n",*ops,class)); + return; + } + ops += 1; + } +} +static void init_bitmap(struct bitmap **bm, const char **ops, + struct vfs_handle_struct *handle) +{ + int i; + bool log_all = False; + bool negated_ops = False; + int class_recursion_count = 0; + const char **classes; + + if (*bm != NULL) + return; *bm = bitmap_allocate(SMB_VFS_OP_LAST); if (*bm == NULL) { @@ -447,12 +539,16 @@ static void init_bitmap(struct bitmap **bm, const char **ops) } while (*ops != NULL) { - int i; bool found = False; + + if ( *(*ops) == '!' && negated_ops == False && log_all == True) { + for (i=0; iconn), + "full_audit", + "classes", + NULL); + class_recursion_count = 0; + while (found == False && *classes != NULL) { + if (strequal(*ops, *classes)) { + audit_apply_opclass(*classes,bm,handle,True, &class_recursion_count); + found = True; + break; } + else if ( *(*ops) =='!' && strequal(*ops+1, + *classes)) { + audit_apply_opclass(*classes,bm,handle,False, &class_recursion_count); + found = True; + break; } + classes += 1; + } + if (!found) { - DEBUG(0, ("Could not find opname %s, logging all\n", + DEBUG(0, ("Could not find VFS operation " + "or class name '%s', logging all\n", *ops)); log_all = True; break; @@ -479,7 +601,7 @@ static void init_bitmap(struct bitmap **bm, const char **ops) ops += 1; } - if (log_all) { + if (log_all && !negated_ops) { /* The query functions default to True */ bitmap_free(*bm); *bm = NULL; @@ -624,10 +746,10 @@ static int smb_full_audit_connect(vfs_handle_struct *handle, init_bitmap(&pd->success_ops, lp_parm_string_list(SNUM(handle->conn), "full_audit", "success", - none)); + none),handle); init_bitmap(&pd->failure_ops, lp_parm_string_list(SNUM(handle->conn), "full_audit", "failure", - all)); + all), handle); /* Store the private data. */ SMB_VFS_HANDLE_SET_DATA(handle, pd, free_private_data, -- 1.6.4.2