-
Notifications
You must be signed in to change notification settings - Fork 30
SPEC Audit Event Parsing Library
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. All events contain information pertaining to where something happened (node), when it happened, what did it (subject), what was done, to what (object), and the result of the action. 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.
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.
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
Fields names in a record should be consistent so that the parser can make sense of the value associated with a field. When writing events, always use a known field name and don't make one up if at all possible. The value associated with the field needs to have the same formatting as listed here or translation can error.
The current field database can be found here:
-
auparse_state_t
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, size_t s);
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. If buffers are used for the source, the 's' parameter shall denote the buffer size. All buffers should be a uniform size. Unused portions should be filled with 0's to prevent the interpretation of uninitialized memory. -
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 occurrence 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_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.
int main(void)
{
auparse_state_t *au = auparse_init(AUSOURCE_LOGS, NULL, 0);
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;
}
All information in this wiki is licensed under the CC BY 4.0 license.