[ Bottom of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]

Kernel Extensions and Device Support Programming Concepts

Loadable Authentication Module Programming Interface

Overview

The loadable authentication module interface provides a means for extending identification and authentication (I&A) for new technologies. The interface implements a set of well-defined functions for performing user and group account access and management.

The degree of integration with the system administrative commands is limited by the amount of functionality provided by the module. When all of the functionality is present, the administrative commands are able to create, delete, modify and view user and group accounts.

The security library and loadable authentication module communicate through the secmethod_table interface. The secmethod_table structure contains a list of subroutine pointers. Each subroutine pointer performs a well-defined operation. These subroutine are used by the security library to perform the operations which would have been performed using the local security database files.

Load Module Interfaces

Each loadable module defines a number of interface subroutines. The interface subroutines which must be present are determined by how the loadable module is to be used by the system. A loadable module may be used to provide identification (account name and attribute information), authentication (password storage and verification) or both. All modules may have additional support interfaces for initializing and configuring the loadable module, creating new user and group accounts, and serializing access to information. This table describes the purpose of each interface. Interfaces may not be required if the loadable module is not used for the purpose of the interface. For example, a loadable module which only performs authentication functions is not required to have interfaces which are only used for identification operations.

 

Method Interface Types
Name Type Required
method_attrlist Support No
method_authenticate Authentication No [ 3]
method_chpass Authentication Yes
method_close Support No
method_commit Support No
method_delgroup Support No
method_deluser Support No
method_getentry Identification [ 1] No
method_getgracct Identification No
method_getgrgid Identification Yes
method_getgrnam Identification Yes
method_getgrset Identification Yes
method_getgrusers Identification No
method_getpasswd Authentication No
method_getpwnam Identification Yes
method_getpwuid Identification Yes
method_lock Support No
method_newgroup Support No
method_newuser Support No
method_normalize Authentication No
method_open Support No
method_passwdexpired Authentication [ 2] No
method_passwdrestrictions Authentication [ 2] No
method_putentry Identification [ 1] No
method_putgrent Identification No
method_putgrusers Identification No
method_putpwent Identification No
method_unlock Support No

Notes:  
  1. Any module which provides a method_attrlist() interface must also provide this interface.
  2. Attributes which are related to password expiration or restrictions should be reported by the method_attrlist() interface.
  3. If this interface is not provided the method_getpasswd() interface must be provided.

Several of the functions make use of a table parameter to select between user, group and system identification information. The table parameter has one of the following values:

 

Identification Table Names
Value Description
"user" The table containing user account information, such as user ID, full name, home directory and login shell.
"group" The table containing group account information, such as group ID and group membership list.
"system" The table containing system information, such as user or group account default values.

When a table parameter is used by an authentification interface, "user" is the only valid value.

Authentication Interfaces

Authentication interfaces perform password validation and modification. The authentication interfaces verify that a user is allowed access to the system. The authentication interfaces also maintain the authentication information, typically passwords, which are used to authorize user access.

The method_authenticate Interface

int method_authenticate (char *user, char *response,
        int **reenter, char **message);

The user parameter points to the requested user. The response parameter points to the user response to the previous message or password prompt. The reenter parameter points to a flag. It is set to a non-zero value when the contents of the message parameter must be used as a prompt and the user's response used as the response parameter when this method is re-invoked. The initial value of the reenter flag is zero. The message parameter points to a character pointer. It is set to a message which is output to the user when an error occurs or an additional prompt is required.

method_authenticate verifies that a named user has the correct authentication information, typically a password, for a user account.

method_authenticate is called indirectly as a result of calling the authenticate subroutine. The grammar given in the SYSTEM attribute normally specifies the name of the loadable authentication module, but it is not required to do so.

method_authenticate returns AUTH_SUCCESS with a reenter value of zero on success. On failure a value of AUTH_FAILURE, AUTH_UNAVAIL or AUTH_NOTFOUND is returned.

The method_chpass Interface

int method_chpass (char *user, char *oldpassword,
        char *newpassword, char **message);

The user parameter points to the requested user. The oldpassword parameter points to the user's current password. The newpassword parameter points to the user's new password. The message parameter points to a character pointer. It will be set to a message which is output to the user.

method_chpass changes the authentication information for a user account.

method_chpass is called indirectly as a result of calling the chpass subroutine. The security library will examine the registry attribute for the user and invoke the method_chpass interface for the named loadable authentication module.

method_chpass returns zero for success or -1 for failure. On failure the message parameter should be initialized with a user message.

The method_getpasswd Interface

char *method_getpasswd (char *user);

The user parameter points to the requested user.

method_getpasswd provides the encrypted password string for a user account. The encrypted password string consists of two salt characters and 11 encrypted password characters. The crypt subroutine is used to create this string and encrypt the user-supplied password for comparison.

method_getpasswd is called when method_authenticate would have been called, but is undefined. The result of this call is compared to the result of a call to the crypt subroutine using the response to the password prompt. See the description of the method_authenticate interface for a description of the response parameter.

method_getpasswd returns a pointer to an encrypted password on success. On failure a NULL pointer is returned and the global variable errno is set to indicate the error. A value of ENOSYS is used when the module cannot return an encrypted password. A value of EPERM is used when the caller does not have the required permissions to retrieve the encrypted password. A value of ENOENT is used when the requested user does not exist.

The method_normalize Interface

int method_normalize (char *longname, char *shortname);

The longname parameter points to a fully-qualified user name for modules which include domain or registry information in a user name. The shortname parameter points to the shortened name of the user, without the domain or registry information.

method_normalize determines the shortened user name which corresponds to a fully-qualified user name. The shortened user name is used for user account queries by the security library. The fully-qualified user name is only used to perform initial authentication.

If the fully-qualified user name is successfully converted to a shortened user name, a non-zero value is returned. If an error occurs a zero value is returned.

The method_passwdexpired Interface

int method_passwdexpired (char *user, char **message);

The user parameter points to the requested user. The message parameter points to a character pointer. It will be set to a message which is output to the user.

method_passwdexpired determines if the authentication information for a user account is expired. This method distinguishes between conditions which allow the user to change their information and those which require administrator intervention. A message is returned which provides more information to the user.

method_passwdexpired is called as a result of calling the passwdexpired subroutine.

method_passwdexpired returns 0 when the password has not expired, 1 when the password is expired and the user is permitted to change their password and 2 when the password has expired and the user is not permitted to change their password. A value of -1 is returned when an error has occurred, such as the user does not exist.

The method_passwdrestrictions Interface

int method_passwdrestrictions (char *user, char *newpassword,
        char *oldpassword, char **message);

The user parameter points to the requested user. The newpassword parameter points to the user's new password. The oldpassword parameter points to the user's current password. The message parameter points to a character pointer. It will be set to a message which is output to the user.

method_passwdrestrictions determines if new password meets the system requirements. This method distinguishes between conditions which allow the user to change their password by selecting a different password and those which prevent the user from changing their password at the present time. A message is returned which provides more information to the user.

method_passwdrestrictions is called as a result of calling the security library subroutine passwdrestrictions.

method_passwdrestrictions returns a value of 0 when newpassword meets all of the requirements, 1 when the password does not meet one or more requirements and 2 when the password may not be changed. A value of -1 is returned when an error has occurred, such as the user does not exist.

Identification Interfaces

Identification interfaces perform user and group identity functions. The identification interfaces store and retrieve user and group identifiers and account information.

The identification interfaces divide information into three different categories: user, group and system. User information consists of the user name, user and primary group identifiers, home directory, login shell and other attributes specific to each user account. Group information consists of the group identifier, group member list, and other attributes specific to each group account. System information consists of default values for user and group accounts, and other attributes about the security state of the current system.

The method_getentry Interface

int method_getentry (char *key, char *table, char *attributes[],
        attrval_t results[], int size);

The key parameter refers to an entry in the named table. The table parameter refers to one of the three tables. The attributes parameter refers to an array of pointers to attribute names. The results parameter refers to an array of value return data structures. Each value return structure contains either the value of the corresponding attribute or a flag indicating a cause of failure. The size parameter is the number of array elements.

method_getentry retrieves user, group and system attributes. One or more attributes may be retrieved for each call. Success or failure is reported for each attribute.

method_getentry is called as a result of calling the getuserattr, getgroupattr and getconfattr subroutines.

method_getentry returns a value of 0 if the key entry was found in the named table. When the entry does not exist in the table, the global variable errno must be set to ENOENT. If an error in the value of table or size is detected, the errno variable must be set to EINVAL. Individual attribute values have additional information about the success or failure for each attribute. On failure a value of -1 is returned.

The method_getgracct Interface

struct group *method_getgracct (void *id, int type);

The id parameter refers to a group name or GID value, depending upon the value of the type parameter. The type parameters indicates whether the id parameter is to be interpreted as a (char *) which references the group name, or (gid_t) for the group.

method_getgracct retrieves basic group account information. The id parameter may be a group name or identifier, as indicated by the type parameter. The basic group information is the group name and identifier. The group member list is not returned by this interface.

method_getgracct may be called as a result of calling the IDtogroup subroutine.

method_getgracct returns a pointer to the group's group file entry on success. The group file entry may not include the list of members. On failure a NULL pointer is returned.

The method_getgrgid Interface

struct group *method_getgrgid (gid_t gid);

The gid parameter is the group identifier for the requested group.

method_getgrgid retrieves group account information given the group identifier. The group account information consists of the group name, identifier and complete member list.

method_getgrgid is called as a result of calling the getgrgid subroutine.

method_getgrgid returns a pointer to the group's group file structure on success. On failure a NULL pointer is returned.

The method_getgrnam Interface

struct group *method_getgrnam (char *group);

The group parameter points to the requested group.

method_getgrnam retrieves group account information given the group name. The group account information consists of the group name, identifier and complete member list.

method_getgrnam is called as a result of calling the getgrnam subroutine. This interface may also be called if method_getentry is not defined.

method_getgrnam returns a pointer to the group's group file structure on success. On failure a NULL pointer is returned.

The method_getgrset Interface

char *method_getgrset (char *user);

The user parameter points to the requested user.

method_getgrset retrieves supplemental group information given a user name. The supplemental group information consists of a comma separated list of group identifiers. The named user is a member of each listed group.

method_getgrset is called as a result of calling the getgrset subroutine.

method_getgrset returns a pointer to the user's concurrent group set on success. On failure a NULL pointer is returned.

The method_getgrusers Interface

int method_getgrusers (char *group, void *result,
        int type, int *size);

The group parameter points to the requested group. The result parameter points to a storage area which will be filled with the group members. The type parameters indicates whether the result parameter is to be interpreted as a (char **) which references a user name array, or (uid_t) array. The size parameter is a pointer to the number of users in the named group. On input it is the size of the result field.

method_getgrusers retrieves group membership information given a group name. The return value may be an array of user names or identifiers.

method_getgrusers may be called by the security library to obtain the group membership information for a group.

method_getgrusers returns 0 on success. On failure a value of -1 is returned and the global variable errno is set. The value ENOENT must be used when the requested group does not exist. The value ENOSPC must be used when the list of group members does not fit in the provided array. When ENOSPC is returned the size parameter is modified to give the size of the required result array.

The method_getpwnam Interface

struct passwd *method_getpwnam (char *user);

The user parameter points to the requested user.

method_getpwnam retrieves user account information given the user name. The user account information consists of the user name, identifier, primary group identifier, full name, login directory and login shell.

method_getpwnam is called as a result of calling the getpwnam subroutine. This interface may also be called if method_getentry is not defined.

method_getpwnam returns a pointer to the user's password structure on success. On failure a NULL pointer is returned.

The method_getpwuid Interface

struct passwd *method_getpwuid (uid_t uid);

The uid parameter points to the user ID of the requested user.

method_getpwuid retrieves user account information given the user identifier. The user account information consists of the user name, identifier, primary group identifier, full name, login directory and login shell.

method_getpwuid is called as a result of calling the getpwuid subroutine.

method_getpwuid returns a pointer to the user's password structure on success. On failure a NULL pointer is returned.

The method_putentry Interface

int method_putentry (char *key, char *table, char *attributes,
        attrval_t values[], int size);

The key parameter refers to an entry in the named table. The table parameter refers to one of the three tables. The attributes parameter refers to an array of pointers to attribute names. The values parameter refers to an array of value structures which correspond to the attributes. Each value structure contains a flag indicating if the attribute was output. The size parameter is the number of array elements.

method_putentry stores user, group and system attributes. One or more attributes may be retrieved for each call. Success or failure is reported for each attribute. Values will be saved until method_commit is invoked.

method_putentry is called as a result of calling the putuserattr, putgroupattr and putconfattr subroutines.

method_putentry returns 0 when the attributes have been updated. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when updating information is not supported by the module. A value of EPERM is used when the invoker does not have permission to create the group. A value of ENOENT is used when the entry does not exist. A value of EROFS is used when the module was not opened for updates.

The method_putgrent Interface

int method_putgrent (struct group *entry);

The entry parameter points to the structure to be output. The account name is contained in the structure.

method_putgrent stores group account information given a group entry. The group account information consists of the group name, identifier and complete member list. Values will be saved until method_commit is invoked.

method_putgrent may be called as a result of calling the putgroupattr subroutine.

method_putgrent returns 0 when the group has been successfully updated. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when updating groups is not supported by the module. A value of EPERM is used when the invoker does not have permission to update the group. A value of ENOENT is used when the group does not exist. A value of EROFS is used when the module was not opened for updates.

The method_putgrusers Interface

int method_putgrusers (char *group, char *users);

The group parameter points to the requested group. The users parameter points to a NUL character separated, double NUL character terminated, list of group members.

method_putgrusers stores group membership information given a group name. Values will be saved until method_commit is invoked.

method_putgrusers may be called as a result of calling the putgroupattr subroutine.

method_putgrusers returns 0 when the group has been successfully updated. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when updating groups is not supported by the module. A value of EPERM is used when the invoker does not have permission to update the group. A value of ENOENT is used when the group does not exist. A value of EROFS is used when the module was not opened for updates.

The method_putpwent Interface

int method_putpwent (struct passwd *entry);

The entry parameter points to the structure to be output. The account name is contained in the structure.

method_putpwent stores user account information given a user entry. The user account information consists of the user name, identifier, primary group identifier, full name, login directory and login shell. Values will be saved until method_commit is invoked.

method_putpwent may be called as a result of calling the putuserattr subroutine.

method_putpwent returns 0 when the user has been successfully updated. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when updating users is not supported by the module. A value of EPERM is used when the invoker does not have permission to update the user. A value of ENOENT is used when the user does not exist. A value of EROFS is used when the module was not opened for updates.

Support Interfaces

Support interfaces perform functions such as initiating and terminating access to the module, creating and deleting accounts, and serializing access to information.

The method_attrlist Interface

attrtab **method_attrlist (void);

This interface does not require any parameters.

method_attrlist provides a means of defining additional attributes for a loadable module. Authentication-only modules may use this interface to override attributes which would normally come from the identification module half of a compound load module.

method_attrlist is called when a loadable module is first initialized. The return value will be saved for use by later calls to various identification and authentication functions.

The method_close Interface

void method_close (void *token);

The token parameter is the value of the corresponding method_open call.

method_close indicates that access to the loadable module has ended and all system resources may be freed. The loadable module must not assume this interface will be invoked as a process may terminate without calling this interface.

method_close is called when the session count maintained by enduserdb reaches zero.

There are no defined error return values. It is expected that the method_close interface handle common programming errors, such as being invoked with an invalid token, or repeatedly being invoked with the same token.

The method_commit Interface

int method_commit (char *key, char *table);

The key parameter refers to an entry in the named table. If it is NULL it refers to all entries in the table. The table parameter refers to one of the three tables.

method_commit indicates that the specified pending modifications are to be made permanent. An entire table or a single entry within a table may be specified. method_lock will be called prior to calling method_commit. method_unlock will be called after method_commit returns.

method_commit is called when putgroupattr or putuserattr are invoked with a Type parameter of SEC_COMMIT. The value of the Group or User parameter will be passed directly to method_commit.

method_commit returns a value of 0 for success. A value of -1 is returned to indicate an error and the global variable errno is set to indicate the cause. A value of ENOSYS is used when the load module does not support modification requests for any users. A value of EROFS is used when the module is not currently opened for updates. A value of EINVAL is used when the table parameter refers to an invalid table. A value of EIO is used when a potentially temporary input-output error has occurred.

The method_delgroup Interface

int method_delgroup (char *group);

The group parameter points to the requested group.

method_delgroup removes a group account and all associated information. A call to method_commit is not required. The group will be removed immediately.

method_delgroup is called when putgroupattr is invoked with a Type parameter of SEC_DELETE. The value of the Group and Attribute parameters will be passed directly to method_delgroup.

method_delgroup returns 0 when the group has been successfully removed. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when deleting groups is not supported by the module. A value of EPERM is used when the invoker does not have permission to delete the group. A value of ENOENT is used when the group does not exist. A value of EROFS is used when the module was not opened for updates. A value of EBUSY is used when the group has defined members.

The method_deluser Interface

int method_deluser (char *user);

The user parameter points to the requested user.

method_delgroup removes a user account and all associated information. A call to method_commit is not required. The user will be removed immediately.

method_deluser is called when putuserattr is invoked with a Type parameter of SEC_DELETE. The value of the User and Attribute parameters will be passed directly to method_deluser.

method_deluser returns 0 when the user has been successfully removed. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when deleting users is not supported by the module. A value of EPERM is used when the invoker does not have permission to delete the user. A value of ENOENT is used when the user does not exist. A value of EROFS is used when the module was not opened for updates.

The method_lock Interface

void *method_lock (char *key, char *table, int wait);

The key parameter refers to an entry in the named table. If it is NULL it refers to all entries in the table. The table parameter refers to one of the three tables. The wait parameter is the number of second to wait for the lock to be acquired. If the wait parameter is zero the call returns without waiting if the entry cannot be locked immediately.

method_lock informs the loadable modules that access to the underlying mechanisms should be serialized for a specific table or table entry.

method_lock is called by the security library when serialization is required. The return value will be saved and used by a later call to method_unlock when serialization is no longer required.

The method_newgroup Interface

int method_newgroup (char *group);

The group parameter points to the requested group.

method_newgroup creates a group account. The basic group account information must be provided with calls to method_putgrent or method_putentry. The group account information will not be made permanent until method_commit is invoked.

method_newgroup is called when putgroupattr is invoked with a Type parameter of SEC_NEW. The value of the Group parameter will be passed directly to method_newgroup.

method_newgroup returns 0 when the group has been successfully created. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when creating group is not supported by the module. A value of EPERM is used when the invoker does not have permission to create the group. A value of EEXIST is used when the group already exists. A value of EROFS is used when the module was not opened for updates. A value of EINVAL is used when the group has an invalid format, length or composition.

The method_newuser Interface

int method_newuser (char *user);

The user parameter points to the requested user.

method_newuser creates a user account. The basic user account information must be provided with calls to method_putpwent or method_putentry. The user account information will not be made permanent until method_commit is invoked.

method_newuser is called when putuserattr is invoked with a Type parameter of SEC_NEW. The value of the User parameter will be passed directly to method_newuser.

method_newuser returns 0 when the user has been successfully created. On failure a value of -1 is returned and the global variable errno is set to indicate the cause. A value of ENOSYS is used when creating users is not supported by the module. A value of EPERM is used when the invoker does not have permission to create the user. A value of EEXIST is used when the user already exists. A value of EROFS is used when the module was not opened for updates. A value of EINVAL is used when the user has an invalid format, length or composition.

The method_open Interface

void *method_open (char *name, char *domain,
        int mode, char *options);

The name parameter is a pointer to the stanza name in the configuration file. The domain parameter is the value of the domain= attribute in the configuration file. The mode parameter is either O_RDONLY or O_RDWR. The options parameter is a pointer to the options= attribute in the configuration file.

method_open prepares a loadable module for use. The domain and options attributes are passed to method_open.

method_open is called by the security library when the loadable module is first initialized and when setuserdb is first called after method_close has been called due to an earlier call to enduserdb. The return value will be saved for a future call to method_close.

The method_unlock Interface

void method_unlock (void *token);

The token parameter is the value of the corresponding method_lock call.

method_unlock informs the loadable modules that an earlier need for access serialization has ended.

method_unlock is called by the security library when serialization is no longer required. The return value from the earlier call to method_lock be used.

Configuration Files

The security library uses the /usr/lib/security/methods.cfg file to control which modules are used by the system. A stanza exists for each loadable module which is to be used by the system. Each stanza contains a number of attributes used to load and initialize the module. The loadable module may use this information to configure its operation when the method_open() interface is invoked immediately after the module is loaded.

The options Attribute

The options attribute will be passed to the loadable module when it is initialized. This string is a comma-separated list of Flag and Flag=Value entries. The entire value of the options attribute is passed to the method_open() subroutine when the module is first initialized. Five pre-defined flags control how the library uses the loadable module.

 

auth=module Module will be used to perform authentication functions for the current loadable authentication module. Subroutine entry points dealing with authentication-related operations will use method table pointers from the named module instead of the module named in the program= or program_64= attribute.
authonly The loadable authentication module only performs authentication operations. Subroutine entry points which are not required for authentication operations, or general support of the loadable module, will be ignored.
db=module Module will be used to perform identification functions for the current loadable authentication module. Subroutine entry points dealing with identification related operations will use method table pointers from the name module instead of the module named in the program= or program_64= attribute.
dbonly The loadable authentication module only provides user and group identification information. Subroutine entry points which are not required for identification operations, or general support of the loadable module, will be ignored.
noprompt The initial password prompt for authentication operations is suppressed. Password prompts are normally performed prior to a call to method_authenticate(). method_authenticate() must be prepared to receive a NULL pointer for the response parameter and set the reenter parameter to TRUE to indicate that the user must be prompted with the contents of the message parameter prior to method_authenticate() being re-invoked. See the description of method_authenticate for more information on these parameters.

Compound Load Modules

Compound load modules are created with the auth= and db= attributes. The security library is responsible for constructing a new method table to perform the compound function.

Interfaces are divided into three categories: identification, authentication and support. Identification interfaces are used when a compound module is performing an identification operation, such as the getpwnam() subroutine. Authentication interfaces are used when a compound module is performing an authentication operation, such as the authenticate() subroutine. Support subroutines are used when initializing the loadable module, creating or deleting entries, and performing other non-data operations. The table Method Interface Types describes the purpose of each interface. The table below describes which support interfaces are called in a compound module and their order of invocation.

 

Support Interface Invocation
Name Invocation Order
method_attrlist Identification, Authentication
method_close Identification, Authentication
method_commit Identification, Authentication
method_deluser Authentication, Identification
method_lock Identification, Authentication
method_newuser Identification, Authentication
method_open Identification, Authentication
method_unlock Authentication, Identification

Related Information

Identification and Authentication Subroutines

/usr/lib/security/methods.cfg File

[ Top of Page | Previous Page | Next Page | Contents | Index | Library Home | Legal | Search ]