This chapter contains the following information:
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 6-1
illustrates the relationship of the components that make up the SIA.
The security-sensitive commands are listed in
Table 6-1.
Table 6-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 |
Table 6-2
and
Table 6-3
list
the SIA porting routines.
Table 6-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 6-3: SIA Mechanism-Dependent Routines
SIA Routine | Description |
siad_init() |
Initializes processing once per reboot |
siad_chk_invoker() |
Verifies 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 Security Administration), 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 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.
6.2 SIA Architecture
The layering architecture 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 Security Administration 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 look up 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 look up the
siad_*
() function addresses.
If you need to preempt the
siad_*
() routines, your names
must be of the form
_
in your library and
the library must be linked ahead of
libc
.
See
Section 6.17
for more information on the naming and preempting requirements.
6.2.1 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.
6.2.2 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.
6.3 SIA 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 an 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.
6.4 SIAENTITY Structure
The SIAENTITY structure contains session processing parameters and is used to transfer session state between the session processing stages. Example 6-1 shows the SIAENTITY structure.
Example 6-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;
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
sia_collect_trm
()interface which is defined in
sia.h
.
See
Example 6-2.
Example 6-2: The sia.h Definition for Parameter Collection
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)6.6 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 6.4) 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 an
sia_ses_estab()
or
sia_ses_launch
() routine causing failure status to be
returned, the routines call
sia_ses_release
().
6.7 SIA 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:
Indicates conditional failure. Lowest bit set to 0. Continue to call subsequent security mechanisms.
Indicates conditional success. Lowest bit set to 1.
Modifies the return to be unconditional. Second lowest bit set to 1. Included with either SIADFAIL or SIADSUCCESS.
SIA supports
a debugging and logging capability that allows appending data to the
/var/adm/sialog
file.
The SIA logging facility supports the following
three log-item types:
Success cases within the SIA processing
Failures within the SIA processing
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 6-3
is a typical
/var/adm/sialog
file.
Example 6-3: Typical /var/adm/sialog File
SIA:EVENT Wed Feb 3 05:21:31 1999 Successful SIA initialization SIA:EVENT Wed Feb 3 05:22:08 1999 Successful session authentication for terry on :0 SIA:EVENT Wed Feb 3 05:22:08 1999 Successful establishment of session SIA:ERROR Wed Feb 3 05:22:47 1999 Failure to authenticate session for root on :0 SIA:ERROR Wed Feb 3 05:22:52 1999 Failure to authenticate session for root on :0 SIA:EVENT Wed Feb 3 05:22:59 1999 Successful session authentication for root on :0 SIA:EVENT Wed Feb 3 05:22:59 1999 Successful establishment of session SIA:EVENT Wed Feb 3 05:23:00 1999 Successful launching of session SIA:EVENT Wed Feb 3 05:24:40 1999 Successful authentication for su from root to terry SIA:EVENT Wed Feb 3 05:25:46 1999 Successful password change for terry
The
sia_log
() routine is for debugging only.
The
_ses_*
routines use
audgen
() for audit logging.
6.9 SIA 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 should 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 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 the
flexibility to change the user interface to suit any workstation or dumb terminal
model.
6.10 SIA 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 6-2 illustrates the SIA routines and their relationship in a typical login session.
Figure 6-2: SIA Login Session Processing
The session processing interfaces to the security mechanism-dependent
routines (siad_*()
) use the same returns to determine the
state of the session and whether it should continue.
The returns are as follows:
A SIADFAIL response from a security
mechanism
siad_*()
routine indicates that the security
mechanism has failed but that processing should continue.
A SIADFAILsiad_*()
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.
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
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 are the first and last stages 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 6-4
is a code fragment that shows session
processing for the
login
command.
Example 6-4: Session Processing Code for the login Command
. . . /* 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 ")); } . . .
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.
6.10.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 cannot 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 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.
6.10.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.
6.10.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.
6.10.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.
6.10.6 Specific Session Processing
The following sections describe specific session processing for the
login
,
rshd
, and
rlogind
commands.
6.10.6.1 The login Process
The most common case of session processing is when the login process
becomes 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 6-4
is part of the
login
command.
6.10.6.2 The rshd Process
Session processing for
/usr/sbin/rshd
differs
from
login
.
The
rshd
process calls
ruserok()
to check the
.rhosts
and
host.equiv
files for authorization.
If
ruserok()
fails, the
rshd
fails.
6.10.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 the
-f
flag 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.
6.11 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.
6.11.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.
6.11.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.
6.11.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.
6.12 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 provide only one routine
for both reentrant and nonreentrant, 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.
6.12.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.
6.12.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 is accomplished
by calling each configured security mechanism in the predefined order until
all group entries have been exhausted.
6.13 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.
6.14 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:
A shared library containing the mechanism-dependent (siad_*()
) routines used as an interface to commands and utilities
A default
/etc/sia/matrix.conf
file, which
is installed to use the security mechanism through SIA
The shared library must contain all of the
siad_*()
routines described in
Table 6-3.
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.
See Security
Administration for 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 an 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 Security Administration for a more detailed discussion of the
matrix.conf
file.
6.15 Security Mechanism-Dependent Interface
Security mechanisms are required to provide all of the
siad_*()
entry points.
(See
Table 6-3.) The
default stub routine should 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 mechanisms 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.
6.16 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 statically
linked binaries found in
/sbin
.
This can be accomplished
by providing an
siad_*()
routine library to precede
libc
in the link order for the affected commands.
The new routines need to override the
_
routines, as opposed to the
siad_*()
routines.
The
siad_*()
naming convention is the weak symbol entry point, while
the
_
convention is the strong symbol
entry point that is actually used.
See
Section 6.17
for more information about routine-naming conventions.
6.17 Symbol Preemption for SIA Routines
This section describes the naming convention for routines (added by
developers) that must be followed to stay in compliance with ANSI C routine
naming rules.
6.17.1 Overview of the Symbol Preemption Problem
Overriding
the symbols used by the SIA routines in
libc
is not as
simple as providing routines named the same as the SIA routines (such as,
siad_ses_init()
) in a library loaded before
libc.a
.
This is because of the ANSI C convention for
libc
routine
names and the symbols that must be reserved to the user.
A conflict exists
between the requirements of ANSI C and the expectations of the application
developers regarding what entry points can exist in the
libc.a
and
libc.so
libraries.
The ANSI C standard lists the symbols
allowed, and the only other symbols that are valid must be of the "reserved-to-vendor"
form.
That is, they must start with two underscores, or one underscore and
a capital letter.
This set of symbols is limited, and does not meet the expectations
of the general user community.
6.17.2 The Tru64 UNIX Solution
To satisfy both ANSI C and developer expectations, Tru64 UNIX
uses "strong" and "weak" symbols to provide the additional
names.
If a routine such as
bcopy()
is not allowed by
ANSI C, it has a weak symbol named
bcopy()
and a strong
symbol named
_
.
The weak symbol can be preempted by the user with no effect on the
bcopy()
routine within
libc
, because the library
uses the strong symbols for these "namespace-protected" routines.
For the SIA
routines, this means that there is a weak symbol for
siad_ses_init
which is normally bound to the strong symbol
_
.
If other code already uses the symbol
siad_ses_init()
, only the binding of the weak symbol is affected.
The SIA code in
libc
references the strong symbol
_
for its own uses.
Thus, to override the
default BASE security mechanism for single-user mode, it is necessary to provide
a replacement for the
_
routine.
For a library that is only dynamically loaded under the control of the
SIA routines and the
/etc/sia/matrix.conf
file, it is only
necessary to provide the
siad_ses_init()
form of the symbol
name.
If the dynamically loaded library is only used through the
matrix.conf
file, it is acceptable to provide both forms of symbols.
This simplifies the code, but is not safe if the library usage ever changes
to require that the library be linked against, not just dynamically loaded.
6.17.3 Replacing the Single-User Environment
Example 6-5
shows the code to use if a security mechanism
library developer needs to replace the single-user environment as well as
provide a normal shared library for
matrix.conf
.
Example 6-5: Preempting Symbols in Single-User Mode
/* preempt libc.a symbols in single-user mode */ #ifdef SINGLE_USER # pragma weak siad_ses_init = __siad_ses_init # define siad_ses_init _ _siad_ses_init #endif #include <sia.h> #include <siad.h>
The single-user (static) library modules are then compiled as follows:
% cc -DSINGLE_USER ...
This keeps the shared library from interfering with the
libc.so
symbols, but allows the preemption of the
libc.a
symbols for the nonshared images used in single-user mode.
The nonshared
images are then built with the replacement mechanism library supplied to the
linker before
libc.a
as in the following example:
% cc -non_shared -o passwd passwd.o -ldemo_mech
The shared library is built in the normal fashion.