Previous Topic: User InformationNext Topic: authxapi_RegisterExitFunction Function


For UNIX

After you compile your code, generate a shared library that contains the compiled version of your code. The apisamples directory contains sample functions and a makefile that demonstrate the process. Note that compilation for shared libraries usually requires additional compiler parameters to create position‑independent code. Consult your compiler or linker documentation to learn how to create shared libraries in your particular system.

After you have written your code and created a shared library, add your shared library to the “on‑demand” shared libraries configuration file relevant to the program to which your code should link.

If you have written a shared library for one of the following daemons or programs, add your shared library to the relevant file (you may need to create these .ext files using the examples in the apisamples directory):

Each file contains two columns: the driver name and the shared library path. By convention, the driver name is a string that has the same name as your target type; however, it can be any valid C language symbol.

For example, if you have written code to implement a pager, your target name should be pager and the complete file entry would be:

pager /usr/local/lib/libseospager.so
This file entry means that the daemon seosd loads the shared library at startup and calls your function:
/usr/local/lib/libseospager.so

Although some systems support a predefined function called _init, we recommend that you use the functiondriver_RegisterDestination instead. This is really the first function called from the shared library. The function driver_RegisterDestination registers your new target type.

On daemon shutdown, we recommend that you use the function driver_UnregisterDestination instead of the predefined function _fini.

Note: Using the CA ControlMinder functions instead of the predefined system functions gives your code greater portability.

The daemon seosd uses the same file configuration format as sepass.

For Windows

After you compile your code, generate a dynamic link library that contains the compiled version of your code. The SDK directory contains sample functions and a makefile to demonstrate the process. Note that compilation for dynamic link libraries usually requires additional compiler parameters. Consult your compiler or linker documentation to learn how to create dynamic link libraries in your particular system.

After you have written your code and created a dynamic link library, you should install it in the CA ControlMinder registry tree as follows:

  1. Create a key with any name you choose under the following existing key:
    HKEY_LOCAL_MACHINE\Software\ComputerAssociates\AccessControl\Exits\Engine
    
  2. Under the newly created sub-key create two values:
System Calls
For UNIX

Since CA ControlMinder intercepts operating system calls, not all system activities can be allowed while you are in the midst of an authorization action. The following functions cannot be called from an Exits API function of seosd:

In This Environment:

Do Not Use These Functions:

NIS or DNS servers running CA ControlMinder; Solaris 2.5.x and later

getgrent
getgrgid
etgrnam
gethostbyaddr
gethostbyname
gethostent
getnetbyaddr
getnetbyname
getnetent
getprotobyname
getprotobynumber
getprotoent
getpwent
getpwnam
getpwuid
getservbyname
getservbyport
getservent

Any station running CA ControlMinder

getrpcbyname
getrpcbynumber
getrpcent

Error Codes

CA ControlMinder uses an error code defined as an integer, composed of two bytes. The MSB contains a layer code and the LSB contains an error code specific to that layer. This allows up to 256 different layers with 256 different error codes each. To simplify error code management, CA ControlMinder uses the macro _SEOS_RC. The Exits API also uses the macro AUTHXAPI_MODULE to define the layer code. Do not use these macros yourself in your code or you may have compilation problems.

Return Codes

CA ControlMinder uses the following convention for return codes: a return value of zero indicates success; any other value indicates an error.

Exits API Examples

The CA ControlMinder package includes the following two sample programs demonstrating use of the Exits API.

CA ControlMinder Daemon Exits for UNIX

The apisamples directory contains the API header files (in the include subdirectory) and the library functions (in the lib subdirectory).

The following program calls a special user‑defined exit function upon any action by the seosd daemon. The function keeps statistics on the number of times each action is executed. When the function senses a login for user root, it simply prints the information gathered. A more detailed explanation of the main points of this function follows the source code.

/*=========================================================
Project  : eTrust
Module   : eTrust
Version  : 8.0
File     : seosdexits.c
Purpose  : eTrust daemon exits sample.
===========================================================

Copyright :
Copyright 2004 Computer Associates International, Inc.
===========================================================*/
#define __SEOSEXIT_C
/* System headers                       :
   *  sys/types.h                       : we cust using uid_t
   *  stdio.h                           : printf
   *  string.h & memory.h               : memcpy
 */
#include sys/types.h
#include stdio.h
#include string.h
#include memory.h

/* authx API header file */
#include authxapi.h

/* This a sample program for making an exit module
 *  for Access Control.
 * The module only 'printf' the information and
 * gathers statistics on the # of events.
 * When the 'root' user logs in the statistics
 * are printed.
 */

typedef struct
{   int nPreRes;
    int nPostRes;
    int nPreLogin;
    int nPostLogin;
    int nPreInet;
int nPostInet;
} EXIT_CALLS_COUNTERS;

static EXIT_CALLS_COUNTERS counters;

static void print_my_statistics(void)
{
    printf(“General Resource ... Pre %6d Post %6d\n”
           “Login .............. Pre %6d Post %6d\n”
           “Internet TCP ....... Pre %6d Post %6d\n”,
           counters.nPreRes, counters.nPostRes,
           counters.nPreLogin, counters.nPostLogin,
           counters.nPreInet, counters.nPostInet);
}

static int ExitFunc_PreResource(void *data, SEOS_EXITRES *p_sexr)
{
    SEOS_EXITGENR *ptr;

    ptr = (SEOS_EXITGENR *)data;
    counters.nPreRes++;
    printf(“Pre General Resource Class %s\n”, ptr‑>szClass);
    return 0;
}

static int ExitFunc_PostResource(void *data, SEOS_EXITRES *p_sexr)
{
    SEOS_EXITGENR *ptr;

    ptr = (SEOS_EXITGENR *)data;
    counters.nPostRes++;
    printf(“Post General Resource Class %s\n”, ptr‑>szClass);
    return 0;
}


static int ExitFunc_PreLogin(void *data, SEOS_EXITRES *p_sexr)
{
    SEOS_EXITLOGIN *p_sexl;
    char buff[20];
    char const *p;
    p_sexl = (SEOS_EXITLOGIN *)data;
    counters.nPreLogin++;
    if (p_sexl‑>szUname == NULL)

       {p = buff; sprintf(buff, “UID=%u”, p_sexl‑>luid);}
    else
        p = p_sexl‑>szUname;
    printf(“Pre Login For %s\n”, p);
    /* For ROOT print some statistics */
    if (p_sexl‑>luid == (uid_t)0)
        print_my_statistics();
    return 0;
}
static int ExitFunc_PostLogin(void *data, SEOS_EXITRES *p_sexr)
{
    SEOS_EXITLOGIN *p_sexl;
    char buff[20];
    char const *p;
    p_sexl = (SEOS_EXITLOGIN *)data;
    counters.nPostLogin++;
    if (p_sexl‑>szUname == NULL)
       {p = buff; sprintf(buff, “UID=%u”, p_sexl‑>luid);}
    else
        p = p_sexl‑>szUname;
    printf(“Post Login For %s\n”, p);
    /* For ROOT print some statistics */
    if (p_sexl‑>luid == (uid_t)0)
        print_my_statistics();
    return 0;
}
static int ExitFunc_PreInet(void *data, SEOS_EXITRES *p_sexr)
{
    /* Don't do too much work on TCP */
    counters.nPreInet++;
    return 0;
}
static int ExitFunc_PostInet(void *data, SEOS_EXITRES *p_sexr)
{
    /* Don't do too much work on TCP */
    counters.nPostInet++;
    return 0;
}
int sample_RegisterExit(void)
{
    int rc;
    memset(&counters, 0, sizeof(counters));
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_PREGNRES,
         ExitFunc_PreResource);
    if (rc) return rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_POSTGNRES,
         ExitFunc_PostResource);
    if (rc) return rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_PRELOGIN,
         ExitFunc_PreLogin);
    if (rc) return rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_POSTLOGIN,
         ExitFunc_PostLogin);
    if (rc) return rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_PREINET,
         ExitFunc_PreInet);
    if (rc) return rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_POSTINET,
         ExitFunc_PostInet);
    return rc;
}
void sample_UnregisterExit(void)
{
    /* We don't have anything to do in this example */
}

The authxapi.h header file contains the prototypes and definitions required to use the API. The code declares a new type EXIT_CALLS_COUNTER. This structure consists of counters for each event the API registers. A static variable of this new local type is declared. The general resource check and TCP/IP request functions listed are simple counters. The login functions have the same counters and also compare the user ID of the logged‑in user to 0. The login functions take advantage of the fact that the UNIX user ID for root is 0 to avoid fetching the real user information from system databases.

Note: This example prints to the screen. CA ControlMinder daemons should not use screen output as it causes a significant decline in performance.

CA ControlMinder SeOS Engine Exits for Windows

The SDK directory contains the API header files (in the include subdirectory) and the library functions (in the lib subdirectory).

The following program calls a special user-defined exit function upon any action by the seosd service. The function keeps statistics on the number of times each action is executed. When the function senses a login for user Administrator, it simply prints the information gathered. A more detailed explanation of the main points of this function follows the source code.

/*========================================================================
   Project:    eTrust Access Control 8.0 for Windows NT/2000
   Module:     eTrust Engine Exits sample.
   File:       main.c
   Purpose:    Sample for eTrust Engine Exits DLL to demonstrate how user
               can use eTrust Engine authorization in Pre and Post checks.
   Usage:      Build ExitsExample.dll and use eTrust Access Control 8.0 for 
               Windows NT/2000 documentation to config your registry and file
               system.
   ========================================================================
     Copyright 2004 Computer Associates International, Inc.
   ======================================================================== */

#include <stdio.h>
#include <authxapi.h>

typedef struct
{
     int nPreRes;
     int nPostRes;
     int nPreLogin;
     int nPostLogin;
} EXIT_CALLS_COUNTERS;

EXIT_CALLS_COUNTERS counters = { 0 };

static void print_my_statistics(void)
{
     //
     // print statistic check counters
     //
     printf("General Resource ... Pre %6d Post %6d \n"
             "Login................Pre %6d Post %6d \n",
             counters.nPreRes, counters.nPostRes,
             counters.nPreLogin, counters.nPostLogin);
}

static int ExitFunc_PreResource(void* data, SEOS_EXITRES *p_sexr)
{
     SEOS_EXITGENR *ptr;

     ptr = (SEOS_EXITGENR *) data;

     counters.nPreRes++;

     //
     // Pre check: Print eTrust Class name of the resource
     //
     printf("Pre General Resource %s of Class %s\n", ptr->szRes, ptr->szClass);
     return 0;
}

static int ExitFunc_PostResource(void* data, SEOS_EXITRES *p_sexr)
{
     SEOS_EXITGENR *ptr;

     ptr = (SEOS_EXITGENR *) data;
     counters.nPostRes++;

     //
     // Post check: Print eTrust Class name of the resource
     //

     printf("Post General Resource %s of Class %s\n", ptr->szRes, ptr->szClass);

     return 0;
}

static int ExitFunc_PreLogin(void* data, SEOS_EXITRES *p_sexr)
{
     SEOS_EXITLOGIN *p_sexl;
     char buff[20];
     char const *p;

     p_sexl = (SEOS_EXITLOGIN*) data;
     counters.nPreLogin++;
     if(p_sexl->szUname == NULL)
     {
          p = buff;
          sprintf(buff, "UID = %u", p_sexl->luid);
     }
     else
          p = p_sexl->szUname;

     //
     // For Pre Login check: print the Login User name
     //
     printf("Pre Login For %s from terminal %s\n", p, p_sexl->szTerm);

     if(strstr(p_sexl->szUname, "Administrator") != NULL)
     {
          print_my_statistics();
     }

     return 0;
}

static int ExitFunc_PostLogin(void* data, SEOS_EXITRES *p_sexr)
{
     SEOS_EXITLOGIN *p_sexl;
     char buff[20];
     char const *p;

     p_sexl = (SEOS_EXITLOGIN*) data;
     counters.nPostLogin++;

     if(p_sexl->szUname == NULL)
     {
          p = buff;
          sprintf(buff, "UID = %u", p_sexl->luid);
     }
     else
          p = p_sexl->szUname;

     //
     // For Post Login check: print the Login User name
     //
     printf("Post Login For %s from terminal %s\n", p, p_sexl->szTerm);

     if(strstr(p_sexl->szUname, "Administrator") != NULL)
     {
          print_my_statistics();
     }

     return 0;
}

typedef int(*PFNEXIT)(void);


// Function name: SM_RegisterExit
// Description: Export exits function
// Return type: int 0
// Argument: IN/OUT PFNEXIT pfnExit[] - array of user defined functions
// Argument: IN/OUT DWORD *pdwType - array of Engine events
_declspec(dllexport) int __stdcall SM_RegisterExit(PFNEXIT pfnExit[], PDWORD pdwType)
{
     pfnExit[0] = (PFNEXIT)ExitFunc_PreLogin;
     pfnExit[1] = (PFNEXIT)ExitFunc_PostLogin;
     pfnExit[2] = (PFNEXIT)ExitFunc_PreResource;
     pfnExit[3] = (PFNEXIT)ExitFunc_PostResource;
     pdwType[0] = AUTHXAPI_EV_PRELOGIN;
     pdwType[1] = AUTHXAPI_EV_POSTLOGIN;
     pdwType[2] = AUTHXAPI_EV_PREGNRES;
     pdwType[3] = AUTHXAPI_EV_POSTGNRES;
     return 0;
}

Additionally you will need another .def file in the project that contains:

The authxapi.h header file contains the prototypes and definitions required to use the API. The code declares a new type EXIT_CALLS_COUNTER. This structure consists of counters for each event the API registers. A static variable of this new local type is declared. The general resource check functions listed are simple counters. The login functions have the same counters and also compare the user name of the logged-in user to Administrator.

Note: This example prints to the screen. CA ControlMinder services should not use screen output because it is not a console application.

Password Utilities Exits
For UNIX

The following code demonstrates a simple user exit function for password verification. This code compares the potential password to the string password and denies permission to choose the password if a match is found.

/*=========================================================
Project    : eTrust
Module     : eTrust
Version    : 8.0
File       : exit.c
Purpose    : Example of exit function for passwords utilities
===========================================================
Copyright :
Copyright 2004 Computer Associates International, Inc.
===========================================================*/
/* Example for using password library to extend password rules*/
/* This function verifies the password before Access Control */
/* does. To override Access Control checks, use result */
/* SEOS_EXITR_PASS.      */
/* Look at Makefile.exits for compilation options. */

#include API/authxapi.h

/* This function does not allow user to use the word “password”*/
/* as the new password.                                        */
int ExitFunc_PreVerify(void *sexp, SEOS_EXITRES *sexr)
{
    if (strcmp(((SEOS_EXITPASS *) sexp)‑>szPass,”password”) == 0)
    {
       printf(“new password is refused by exit function\n”);
       sexr‑>result = SEOS_EXITR_DENY;
                  /* Do not allow that password */
    }
    else
       sexr‑>result = SEOS_EXITR_CHECK;
                  /* Continue with Access Control checks  */
    return 0;
}
/* must register the above exit function */
int sample_RegisterExit(void)
{
    int rc;
    rc = authxapi_RegisterExitFunction(AUTHXAPI_EV_PREVERPWD,
             ExitFunc_PreVerify);
    if (rc) return rc;
}
void sample_UnregisterExit(void)
{
    /* Nothing to do really in this case */
}
For Windows

The following code demonstrates a simple user exit function for password verification. This code compares the potential password to the string password and denies permission to choose the password if a match is found.

/* ========================================================================
     Project: eTrust Access Control 8.0 for Windows NT/2000    
     Module: eTrust Password Exits sample.
     File: main.c
     Purpose: Sample for eTrust Password Exits DLL to demonstrate how user
an
              use eTrust Password authorization in Pre and Post checks.
     Usage: Build PasswordExitsExample.dll and use eTrust Access Control
.0 for
            Windows NT/2000 documentation to config your registry and file
            system.
  
=======================================================================
     Copyright 2004 Computer Associates International, Inc.
  
======================================================================= */

#include <stdio.h>
#include <authxapi.h>

static int ExitFunc_PreVerifyPassword(void* data, SEOS_EXITRES *p_sexr)
{
     SEOS_EXITPASS *ptr;

     ptr = (SEOS_EXITPASS *) data;
    
     if (strcmp(ptr->szPass, "password") == 0)
     {
          p_sexr->result = SEOS_EXITR_DENY;
          /* Do not allow that password */
     }
     else
     {
          /* Continue with Access Control checks */
          p_sexr->result = SEOS_EXITR_CHECK;
     }

     return 0;
}

typedef int(*PFNEXIT)(void);


// Function name: PWD_RegisterExit
// Description: Export exits function
// Return type: int 0
// Argument: IN/OUT PFNEXIT pfnExit[] - array of user defined functions
// Argument: IN/OUT DWORD *pdwType - array of Engine events
_declspec(dllexport) int __stdcall PWD_RegisterExit(PFNEXIT pfnExit[],
DWORD pdwType)
{
     pfnExit[0] = (PFNEXIT)ExitFunc_PreVerifyPassword;
     pdwType[0] = AUTHXAPI_EV_PREVERPWD;
     return 0;
}

Note: In order to use password-related exits, after installing the exits dynamic link library in the registry, you must reboot the machine. This is mandatory because the pwdchange dynamic link library that handles CA ControlMinder password verification is loaded only when the machine starts up.

Functions for UNIX

The Exits API functions provided by CA ControlMinder are grouped according to the following categories:

General Functions

authxapi_IsThereExitFunction

Checks if an Exits API function for a specific event has been registered with CA ControlMinder.

authxapi_RegisterExitFunction

Registers your new Exits API function with CA ControlMinder.

authxapi_UnregisterExitFunction

Removes an Exits API function that was previously registered with CA ControlMinder.

Database Interface Functions

authxapi_FreeListValues

Frees the memory allocated during a previous call to the function authxapi_GetObjectListValue.

authxapi_GetObjectListValue

Retrieves the values of a list value property from a database object.

authxapi_GetObjectProperty

Retrieves the value of a single value property from a database object.

authxapi_GetUserInfo

Retrieves user name when given a user handle from an Exits API function.

Shared Library Functions

driver_RegisterExit

Provided by the extension and called on program startup.

driver_UnregisterExit

Provided by the extension and called on program termination.