20    Using the SIA Interface

This chapter documents the Security Integration Architecture (SIA) interfaces.

20.1    Overview

The Security Integration Architecture (SIA) allows the layering of local and distributed security authentication mechanisms onto the Tru64 UNIX operating system. The SIA configuration framework isolates security sensitive commands from the specific security mechanisms. The Tru64 UNIX security sensitive commands have been modified to call a set of mechanism-dependent routines. By providing a library with a unique set of routines, developers can change the behavior of security sensitive commands, without changing the commands themselves. The SIA defines the security mechanism-dependent interfaces (siad_*() routines) required for SIA configurability. Figure 20-1 illustrates the relationship of the components that make up the SIA.

The security sensitive commands are listed in Table 20-1.

Table 20-1:  Security Sensitive Operating System Commands

Command Description
chfn Changes finger information
chsh Changes login shell information
dnascd Spans DECnet
ftpd Serves the Internet File Transfer Protocol
login Authenticates users
passwd Creates or changes user passwords
rshd Serves remote execution
su Substitutes a user ID

Figure 20-1:  SIA Layering

Table 20-2 and Table 20-3 list the SIA porting routines.

Table 20-2:  SIA Mechanism-Independent Routines

SIA Routine Description
sia_init() Initializes the SIA configuration
sia_chk_invoker() Checks the calling application for privileges
sia_collect_trm() Collects parameters
sia_chg_finger() Changes finger information
sia_chg_password() Changes the user's password
sia_chg_shell() Changes the login shell
sia_ses_init() Initializes SIA session processing
sia_ses_authent() Authenticates an entity
sia_ses_reauthent() Revalidates a user's password
sia_ses_suauthent() Processes the su command
sia_ses_estab() Establishes the context for a session
sia_ses_launch() Logs session startup and any tty conditioning
sia_ses_release() Releases resources associated with session
sia_make_entity_pwd() Provides the password structure for SIAENTITY
sia_audit() Generates the audit records
sia_chdir() Changes the current directory safely (NFS-safe)
sia_timed_action() Calls with a time limit and signal protection
sia_become_user() su routine
sia_validate_user() Validate a user's password
sia_get_groups() Gets groups

Table 20-3:  SIA Mechanism-Dependent Routines

SIA Routine Description
siad_init() Initializes processing once per reboot
siad_chk_invoker() Verifys the calling program privileges
siad_ses_init() Initializes the session
siad_ses_authent() Authenticates the session
siad_ses_estab() Checks resources and licensing
siad_ses_launch() Logs the session startup
siad_ses_suauthent() Processes the su command
siad_ses_reauthent() Revalidates a user's password
siad_ses_release() Releases session resources
siad_chg_finger() Processes the chfn command
siad_chg_password() Invokes a function to change passwords
siad_chg_shell() Processes the chsh command
siad_getpwent() Processes getpwent and getpwent_r
siad_getpwuid() Processes getpwuid() and getpwuid_r()
siad_getpwnam() Processes getpwnam() and getpwnam_r()
siad_setpwent() Initializes a series of getpwent calls
siad_endpwent() Releases resources after a series of getpwent calls
siad_getgrent() Processes getgrent() and getgrent_r()
siad_getgrgid() Processes getgrgid() and getgrgid_r()
siad_getgrnam() Processes getgrnam() and getgrnam_r()
siad_setgrent() Initializes a series of getgrent() calls
siad_endgrent() Closes series of getgrent() calls
siad_chk_user() Determines if a mechanism can change the requested information
siad_get_groups() Fills in the array of a user's supplementary groups

The SIA establishes a layer between the security sensitive commands and the security mechanisms that deliver the security mechanism-dependent functions. Each of the security-dependent SIA routines can be configured to use up to four security mechanisms, called in varying orders.

The selection and order of the calls to the different security mechanisms is established by a switch table file, /etc/sia/matrix.conf (see Chapter 13), similar to the way /etc/svc.conf is used to control libc get* functions. However, the calling mechanism is distinctly different.

The SIA calling mechanism looks up the addresses of routines in the shared libraries and calls them to access the specific security mechanism routine. SIA provides alternative control and configuration for the getpw* and getgr* functions in Tru64 UNIX.

SIA layering establishes internationalized message catalog support and thread-safe porting interfaces for new security mechanisms and new security sensitive commands that need transparency. The thread safety is provided by a set of locks pertaining to types of SIA interfaces. However, because SIA is a layer between utilities and security mechanisms, it is the responsibility of the layered security mechanisms to provide reentrancy in their implementations.

The primary focus for SIA is to provide transparent interfaces for security sensitive commands like login, su, and passwd that are sufficiently flexible and extensible to suit future security requirements. Any layered product on Tru64 UNIX that is either creating a new security mechanism or includes security sensitive commands, requires SIA integration in order to preserve these transparent interfaces.

The SIA components consist of only user-level modules. The components resolve the configuration issues with respect to the security sensitive command's utilization of multiple security mechanisms. The SIA components do not resolve any kernel issues pertaining to the configuration and utilization of multiple security mechanisms.

20.2    SIA Layering

The layering introduced by SIA in Tru64 UNIX consists of the following two groups of interface routines:

sia_*()

The security mechanism-independent interface used by security sensitive commands.

siad_*()

The security mechanism-dependent interface supplied by each specific security mechanism.

Each security mechanism delivers a shared library containing the siad_*() routines and provides a unique security mechanism name to satisfy the configuration. The one word security mechanism name and the library name are used as keys in the matrix.conf file to specify which mechanisms to call and in what order.

The Tru64 UNIX security-sensitive commands have been modified to use the mechanism-independent sia_*() routines. These routines are used by the commands and utilities to access security functions yet remain isolated from the specific security technologies. Each sia_*() routine calls the associated mechanism-dependent siad_*() routines, depending on the selected configuration specified in the matrix.conf file. See Chapter 13 for a more detailed discussion of the file.

The mechanism-dependent siad_*() interface routines are defined by SIA as callouts to security mechanism-dependent functions provided by the security mechanisms. The matrix.conf file is used to determine which security mechanisms are called and in what order they are called for each SIA function.

The process of calling a particular module within a specified security mechanism and passing the required state is done by the mechanism-independent layer. The calling process uses shared library functions to access and lookup specific module addresses within specified shared libraries provided by the security mechanisms.

The naming of the security mechanism-dependent modules, siad_*() routines, is fixed to alleviate name conflicts and to simplify the calling sequence. Tru64 UNIX uses the dlopen() and dlsym() shared library interfaces to open the specified security-mechanism shared library and lookup the siad_*() function addresses. If you need to preempt the siad_*() routines, your names must be of the form _ _siad_* in your library and the library must be linked ahead of libc. See Appendix E for more information on the naming and preempting requirements.

20.3    System Initialization

The SIA provides a callout to each security mechanism on each reboot of the system. This callout is performed by the /usr/sbin/siainit program, which calls each of the configured security mechanisms at their siad_init() entry point. This allows the security mechanisms to perform a reboot initialization. A SIADFAIL response from the siad_init() call causes the system to not reboot and a SIA INITIALIZATION FAILURE message to be sent to the console. Consequently, only problems that would cause a security risk or would not allow root to log in should warrant a SIADFAIL response from the siad_init() call.

20.4    Libraries

SIA security mechanisms are configured as separate shared libraries with entry points that are SIA defined names. Each mechanism is required to have a unique mechanism identifier. The actual entry points in the shared library provided by the security mechanism are the same for each mechanism, siad_*() form entry points.

The default security configuration is the BASE security mechanism contained in libc. The default BASE security mechanism uses the /etc/passwd file, or a hashed database version, as the user database and the /etc/group file as the group's database. The default BASE mechanism also uses the network information service (NIS) if it is configured. In single-user mode or during installation the BASE security mechanism is in effect.

20.5    Header Files

The SIA interfaces and structures are defined in the /usr/include/sia.h and /usr/include/siad.h files. The sia*.h files are part of the program development subsets.

20.6    SIAENTITY Structure

The SIAENTITY structure contains session processing parameters and is used to transfer session state between the session processing stages. Example 20-1 is the SIAENTITY structure:

Example 20-1:  The SIAENTITY Structure

typedef struct siaentity {
    char *name;            /* collected name                */
    char *password;        /* entered or collected password */
    char *acctname;        /* verified account name         */
    char **argv;           /* calling command argument list */
    int  argc;             /* number of arguments           */
    uid_t  suid;           /* starting ruid                 */
    char *hostname;        /* requesting host NULL=>local   */
    char *tty;             /* pathname of local tty         */
    int can_collect_input; /* 1 => yes, 0 => no input       */
    int error;             /* error message value           */
    int authcount;         /* Number of consecutive         */
                           /* failed authent attempts       */
    int authtype;          /* Type of last authent          */
    struct passwd *pwd;    /* pointer to passwd struct      */
    char *gssapi;          /* for gss_api prototyping       */
    char *sia_pp;          /* for passport prototyping      */
    int *mech[SIASWMAX];   /* pointers to mech-specific data  */
                           /* allocated by mechanisms indexed */
                           /* by the mechind argument         */
} SIAENTITY;

20.7    Parameter Collection

The SIA provides parameter collection callback capability so that any graphical user interface (GUI) can provide a callback. The sia_collect_trm() routine is used for terminal parameter collection. Commands calling the sia_*() routines pass as an argument to the appropriate collection routine pointer, thus allowing the security mechanism to prompt the user for specific input. If the collection routine argument is NULL, the security mechanism assumes that no collection is allowed and that the other arguments must be used to satisfy the request. The NULL case is used for noninteractive commands. For reliability, use a collection routine whenever possible.

The can_collect_input argument is included in the session processing and disables the collection facility for input while allowing the output of warnings or error messages. Collection routines support simple form and menu data collection. Some field verification is supported to check parameter lengths and content (alphanumeric, numeric only, letters only, and invisible). The collection routine supplied by the security sensitive command or utility is responsible for providing the appropriate display characteristics.

The parameter collection capability provided by SIA uses the following interface definition in sia.h:

int sia_collect_trm(timeout, rendition, title,
				num_prompts, prompts);
 
int timeout               /* number of seconds to wait */
                          /* 0 => wait forever */
int rendition
   SIAMENUONE      1      /* select one of the choices given */
   SIAMENUANY      2      /* select any of the choices given */
   SIAFORM         3      /* fill out the form               */
   SIAONELINER     4      /* One question with one answer    */
   SIAINFO         5      /* Information only                */
   SIAWARNING      6      /* ERROR or WARNING message        */
 
unsigned char *title      /* pointer to a title string. */
                          /* NULL => no title */
 
int num_prompts           /* Number of prompts in collection */
 
prompt_t *prompts         /* pointer to prompts */
 
typedef struct prompt_t
   {
   unsigned char *prompt;
   unsigned char *result;
   int max_result_length; /* in chars */
   int min_result_length; /* in chars */
   int control_flags;
   } prompt_t;
 
control_flags
  SIARESINVIS  0x2   result is invisible
  SIARESANY    0x10  result can contain any ASCII chars
  SIAPRINTABLE 0x20  result can contain only printable chars
  SIAALPHA     0x40  result can contain only letters
  SIANUMBER    0x80  result can contain only numbers
  SIAALPHANUM  0x100 result can contain only letters and numbers

See the sia_collect_trm(3) reference page for more information on parameter collection.

20.8    Maintaining State

Some commands require making multiple calls to sia_*() routines and maintaining state across those calls. The state is always associated with a particular user (also called an entity). SIA uses the term entity to mean a user, program, or system which can be authenticated. The entity identifier is the user ID (UID). All security mechanisms which are ported to Tru64 UNIX must be administered such that a particular UID maps equivalently across each mechanism. This constraint allows for the interaction and coexistence of multiple security mechanisms. If a security mechanism has an alternative identifier for a user, it must provide a mapping to a unique UID for other mechanisms to properly interoperate and provide synchronized security information.

A pointer to the SIAENTITY structure (see Section 20.6) is used as an argument containing intermediate state identifying the entity requesting a security session function. The SIAENTITY structure also allows for the sharing of state between security mechanisms while processing a session.

The libc library provides for the allocating and freeing of primitives for SIAENTITY structures. The allocation of the SIAENTITY structures occurs as part of the session initialization routine, sia_ses_init(). The deallocation of the SIAENTITY structure occurs in the call to the session release sia_ses_release() routine. If errors occur during session processing (such as in the sia_ses_*authent() routines) and you give up instead of retrying, sia_ses_release() must be called to clean or free up the SIAENTITY structure related to the session. If errors occur during a sia_ses_estab() or sia_ses_launch() routine causing failure status to be returned, the routines call sia_ses_release().

20.9    Return Values

SIA supports the passing of a success or failure response back to the calling command or utility. The SIAENTITY structure has a reserved error code field (error), which is available for finer error definition.

The siad_ses_*() routines return bitmapped values that indicate the following status:

SIADFAIL

Indicates conditional failure. Lowest bit set to 0. Continue to call subsequent security mechanisms.

SIADSUCCESS

Indicates conditional success. Lowest bit set to 1.

SIADSTOP

Modifies the return to be unconditional. Second lowest bit set to 1. Included with either SIADFAIL or SIADSUCCESS.

20.10    Debugging and Logging

SIA supports a debuggingl logging capability that allows appending data to the /var/adm/sialog file. The SIA logging facility supports the following three log-item types:

EVENT

Success cases within the SIA processing

ERROR

Failures within the SIA processing

ALERT

Security configuration or security risks within the SIA interfaces

The sia_log() logging routine is available to security mechanisms and accepts formatting strings compatible to printf() format. Each log entry is time stamped. Example 20-2 is a typical /var/adm/sialog file.

Example 20-2:  Typical /var/adm/sialog File

SIA:EVENT Wed Feb  3 05:21:31 1995
Successful SIA initialization
SIA:EVENT Wed Feb  3 05:22:08 1995
Successful session authentication for terry on :0
SIA:EVENT Wed Feb  3 05:22:08 1995
Successful establishment of session
SIA:ERROR Wed Feb  3 05:22:47 1995
Failure to authenticate session for root on :0
SIA:ERROR Wed Feb  3 05:22:52 1995
Failure to authenticate session for root on :0
SIA:EVENT Wed Feb  3 05:22:59 1995
Successful session authentication for root on :0
SIA:EVENT Wed Feb  3 05:22:59 1995
Successful establishment of session
SIA:EVENT Wed Feb  3 05:23:00 1995
Successful launching of session
SIA:EVENT Wed Feb  3 05:24:40 1995
Successful authentication for su from root to terry
SIA:EVENT Wed Feb  3 05:25:46 1995
Successful password change for terry

The sia_log() routine is for debugging only. The _ses_* routines use audgen() for audit logging.

20.11    Integrating Security Mechanisms

Depending on the class or type of SIA processing being requested, the selection and order of security mechanisms may vary. A typical set of security mechanisms might include a local mechanism (one that is only concerned with the local system security) and a distributed security mechanism (one that is concerned with aspects of security that span several systems). SIA layering allows these two security mechanisms to either coexist or be better integrated.

An example of security mechanism integration is the log in or session processing. SIA layering passes state (SIAENTITY) between the various security mechanisms during the session processing. This state contains collected names and passwords and the current state of session processing. The local security mechanism can be designed to trust the authentication process of a previously run security mechanism, thus allowing authentication vouching. In this case, if a user is successfully authenticated by the distributed mechanism, the local mechanism can accept or trust that authentication and continue with session processing.

SIA also allows the local mechanism to not accept vouching. In this case, the local mechanism would be forced to do its own authentication process regardless of previous authentication outcomes. This typically results in the user being asked for several sets of user names and passwords. Although SIA allows any ordering of security mechanisms, it makes sense that those mechanisms that accept vouching be ordered after those that do not.

Notes

The default security mechanism, BASE, accepts authentication vouching.

The SIA layer deals with the isolation of security mechanisms from the commands' specific user interface preferences. To accomplish this isolation, the calling command provides a pointer to a parameter collection routine as an argument to the sia_*() routines. The collection routine must support simple form and menu type of processing. The definitions or the requirements of the collection routine are defined in sia.h. This separation of user interface from the security mechanisms allows for the flexibility to change the user interface to suit any workstation or dumb terminal model.

20.12    Session Processing

The session processing interfaces are associated with the process of a utility or command that needs to become or act as some other entity. Figure 20-2 illustrates the SIA routines and their relationship in a typical login session.

Figure 20-2:  SIA Session Processing

The session processing interfaces to the security mechanism-dependent routines (siad_*()) all use the same returns to determine the state of the session and whether it should continue. The returns are as follows:

SIADFAIL

A SIADFAIL response from a security mechanism siad_*() routine indicates that the security mechanism has failed but that processing should continue.

SIADFAIL or SIASTOP

A SIADFAIL | SIADSTOP response from a security mechanism siad_*() routine indicates that the security mechanism has failed and that the session processing should be stopped. This return is used if some major security problem or risk is found. Such an event should be sent to the sialog file as an ALERT.

SIADSUCCESS

The final response is SIADSUCCESS, which indicates that the security mechanism has successfully completed that phase of session processing. Under some conditions, a return of SIADSUCCESS | SIADSTOP is also useful.

Not all security mechanisms have processing required in each phase of the session processing. In general, the default response is SIADFAIL to force the other configured security mechanisms to produce the required SIADSUCCESS response. The only exceptions to this is the first and last stage of session processing. If a security mechanism has nothing to do in either session initialization or session release, it should return a SIADSUCCESS response. For all other phases of session processing, a SIADFAIL response is the default.

The session processing interfaces are typically called in the following order:

sia_ses_init()

Initialize the session.

sia_ses_authent()

Authenticate the session. Can be recalled on failure for retries.

sia_ses_estab()

Establish the session. On failure, calls sia_ses_release().

sia_ses_launch()

Launch the session. On failure, calls sia_ses_release().

sia_ses_release()

Release the session

The session routines must all have the same number and order of mechanisms to keep the mechanism index (mechind) consistent.

Example 20-3 is a code fragment that shows session processing for the login command.

Example 20-3:  Session Processing Code

		.
		.
		.
/* SIA LOGIN PROCESS BEGINS */
 
/* Logging of failures to sia_log is done within the libsia */
/* Logging to syslog is responsibility of calling routine   */
 
if((sia_ses_init(&entity, oargc, oargv, hostname, loginname, \
			ttyn, 1, NULL)) == SIASUCCESS) {
 
/***** SIA SESSION AUTHENTICATION *****/
 
   if(!fflag) {
      for(cnt=5; cnt; cnt--) {
         if((authret=sia_ses_authent(sia_collect,NULL,entity)) \
			== SIASUCCESS)
           break;
         else    if(authret & SIASTOP)
           break;
         fputs(MSGSTR(INCORRECT, "Login incorrect\n"), stderr);
      }
      if(cnt <= 0 || (authret & SIASTOP)) {
         sia_ses_release(&entity);
         exit(1);
      }
   }
 
/***** SIA SESSION ESTABLISHMENT *****/
 
   if(sia_ses_estab(sia_collect,entity) == SIASUCCESS) {
      /****** set up environment   *******/
      /* destroy environ. unless user requested preservation */
      if (!pflag) {
        pp = getenv("TERM");
        if (pp)
        strncpy(term, pp, sizeof term);
        clearenv();
   }
   (void)setenv("HOME", entity->pwd->pw_dir, 1);
      if(entity->pwd->pw_shell && *entity->pwd->pw_shell)
        strncpy(shell, entity->pwd->pw_shell, sizeof shell);
   (void)setenv("SHELL", shell, 1);
   if (term[0] == ' ')
      (void)strncpy(term, stypeof(tty), sizeof(term));
   (void)setenv("TERM", term, 0);
   (void)setenv("USER", entity->pwd->pw_name, 1);
   (void)setenv("LOGNAME", entity->pwd->pw_name, 1);
   (void)setenv("PATH", _PATH_DEFPATH, 0);
 
/***** SIA LAUNCHING SESSION *****/
 
   if(sia_ses_launch(sia_collect,entity) == SIASUCCESS) {
   /* 004 - start */
   if ((entity -> pwd           != NULL) &&
       (entity -> pwd -> pw_dir != NULL) &&
       (entity -> pwd -> pw_dir [0] != 0))
          sprintf (hush_path, "%s/%s",
             entity -> pwd -> pw_dir,
             _PATH_HUSHLOGIN);
   else    strcpy (hush_path, _PATH_HUSHLOGIN);
   quietlog = access(hush_path, F_OK) == 0;
   /* 004 - end */
   if(!quietlog)
      quietlog = !*entity->pwd->pw_passwd && \
			!usershell(entity->pwd->pw_shell);
         if (!quietlog) {
            struct stat st;
            motd();
            (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, \
				entity->pwd->pw_name);
            if (stat(tbuf, &st) == 0 && st.st_size != 0)
               (void)printf(MSGSTR(MAIL, "You have %smail.\n"),
                      (st.st_mtime > st.st_atime) ? MSGSTR(NEW, \
					"new ") : );
         }
         sia_ses_release(&entity);
 
/******* Setup default signals **********/
 
         (void)signal(SIGALRM, SIG_DFL);
         (void)signal(SIGQUIT, SIG_DFL);
         (void)signal(SIGINT, SIG_DFL);
         (void)signal(SIGTSTP, SIG_IGN);
 
         tbuf[0] = '-';
         (void)strcpy(tbuf + 1, (p = rindex(shell, '/')) ?
                         p + 1 : shell);
 
/****** Nothing left to fail *******/
 
         if(setreuid(geteuid(),geteuid()) < 0) {
            perror("setreuid()");
            exit(3);
         }
         execlp(shell, tbuf, 0);
         (void)fprintf(stderr, MSGSTR(NO_SHELL, \
		"login: no shell: %s.\n"), strerror(errno));
         exit(0);
      }
/***** SIA session launch failure *****/
    }
/***** SIA session establishment failure *****/
  }
  logerror(entity);
  exit(1);
}
 
logerror(entity)
SIAENTITY *entity;
{
  if(entity != NULL)
    {
    sia_ses_release(&entity);
    }
  syslog(LOG_ERR, MSGSTR(FAILURE3," LOGIN FAILURE "));
}
		.
		.
		.

20.12.1    Session Initialization

Session initialization is performed by the sia_ses_init() routine. The sia_ses_init() routine calls each configured security mechanism's siad_ses_init() entry point to do any processing associated with the start of a session processing sequence. The session initialization stage is responsible for setting up the SIAENTITY structure, which is used to maintain state though the different stages of session processing.

20.12.2    Session Authentication

The authentication stage of session processing is responsible for proving the identity for the session. This stage of the processing must determine the entity associated with the session. If the entity can not be determined, the authentication fails. If the authentication is successful, an entity is derived.

The top level SIA session authentication routine, sia_ses_authent(), calls the security mechanism-dependent siad_ses_authent() routines according to the configured sequence stored in the matrix.conf file. As the multiple authentication routines are called, the SIAENTITY structure is used to hold precollected parameters like the name, password, and eventually the associated /etc/passwd entry of the entity.

By using precollected arguments, the security mechanisms avoid recollecting arguments. An example is when root attempts to log in to a system configured to first call the DCE siad_ses_authent() routine followed by the local ENHANCED (enhanced security) siad_ses_authent() routine.

It is likely that the DCE authentication process will not be capable of authenticating root. However, it is capable of asking the user for a name and password, which are then passed on to the ENHANCED siad_ses_authent() routine using the SIAENTITY structure. This allows the ENHANCED mechanism to verify the root name and password, thus authenticating root. As soon as the session authentication stage is complete, the password field is cleared.

Each security mechanism-dependent authentication routine must have the ability to determine and set the entity on a successful authentication. If a security mechanism has its own private interpretation of the entity, it must provide a translation to the common SIA entity, user name and UID. Without this restriction there is no way to synchronize security mechanisms with respect to a common entity.

At the successful completion of the session authentication stage, the SIAENTITY structure must contain the user name and UID of the authenticated entity. If the session authentication fails, the calling command or program can call sia_ses_authent() again to retry the authentication process. Certain mechanisms may allow other mechanisms to vouch for this stage of session processing. This usually occurs when local mechanisms default their authentication process to other distributed mechanisms.

20.12.3    Session Establishment

The session establishment stage is invoked with sia_ses_estab() following a successful session authentication stage. The sia_ses_estab() routine is configured to call multiple security mechanism's siad_ses_estab() routines in the order defined in the matrix.conf file. The session establishment stage of session processing is responsible for checking mechanism resources and licensing to determine whether this session can be successfully launched. The determination of the passwd struct entry and any other required security context must occur in this stage. At the successful completion of the session establishment stage, the system is prepared to grant the session launching.

20.12.4    Session Launch

The session launch stage is responsible for the logging and the accounting of the session startup. The local mechanism is additionally responsible for setting the wtmp and utmp entries, and for setting the effective UID to the UID associated with the entity. The processing by the setgid() and initgroup() routines as well as lastlog updating are also done by the local mechanism. Only catastrophic errors should be able to stop the session from continuing.

20.12.5    Session Release

The last stage of the session processing sequence (either successful or failed) is the call to the sia_ses_release() routine. This routine frees all session processing resources, such as the SIAENTITY structure. Each configured mechanism is called to release any resources which are no longer required for the session.

20.12.6    Specific Session Processing

The following sections describe specific session processing for the login, rshd, and rlogind commands. See Section 20.12 for a generic description of session processing.

20.12.6.1    The login Process

The most common case of session processing is the login process becoming the entity associated with a user. The entity is the unique SIA identifier for any person or process that can be authenticated and authorized. The code in Example 20-3 is from the login command.

20.12.6.2    The rshd Process

Session processing for /usr/sbin/rshd differs from login. The rshd process requires calling ruserok() to check the .rhosts and host.equiv files for authorization. If ruserok() fails, the rshd fails.

20.12.6.3    The rlogind Process

The rlogind, program executes the login command with the -f flag if its call to ruserok() is successful, and without -f if the call to ruserok() is unsuccessful. If login is executed without the -f flag, sia_ses_authent() is called, which prompts for a user name and password, if required.

20.13    Changing Secure Information

The routines described in this section handle the changing of the traditional /etc/passwd entry information. This class of routines could be extended to handle other types of common secure information. Only the traditional passwd, chfn, and chsh types of command processing are specified. Each of these routines follows the same operational model. When a user requests a change, the routines in this class check each mechanism that was configured by calling siad_chk_user() to determine whether the user is registered with the mechanism. Once it is determined that the user is registered with more than one security mechanism, the user is given a menu selection by the collection routine, to choose which mechanism is targeted for the change. If only one mechanism is configured to handle the request then that mechanism is called directly.

20.13.1    Changing a User's Password

To change a password, the sia_chg_password() routine calls the configured mechanisms by using the siad_chg_password() routine. To determine which mechanisms support a particular user, the siad_chk_user() call is made to all mechanisms configured for the siad_chg_passwd() routine. When multiple mechanisms claim registry of a user, the user is given a selection to choose from. If the user is only registered with one mechanism, then that mechanism is called.

20.13.2    Changing a User's Finger Information

The sia_chg_finger() routine calls the configured mechanisms by the siad_chg_finger() routine to change finger information. To determine which mechanisms support a particular user, the siad_chk_user() call is made to all mechanisms configured for the siad_chg_finger() routine. When multiple mechanisms claim registry of the user, the user is given a selection menu to choose one from. If the user is only registered with one mechanism, then that mechanism is called.

20.13.3    Changing a User's Shell

The sia_chg_shell() routine calls the configured mechanisms by the siad_chg_shell() routine to change a user's login shell. To determine which mechanisms support a particular user, the siad_chk_user() call is made to all mechanisms configured for the siad_chg_shell() routine. When multiple mechanisms claim registry of the user, the user is given a selection menu from which to choose a mechanism. If the user is only registered with one mechanism, then that mechanism is called.

20.14    Accessing Security Information

The SIA interfaces described in the following sections handle the access to the traditional UNIX /etc/passwd and /etc/group information. You can create routines to handle the access of other common secure information. Mechanism-dependent security information access should not be handled by the SIA interfaces unless nearly all mechanisms support the type of information being accessed.

The sia_context and mech_contexts structures, defined in sia.h, are used to maintain state across mechanisms. The structures are as follows:

struct mech_contexts {
        void *value;
        void (*destructor)();
};
 
struct sia_context {
        FILE *fp;
        union {
        struct group *group;
        struct passwd *pass;
        } value;
        int pkgind;
        unsigned buflen;
        char *buffer;
        struct mech_contexts mech_contexts[SIASWMAX];
};

Because the getgr*() and the getpw*() routines have SIA interfaces, security mechanisms need only provide one routine for both reentrant and non-reentrant, threadsafe applications. This is accomplished by the sia_getpasswd() and sia_getgroup() routines which encapsulate the arguments in a common form for the security mechanism's siad_*() routines.

20.14.1    Accessing /etc/passwd Information

Access to traditional /etc/passwd entries is accomplished by the getpw*() routines in libc and libc_r. The sia_getpasswd() routine in the SIA layer preserves the calling semantics of the current getpw*() routines and converts them into one common routine used for both single and multithreaded processes. By doing this conversion, security mechanisms need only support one set of getpw*() routines. The processing of the getpwent() routine is accomplished by calling each configured security mechanism in the predefined order until all entries have been exhausted.

20.14.2    Accessing /etc/group Information

Access to traditional /etc/group entries is accomplished by the getgr*() routines in libc and libc_r. The sia_getgroup() routine in the SIA layer preserves the calling semantics of the current getgr*() routines and converts them into one common routine used for both single and multithreaded processes. The conversion to a single routine eases the security mechanism port by reducing the number of routines required. The processing of the getgrent() routine works by calling each configured security mechanism in the predefined order until all group entries have been exhausted.

20.15    Session Parameter Collection

The SIA session interfaces and the interfaces that change secure information use a predefined parameter collection capability. The calling application passes the address to a parameter collection routine through the SIA to the siad_*() routines. The collection routine allows different security mechanisms to prompt the user for different parameters without having to be aware of the user interface details.

This capability isolates the SIA security mechanisms from the user interface and the ability to do simple forms and menus. This collection capability is sufficiently limited to allow ease of implementation by different user-interface packages or windowing systems. However, the collection routines must support simple (up to eight item) menu or form styles of processing. On dumb terminals, forms processing becomes a set of one line questions. Without this capability, the application needs to be modified to support new security questions.

20.16    Packaging Products for the SIA

The SIA defines the security mechanism components that are required to port to the Tru64 UNIX system. These components are as follows:

The shared library must contain all of the siad_*() routines described in this chapter. The default dummy routine for any siad_*() routine always returns the SIADFAIL failure response. If a security mechanism is supplying dummy routines, these routines should not be configured into the matrix.conf file.

The /etc/sia/matrix.conf file contains one line for each siad_*() routine. This line contains the mechanism identifiers (called mech_types) and the actual path to the security mechanism library. The sia_*() routines use this set of keys to call mechanisms in a right to left ordering. Example 13-1 illustrates the default matrix.conf settings for Tru64 UNIX.

If the DCE security mechanism is to be called first followed by the BASE (BSD) security mechanism, the configuration line for siad_init() might look like the following:

siad_init=(DCE,/usr/shlib/libdcesia.so)(BSD,libc.so)

Layered security products must deliver pretested matrix.conf files on their kits. The modification of a SIA matrix.conf file must be followed by a reboot. System administrators must never be required to edit a live matrix.conf file hand.

See Chapter 13 for a more detailed discussion of the matrix.conf file.

20.17    Security Mechanism-Dependent Interface

Security mechanisms are required to provide all of the siad_*() entry points (See Table 20-3). The default stub routine should simply return SIADFAIL. With the exception of the session routines, no stubs should ever be called in the /etc/sia/matrix.conf file. The session routines must all have the same number and order of mechanism to keep the mechanism index (mechind) consistent. However, if an error in configuration occurs, the stub routines deliver the appropriate SIADFAIL response.

The order of security mechanisms in the /etc/sia/matrix.conf file is the same for each class of interfaces. Therefore, if a security mechanism supports session processing it is called in the same order for all the session related interfaces.

The layered security mechanism should provide a set of private entry points prefixed by mechanism_name__ for each of the siad_*() entries used for internal calls within the mechanism to siad_*() routines. An example of this is in the BASE mechanism in libc. To assure that the BASE mechanism is calling its own siad_getpwuid() routine, a separate entry point is created and called from the siad_getpwuid() entry as follows:

int siad_getpwuid(uid_t uid, struct passwd *result, \
                                   char *buffer, int buflen)
        {
        return(bsd_siad_getpwuid(uid,result,buffer,buflen));
        }
 
static int bsd_siad_getpwuid(uid_t uid, struct passwd *result, \
                                       char *buffer, int buflen)
        {
        /* The BSD security mechanism siad_getpwuid() routine */
        }

If the convention of supplying internal names is used for all of the siad_*() entry points, a layered security mechanism can then produce a separate library containing all the security mechanism-dependent code. This leaves the configured shared library with only stubs that call the other library.

Security mechanisms generally fall into two categories: local and distributed. The local security mechanism is responsible for establishing all of the local context required to establish a session on the local system. There are two local security mechanism in Tru64 UNIX: the BASE mechanism and the ENHANCED mechanism.

Distributed mechanisms, like DCE, are more concerned with establishing distributed session context like Kerberos tickets. However, the distributed security mechanism may provide some local context that can be used by the local security mechanism. The distributed security mechanism may also provide a sufficiently strong authentication to allow a local mechanism to trust it for authentication. This notion of one mechanism trusting another is called vouching and allows the user to be authenticated only once to establish a login session. Local mechanisms should always be configured last in the calling sequences.

All of the SIA capabilities listed in this section can be configured to use multiple security mechanisms.

20.18    Single User Mode

If you want to have your own single-user security mode, you need to rebuild and replace the commands and utilities affected, such as any staticly linked binaries found in /sbin. This can be accomplished by providing a siad_*() routine library to precede libc in the link order for the affected commands.

The new routines need to override the _ _siad_*() routines, as opposed to the siad_*() routines. The siad_*() naming convention is the weak symbol, while the _ _siad_*() convention is the strong symbol entry point that is actually used. See Appendix E for more information about routine naming conventions.