Below are the structures that we (Loulwa Salem, Mike Thompson, Tim Chavez
and I) had envisioned the structures for the new API to look like.
Basically we imagine a list of lists. Below that are some function
prototypes needed in the API.
I'm new to Python so I will study the Python/C API link posted.
typedef struct records {
time_t time;
serial_t serial;
record_t record;
records_t * next_record;
} records_t;
typedef struct record {
recordtype kind; //what kind of audit_record record it is
record_data data;
record * next;
} record_t;
union record_data {
syscall_t syscall;
ipc_t ipc;
fs_watch_t fs_watch;
fs_inode_t fs_inode;
cwd_t cwd;
path_t path;
config_change_t config_change;
daemon_end_t daemon_end;
user_t user;
user_chauthtok_t user_chauthtok;
user_auth_t user_auth;
user_acct_t user_acct;
user_start_t user_start;
user_end_t user_end;
cred_acq_t cred_acq;
cred_disp_t cred_disp;
cred_refr_t cred_refr;
login_t longin;
} record_data_t;
typedef struct syscall {
arch_t arch;
syscall_num_t syscall_num; //note used syscall_num rather than
syscall at some point they could add syscall_name
success_t success;
exit_t exit;
a_t a0;
a_t a1;
a_t a2;
a_t a3;
items_t items;
id_t pid;
id_t auid;
id_t uid;
id_t gid;
id_t euid;
id_t suid;
id_t fsuid;
id_t egid;
id_t sgid;
id_t fsgid;
comm_t comm;
exe_t exe;
} syscall_t;
typedef struct fs_watch {
inode_t watch_inode;
watch_t watch;
filterkey_t filterkey;
perm_t perm;
perm_mask_t perm_mask;
} fs_watch_t;
typedef struct fs_inode {
inode_t inode;
id_t inode_uid;
id_t inode_gid;
dev_t inode_dev;
rdev_t inode_rdev
} fs_inode_t;
typedef struct cwd {
cwd_t cwd;
} cwd_t;
typedef struct path {
name_t name;
flags_t flags;
inode_t inode;
dev_t dev;
mode_t mode;
id_t ouid;
id_t ogid;
rdev_t rdev;
} path_t;
typedef struct config_change {
time_t time;
id_t auid;
text_t text; //"removed watch"
audit_enabled_t audit_enabled;
old_t old;
} config_change_t;
typedef struct daemon_start {
version_t version;
format_t format;
id_t auid;
id_t auditd_pid;
text_t text; //"auditd start"
} daemon_start_t;
typedef struct daemon_end {
id_t auid;
id_t sending_pid;
id_t auditd_pid;
text_t text; //"auditd normal halt"
} daemon_end_t;
typedef struct ipc {
qbytes_t qbytes;
id_t iuid;
id_t igid;
mode_t mode;
} ipc_t;
typedef struct login {
msg_t msg; //message needs to be parsed to figure out the
following
id_t pid;
id_t uid;
id_t old_auid;
id_t new_auid;
} login_t;
typedef struct user {
id_t pid;
id_t uid;
id_t auid;
msg_t msg;
text_t text; //"user"
} user_t;
typedef struct user_chauthtok {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
res_t res; //records using 'res' should be changed to
use 'result'
result_t result;
op_t op;
acct_t acct;
} user_chauthtok_t;
Note: user_auth, user_acct, user_start, user_end, cred_acq, cred_disp,
cred_refr have the same tydef, but the message parsed differs slightly.
typedef struct user_auth {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} user_auth_t;
typedef struct user_acct {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} user_acct_t;
typedef struct user_start {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} user_start_t;
typedef struct user_end {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} user_end_t;
typedef struct cred_acq {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} cred_acq_t;
typedef struct cred_disp {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} cred_disp_t;
typedef struct cred_refr {
id_t pid;
id_t uid;
id_t auid;
msg_t msg; //message needs to be parsed to figure out the
following
user_t user;
exe_t exe;
hostname_t hostname;
addr_t addr;
terminal_t terminal;
result_t result;
} cred_refr_t;
/* The following struct is the generic record struct which does not have a
record type */
/* It is used by get_by_fields(). */
typedef struct generic_field_data {
a_t a0;
a_t a1;
a_t a2;
a_t a3;
acct_t acct;
addr_t addr;
arch_t arch;
comm_t comm;
cwd_t cwd;
dev_t dev;
dev_t inode_dev;
audit_enabled_t audit_enabled;
exe_t exe;
exit_t exit;
filterkey_t filterkey;
flags_t flags;
format_t format;
hostname_t hostname;
id_t auditd_pid;
id_t auid;
id_t egid;
id_t euid;
id_t fsgid;
id_t fsuid;
id_t gid;
id_t igid;
id_t inode_gid;
id_t inode_uid;
id_t iuid;
id_t new_auid;
id_t ogid;
id_t ouid;
id_t old_auid;
id_t ouid;
id_t pid;
id_t sending_pid;
id_t sgid;
id_t suid;
id_t uid;
inode_t inode;
inode_t watch_inode;
items_t items;
mode_t mode;
msg_t msg;
name_t name;
old_t old;
op_t op;
perm_mask_t perm_mask;
perm_t perm;
qbytes_t qbytes;
rdev_t inode_rdev;
rdev_t rdev;
result_t res;
result_t result;
serial_t serial;
success_t success;
syscall_num_t syscall_num; //note used syscall_num rather than
syscall at some point they could add syscall_name
terminal_t terminal;
text_t text; // example "removed watch"
time_t time;
type_t type;
user_t user;
version_t version;
watch_t watch;
} generic_field_data_t;
Some function prototypes:
struct record * get_records(time_t start, time_t end){
// start and end time can be specified
// If zero is passed in for start time, then start searching at beginning
of log
// If zero is passed in for the end time, then search until the end of the
log
// returns pointer to link list of all records within start and end time
(which are themselves a link list)
// if no records were found during specified start and end time, returns
NULL
}
struct record * get_matching_records(struct record * matching_criteria,
time_t start, time_t end){
// matching_criteria is passed into function
// matching_criteria is a pointer to a linked list of record pieces we are
looking for
// start and end time can be specified
// If zero is passed in for start time, then start searching at beginning
of log
// If zero is passed in for the end time, then search until the end of the
log
// returns pointer to link list of all matching records (which are
themselves a link list)
// if no matching record is found, returns NULL
}
struct record * get_records_by_fields(struct generic_field_data *
fields_to_match, time_t start, time_t end){
// fields_to_match is passed into the function
// fields_to_match is a pointer to one structure with all the fields we
want to match filled in and the rest initialized
// start and end time can be specified
// If zero is passed in for start time, then start searching at beginning
of log
// If zero is passed in for the end time, then search until the end of the
log
// returns pointer to link list of all matching records (which are
themselves a link list)
// if no matching record is found, returns NULL
}
record_data * initialize_record_data(record_data * matching_criteria){
//initializes all fields in generic field data type
}
generic_field_data * initialize_generic_field_data(generic_field_data *
fields_to_match){
//initializes all fields in generic field data type
}