Audit Event Parsing Library Specifications ========================================== Definitions ----------- An audit event is all records that have the same host (node), timestamp, and serial number. Each event on a host (node) has a unique timestamp and serial number. An event is composed of multiple records which have information about different aspects of an audit event. Each record is denoted by a type which indicates what fields will follow. Information in the fields are held by a name/value pair that contains an '=' between them. Each field is separated from one another by a space or comma. Ground Rules ------------ All functions that begin with ausearch are related to searching for a subset of events based on certain criteria. All functions that begin with auparse are used to access events, records, and fields sequentially and without regard to any search options that may be in effect. All functions return 1 on success and 0 on failure unless otherwise noted. Where the return type is a char pointer, NULL will indicate failure. The data structures will be hidden from the external application. Access to fields is a name/value style. You access the fields through functions that either return a pointer to a zero-terminated array of ASCII characters or integral values. Every function (except auparse_init) takes a parameter, au, which is the internal state information for the current query. Name-Value Matching Operators ----------------------------- The ausearch_ functions will select records in its search results based on operators used for matching name/value pairs. For fields that are numeric, the following mathematical operators are allowed: =,!=,>,=>,<,<=. The field is converted to a number before matching is done. For fields that are non-numeric, the operators in use will be: = The string completely matches != The string does not match ~ A substring match is done regex Regular expression is used Field Names ----------- Fields names in a record should be consistent so that the parser can make sense of the value associated with a field. The following list enumerates preferred field names. a? - alphanumeric, the arguments to a syscall acct - alphanumeric, a user's account name addr - the remote address that the user is connecting from arch - numeric, the elf architecture flags audit_backlog_limit - numeric, audit system's backlog queue size audit_enabled - numeric, audit systems's enable/disable status audit_failure - numeric, audit system's failure mode auid - numeric, login user id comm - alphanumeric, command line program name cwd - path name, the current working directory dev - numeric, in path records, major and minor for device dev - in avc records, device name as found in /dev egid - numeric, effective group id euid - numeric, effective user id exe - path name, executable name exit - numeric, syscall exit code file - file name flags - numeric, file system namei flags format - alphanumeric, audit log's format fsgid - numeric, file system group id fsuid - numeric, file system user id gid - numeric, group id hostname - alphanumeric, the hostname that the user is connecting from id - numeric, during account changes, the user id of the account inode - numeric, inode number inode_gid - numeric, group id of the inode's owner inode_uid - numeric, user id of the inode's owner item - numeric, which item is being recorded items - numeric, the number of path records in the event list - numeric, the audit system's filter list number mode - numeric, mode flags on a file msg - alphanumeric, the payload of the audit record nargs - numeric, the number of arguments to a socket call name - file name in avcs obj - alphanumeric, lspp object context string ogid - numeric, object owner's group id old - numeric, old audit_enabled, audit_backlog, or audit_failure value old_prom - numeric, network promiscuity flag op - alphanumeric, the operation being performed that is audited ouid - numeric, object owner's user id parent - numeric, the inode number of the parent file path - file system path name perm - numeric, the file permission being used perm_mask - numeric, file permission audit mask that triggered a watch event pid - numeric, process id prom - numeric, network promiscuity flag qbytes - numeric, ipc objects quantity of bytes range - alphanumeric, user's SE Linux range rdev - numeric, the device identifier (special files only) res - alphanumeric, result of the audited operation (success/fail) result - alphanumeric, result of the audited operation (success/fail) role - alphanumeric, user's SE linux role saddr - alphanumeric, socket address sauid - numeric, sending login user id scontext - alphanumeric, the subject's context string seuser - alphanumeric, user's SE Linux user acct sgid - numeric, set group id spid - numeric, sending process id subj- alphanumeric, lspp subject's context string success - alphanumeric, whether the syscall was successful or not suid - numeric, sending user id syscall - numeric, the syscall number in effect when the event occurred tclass - alphanumeric, target's object classification tcontext - alphanumeric, the target's or object's context string terminal - alphanumeric, terminal name the user is running programs on tty - alphanumeric, tty interface that the user is running programs on type - alphanumeric, the audit record's type uid - numeric, user id user - alphanumeric, account the user claims to be prior to authentication ver - numeric, audit daemon's version number watch - the file name in a watch record Functions --------- auparse_state_t - is an opaque data type used for maintaining library state. typedef enum { AUSOURCE_LOGS, AUSOURCE_FILE, AUSOURCE_FILE_ARRAY, AUSOURCE_BUFFER, AUSOURCE_BUFFER_ARRAY } ausource_t; auparse_state_t *auparse_init(ausource_t source, const void *b) - allow init of library. Set data source: logs, file, null terminated array of filenames, buffer, null terminated array of addresses. The pointer 'b' is used to set the file name or pass the buff when those types are given. int auparse_reset(auparse_state_t *au) - reset all internal cursors to the beginning. typedef enum { AUSEARCH_STOP_EVENT, AUSEARCH_STOP_RECORD, AUSEARCH_STOP_FIELD } austop_t; int ausearch_set_param(auparse_state_t *au, const char *field, const char *op, const char *value, austop_t where) - set search options. The field would be the left hand side of the audit name/value pairs. The op would be the operator described in the section above telling how to match. The value would be the right hand side of the audit field name/value pairs. The where parameter tells the search library where to place the internal cursor when a match is found. It could be on first field of first record, first field of record containing the match, or the field that matches. This function my be called more than once to set a compound search condition. Each search statement passed in forms an "and" with anything else already in the search rule. int ausearch_clear_param(auparse_state_t *au) - clears any set search rule currently in effect. int ausearch_next_event(auparse_state_t *au) - traverse to the next event that yields a match based on the given search criteria. int auparse_next_event(auparse_state_t *au) - traverse to next event. This allows access to time and serial number. typedef struct { time_t sec; // Event seconds unsigned int milli; // millisecond of the timestamp unsigned long serial; // Serial number of the event const char *host; // Machine's name } event_t; const event_t *auparse_get_timestamp(auparse_state_t *au) - retrieve time stamp of current record time_t auparse_get_time(auparse_state_t *au) - retrieve time in seconds of current record time_t auparse_get_milli(auparse_state_t *au) - retrieve milliseconds time of current record unsigned long auparse_get_serial(auparse_state_t *au) - retrieve serial number of current record const char *auparse_get_node(auparse_state_t *au) - retrieve host (node) name of current record int auparse_timestamp_compare(event_t *e1, event_t *e2) - compare 2 timestamps. The results are either less than, equal to, or greater than 0 if e1 is found to be respectively less than, equal to, or greater than e2. int auparse_first_record(auparse_state_t *au) - set iterator to first record in current event int auparse_next_record(auparse_state_t *au) - traverse to next record in event. This allows access to the event type int auparse_get_type(auparse_state_t *au) - retrieve type of current record int auparse_first_field(auparse_state_t *au) - set field pointer to first in current record int auparse_next_field(auparse_state_t *au) - traverse the fields in a record const char *auparse_get_record_text(auparse_state_t *au) - return a pointer to the full, unparsed record. const char *auparse_find_field(auparse_state_t *au, const char *name) - find a given field in a event or record. Name is the left hand side of the name/value pair. Returns pointer to the value as ascii text. const char *auparse_find_field_next(auparse_state_t *au) - find the next occurance of that field in the same record. Returns pointer to the value as ascii text. const char *auparse_get_field_name(auparse_state_t *au) - return current field name as a string const char *auparse_get_field_name_aux(auparse_state_t *au) - return supplemental information about the field's name. const char *auparse_get_field_str(auparse_state_t *au) - return current field value as a string int auparse_get_field_int(auparse_state_t *au) - return current field value as an int const char *auparse_interpret_field(auparse_state_t *au) - interpret the current field int auparse_destroy(auparse_state_t *au) - free all data structures and close file descriptors Code Example ------------ int main(void) { auparse_state_t *au = auparse_init(AUSOURCE_LOGS, NULL); if (au == NULL) exit(1); if (!ausearch_set_param(au, "auid", "=", "500", AUSEARCH_STOP_EVENT)) exit(1); while (ausearch_next_event(au)) { if (auparse_find_field(au, "auid")) { printf("auid=%s\n", auparse_interpret_field(au)); } } auparse_destroy(au); return 0; }