summaryrefslogtreecommitdiff
path: root/Linux-PAM/doc/pam_appl.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/doc/pam_appl.sgml')
-rw-r--r--Linux-PAM/doc/pam_appl.sgml1782
1 files changed, 1782 insertions, 0 deletions
diff --git a/Linux-PAM/doc/pam_appl.sgml b/Linux-PAM/doc/pam_appl.sgml
new file mode 100644
index 00000000..f6d35b4e
--- /dev/null
+++ b/Linux-PAM/doc/pam_appl.sgml
@@ -0,0 +1,1782 @@
+<!doctype linuxdoc system>
+
+<!--
+
+ $Id: pam_appl.sgml,v 1.1.1.2 2002/09/15 20:08:24 hartmans Exp $
+
+ 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>&lt;security/pam_appl.h&gt;</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 who's 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/&dollar;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>&lt;NUL&gt;</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>
+Note, in the case of an error, the contents of <tt/item/ is not
+modified - that is, it retains its pre-call value. One should take
+care to initialize this value prior to calling
+<tt/pam_get_item()/. Since, if its value - despite the
+<tt/pam_get_item()/ function failing - is to be used the consequences
+are undefined.
+
+<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>&lt;security/pam_appl.h&gt</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>&lt;security/pam_appl.h&gt;</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>&lt;security/pam_appl.h&gt;</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/&lt;unset&gt;/
+= 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>&lt;security/pam_misc.h&gt;</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
+``..&bsol;a.Time is running out...&bsol;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 ``..&bsol;a.Sorry, your time is
+up!&bsol;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: pam_appl.sgml,v 1.1.1.2 2002/09/15 20:08:24 hartmans Exp $
+ -->
+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>&lt;morgan@kernel.org&gt;</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: pam_appl.sgml,v 1.1.1.2 2002/09/15 20:08:24 hartmans Exp $</tt>
+
+</article>