This chapter documents the Security Integration Architecture (SIA) interfaces.
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.
These 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.
| Command | Description |
chfn |
Changes finger information |
chsh |
Changes login shell information |
dnascd |
Spwans 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 20-2 and Table 20-3 list the SIA porting 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 |
| 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 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 planning to use a specific
security mechanism, requires SIA integration.
The SIA components consist of only user-level modules. The components resolve the configuration issues with respect to command and utility utilization of multiple security mechanisms. The SIA components do not resolve any kernel issues pertaining to the configuration and utilization of multiple security mechanisms.
The layering introduced by SIA in Tru64 UNIX consists of the following two groups of interface routines:
sia_*()The commands and utilities porting interface
siad_*()The security mechanism-dependent porting interface
Security
mechanisms deliver a shared library containing the
siad_*()
routines and provide 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 security-sensitive commands
have been modified to use the mechanism-independent
sia_*()
routines.
The routines are used by the commands and utilities to
access security functions yet remain isolated from the specific
security technologies.
The
sia_*()
routines
call the associated mechanism-dependent
siad_*()
routine, 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-dependent 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
linc.
See
Appendix E
for more information on the naming and preempting requirements.
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.
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.
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.
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:
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 previous 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 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.
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().
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 general 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 20-2
is
a 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.
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.
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.
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:
A SIADFAIL
response from a security mechanism
siad_*()
routine indicates that the
security mechanism has failed but that processing should continue.
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.
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.
.
.
.
/* 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.
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
re-collecting 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 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 relinking of a SIA
matrix.conf
file is followed by a reboot.
System
administrators must never be required to edit a live
matrix.conf
file.
See
Chapter 13
for a more detailed discussion of the
matrix.conf
file.
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.
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.