This chapter presents an overview of the audit concerns from a programmer's perspective. The following subjects are discussed:
Auditable events
Disabling auditing for the current process
Modifying what gets audited for the current process
Generation of application-specific audit records
Tokens
Auditable events are divided into the following categories:
System calls
Trusted events (user events such as
login)
Site-defined events
A list of the default auditable events can be found in the
Appendix B
or by looking at the
/etc/sec/audit_events
file as delivered on your system.
You can use the
audit_setup
script to establish the auditable events on your system.
See the
audit_setup(8)
reference page for more information.
Whether an auditable event actually results in the generation of an audit record depends on the following:
Process audit control flag
System audit mask
Process audit mask
The process audit control flag has four exclusive states:
An audit record is generated if either the system audit mask or the process audit mask indicates such an event should be audited.
An audit record is generated if both the system audit mask and the process audit mask indicate such an event should be audited.
No audit records are generated for the current process.
An audit record gets generated if the process audit mask indicates such an event should be audited.
The process audit control flag also has two nonexclusive states:
Turns off system call record generation for the application. The system calls specified in the system mask continue to be audited.
Allows turning on the habitat system calls in the user mask for an application while system calls are turned off for the system mask. See Appendix B for the habitat events.
A default audit level can be established for most users, while being
able to single out specific users to audit more or less closely.
A privileged
process is allowed to specify what gets audited for itself either absolutely,
or relative to the system audit mask.
The process audit control flag can be
set with with the
audcntl()
system call (privileged process
only).
Control over what events get audited is an important step in fine-tuning the audit data to indicate only events of interest. Sometimes too much audit data is generated by system calls. For example, the login process executes thousands of system calls, but a single audit record for the login process is easier to understand, less stressful on the system, and fewer entries in the auditlog. Modification of a security-relevant database, such as the password file, requires the auditing of information not easily picked up from the system calls, such as which field of which entry is being modified.
Use the
audcntl()
system call
to disable auditing for the current process as follows:
audcntl ( SET_PROC_ACNTL, (char *)0, 0, AUDIT_OFF, 0, 0 );
Control over what events are audited
for a specific process is achieved by modifying the process'
auditmask
and
audcntl
flags.
Modify the process' audit
mask as follows:
/* ex. set the process' auditmask to audit only LOGIN
events and successful setgroups calls
*/
#include <sys/audit.h>
#include <sys/syscall.h>
char buf[AUDIT_MASK_LEN];
bzero ( buf, sizeof(buf) );
A_PROCMASK_SET ( buf, LOGIN, 1, 1 );
A_PROCMASK_SET ( buf, SYS_setgroups, 1, 0 );
if ( audcntl ( SET_PROC_AMASK, buf, AUDIT_MASK_LEN, \
0, 0, 0 ) == -1 )
perror ( "audcntl" );
The
A_PROCMASK_SET
macro (found in
<sys/audit.h>), takes the following arguments:
The buffer in which the mask gets built
The
<sys/audit.h>
header file contains
application event names.
The
<sys/*syscall.h>
header
files contains system call names.
Indicates whether to audit successful occurrences of the event.
A
1
means audit success.
Indicates whether to audit failed occurrences of the event.
A
1
means audit failure.
See the
audcntl(2)
reference page for more information.
The audit subsystem is designed to make it easy to add application-specific auditing.
The audit subsystem has no fixed record type. Instead, the various possible elements of an audit record are tuples consisting of defined audit tokens and corresponding values. Each audit record is then built up from those elements. This approach provides flexibility in the kind and amount of data that can go into an audit record. It also avoids the problems associated with a less flexible design that defines a number of fixed audit record types and requires all software that uses the audit subsystem to work within those record types.
Most tokens specify an audit value that is fixed in
length and allow four bytes for the value.
Examples of fixed-length tokens
are
AUD_T_AUID
(audit ID),
AUD_TP_DEV
(device number), and
AUD_TP_PID
(process ID number).
Some types of audit values are of variable length.
These are accommodated
by tokens that are pointer types.
AUD_T_CHARP
(character
parameter) and
AUD_T_HOMEDIR
(home directory) are two of
the pointer-type tokens.
Some pointer-type tokens use
iovec
structures.
Examples of these are
AUD_T_OPAQUE, and
AUD_T_INTARRAY
which is used for data in integer arrays.
Opaque
data is displayed as an alphanumeric or in octal format.
The
iovec
structure is defined in
<sys/uio.h>.
For
information about
iovec
see the reference pages for
readv(2)
and
writev(2).
The tokens available to programs using the
audgen( )
and
audgenl( ) routines are called
public
tokens,
and
are named
AUD_T_name
in the
<sys/audit.h>
file.
Example 19-1
lists the public tokens:
/* start of ptr token types */ AUD_T_CHARP character string AUD_T_SOCK socket AUD_T_LOGIN login name AUD_T_HOMEDIR home directory AUD_T_SHELL shell AUD_T_DEVNAME device name AUD_T_SERVICE service string (rfu) AUD_T_HOSTNAME host name AUD_T_INTP integer array (deprecated) /* 1st element of int array is # of data elements in array */ /* start of iovec style data */ AUD_TOKEN_IOVEC_MIN AUD_T_OPAQUE opaque data AUD_T_INTARRAY integer array AUD_T_GIDSET group set AUD_T_XDATA aud_xdata structure AUD_TOKEN_PTR_MAX /* end of iovec style data */ /* end of ptr token types */ AUD_T_AUID audit id AUD_T_RUID real uid AUD_T_UID effective uid AUD_T_PID pid AUD_T_PPID ppid AUD_T_GID gid AUD_T_EVENT event # AUD_T_SUBEVENT subevent # AUD_T_DEV dev major,minor # AUD_T_ERRNO errno value AUD_T_RESULT result value AUD_T_MODE object mode AUD_T_HOSTADDR ip address AUD_T_INT integer data AUD_T_DESCRIP descriptor AUD_T_HOSTID hostid AUD_T_X_ATOM X atom AUD_T_X_CLIENT X client identifier AUD_T_X_PROPERTY X property identifier AUD_T_X_RES_CLASS X resource class AUD_T_X_RES_TYPE X resource type AUD_T_X_RES_ID X resource identifier
Only the public tokens can be added to records from user space using
the
audgen
call; the private tokens cannot.
Further, the public tokens are broken down into 3 categories:
Represent data strings or structures
Added as iovec-formated data
32 or 64-bit quantities (AUD_T_RESULT is 64-bit; others are 32-bit)
Tokens with security implications that are not available to users are
called
private tokens,
and are named
AUD_TP_name.
Example 19-2 lists the private tokens:
AUD_TP_ACCRGHT msghdr's access rights data (sendmsg, recvmsg) AUD_TP_MSGHDR msghdr's name field (sendmsg, recvmsg) AUD_TP_EVENTP event name (for alternate habitats) AUD_TP_HABITAT habitat name AUD_TP_ADDRVEC address vectors (exportfs) AUD_TP_INTP integer array AUD_TP_AUID audit id AUD_TP_RUID real uid AUD_TP_UID effective uid AUD_TP_PID pid AUD_TP_PPID ppid AUD_TP_HOSTADDR host address (ip) AUD_TP_EVENT event # AUD_TP_SUBEVENT subevent # AUD_TP_NCPU cpu # AUD_TP_DEV device # AUD_TP_LENGTH audit record length AUD_TP_IPC_GID sysV structure gid value AUD_TP_IPC_MODE sysV structure mode bits AUD_TP_IPC_UID sysV structure uid value AUD_TP_TV_SEC timestamp (sec) AUD_TP_TV_USEC timestamp (usec) AUD_TP_SHORT short data AUD_TP_LONG long data AUD_TP_VNODE_DEV device on which inode resides AUD_TP_VNODE_ID inode identifier AUD_TP_VNODE_MODE object mode AUD_TP_VERSION version # AUD_TP_SET_UIDS flag indicating a uid change occurred AUD_TP_CONT continuation flag AUD_TP_TID thread identifier (address)
The following are examples of code to generate an application-specific audit record:
/* ex. generate an event of type `event`, with "some string",
and a result of 66
*/
#include <sys/audit.h>
if ( audgenl ( `event`, AUD_T_CHARP, "some string", \
AUD_T_RESULT, 66L, 0 ) == -1 )
perror ( "audgenl" );
The event can be either a trusted event (see
audit.h)
or an
administratively defined site-specific event.
/* ex. generate audit record for administratively defined event
event is "rdb", subevent is "commit"
note: this event must be registered in /etc/sec/site_events
link with -laud
*/
#include <sys/audit.h>
int eventnum, subeventnum;
if ( aud_sitevent_num ( "rdb", "commit", &eventnum, \
&subeventnum ) == -1 )
return(-1);
if ( audgenl ( eventnum, AUD_T_SUBEVENT, subeventnum, \
AUD_T_CHARP, "whatever", 0 ) == -1 )
return(-1);
See the
audgenl(3)
and
aud_sitevent(3)
reference pages for more information.
The examples in this section generate audit records only if the respective event types are selected to be audited and the auditable event actually results in the generation of an audit record (see Section 19.2).