Previous Topic: Customizing selogrdNext Topic: lograpi_UnregisterTargetType Function


Format of the Log File

The format in which CA ControlMinder writes the auditing log is not publicly available. However, it is essential that programmers who use this API understand the basics of the audit log file format. The information programmers must know is provided in this section.

The audit log file is composed of a file header followed by records sequentially written to the file. Each record is composed of a record header followed by information specific to the record. The header of each record includes information about the time that the record was placed in the file, the record type (a code known only by the application), and the size of the record that follows the header. The data itself is written in a compressed format; the record size specified in the record header is the size in bytes of the compressed data. The format of the file is shown schematically in the following diagram.

The programmer using this API does not need to know the compression algorithm or the exact format of the file. Information passed to a user application is placed in structures in uncompressed format. Your application simply retrieves the information from the structure.

More information:

Structures and Data Types

LogRoute API Example

The API subdirectory under the local CA ControlMinder directory contains the API header files and the library functions. The CA ControlMinder package also includes the following sample program demonstrating LogRoute API use-adding the destination target syslog to CA ControlMinder to send audit information to UNIX system logs.

/*=========================================================
Project      : eTrust
Module       : eTrust
Version      : 8.0
File         : audit2syslog.c
Purpose      : Provide sample usage of the selogrd API to place
               audit log records in UNIX syslog.
===========================================================
Copyright :
Copyright 2004 Computer Associates International, Inc.
============================================================*/
#define __LOGRSAMPLE_C
#include <syslog.h>
#include <lograpi.h>

/* Include the .h file required by API */
/* Prototypes for our local functions */
static int sample_Sense(SEOS_ROUTENTRY *pre);
static void sample_Free(SEOS_ROUTENTRY *pre);
static int sample_Send(LOGRECORD *plr, SEOS_ROUTENTRY *pre,
                       int notify, void *data);
/* 
   * We don't use the code of the new route type target, but
   * if we wanted more than one target type, we could use
   * it to distinguish between the two.
*/
static int our_dest_type_code;
/*
   * We preserve here the syslog priority required by
   * the configuration file.
   * This of course means that by storing it in global
   * variable we provide only one route line in the
   * configuration file for syslog. Other lines will just
   * overwrite this variable.
*/
static int syslog_priority;
/*
   * This like our 'main'. This function is the one called by
   * the selogrd.
*/
int lograpi_RegisterDestinations(void)
{
    static LOGRAPI_FUNCS funs =
    {sample_Send, sample_Free, sample_Sense};
    /*...*/
    return lograpi_RegisterTargetType(“syslog”, &funs,
                                      &our_dest_type_code);
}
static int sample_Sense(SEOS_ROUTENTRY *pre)
{
    /* Actually we have nothing to do, since syslog 
     * should be there.
     * Anyway, just to demonstrate what to do we will look
     * at the destination name in this type of function,
     * we will check that the destination is one of the
     * known syslog priorities.
     */
    typedef struct tagAllowedDestNames

    {
    char const *name;
    int code;
    } ALLOWED_DEST_NAMES;
    static ALLOWED_DEST_NAMES allowed_names[] =
    {
    {“LOG_EMERG”, LOG_EMERG},
    {“LOG_ALERT”, LOG_ALERT},
    {“LOG_CRIT”, LOG_CRIT},
    {“LOG_ERR”, LOG_ERR},
    {“LOG_WARNING”, LOG_WARNING},
    {“LOG_NOTICE”, LOG_NOTICE},
    {“LOG_INFO”, LOG_INFO},
    {“LOG_DEBUG”, LOG_DEBUG},
    {NULL, 0}
    };
    register int i;
    for (i = 0; allowed_names[i].name != NULL; i++) {
                if (strcmp(allowed_names[i].name, pre‑>out) == 0) {
                    /* Preserve the method we should use in syslog */
                        syslog_priority = allowed_names[i].code;
                        return 0;
                    }
    }
    return 1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static void sample_Free(SEOS_ROUTENTRY * pre)
{
    /*...*/      /* Now really nothing to be done */
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static int sample_Send(LOGRECORD * plr, SEOS_ROUTENTRY * pre,
                         int notify, void *data)
{
    char *as_string;

    if (notify)           /* Ignore any NOTIFY messages */
                    return 0;
    as_string = lograpi_MakeStringMessage(plr, data);
    if (as_string != NULL)
                    syslog(syslog_priority, as_string);
    return 0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

Notification Audit Log Records

CA ControlMinder lets you store notification information in the database as a string associated with a user or resource record. The administrator can specify mail addresses to be notified each time an attempt is made to access the resource. A notification request is stored as a special audit log record in the audit log file. selogrd routes the notification request to the mail or the screen address of the destination specified in the audit log record.

Notification records for a given event are identical to the standard audit log records associated with that event, except that notification records also have their targets stored at the beginning of the audit log record. The log codes for the notification records are simply the log codes of regular audit log records, offset by 2048. For example, a normal login audit log record has a log type code of 1. The notification log type code would be 2049. Note that an audit log record can appear in the audit log file followed by the notification record of the same event.

The format of the structure name a notification record is SEOSNF_AUDIT*. The exact names correspond to the matching audit log record name:

Notification Record

Audit Log Record

SEOSNF_AUDITADMIN

SEOS_AUDITADMIN

SEOSNF_AUDITGENR

SEOS_AUDITGENR

SEOSNF_AUDITINWARN

SEOS_AUDITINWARN

SEOSNF_AUDITLOGIN

SEOS_AUDITLOGIN

SEOSNF_AUDITWDWARN

SEOS_AUDITWDWARN

In each structure, the first field is SEOS_NOTIFYSTR, a buffer of up to 30 bytes to hold the destination string pulled from the database. The second field is the audit log record corresponding to this notification record.

Functions

CA ControlMinder provides the following functions:

driver_Register

Must be in your shared library and is called when selogrcd starts.

driver_UnRegister

Must be in your shared library and is called when selogrcd shuts down.

driver_RegisterDestination

Must be in your shared library and is called when selogrd starts.

driver_UnregisterDestination

Must be in your shared library and is called when selogrd shuts down.

lograpi_Interpret_Record

Converts an audit log record to the vector of text string pairs.

lograpi_MakeStringMessage

Converts an audit log record structure to the one‑line text format used by seaudit and seauditx.

lograpi_RegisterTargetType

Informs CA ControlMinder of the exact implementation details of the new target types being registered.

lograpi_UnregisterTargetType

Removes a destination type that was previously registered with the log routing daemon.

servlog_IsThereExit

Tests whether an exit function exists.

servlog_RegisterExit

Registers an exit function.

servlog_UnRegisterExit

Unregisters an exit function.

Your LogRoute API functions that implement a new destination type must supply code for the following tasks:

LogrApiFreeFunc

Frees any memory allocated by the user code for storage, sockets, and so on, and closes all network connections.

LogrApiSendFunc

Sends the selected audit log record to the user‑specified target.

LogrApiSenseFunc

Tests the target addresses in each configuration file line for correctness.

driver_Register Function

The driver_Register function is a predefined function called by the selogrcd daemon when it starts. You insert your own code into driver_Register to register all your new customized destination types. The function should register the exit functions needed for each audit record type.

Replace driver with the destination type as it appears in both the route configuration file and extension configuration file of selogrcd.

int driver_Register (void);

If the function succeeds, it should return 0. If it fails, it returns a nonzero integer error code. This return code can be seen in syslog. If selogrcd is using debug mode, the return code can also be seen on the screen.

More information:

driver_UnRegister Function

lograpi_RegisterTargetType Function

driver_UnRegister Function

The driver_UnRegister function is a predefined function called by the selogrcd daemon when it shuts down. You insert your own code into driver_UnRegister to unregister all the destination types you registered.

Replace driver with the destination type as it appears in both the route configuration file and extension configuration file of selogrcd.

int driver_UnRegister (void);

If the function succeeds, it should return 0. If it fails, it returns a nonzero integer error code. This return code can be seen in syslog. If selogrcd is using debug mode, the return code can also be seen on the screen.

More information:

driver_Register Function

driver_RegisterDestination Function

The driver_RegisterDestination function is a predefined function called by the selogrd daemon when the daemon starts. You insert your own code into driver_RegisterDestination to register all your new customized destination types.

Replace driver with the destination type as it appears in both the route configuration file and extension configuration file of selogrd.

The function is called when the shared library is loaded. The function should initialize the library and register the new target type by calling the function lograpi_RegisterTargetType.

int driver_RegisterDestination (void);

If the function succeeds, it should return 0. If it fails, it returns a nonzero integer error code. This return code can be seen in syslog. If selogrd is using debug mode, the return code can also be seen on the screen.

More information:

lograpi_RegisterTargetType Function

driver_UnregisterDestination Function

driver_UnregisterDestination Function

The driver_UnregisterDestination function is a predefined function called by the selogrd daemon at system termination. You insert your own code into driver_UnregisterDestination to unregister all the destination types you registered.

Important! Once you unregister a destination type, it cannot be registered again during the current session. However, all subsequent records are marked as if the send to that destination was successful. Therefore, do not unregister a target type unless you definitely will not be working with that target type again during the current session.

Replace driver with the destination type as it appears in both the route configuration file and extension configuration file of selogrd.

The function is called when the shared library is loaded. The function should initialize the library and register the new target type by calling the function lograpi_RegisterTargetType.

int driver_UnregisterDestination (void);

If the function succeeds, it should return 0. If it fails, it returns a nonzero integer error code. This return code can be seen in syslog. If selogrd is using debug mode, the return code can also be seen on the screen.

More information:

driver_RegisterDestination Function

lograpi_InterpretRecord Function

The lograpi_InterpretRecord function converts an audit log record to a vector of text string pairs. Each pair consists of the label of the field in the record and the text for that field. The vector itself ends when both members-label and value-are NULL pointers. The value can be a NULL pointer when a specific field has no value in the audit record.

If the function succeeds, it returns a pointer to the vector of structures. Each element in the vector is a structure that contains two members: a label and a value. The pointers Label and Value point to a static memory region that is overwritten by any call to the function. The vector itself ends when both members are NULL pointers.

The seauditx utility displays audit records in a format similar to this when the user requests more detail about displayed records.

SEOS_AUDLOGINTERP * lograpi_InterpretRecord P(LOGRECORD *plr, void *unc_buff);
plr

A pointer to the audit log record structure passed to the LogrApiSendFunc function.

unc_buff

A pointer to the uncompressed audit log record information passed to the LogApiSendFunc function.

More information:

lograpi_MakeStringMessage Function

lograpi_RegisterTargetType Function

The lograpi_RegisterTargetType function registers a new target or destination type with the log routing daemon. lograpi_RegisterTargetType provides the LOGRAPI_FUNCS structure with pointers to the three user functions used to sense a valid configuration file entry, send the record, and free the allocated memory space. lograpi_RegisterTargetType is normally called by the driver_RegisterDestination function, to register your functions with the log router.

If the function succeeds, it returns 0. If it fails, it returns an unsigned integer error code and assigns a value to the global variable errno according to the following table of values:

Return Value

ERRNO

Meaning

LOGRAPI_E_DESTFULL

ENOMEM

Destination table is full; maximum table size is 10 elements.

LOGRAPI_E_NULLPARAM

EINVAL

One of the parameters is NULL.

LOGRAPI_E_NOSENDFUNC

EINVAL

No send function specified.

int lograpi_RegisterTargetType (const char *name, LOGRAPI_FUNCS *funcs, int *code);
name

The name of the newly added destination type.

funcs

A pointer to a LOGRAPI_FUNCS structure containing the three destination type functions, LogrApiSendFunc, LogrApiFreeFunc, and LogrApiSenseFunc.

code

The code assigned to this target destination. The code is the value stored in the destination data member of the SEOS_ROUTENTRY structure.

More information:

driver_RegisterDestination Function

lograpi_UnregisterTargetType Function