diff options
author | Thorsten Kukuk <kukuk@thkukuk.de> | 2006-06-28 14:41:18 +0000 |
---|---|---|
committer | Thorsten Kukuk <kukuk@thkukuk.de> | 2006-06-28 14:41:18 +0000 |
commit | 95e6b22ccd72741a4b651deae208b184086f2e52 (patch) | |
tree | 0bc38582d9ebe760b8ddc8645cd581d9fa552ed6 /doc/pam_appl.sgml | |
parent | 504eedccf7e1d222092c6005fdc13705ab5d26b8 (diff) | |
download | pam-95e6b22ccd72741a4b651deae208b184086f2e52.tar.gz pam-95e6b22ccd72741a4b651deae208b184086f2e52.tar.bz2 pam-95e6b22ccd72741a4b651deae208b184086f2e52.zip |
Relevant BUGIDs:
Purpose of commit: cleanup
Commit summary:
---------------
* doc/CREDITS: Removed.
* doc/NOTES: Removed.
* doc/pam_appl.sgml: Removed.
* doc/pam_modules.sgml: Removed.
* doc/pam_source.sgml: Removed.
* doc/figs/pam_orient.txt: Removed.
* doc/figs: Removed.
* configure.in: Remove checks for sgml2* progrs, add sag, adg
and mwg Makefiles.
* doc/Makefile.am: Remove references to sgml, add sag, adg and mwg
directories.
Diffstat (limited to 'doc/pam_appl.sgml')
-rw-r--r-- | doc/pam_appl.sgml | 1777 |
1 files changed, 0 insertions, 1777 deletions
diff --git a/doc/pam_appl.sgml b/doc/pam_appl.sgml deleted file mode 100644 index a80bcbb6..00000000 --- a/doc/pam_appl.sgml +++ /dev/null @@ -1,1777 +0,0 @@ -<!doctype linuxdoc system> - -<!-- - - $Id$ - - Copyright (C) Andrew G. Morgan 1996-2001. All rights reserved. - -Redistribution and use in source (sgml) and binary (derived) forms, -with or without modification, are permitted provided that the -following conditions are met: - -1. Redistributions of source code must retain the above copyright - notice, and the entire permission notice in its entirety, - including the disclaimer of warranties. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -ALTERNATIVELY, this product may be distributed under the terms of the -GNU General Public License, in which case the provisions of the GNU -GPL are required INSTEAD OF the above restrictions. (This clause is -necessary due to a potential bad interaction between the GNU GPL and -the restrictions contained in a BSD-style copyright.) - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - - --> - -<article> - -<title>The Linux-PAM Application Developers' Guide -<author>Andrew G. Morgan, <tt>morgan@kernel.org</tt> -<date>DRAFT v0.76 2001/12/08 -<abstract> -This manual documents what an application developer needs to know -about the <bf>Linux-PAM</bf> library. It describes how an application -might use the <bf>Linux-PAM</bf> library to authenticate users. In -addition it contains a description of the funtions to be found in -<tt/libpam_misc/ library, that can be used in general applications. -Finally, it contains some comments on PAM related security issues for -the application developer. -</abstract> - -<toc> - -<sect>Introduction - -<sect1>Synopsis - -<p> -For general applications that wish to use the services provided by -<bf/Linux-PAM/ the following is a summary of the relevant linking -information: -<tscreen> -<verb> -#include <security/pam_appl.h> - -cc -o application .... -lpam -ldl -</verb> -</tscreen> - -<p> -In addition to <tt/libpam/, there is a library of miscellaneous -functions that make the job of writing <em/PAM-aware/ applications -easier (this library is not covered in the DCE-RFC for PAM and is -specific to the Linux-PAM distribution): -<tscreen> -<verb> -... -#include <security/pam_misc.h> - -cc -o application .... -lpam -lpam_misc -ldl -</verb> -</tscreen> - -<sect1> Description - -<p> -<bf>Linux-PAM</bf> (Pluggable Authentication Modules for Linux) is a -library that enables the local system administrator to choose how -individual applications authenticate users. For an overview of the -<bf>Linux-PAM</bf> library see the <bf/Linux-PAM/ System -Administrators' Guide. - -<p> -It is the purpose of the <bf>Linux-PAM</bf> project to liberate the -development of privilege granting software from the development of -secure and appropriate authentication schemes. This is accomplished -by providing a documented library of functions that an application may -use for all forms of user authentication management. This library -dynamically loads locally configured authentication modules that -actually perform the authentication tasks. - -<p> -From the perspective of an application developer the information -contained in the local configuration of the PAM library should not be -important. Indeed it is intended that an application treat the -functions documented here as a ``black box'' that will deal with all -aspects of user authentication. ``All aspects'' includes user -verification, account management, session initialization/termination -and also the resetting of passwords (<em/authentication tokens/). - -<sect>Overview - -<p> -Most service-giving applications are restricted. In other words, -their service is not available to all and every prospective client. -Instead, the applying client must jump through a number of hoops to -convince the serving application that they are authorized to obtain -service. - -The process of <em/authenticating/ a client is what PAM is designed to -manage. In addition to authentication, PAM provides account -management, credential management, session management and -authentication-token (password changing) management services. It is -important to realize when writing a PAM based application that these -services are provided in a manner that is <bf>transparent</bf> to -the application. That is to say, when the application is written, no -assumptions can be made about <em>how</em> the client will be -authenticated. - -<p> -The process of authentication is performed by the PAM library via a -call to <tt>pam_authenticate()</tt>. The return value of this -function will indicate whether a named client (the <em>user</em>) has -been authenticated. If the PAM library needs to prompt the user for -any information, such as their <em>name</em> or a <em>password</em> -then it will do so. If the PAM library is configured to authenticate -the user using some silent protocol, it will do this too. (This -latter case might be via some hardware interface for example.) - -<p> -It is important to note that the application must leave all decisions -about when to prompt the user at the discretion of the PAM library. - -<p> -The PAM library, however, must work equally well for different styles -of application. Some applications, like the familiar <tt>login</tt> -and <tt>passwd</tt> are terminal based applications, exchanges of -information with the client in these cases is as plain text messages. -Graphically based applications, however, have a more sophisticated -interface. They generally interact with the user via specially -constructed dialogue boxes. Additionally, network based services -require that text messages exchanged with the client are specially -formatted for automated processing: one such example is <tt>ftpd</tt> -which prefixes each exchanged message with a numeric identifier. - -<p> -The presentation of simple requests to a client is thus something very -dependent on the protocol that the serving application will use. In -spite of the fact that PAM demands that it drives the whole -authentication process, it is not possible to leave such protocol -subtleties up to the PAM library. To overcome this potential problem, -the application provides the PAM library with a <em>conversation</em> -function. This function is called from <bf>within</bf> the PAM -library and enables the PAM to directly interact with the client. The -sorts of things that this conversation function must be able to do are -prompt the user with text and/or obtain textual input from the user -for processing by the PAM library. The details of this function are -provided in a later section. - -<p> -For example, the conversation function may be called by the PAM library -with a request to prompt the user for a password. Its job is to -reformat the prompt request into a form that the client will -understand. In the case of <tt>ftpd</tt>, this might involve prefixing -the string with the number <tt>331</tt> and sending the request over -the network to a connected client. The conversation function will -then obtain any reply and, after extracting the typed password, will -return this string of text to the PAM library. Similar concerns need -to be addressed in the case of an X-based graphical server. - -<p> -There are a number of issues that need to be addressed when one is -porting an existing application to become PAM compliant. A section -below has been devoted to this: Porting legacy applications. - -<p> -Besides authentication, PAM provides other forms of management. -Session management is provided with calls to -<tt>pam_open_session()</tt> and <tt>pam_close_session()</tt>. What -these functions actually do is up to the local administrator. But -typically, they could be used to log entry and exit from the system or -for mounting and unmounting the user's home directory. If an -application provides continuous service for a period of time, it -should probably call these functions, first open after the user is -authenticated and then close when the service is terminated. - -<p> -Account management is another area that an application developer -should include with a call to <tt/pam_acct_mgmt()/. This call will -perform checks on the good health of the user's account (has it -expired etc.). One of the things this function may check is whether -the user's authentication token has expired - in such a case the -application may choose to attempt to update it with a call to -<tt/pam_chauthtok()/, although some applications are not suited to -this task (<em>ftp</em> for example) and in this case the application -should deny access to the user. - -<p> -PAM is also capable of setting and deleting the users credentials with -the call <tt>pam_setcred()</tt>. This function should always be -called after the user is authenticated and before service is offered -to the user. By convention, this should be the last call to the PAM -library before the PAM session is opened. What exactly a credential -is, is not well defined. However, some examples are given in the -glossary below. - -<sect>The public interface to <bf>Linux-PAM</bf> - -<p> -Firstly, the relevant include file for the <bf>Linux-PAM</bf> library -is <tt><security/pam_appl.h></tt>. It contains the definitions -for a number of functions. After listing these functions, we collect -some guiding remarks for programmers. - -<sect1>What can be expected by the application - -<p> -Below we document those functions in the <bf/Linux-PAM/ library that -may be called from an application. - -<sect2>Initialization of Linux-PAM -<label id="pam-start-section"> - -<p> -<tscreen> -<verb> -extern int pam_start(const char *service_name, const char *user, - const struct pam_conv *pam_conversation, - pam_handle_t **pamh); -</verb> -</tscreen> - -<p> -This is the first of the <bf>Linux-PAM</bf> functions that must be -called by an application. It initializes the interface and reads the -system configuration file, <tt>/etc/pam.conf</tt> (see the -<bf/Linux-PAM/ System Administrators' Guide). Following a successful -return (<tt/PAM_SUCCESS/) the contents of <tt/*pamh/ is a handle that -provides continuity for successive calls to the <bf/Linux-PAM/ -library. The arguments expected by <tt/pam_start/ are as follows: the -<tt/service_name/ of the program, the <tt/user/name of the individual -to be authenticated, a pointer to an application-supplied -<tt/pam_conv/ structure and a pointer to a <tt/pam_handle_t/ -<em/pointer/. - -<p> -The <tt>pam_conv</tt> structure is discussed more fully in the section -<ref id="the-conversation-function" name="below">. The -<tt>pam_handle_t</tt> is a <em>blind</em> structure and the -application should not attempt to probe it directly for information. -Instead the <bf>Linux-PAM</bf> library provides the functions -<tt>pam_set_item</tt> and <tt>pam_get_item</tt>. These functions are -documented below. - -<sect2>Termination of the library -<label id="pam-end-section"> - -<p> -<tscreen> -<verb> -extern int pam_end(pam_handle_t *pamh, int pam_status); -</verb> -</tscreen> - -<p> -This function is the last function an application should call in the -<bf>Linux-PAM</bf> library. Upon return the handle <tt/pamh/ is no -longer valid and all memory associated with it will be invalid (likely -to cause a segmentation fault if accessed). - -<p> -Under normal conditions the argument <tt/pam_status/ has the value -PAM_SUCCESS, but in the event of an unsuccessful application for -service the appropriate <bf/Linux-PAM/ error-return value should be -used here. Note, <tt/pam_end()/ unconditionally shuts down the -authentication stack associated with the <tt/pamh/ handle. The value -taken by <tt/pam_status/ is used as an argument to the module specific -callback functions, <tt/cleanup()/ (see the <bf/Linux-PAM/ <htmlurl -url="pam_modules.html" name="Module Developers' Guide">). In this way, -the module can be given notification of the pass/fail nature of the -tear-down process, and perform any last minute tasks that are -appropriate to the module before it is unlinked. - -<sect2>Setting PAM items -<label id="pam-set-item-section"> - -<p> -<tscreen> -<verb> -extern int pam_set_item(pam_handle_t *pamh, int item_type, - const void *item); -</verb> -</tscreen> - -<p>This function is used to (re)set the value of one of the following -<bf/item_type/s: - -<p><descrip> -<tag><tt/PAM_SERVICE/</tag> - - The service name (which identifies that PAM stack that - <tt/libpam/ will use to authenticate the program). - -<tag><tt/PAM_USER/</tag> - - The username of the entity under whose identity service will - be given. That is, following authentication, <tt/PAM_USER/ - identifies the local entity that gets to use the - service. Note, this value can be mapped from something (eg., - "<tt/anonymous/") to something else (eg. "<tt/guest119/") by - any module in the PAM stack. As such an application should - consult the value of <tt/PAM_USER/ after each call to a - <tt/pam_*()/ function. - -<tag><tt/PAM_USER_PROMPT/</tag> - - The string used when prompting for a user's name. The default - value for this string is ``Please enter username: ''. - -<tag><tt/PAM_TTY/</tag> - - The terminal name: prefixed by <tt>/dev/</tt> if it is a - device file; for graphical, X-based, applications the value - for this item should be the <tt/$DISPLAY/ variable. - -<tag><tt/PAM_RUSER/</tag> - - The requesting entity: user's username for a locally - requesting user or a remote requesting user - generally an - application or module will attempt to supply the value that is - most strongly authenticated (a local account before a remote - one. The level of trust in this value is embodied in the - actual authentication stack associated with the application, - so it is ultimately at the discretion of the system - administrator. It should generally match the current - <tt/PAM_RHOST/ value. That is, "<tt/PAM_RUSER@PAM_RHOST/" - should always identify the requesting user. In some cases, - <tt/PAM_RUSER/ may be NULL. In such situations, it is unclear - who the requesting entity is. - -<tag><tt/PAM_RHOST/</tag> - - The requesting hostname (the hostname of the machine from - which the <tt/PAM_RUSER/ entity is requesting service). That - is "<tt/PAM_RUSER@PAM_RHOST/" does identify the requesting - user. "<tt/luser@localhost/" or "<tt/evil@evilcom.com/" are - valid "<tt/PAM_RUSER@PAM_RHOST/" examples. In some - applications, <tt/PAM_RHOST/ may be NULL. In such situations, - it is unclear where the authentication request is originating - from. - -<tag><tt/PAM_CONV/</tag> - - The conversation structure (see section <ref - id="the-conversation-function" name="below">). - -<tag><tt/PAM_FAIL_DELAY/</tag> A function pointer to redirect - centrally managed failure delays (see section <ref - id="the-failure-delay-function" name="below">). - -</descrip> - -<p> -For all <tt/item_type/s, other than <tt/PAM_CONV/ and -<tt/PAM_FAIL_DELAY/, <tt/item/ is a pointer to a <tt><NUL></tt> -terminated character string. In the case of <tt/PAM_CONV/, <tt/item/ -points to an initialized <tt/pam_conv/ structure (see section <ref -id="the-conversation-function" name="below">). In the case of -<tt/PAM_FAIL_DELAY/, <tt/item/ is a function pointer: <tt/void -(*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr)/ (see -section <ref id="the-failure-delay-function" name="below">). - -<p> -A successful call to this function returns <tt/PAM_SUCCESS/. However, -the application should expect at least one the following errors: - -<p> -<descrip> -<tag><tt/PAM_SYSTEM_ERR/</tag> - The <tt/pam_handle_t/ passed as a first argument to this - function was invalid. -<tag><tt/PAM_PERM_DENIED/</tag> - An attempt was made to replace the conversation structure with - a <tt/NULL/ value. -<tag><tt/PAM_BUF_ERR/</tag> - The function ran out of memory making a copy of the item. -<tag><tt/PAM_BAD_ITEM/</tag> - The application attempted to set an undefined or inaccessible - item. -</descrip> - -<sect2>Getting PAM items -<label id="pam-get-item-section"> - -<p> -<tscreen> -<verb> -extern int pam_get_item(const pam_handle_t *pamh, int item_type, - const void **item); -</verb> -</tscreen> - -<p> -This function is used to obtain the value of the indicated -<tt/item_type/. Upon successful return, <tt/*item/ contains a pointer -to the value of the corresponding item. Note, this is a pointer to -the <em/actual/ data and should <em/not/ be <tt/free()/'ed or -over-written! - -<p> -A successful call is signaled by a return value of <tt/PAM_SUCCESS/. -However, the application should expect one of the following errors: - -<p> -<descrip> -<tag><tt/PAM_SYSTEM_ERR/</tag> - The <tt/pam_handle_t/ passed as a first argument to this - function was invalid. -<tag><tt/PAM_PERM_DENIED/</tag> - The value of <tt/item/ was <tt/NULL/. -<tag><tt/PAM_BAD_ITEM/</tag> - The application attempted to set an undefined or inaccessible - item. -</descrip> - -<p> -In the case of an error, the contents of <tt/item/ is set to <tt/NULL/. - -<sect2>Understanding errors -<label id="pam-strerror-section"> - -<p> -<tscreen> -<verb> -extern const char *pam_strerror(pam_handle_t *pamh, int errnum); -</verb> -</tscreen> - -<p> -This function returns some text describing the <bf>Linux-PAM</bf> -error associated with the argument <tt/errnum/. If the error is not -recognized ``<tt/Unknown Linux-PAM error/'' is returned. - -<sect2>Planning for delays -<label id="the-failure-delay-function"> - -<p> -<tscreen> -<verb> -extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec); -</verb> -</tscreen> - -<p> -This function is offered by <bf/Linux-PAM/ to facilitate time delays -following a failed call to <tt/pam_authenticate()/ and before control -is returned to the application. When using this function the -application programmer should check if it is available with, -<tscreen> -<verb> -#ifdef PAM_FAIL_DELAY - .... -#endif /* PAM_FAIL_DELAY */ -</verb> -</tscreen> - - -<p> -Generally, an application requests that a user is authenticated by -<bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or -<tt/pam_chauthtok()/. These functions call each of the <em/stacked/ -authentication modules listed in the relevant <bf/Linux-PAM/ -configuration file. As directed by this file, one of more of the -modules may fail causing the <tt/pam_...()/ call to return an error. -It is desirable for there to also be a pause before the application -continues. The principal reason for such a delay is security: a delay -acts to discourage <em/brute force/ dictionary attacks primarily, but -also helps hinder <em/timed/ (covert channel) attacks. - -<p> -The <tt/pam_fail_delay()/ function provides the mechanism by which an -application or module can suggest a minimum delay (of <tt/micro_sec/ -<em/micro-seconds/). <bf/Linux-PAM/ keeps a record of the longest time -requested with this function. Should <tt/pam_authenticate()/ fail, -the failing return to the application is delayed by an amount of time -randomly distributed (by up to 25%) about this longest value. - -<p> -Independent of success, the delay time is reset to its zero default -value when <bf/Linux-PAM/ returns control to the application. - -<p> -For applications written with a single thread that are event driven in -nature, <tt/libpam/ generating this delay may be undesirable. Instead, -the application may want to register the delay in some other way. For -example, in a single threaded server that serves multiple -authentication requests from a single event loop, the application -might want to simply mark a given connection as blocked until an -application timer expires. For this reason, <bf/Linux-PAM/ supplies -the <tt/PAM_FAIL_DELAY/ item. It can be queried and set with -<tt/pam_get_item()/ and <tt/pam_set_item()/ respectively. The value -used to set it should be a function pointer of the following -prototype: - -<tscreen> -<verb> -void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr); -</verb> -</tscreen> - -The arguments being the <tt/retval/ return code of the module stack, -the <tt/usec_delay/ micro-second delay that libpam is requesting and -the <tt/appdata_ptr/ that the application has associated with the -current <tt/pamh/ (<tt/pam_handle_t/). This last value was set by the -application when it called <tt/pam_start/ or explicitly with -<tt/pam_set_item(... , PAM_CONV, ...)/. Note, if <tt/PAM_FAIL_DELAY/ -is unset (or set to <tt/NULL/), then <tt/libpam/ will perform any -delay. - -<sect2>Authenticating the user - -<p> -<tscreen> -<verb> -extern int pam_authenticate(pam_handle_t *pamh, int flags); -</verb> -</tscreen> - -<p> -This function serves as an interface to the authentication mechanisms -of the loaded modules. The single <em/optional/ flag, which may be -logically OR'd with <tt/PAM_SILENT/, takes the following value, - -<p><descrip> - -<tag><tt/PAM_DISALLOW_NULL_AUTHTOK/</tag> - Instruct the authentication modules to return -<tt/PAM_AUTH_ERR/ if the user does not have a registered -authorization token---it is set to <tt/NULL/ in the system database. -</descrip> - -<p> -The value returned by this function is one of the following: - -<p><descrip> - -<tag><tt/PAM_AUTH_ERR/</tag> - The user was not authenticated -<tag><tt/PAM_CRED_INSUFFICIENT/</tag> - For some reason the application does not have sufficient -credentials to authenticate the user. -<tag><tt/PAM_AUTHINFO_UNAVAIL/</tag> - The modules were not able to access the authentication -information. This might be due to a network or hardware failure etc. -<tag><tt/PAM_USER_UNKNOWN/</tag> - The supplied username is not known to the authentication -service -<tag><tt/PAM_MAXTRIES/</tag> - One or more of the authentication modules has reached its -limit of tries authenticating the user. Do not try again. - -</descrip> - -<p> -If one or more of the authentication modules fails to load, for -whatever reason, this function will return <tt/PAM_ABORT/. - -<sect2>Setting user credentials -<label id="pam-setcred-section"> - -<p> -<tscreen> -<verb> -extern int pam_setcred(pam_handle_t *pamh, int flags); -</verb> -</tscreen> - -<p> -This function is used to set the module-specific credentials of the -user. It is usually called after the user has been authenticated, -after the account management function has been called but before a -session has been opened for the user. - -<p> -A credential is something that the user possesses. It is some -property, such as a <em>Kerberos</em> ticket, or a supplementary group -membership that make up the uniqueness of a given user. On a Linux -(or UN*X system) the user's <tt>UID</tt> and <tt>GID</tt>'s are -credentials too. However, it has been decided that these properties -(along with the default supplementary groups of which the user is a -member) are credentials that should be set directly by the application -and not by PAM. - -<p> -This function simply calls the <tt/pam_sm_setcred/ functions of each -of the loaded modules. Valid <tt/flags/, any one of which, may be -logically OR'd with <tt/PAM_SILENT/, are: - -<p><descrip> -<tag><tt/PAM_ESTABLISH_CRED/</tag> - Set the credentials for the authentication service, -<tag><tt/PAM_DELETE_CRED/</tag> - Delete the credentials associated with the authentication service, -<tag><tt/PAM_REINITIALIZE_CRED/</tag> - Reinitialize the user credentials, and -<tag><tt/PAM_REFRESH_CRED/</tag> - Extend the lifetime of the user credentials. -</descrip> - -<p> -A successful return is signalled with <tt/PAM_SUCCESS/. Errors that -are especially relevant to this function are the following: - -<p><descrip> -<tag><tt/PAM_CRED_UNAVAIL/</tag> - A module cannot retrieve the user's credentials. -<tag><tt/PAM_CRED_EXPIRED/</tag> - The user's credentials have expired. -<tag><tt/PAM_USER_UNKNOWN/</tag> - The user is not known to an authentication module. -<tag><tt/PAM_CRED_ERR/</tag> - A module was unable to set the credentials of the user. -</descrip> - -<sect2>Account management - -<p> -<tscreen> -<verb> -extern int pam_acct_mgmt(pam_handle_t *pamh, int flags); -</verb> -</tscreen> - -<p> -This function is typically called after the user has been -authenticated. It establishes whether the user's account is healthy. -That is to say, whether the user's account is still active and whether -the user is permitted to gain access to the system at this time. -Valid flags, any one of which, may be logically OR'd with -<tt/PAM_SILENT/, and are the same as those applicable to the -<tt/flags/ argument of <tt/pam_authenticate/. - -<p> -This function simply calls the corresponding functions of each of the -loaded modules, as instructed by the configuration file, -<tt>/etc/pam.conf</tt>. - -<p> -The normal response from this function is <tt/PAM_SUCCESS/, however, -specific failures are indicated by the following error returns: - -<descrip> -<tag><tt/PAM_AUTHTOKEN_REQD/</tag> -The user <bf/is/ valid but their authentication token has -<em/expired/. The correct response to this return-value is to require -that the user satisfies the <tt/pam_chauthtok()/ function before -obtaining service. It may not be possible for some applications to do -this. In such cases, the user should be denied access until such time -as they can update their password. - -<tag><tt/PAM_ACCT_EXPIRED/</tag> - The user is no longer permitted to access the system. -<tag><tt/PAM_AUTH_ERR/</tag> - There was an authentication error. - -<tag><tt/PAM_PERM_DENIED/</tag> - The user is not permitted to gain access at this time. -<tag><tt/PAM_USER_UNKNOWN/</tag> - The user is not known to a module's account management -component. - -</descrip> - -<sect2>Updating authentication tokens -<label id="pam-chauthtok-section"> - -<p> -<tscreen> -<verb> -extern int pam_chauthtok(pam_handle_t *pamh, const int flags); -</verb> -</tscreen> - -<p> -This function is used to change the authentication token for a given -user (as indicated by the state associated with the handle, -<tt/pamh/). The following is a valid but optional flag which may be -logically OR'd with <tt/PAM_SILENT/, - -<descrip> -<tag><tt/PAM_CHANGE_EXPIRED_AUTHTOK/</tag> - This argument indicates to the modules that the users -authentication token (password) should only be changed if it has -expired. -</descrip> - -<p> -Note, if this argument is not passed, the application requires that -<em/all/ authentication tokens are to be changed. - -<p> -<tt/PAM_SUCCESS/ is the only successful return value, valid -error-returns are: - -<descrip> -<tag><tt/PAM_AUTHTOK_ERR/</tag> - A module was unable to obtain the new authentication token. - -<tag><tt/PAM_AUTHTOK_RECOVERY_ERR/</tag> - A module was unable to obtain the old authentication token. - -<tag><tt/PAM_AUTHTOK_LOCK_BUSY/</tag> - One or more of the modules was unable to change the -authentication token since it is currently locked. - -<tag><tt/PAM_AUTHTOK_DISABLE_AGING/</tag> - Authentication token aging has been disabled for at least one -of the modules. - -<tag><tt/PAM_PERM_DENIED/</tag> - Permission denied. - -<tag><tt/PAM_TRY_AGAIN/</tag> - Not all of the modules were in a position to update the -authentication token(s). In such a case none of the user's -authentication tokens are updated. - -<tag><tt/PAM_USER_UNKNOWN/</tag> - The user is not known to the authentication token changing -service. - -</descrip> - -<sect2>Session initialization -<label id="pam-open-session-section"> - -<p> -<tscreen> -<verb> -extern int pam_open_session(pam_handle_t *pamh, int flags); -</verb> -</tscreen> - -<p> -This function is used to indicate that an authenticated session has -begun. It is used to inform the modules that the user is currently in -a session. It should be possible for the <bf>Linux-PAM</bf> library -to open a session and close the same session (see section <ref -id="pam-close-session-section" name="below">) from different -applications. - -<p> -Currently, this function simply calls each of the corresponding -functions of the loaded modules. The only valid flag is -<tt/PAM_SILENT/ and this is, of course, <em/optional/. - -<p> -If any of the <em/required/ loaded modules are unable to open a -session for the user, this function will return <tt/PAM_SESSION_ERR/. - -<sect2>Terminating sessions -<label id="pam-close-session-section"> - -<p> -<tscreen> -<verb> -extern int pam_close_session(pam_handle_t *pamh, int flags); -</verb> -</tscreen> - -<p> -This function is used to indicate that an authenticated session has -ended. It is used to inform the modules that the user is exiting a -session. It should be possible for the <bf>Linux-PAM</bf> library to -open a session and close the same session from different applications. - -<p> -This function simply calls each of the corresponding functions of the -loaded modules in the same order that they were invoked with -<tt/pam_open_session()/. The only valid flag is <tt/PAM_SILENT/ and -this is, of course, <em/optional/. - -<p> -If any of the <em/required/ loaded modules are unable to close a -session for the user, this function will return <tt/PAM_SESSION_ERR/. - -<sect2>Setting PAM environment variables -<label id="pam-putenv-section"> - -<p> -The <tt/libpam/ library associates with each PAM-handle (<tt/pamh/), a -set of <it/PAM environment variables/. These variables are intended to -hold the session environment variables that the user will inherit when -the session is granted and the authenticated user obtains access to -the requested service. For example, when <tt/login/ has finally given -the user a shell, the environment (as viewed with the command -<tt/env/) will be what <tt/libpam/ was maintaining as the PAM -environment for that service application. Note, these variables are not -the environment variables of the <tt/login/ application. This is -principally for two reasons: <tt/login/ may want to have an -environment that cannot be seen or manipulated by a user; and -<tt/login/ (or whatever the serving application is) may be maintaining -a number of parallel sessions, via different <tt/pamh/ values, at the -same time and a single environment may not be appropriately shared -between each of these. The PAM environment may contain variables -seeded by the applicant user's client program, for example, and as -such it is not appropriate for one applicant to interfere with the -environment of another applicant. - -<p> -<tscreen> -<verb> -extern int pam_putenv(pam_handle_t *pamh, const char *name_value); -</verb> -</tscreen> - -<p> -This function attempts to (re)set a <bf/Linux-PAM/ environment -variable. The <tt/name_value/ argument is a single <tt/NUL/ terminated -string of one of the following forms: -<descrip> -<tag>``<tt/NAME=value of variable/''</tag> - -In this case the environment variable of the given <tt/NAME/ is set to -the indicated value: ``<tt/value of variable/''. If this variable is -already known, it is overwritten. Otherwise it is added to the -<bf/Linux-PAM/ environment. - -<tag>``<tt/NAME=/''</tag> - -This function sets the variable to an empty value. It is listed -separately to indicate that this is the correct way to achieve such a -setting. - -<tag>``<tt/NAME/''</tag> - -Without an `<tt/=/' the <tt/pam_putenv()/ function will delete the -corresponding variable from the <bf/Linux-PAM/ environment. - -</descrip> - -<p> -Success is indicated with a return value of <tt/PAM_SUCCESS/. Failure -is indicated by one of the following returns: - -<descrip> -<tag><tt/PAM_PERM_DENIED/</tag> - name given is a <tt/NULL/ pointer - -<tag><tt/PAM_BAD_ITEM/</tag> - variable requested (for deletion) is not currently set - -<tag><tt/PAM_ABORT/</tag> - the <bf/Linux-PAM/ handle, <tt/pamh/, is corrupt - -<tag><tt/PAM_BUF_ERR/</tag> - failed to allocate memory when attempting update - -</descrip> - -<sect2>Getting a PAM environment variable -<label id="pam-getenv-section"> - -<p> -<tscreen> -<verb> -extern const char *pam_getenv(pam_handle_t *pamh, const char *name); -</verb> -</tscreen> - -<p> -Obtain the value of the indicated <bf/Linux-PAM/ environment -variable. On error, internal failure or the unavailability of the -given variable (unspecified), this function simply returns <tt/NULL/. - -<sect2>Getting the PAM environment -<label id="pam-getenvlist-section"> - -<p> -<tscreen> -<verb> -extern const char * const *pam_getenvlist(pam_handle_t *pamh); -</verb> -</tscreen> - -<p> -The PAM environment variables (see section <ref -id="pam-putenv-section" name="above">) are a complete set of enviroment -variables that are associated with a PAM-handle (<tt/pamh/). They -represent the contents of the <it/regular/ environment variables of -the authenticated user when service is granted. - -<p> -Th function, <tt>pam_getenvlist()</tt> returns a pointer to a complete, -<tt/malloc()/'d, copy of the PAM environment. It is a pointer to a -duplicated list of environment variables. It should be noted that -this memory will never be <tt/free()'d/ by <tt/libpam/. Once obtained -by a call to <tt/pam_getenvlist()/, <bf>it is the responsibility of -the calling application</bf> to <tt/free()/ this memory. - -<p> -The format of the memory is a <tt/malloc()/'d array of <tt/char */ -pointers, the last element of which is set to <tt/NULL/. Each of the -non-<tt/NULL/ entries in this array point to a <tt/NUL/ terminated and -<tt/malloc()/'d <tt/char/ string of the form: -<tt/"/<it/name/<tt/=/<it/value/<tt/"/. - -<p> -It is by design, and not a coincidence, that the format and contents -of the returned array matches that required for the third argument of -the <tt/execle(3)/ function call. - -<sect1>What is expected of an application - -<sect2>The conversation function -<label id="the-conversation-function"> - -<p> -An application must provide a ``conversation function''. It is used -for direct communication between a loaded module and the application -and will typically provide a means for the module to prompt the user -for a password etc. . The structure, <tt/pam_conv/, is defined by -including <tt><security/pam_appl.h></tt>; to be, - -<p> -<tscreen> -<verb> -struct pam_conv { - int (*conv)(int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - void *appdata_ptr); - void *appdata_ptr; -}; -</verb> -</tscreen> - -<p> -It is initialized by the application before it is passed to the -library. The <em/contents/ of this structure are attached to the -<tt/*pamh/ handle. The point of this argument is to provide a -mechanism for any loaded module to interact directly with the -application program. This is why it is called a <em/conversation/ -structure. - -<p> -When a module calls the referenced <tt/conv()/ function, the argument -<tt/*appdata_ptr/ is set to the second element of this structure. - -<p> -The other arguments of a call to <tt/conv()/ concern the information -exchanged by module and application. That is to say, <tt/num_msg/ -holds the length of the array of pointers, <tt/msg/. After a -successful return, the pointer <tt/*resp/ points to an array of -<tt/pam_response/ structures, holding the application supplied text. -Note, <tt/*resp/ is an <tt/struct pam_response/ array and <em/not/ an -array of pointers. - -<p> -The message (from the module to the application) passing structure is -defined by <tt><security/pam_appl.h></tt> as: - -<p> -<tscreen> -<verb> -struct pam_message { - int msg_style; - const char *msg; -}; -</verb> -</tscreen> - -<p> -Valid choices for <tt/msg_style/ are: - -<p><descrip> -<tag><tt/PAM_PROMPT_ECHO_OFF/</tag> - Obtain a string without echoing any text -<tag><tt/PAM_PROMPT_ECHO_ON/</tag> - Obtain a string whilst echoing text -<tag><tt/PAM_ERROR_MSG/</tag> - Display an error -<tag><tt/PAM_TEXT_INFO/</tag> - Display some text. -</descrip> - -<p> -The point of having an array of messages is that it becomes possible -to pass a number of things to the application in a single call from -the module. It can also be convenient for the application that related -things come at once: a windows based application can then present a -single form with many messages/prompts on at once. - -<p> -In passing, it is worth noting that there is a descrepency between the -way Linux-PAM handles the <tt/const struct pam_message **msg/ -conversation function argument from the way that Solaris' PAM (and -derivitives, known to include HP/UX, <em/are there others?/) -does. Linux-PAM interprets the <tt/msg/ argument as entirely -equivalent to the following prototype <tt/const struct pam_message -*msg[]/ (which, in spirit, is consistent with the commonly used -prototypes for <tt/argv/ argument to the familiar <tt/main()/ -function: <tt/char **argv/; and <tt/char *argv[]/). Said another way -Linux-PAM interprets the <tt/msg/ argument as a pointer to an array of -<tt/num_meg/ read only 'struct pam_message' <em/pointers/. Solaris' -PAM implementation interprets this argument as a pointer to a pointer -to an array of <tt/num_meg/ <tt/pam_message/ structures. Fortunately, -perhaps, for most module/application developers when <tt/num_msg/ has -a value of one these two definitions are entirely -equivalent. Unfortunately, casually raising this number to two has led -to unanticipated compatibility problems. - -<p> -For what its worth the two known module writer work-arounds for trying -to maintain source level compatibility with both PAM implementations -are: -<itemize> -<item> never call the conversation function with <tt/num_msg/ greater -than one. -<item> set up <tt/msg/ as doubly referenced so both types of -conversation function can find the messages. That is, make -<p><tscreen> -<verb> -msg[n] = & (( *msg )[n]) -</verb> -</tscreen> -</itemize> -<p> -The response (from the application to the module) passing structure is -defined by including <tt><security/pam_appl.h></tt> as: - -<p><tscreen><verb> -struct pam_response { - char *resp; - int resp_retcode; -}; -</verb></tscreen> - -<p> -Currently, there are no definitions for <tt/resp_retcode/ values; the -normal value is <tt/0/. - -<p> -Prior to the 0.59 release of Linux-PAM, the length of the returned -<tt/pam_response/ array was equal to the number of <em/prompts/ (types -<tt/PAM_PROMPT_ECHO_OFF/ and <tt/PAM_PROMPT_ECHO_ON/) in the -<tt/pam_message/ array with which the conversation function was -called. This meant that it was not always necessary for the module to -<tt/free(3)/ the responses if the conversation function was only used -to display some text. - -<p> -Post Linux-PAM-0.59. The number of responses is always equal to the -<tt/num_msg/ conversation function argument. This is slightly easier -to program but does require that the response array is <tt/free(3)/'d -after every call to the conversation function. The index of the -responses corresponds directly to the prompt index in the -<tt/pam_message/ array. - -<p> -The maximum length of the <tt/pam_msg.msg/ and <tt/pam_response.resp/ -character strings is <tt/PAM_MAX_MSG_SIZE/. (This is not enforced by -Linux-PAM.) - -<p> -<tt/PAM_SUCCESS/ is the expected return value of this -function. However, should an error occur the application should not -set <tt/*resp/ but simply return <tt/PAM_CONV_ERR/. - -<p> -Note, if an application wishes to use two conversation functions, it -should activate the second with a call to <tt/pam_set_item()/. - -<p> -<bf>Notes:</bf> New item types are being added to the conversation -protocol. Currently Linux-PAM supports: <tt>PAM_BINARY_PROMPT</tt> -and <tt>PAM_BINARY_MSG</tt>. These two are intended for server-client -hidden information exchange and may be used as an interface for -maching-machine authentication. - -<sect1>Programming notes - -<p> -Note, all of the authentication service function calls accept the -token <tt/PAM_SILENT/, which instructs the modules to not send -messages to the application. This token can be logically OR'd with any -one of the permitted tokens specific to the individual function calls. -<tt/PAM_SILENT/ does not override the prompting of the user for -passwords etc., it only stops informative messages from being -generated. - -<sect>Security issues of <bf>Linux-PAM</bf> - -<p> -PAM, from the perspective of an application, is a convenient API for -authenticating users. PAM modules generally have no increased -privilege over that possessed by the application that is making use of -it. For this reason, the application must take ultimate responsibility -for protecting the environment in which PAM operates. - -<p> -A poorly (or maliciously) written application can defeat any -<bf/Linux-PAM/ module's authentication mechanisms by simply ignoring -it's return values. It is the applications task and responsibility to -grant privileges and access to services. The <bf/Linux-PAM/ library -simply assumes the responsibility of <em/authenticating/ the user; -ascertaining that the user <em/is/ who they say they are. Care should -be taken to anticipate all of the documented behavior of the -<bf/Linux-PAM/ library functions. A failure to do this will most -certainly lead to a future security breach. - -<sect1>Care about standard library calls - -<p> -In general, writers of authorization-granting applications should -assume that each module is likely to call any or <em/all/ `libc' -functions. For `libc' functions that return pointers to -static/dynamically allocated structures (ie. the library allocates the -memory and the user is not expected to `<tt/free()/' it) any module -call to this function is likely to corrupt a pointer previously -obtained by the application. The application programmer should either -re-call such a `libc' function after a call to the <bf/Linux-PAM/ -library, or copy the structure contents to some safe area of memory -before passing control to the <bf/Linux-PAM/ library. - -<p> -Two important function classes that fall into this category are -<tt>getpwnam(3)</tt> and <tt>syslog(3)</tt>. - -<sect1>Choice of a service name - -<p> -When picking the <em/service-name/ that corresponds to the first entry -in the <bf/Linux-PAM/ configuration file, the application programmer -should <bf/avoid/ the temptation of choosing something related to -<tt/argv[0]/. It is a trivial matter for any user to invoke any -application on a system under a different name and this should not be -permitted to cause a security breach. - -<p> -In general, this is always the right advice if the program is setuid, -or otherwise more privileged than the user that invokes it. In some -cases, avoiding this advice is convenient, but as an author of such an -application, you should consider well the ways in which your program -will be installed and used. (Its often the case that programs are not -intended to be setuid, but end up being installed that way for -convenience. If your program falls into this category, don't fall into -the trap of making this mistake.) - -<p> -To invoke some <tt/target/ application by another name, the user may -symbolically link the target application with the desired name. To be -precise all the user need do is, -<tscreen> -<verb> -ln -s /target/application ./preferred_name -</verb> -</tscreen> -and then <em/run/ <tt>./preferred_name</tt> - -<p> -By studying the <bf/Linux-PAM/ configuration file(s), an attacker can -choose the <tt/preferred_name/ to be that of a service enjoying -minimal protection; for example a game which uses <bf/Linux-PAM/ to -restrict access to certain hours of the day. If the service-name were -to be linked to the filename under which the service was invoked, it -is clear that the user is effectively in the position of dictating -which authentication scheme the service uses. Needless to say, this -is not a secure situation. - -<p> -The conclusion is that the application developer should carefully -define the service-name of an application. The safest thing is to make -it a single hard-wired name. - -<sect1>The conversation function - -<p> -Care should be taken to ensure that the <tt/conv()/ function is -robust. Such a function is provided in the library <tt/libpam_misc/ -(see <ref id="libpam-misc-section" name="below">). - -<sect1>The identity of the user - -<p> -The <bf/Linux-PAM/ modules will need to determine the identity of the -user who requests a service, and the identity of the user who grants -the service. These two users will seldom be the same. Indeed there -is generally a third user identity to be considered, the new (assumed) -identity of the user once the service is granted. - -<p> -The need for keeping tabs on these identities is clearly an issue of -security. One convention that is actively used by some modules is -that the identity of the user requesting a service should be the -current <tt/uid/ (userid) of the running process; the identity of the -privilege granting user is the <tt/euid/ (effective userid) of the -running process; the identity of the user, under whose name the -service will be executed, is given by the contents of the -<tt/PAM_USER/ <tt/pam_get_item(3)/. Note, modules can change the -values of <tt/PAM_USER/ and <tt/PAM_RUSER/ during any of the -<tt/pam_*()/ library calls. For this reason, the application should -take care to use the <tt/pam_get_item()/ every time it wishes to -establish who the authenticated user is (or will currently be). - -<p> -For network-serving databases and other applications that provide -their own security model (independent of the OS kernel) the above -scheme is insufficient to identify the requesting user. - -<p> -A more portable solution to storing the identity of the requesting -user is to use the <tt/PAM_RUSER/ <tt/pam_get_item(3)/. The -application should supply this value before attempting to authenticate -the user with <tt/pam_authenticate()/. How well this name can be -trusted will ultimately be at the discretion of the local -administrator (who configures PAM for your application) and a selected -module may attempt to override the value where it can obtain more -reliable data. If an application is unable to determine the identity -of the requesting entity/user, it should not call <tt/pam_set_item(3)/ -to set <tt/PAM_RUSER/. - -<p> -In addition to the <tt/PAM_RUSER/ item, the application should supply -the <tt/PAM_RHOST/ (<em/requesting host/) item. As a general rule, the -following convention for its value can be assumed: <tt/<unset>/ -= unknown; <tt/localhost/ = invoked directly from the local system; -<em/other.place.xyz/ = some component of the user's connection -originates from this remote/requesting host. At present, PAM has no -established convention for indicating whether the application supports -a trusted path to communication from this host. - -<sect1>Sufficient resources - -<p> -Care should be taken to ensure that the proper execution of an -application is not compromised by a lack of system resources. If an -application is unable to open sufficient files to perform its service, -it should fail gracefully, or request additional resources. -Specifically, the quantities manipulated by the <tt/setrlimit(2)/ -family of commands should be taken into consideration. - -<p> -This is also true of conversation prompts. The application should not -accept prompts of arbitrary length with out checking for resource -allocation failure and dealing with such extreme conditions gracefully -and in a mannor that preserves the PAM API. Such tolerance may be -especially important when attempting to track a malicious adversary. - -<sect>A library of miscellaneous helper functions -<label id="libpam-misc-section"> - -<p> -To aid the work of the application developer a library of -miscellaneous functions is provided. It is called <tt/libpam_misc/, -and contains functions for allocating memory (securely), a text based -conversation function, and routines for enhancing the standard -PAM-environment variable support. - -<sect1>Requirements - -<p> -The functions, structures and macros, made available by this library -can be defined by including <tt><security/pam_misc.h></tt>. It -should be noted that this library is specific to <bf/Linux-PAM/ and is -not referred to in the defining DCE-RFC (see <ref id="bibliography" -name="the bibliography">) below. - -<sect1>Macros supplied - -<sect2>Safe duplication of strings - -<p> -<tscreen> -<verb> -x_strdup(const char *s) -</verb> -</tscreen> - -<p> -This macro is a replacement for the <tt/xstrdup()/ function that was -present in earlier versions of the library and which clashed horribly -with a number of applications. It returns a duplicate copy of the -<tt/NUL/ terminated string, <tt/s/. <tt/NULL/ is returned if there is -insufficient memory available for the duplicate or if <tt/s/ is -<tt/NULL/ to begin with. - -<sect1>Functions supplied - -<sect2>A text based conversation function - -<p> -<tscreen> -<verb> -extern int misc_conv(int num_msg, const struct pam_message **msgm, - struct pam_response **response, void *appdata_ptr); -</verb> -</tscreen> - -<p> -This is a function that will prompt the user with the appropriate -comments and obtain the appropriate inputs as directed by -authentication modules. - -<p> -In addition to simply slotting into the appropriate <tt/struct -pam_conv/, this function provides some time-out facilities. The -function exports five variables that can be used by an application -programmer to limit the amount of time this conversation function will -spend waiting for the user to type something. - -<p> -The five variables are as follows: -<descrip> -<tag><tt>extern time_t pam_misc_conv_warn_time;</tt></tag> - -This variable contains the <em/time/ (as returned by <tt/time()/) that -the user should be first warned that the clock is ticking. By default -it has the value <tt/0/, which indicates that no such warning will be -given. The application may set its value to sometime in the future, -but this should be done prior to passing control to the <bf/Linux-PAM/ -library. - -<tag><tt>extern const char *pam_misc_conv_warn_line;</tt></tag> - -Used in conjuction with <tt/pam_misc_conv_warn_time/, this variable is -a pointer to the string that will be displayed when it becomes time to -warn the user that the timeout is approaching. Its default value is -``..\a.Time is running out...\n'', but this can be changed -by the application prior to passing control to <bf/Linux-PAM/. - -<tag><tt>extern time_t pam_misc_conv_die_time;</tt></tag> - -This variable contains the <em/time/ (as returned by <tt/time()/) that -the conversation will time out. By default it has the value <tt/0/, -which indicates that the conversation function will not timeout. The -application may set its value to sometime in the future, this should -be done prior to passing control to the <bf/Linux-PAM/ library. - -<tag><tt>extern const char *pam_misc_conv_die_line;</tt></tag> - -Used in conjuction with <tt/pam_misc_conv_die_time/, this variable is -a pointer to the string that will be displayed when the conversation -times out. Its default value is ``..\a.Sorry, your time is -up!\n'', but this can be changed by the application prior to -passing control to <bf/Linux-PAM/. - -<tag><tt>extern int pam_misc_conv_died;</tt></tag> - -Following a return from the <bf/Linux-PAM/ libraray, the value of this -variable indicates whether the conversation has timed out. A value of -<tt/1/ indicates the time-out occurred. - -</descrip> - -<p> -The following two function pointers are available for supporting binary -prompts in the conversation function. They are optimized for the -current incarnation of the <tt/libpamc/ library and are subject to -change. -<descrip> -<tag><tt>extern int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t -*prompt_p);</tt></tag> - -This function pointer is initialized to <tt/NULL/ but can be filled -with a function that provides machine-machine (hidden) message -exchange. It is intended for use with hidden authentication protocols -such as RSA or Diffie-Hellman key exchanges. (This is still under -development.) - -<tag><tt>extern int (*pam_binary_handler_free)(void *appdata, -pamc_bp_t *delete_me);</tt></tag> - -This function pointer is initialized to <tt/PAM_BP_RENEW(delete_me, 0, -0)/, but can be redefined as desired by the application. - -</descrip> - -<sect2>Transcribing an environment to that of Linux-PAM -<p> -<tscreen> -<verb> -extern int pam_misc_paste_env(pam_handle_t *pamh, - const char * const * user_env); -</verb> -</tscreen> - -This function takes the supplied list of environment pointers and -<em/uploads/ its contents to the <bf/Linux-PAM/ environment. Success -is indicated by <tt/PAM_SUCCESS/. - -<sect2>Liberating a locally saved environment -<p> -<tscreen> -<verb> -extern char **pam_misc_drop_env(char **env); -</verb> -</tscreen> - -This function is defined to complement the <tt/pam_getenvlist()/ -function. It liberates the memory associated with <tt/env/, -<em/overwriting/ with <tt/0/ all memory before <tt/free()/ing it. - -<sect2>BSD like Linux-PAM environment variable setting -<p> -<tscreen> -<verb> -extern int pam_misc_setenv(pam_handle_t *pamh, const char *name, - const char *value, int readonly); -</verb> -</tscreen> - -This function performs a task equivalent to <tt/pam_putenv()/, its -syntax is, however, more like the BSD style function; <tt/setenv()/. -The <tt/name/ and <tt/value/ are concatenated with an ``<tt/=/'' to -form a <tt/name_value/ and passed to <tt/pam_putenv()/. If, however, -the <bf/Linux-PAM/ variable is already set, the replacement will only -be applied if the last argument, <tt/readonly/, is zero. - -<sect>Porting legacy applications - -<p> -The following is extracted from an email. I'll tidy it up later. - -<p> -The point of PAM is that the application is not supposed to have any -idea how the attached authentication modules will choose to -authenticate the user. So all they can do is provide a conversation -function that will talk directly to the user(client) on the modules' -behalf. - -<p> -Consider the case that you plug a retinal scanner into the login -program. In this situation the user would be prompted: "please look -into the scanner". No username or password would be needed - all this -information could be deduced from the scan and a database lookup. The -point is that the retinal scanner is an ideal task for a "module". - -<p> -While it is true that a pop-daemon program is designed with the POP -protocol in mind and no-one ever considered attaching a retinal -scanner to it, it is also the case that the "clean" PAM'ification of -such a daemon would allow for the possibility of a scanner module -being be attached to it. The point being that the "standard" -pop-authentication protocol(s) [which will be needed to satisfy -inflexible/legacy clients] would be supported by inserting an -appropriate pam_qpopper module(s). However, having rewritten popd -once in this way any new protocols can be implemented in-situ. - -<p> -One simple test of a ported application would be to insert the -<tt/pam_permit/ module and see if the application demands you type a -password... In such a case, <tt/xlock/ would fail to lock the -terminal - or would at best be a screen-saver, ftp would give password -free access to all etc.. Neither of these is a very secure thing to -do, but they do illustrate how much flexibility PAM puts in the hands -of the local admin. - -<p> -The key issue, in doing things correctly, is identifying what is part -of the authentication procedure (how many passwords etc..) the -exchange protocol (prefixes to prompts etc., numbers like 331 in the -case of ftpd) and what is part of the service that the application -delivers. PAM really needs to have total control in the -authentication "procedure", the conversation function should only -deal with reformatting user prompts and extracting responses from raw -input. - -<sect>Glossary of PAM related terms - -<p> -The following are a list of terms used within this document. - -<p> -<descrip> - -<tag>Authentication token</tag> -Generally, this is a password. However, a user can authenticate -him/herself in a variety of ways. Updating the user's authentication -token thus corresponds to <em>refreshing</em> the object they use to -authenticate themself with the system. The word password is avoided -to keep open the possibility that the authentication involves a -retinal scan or other non-textual mode of challenge/response. - -<tag>Credentials</tag> -Having successfully authenticated the user, PAM is able to establish -certain characteristics/attributes of the user. These are termed -<em>credentials</em>. Examples of which are group memberships to -perform privileged tasks with, and <em>tickets</em> in the form of -environment variables etc. . Some user-credentials, such as the -user's UID and GID (plus default group memberships) are not deemed to -be PAM-credentials. It is the responsibility of the application to -grant these directly. - -</descrip> - -<sect>An example application - -<p> -To get a flavor of the way a <tt/Linux-PAM/ application is written we -include the following example. It prompts the user for their password -and indicates whether their account is valid on the standard output, -its return code also indicates the success (<tt/0/ for success; <tt/1/ -for failure). - -<p> -<tscreen> -<verb> -/* - This program was contributed by Shane Watts - [modifications by AGM] - - You need to add the following (or equivalent) to the /etc/pam.conf file. - # check authorization - check_user auth required /usr/lib/security/pam_unix_auth.so - check_user account required /usr/lib/security/pam_unix_acct.so - */ - -#include <security/pam_appl.h> -#include <security/pam_misc.h> -#include <stdio.h> - -static struct pam_conv conv = { - misc_conv, - NULL -}; - -int main(int argc, char *argv[]) -{ - pam_handle_t *pamh=NULL; - int retval; - const char *user="nobody"; - - if(argc == 2) { - user = argv[1]; - } - - if(argc > 2) { - fprintf(stderr, "Usage: check_user [username]\n"); - exit(1); - } - - retval = pam_start("check_user", user, &ero;conv, &ero;pamh); - - if (retval == PAM_SUCCESS) - retval = pam_authenticate(pamh, 0); /* is user really user? */ - - if (retval == PAM_SUCCESS) - retval = pam_acct_mgmt(pamh, 0); /* permitted access? */ - - /* This is where we have been authorized or not. */ - - if (retval == PAM_SUCCESS) { - fprintf(stdout, "Authenticated\n"); - } else { - fprintf(stdout, "Not Authenticated\n"); - } - - if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */ - pamh = NULL; - fprintf(stderr, "check_user: failed to release authenticator\n"); - exit(1); - } - - return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */ -} -</verb> -</tscreen> - -<sect>Files - -<p><descrip> - -<tag><tt>/usr/include/security/pam_appl.h</tt></tag> - -header file for <bf/Linux-PAM/ applications interface - -<tag><tt>/usr/include/security/pam_misc.h</tt></tag> - -header file for useful library functions for making applications -easier to write - -<tag><tt>/usr/lib/libpam.so.*</tt></tag> - -the shared library providing applications with access to -<bf/Linux-PAM/. - -<tag><tt>/etc/pam.conf</tt></tag> - -the <bf/Linux-PAM/ configuration file. - -<tag><tt>/usr/lib/security/pam_*.so</tt></tag> - -the primary location for <bf/Linux-PAM/ dynamically loadable object -files; the modules. - -</descrip> - -<sect>See also -<label id="bibliography"> - -<p><itemize> - -<item>The <bf/Linux-PAM/ -<htmlurl url="pam.html" name="System Administrators' Guide">. - -<item>The <bf/Linux-PAM/ -<htmlurl url="pam_modules.html" name="Module Writers' Guide">. - -<item>The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH -PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation Request -For Comments 86.0, October 1995. - -</itemize> - -<sect>Notes - -<p> -I intend to put development comments here... like ``at the moment -this isn't actually supported''. At release time what ever is in -this section will be placed in the Bugs section below! :) - -<p> -<itemize> - -<item> <tt/pam_strerror()/ should be internationalized.... - -<item> -Note, the <tt/resp_retcode/ of struct <tt/pam_message/, has no -purpose at the moment. Ideas/suggestions welcome! - -<item> more security issues are required.... - -</itemize> - -<sect>Author/acknowledgments - -<p> -This document was written by Andrew G. Morgan -(morgan@kernel.org) with many contributions from -<!-- insert credits here --> -<!-- - an sgml list of people to credit for their contributions to Linux-PAM - $Id$ - --> -Chris Adams, -Peter Allgeyer, -Tim Baverstock, -Tim Berger, -Craig S. Bell, -Derrick J. Brashear, -Ben Buxton, -Seth Chaiklin, -Oliver Crow, -Chris Dent, -Marc Ewing, -Cristian Gafton, -Emmanuel Galanos, -Brad M. Garcia, -Eric Hester, -Roger Hu, -Eric Jacksch, -Michael K. Johnson, -David Kinchlea, -Olaf Kirch, -Marcin Korzonek, -Stephen Langasek, -Nicolai Langfeldt, -Elliot Lee, -Luke Kenneth Casson Leighton, -Al Longyear, -Ingo Luetkebohle, -Marek Michalkiewicz, -Robert Milkowski, -Aleph One, -Martin Pool, -Sean Reifschneider, -Jan Rekorajski, -Erik Troan, -Theodore Ts'o, -Jeff Uphoff, -Myles Uyema, -Savochkin Andrey Vladimirovich, -Ronald Wahl, -David Wood, -John Wilmes, -Joseph S. D. Yao -and -Alex O. Yuriev. - -<p> -Thanks are also due to Sun Microsystems, especially to Vipin Samar and -Charlie Lai for their advice. At an early stage in the development of -<bf/Linux-PAM/, Sun graciously made the documentation for their -implementation of PAM available. This act greatly accelerated the -development of <bf/Linux-PAM/. - -<sect>Bugs/omissions - -<p> -This manual is hopelessly unfinished. Only a partial list of people is -credited for all the good work they have done. - -<sect>Copyright information for this document - -<p> -Copyright (c) Andrew G. Morgan 1996-9,2000-1. All rights reserved. -<newline> -Email: <tt><morgan@kernel.org></tt> - -<p> -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -<p> -<itemize> - -<item> -1. Redistributions of source code must retain the above copyright - notice, and the entire permission notice in its entirety, - including the disclaimer of warranties. - -<item> -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -<item> -3. The name of the author may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -</itemize> - -<p> -<bf/Alternatively/, this product may be distributed under the terms of -the GNU General Public License (GPL), in which case the provisions of -the GNU GPL are required <bf/instead of/ the above restrictions. -(This clause is necessary due to a potential bad interaction between -the GNU GPL and the restrictions contained in a BSD-style copyright.) - -<p> -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -<p> -<tt>$Id$</tt> - -</article> |