1 <!doctype linuxdoc system>
5 $Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $
6 $FreeBSD: src/contrib/libpam/doc/pam_appl.sgml,v 1.1.1.1.6.2 2001/06/11 15:28:10 markm Exp $
7 $DragonFly: src/contrib/libpam/doc/Attic/pam_appl.sgml,v 1.2 2003/06/17 04:24:02 dillon Exp $
9 Copyright (C) Andrew G. Morgan 1996, 1997. All rights reserved.
11 Redistribution and use in source (sgml) and binary (derived) forms,
12 with or without modification, are permitted provided that the
13 following conditions are met:
15 1. Redistributions of source code must retain the above copyright
16 notice, and the entire permission notice in its entirety,
17 including the disclaimer of warranties.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. The name of the author may not be used to endorse or promote
24 products derived from this software without specific prior
27 ALTERNATIVELY, this product may be distributed under the terms of the
28 GNU General Public License, in which case the provisions of the GNU
29 GPL are required INSTEAD OF the above restrictions. (This clause is
30 necessary due to a potential bad interaction between the GNU GPL and
31 the restrictions contained in a BSD-style copyright.)
33 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
34 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
35 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
36 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
37 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
38 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
39 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
42 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
49 <title>The Linux-PAM Application Developers' Guide
50 <author>Andrew G. Morgan, <tt>morgan@linux.kernel.org</tt>
51 <date>DRAFT v0.63 1998/1/18
53 This manual documents what an application developer needs to know
54 about the <bf>Linux-PAM</bf> library. It describes how an application
55 might use the <bf>Linux-PAM</bf> library to authenticate users. In
56 addition it contains a description of the funtions to be found in
57 <tt/libpam_misc/ library, that can be used in general applications.
58 Finally, it contains some comments on PAM related security issues for
59 the application developer.
69 For general applications that wish to use the services provided by
70 <bf/Linux-PAM/ the following is a summary of the relevant linking
74 #include <security/pam_appl.h>
76 cc -o application .... -lpam
81 In addition to <tt/libpam/, there is a library of miscellaneous
82 functions that make the job of writing <em/PAM-aware/ applications
83 easier (this library is not covered in the DCE-RFC for PAM and is
84 specific to the Linux-PAM distribution):
88 #include <security/pam_misc.h>
90 cc -o application .... -lpam -lpam_misc
97 <bf>Linux-PAM</bf> (Pluggable Authentication Modules for Linux) is a
98 library that enables the local system administrator to choose how
99 individual applications authenticate users. For an overview of the
100 <bf>Linux-PAM</bf> library see the <bf/Linux-PAM/ System
101 Administrators' Guide.
104 It is the purpose of the <bf>Linux-PAM</bf> project to liberate the
105 development of privilege granting software from the development of
106 secure and appropriate authentication schemes. This is accomplished
107 by providing a documented library of functions that an application may
108 use for all forms of user authentication management. This library
109 dynamically loads locally configured authentication modules that
110 actually perform the authentication tasks.
113 From the perspective of an application developer the information
114 contained in the local configuration of the PAM library should not be
115 important. Indeed it is intended that an application treat the
116 functions documented here as a ``black box'' that will deal with all
117 aspects of user authentication. ``All aspects'' includes user
118 verification, account management, session initialization/termination
119 and also the resetting of passwords (<em/authentication tokens/).
124 Most service-giving applications are restricted. In other words,
125 their service is not available to all and every prospective client.
126 Instead, the applying client must jump through a number of hoops to
127 convince the serving application that they are authorized to obtain
130 The process of <em/authenticating/ a client is what PAM is designed to
131 manage. In addition to authentication, PAM provides account
132 management, credential management, session management and
133 authentication-token (password changing) management services. It is
134 important to realize when writing a PAM based application that these
135 services are provided in a manner that is <bf>transparent</bf> to the
136 the application. That is to say, when the application is written, no
137 assumptions can be made about <em>how</em> the client will be
141 The process of authentication is performed by the PAM library via a
142 call to <tt>pam_authenticate()</tt>. The return value of this
143 function will indicate whether a named client (the <em>user</em>) has
144 been authenticated. If the PAM library needs to prompt the user for
145 any information, such as their <em>name</em> or a <em>password</em>
146 then it will do so. If the PAM library is configured to authenticate
147 the user using some silent protocol, it will do this too. (This
148 latter case might be via some hardware interface for example.)
151 It is important to note that the application must leave all decisions
152 about when to prompt the user at the discretion of the PAM library.
155 The PAM library, however, must work equally well for different styles
156 of application. Some applications, like the familiar <tt>login</tt>
157 and <tt>passwd</tt> are terminal based applications, exchanges of
158 information with the client in these cases is as plain text messages.
159 Graphically based applications, however, have a more sophisticated
160 interface. They generally interact with the user via specially
161 constructed dialogue boxes. Additionally, network based services
162 require that text messages exchanged with the client are specially
163 formatted for automated processing: one such example is <tt>ftpd</tt>
164 which prefixes each exchanged message with a numeric identifier.
167 The presentation of simple requests to a client is thus something very
168 dependent on the protocol that the serving application will use. In
169 spite of the fact that PAM demands that it drives the whole
170 authentication process, it is not possible to leave such protocol
171 subtleties up to the PAM library. To overcome this potential problem,
172 the application provides the PAM library with a <em>conversation</em>
173 function. This function is called from <bf>within</bf> the PAM
174 library and enables the PAM to directly interact with the client. The
175 sorts of things that this conversation function must be able to do are
176 prompt the user with text and/or obtain textual input from the user
177 for processing by the PAM library. The details of this function are
178 provided in a later section.
181 For example, the conversation function may be called by the PAM library
182 with a request to prompt the user for a password. Its job is to
183 reformat the prompt request into a form that the client will
184 understand. In the case of <tt>ftpd</tt>, this will involve prefixing
185 the string with the number <tt>331</tt> and sending the request over
186 the network to a connected client. The conversation function will
187 then obtain any reply and, after extracting the typed password, will
188 return this string of text to the PAM library. Similar concerns need
189 to be addressed in the case of an X-based graphical server.
192 There are a number of issues that need to be addressed when one is
193 porting an existing application to become PAM compliant. A section
194 below has been devoted to this: Porting legacy applications.
197 Besides authentication, PAM provides other forms of management.
198 Session management is provided with calls to
199 <tt>pam_open_session()</tt> and <tt>pam_close_session()</tt>. What
200 these functions actually do is up to the local administrator. But
201 typically, they could be used to log entry and exit from the system or
202 for mounting and unmounting the user's home directory. If an
203 application provides continuous service for a period of time, it
204 should probably call these functions, first open after the user is
205 authenticated and then close when the service is terminated.
208 Account management is another area that an application developer
209 should include with a call to <tt/pam_acct_mgmt()/. This call will
210 perform checks on the good health of the user's account (has it
211 expired etc.). One of the things this function may check is whether
212 the user's authentication token has expired - in such a case the
213 application may choose to attempt to update it with a call to
214 <tt/pam_chauthtok()/, although some applications are not suited to
215 this task (<em>ftp</em> for example) and in this case the application
216 should deny access to the user.
219 PAM is also capable of setting and deleting the users credentials with
220 the call <tt>pam_setcred()</tt>. This function should always be
221 called after the user is authenticated and before service is offered
222 to the user. By convention, this should be the last call to the PAM
223 library before service is given to the user. What exactly a
224 credential is, is not well defined. However, some examples are given
225 in the glossary below.
227 <sect>The public interface to <bf>Linux-PAM</bf>
230 Firstly, the relevant include file for the <bf>Linux-PAM</bf> library
231 is <tt><security/pam_appl.h></tt>. It contains the definitions
232 for a number of functions. After listing these functions, we collect
233 some guiding remarks for programmers.
235 <sect1>What can be expected by the application
238 Here we document those functions in the <bf/Linux-PAM/ library that
239 may be called from an application.
241 <sect2>Initialization of Linux-PAM
242 <label id="pam-start-section">
247 extern int pam_start(const char *service_name, const char *user,
248 const struct pam_conv *pam_conversation,
249 pam_handle_t **pamh);
254 This is the first of the <bf>Linux-PAM</bf> functions that must be
255 called by an application. It initializes the interface and reads the
256 system configuration file, <tt>/etc/pam.conf</tt> (see the
257 <bf/Linux-PAM/ System Administrators' Guide). Following a successful
258 return (<tt/PAM_SUCCESS/) the contents of <tt/*pamh/ is a handle that
259 provides continuity for successive calls to the <bf/Linux-PAM/
260 library. The arguments expected by <tt/pam_start/ are as follows: the
261 <tt/service_name/ of the program, the <tt/user/name of the individual
262 to be authenticated, a pointer to an application-supplied
263 <tt/pam_conv/ structure and a pointer to a <tt/pam_handle_t/
267 The <tt>pam_conv</tt> structure is discussed more fully in the section
268 <ref id="the-conversation-function" name="below">. The
269 <tt>pam_handle_t</tt> is a <em>blind</em> structure and the
270 application should not attempt to probe it directly for information.
271 Instead the <bf>Linux-PAM</bf> library provides the functions
272 <tt>pam_set_item</tt> and <tt>pam_get_item</tt>. These functions are
275 <sect2>Termination of the library
276 <label id="pam-end-section">
281 extern int pam_end(pam_handle_t *pamh, int pam_status);
286 This function is the last function an application should call in the
287 <bf>Linux-PAM</bf> library. Upon return the handle <tt/pamh/ is no
288 longer valid and all memory associated with it will be invalid (likely
289 to cause a segmentation fault if accessed).
292 Under normal conditions the argument <tt/pam_status/ has the value
293 PAM_SUCCESS, but in the event of an unsuccessful service application
294 the approprite <bf/Linux-PAM/ error-return value should be used
296 attempt its purpose is to be passed as an argument to the
297 module specific function <tt/cleanup()/ (see the <bf/Linux-PAM/
298 <htmlurl url="pam_modules.html" name="Module Developers' Guide">).
300 <sect2>Setting PAM items
301 <label id="pam-set-item-section">
306 extern int pam_set_item(pam_handle_t *pamh, int item_type,
311 <p>This function is used to (re)set the value of one of the following
315 <tag><tt/PAM_SERVICE/</tag>
318 <tag><tt/PAM_USER/</tag>
321 <tag><tt/PAM_TTY/</tag>
322 The terminal name: prefixed by <tt>/dev/</tt> if it is a
323 device file; for graphical, X-based, applications the value for this
324 item should be the <tt/$DISPLAY/ variable.
326 <tag><tt/PAM_RHOST/</tag>
329 <tag><tt/PAM_CONV/</tag>
330 The conversation structure (see section <ref
331 id="the-conversation-function" name="below">)
333 <tag><tt/PAM_RUSER/</tag>
336 <tag><tt/PAM_USER_PROMPT/</tag>
337 The string used when prompting for a user's name. The default
338 value for this string is ``Please enter username: ''.
343 For all <tt/item_type/s, other than <tt/PAM_CONV/, <tt/item/ is a
344 pointer to a <tt><NUL></tt> terminated character string. In the
345 case of <tt/PAM_CONV/, <tt/item/ points to an initialized
346 <tt/pam_conv/ structure (see section <ref
347 id="the-conversation-function" name="below">).
350 A successful call to this function returns <tt/PAM_SUCCESS/. However,
351 the application should expect one of the following errors:
355 <tag><tt/PAM_PERM_DENIED/</tag>
356 An attempt was made to replace the conversation structure with
358 <tag><tt/PAM_BUF_ERR/</tag>
359 The function ran out of memory making a copy of the item.
360 <tag><tt/PAM_BAD_ITEM/</tag>
361 The application attempted to set an undefined item.
364 <sect2>Getting PAM items
365 <label id="pam-get-item-section">
370 extern int pam_get_item(const pam_handle_t *pamh, int item_type,
376 This function is used to obtain the value of the indicated
377 <tt/item_type/. Upon successful return, <tt/*item/ contains a pointer
378 to the value of the corresponding item. Note, this is a pointer to
379 the <em/actual/ data and should <em/not/ be <tt/free()/'ed or
380 over-written! A successful call is signaled by a return value of
381 <tt/PAM_SUCCESS/. If an attempt is made to get an undefined item,
382 <tt/PAM_BAD_ITEM/ is returned.
384 <sect2>Understanding errors
385 <label id="pam-strerror-section">
390 extern const char *pam_strerror(pam_handle_t *pamh, int errnum);
395 This function returns some text describing the <bf>Linux-PAM</bf>
396 error associated with the argument <tt/errnum/. If the error is not
397 recognized ``<tt/Unknown Linux-PAM error/'' is returned.
399 <sect2>Planning for delays
404 extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec);
409 This function is offered by <bf/Linux-PAM/ to facilitate time delays
410 following a failed call to <tt/pam_authenticate()/ and before control
411 is returned to the application. When using this function the
412 application programmer should check if it is available with,
415 #ifdef HAVE_PAM_FAIL_DELAY
417 #endif /* HAVE_PAM_FAIL_DELAY */
423 Generally, an application requests that a user is authenticated by
424 <bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or
425 <tt/pam_chauthtok()/. These functions calls each of the <em/stacked/
426 authentication modules listed in the <tt>/etc/pam.conf</tt> file. As
427 directed by this file, one of more of the modules may fail causing the
428 <tt/pam_...()/ call to return an error. It is desirable for there to
429 also be a pause before the application continues. The principal reason
430 for such a delay is security: a delay acts to discourage <em/brute
431 force/ dictionary attacks primarily, but also helps hinder
432 <em/timed/ (covert channel) attacks.
435 The <tt/pam_fail_delay()/ function provides the mechanism by which an
436 application or module can suggest a minimum delay (of <tt/micro_sec/
437 <em/micro-seconds/). <bf/Linux-PAM/ keeps a record of the longest time
438 requested with this function. Should <tt/pam_authenticate()/ fail,
439 the failing return to the application is delayed by an amount of time
440 randomly distributed (by up to 25%) about this longest value.
443 Independent of success, the delay time is reset to its zero default
444 value when <bf/Linux-PAM/ returns control to the application.
446 <sect2>Authenticating the user
451 extern int pam_authenticate(pam_handle_t *pamh, int flags);
456 This function serves as an interface to the authentication mechanisms
457 of the loaded modules. The single <em/optional/ flag, which may be
458 logically OR'd with <tt/PAM_SILENT/, takes the following value,
462 <tag><tt/PAM_DISALLOW_NULL_AUTHTOK/</tag>
463 Instruct the authentication modules to return
464 <tt/PAM_AUTH_ERR/ if the user does not have a registered
465 authorization token---it is set to <tt/NULL/ in the system database.
469 The value returned by this function is one of the following:
473 <tag><tt/PAM_AUTH_ERR/</tag>
474 The user was not authenticated
475 <tag><tt/PAM_CRED_INSUFFICIENT/</tag>
476 For some reason the application does not have sufficient
477 credentials to authenticate the user.
478 <tag><tt/PAM_AUTHINFO_UNAVAIL/</tag>
479 The modules were not able to access the authentication
480 information. This might be due to a network or hardware failure etc.
481 <tag><tt/PAM_USER_UNKNOWN/</tag>
482 The supplied username is not known to the authentication
484 <tag><tt/PAM_MAXTRIES/</tag>
485 One or more of the authentication modules has reached its
486 limit of tries authenticating the user. Do not try again.
491 If one or more of the authentication modules fails to load, for
492 whatever reason, this function will return <tt/PAM_ABORT/.
494 <sect2>Setting user credentials
495 <label id="pam-setcred-section">
500 extern int pam_setcred(pam_handle_t *pamh, int flags);
505 This function is used to set the module-specific credentials of the
506 user. It is usually called after the user has been authenticated,
507 after the account management function has been called and after a
508 session has been opened for the user.
511 A credential is something that the user possesses. It is some
512 property, such as a <em>Kerberos</em> ticket, or a supplementary group
513 membership that make up the uniqueness of a given user. On a Linux
514 (or UN*X system) the user's <tt>UID</tt> and <tt>GID</tt>'s are
515 credentials too. However, it has been decided that these properties
516 (along with the default supplementary groups of which the user is a
517 member) are credentials that should be set directly by the application
521 This function simply calls the <tt/pam_sm_setcred/ functions of each
522 of the loaded modules. Valid <tt/flags/, any one of which, may be
523 logically OR'd with <tt/PAM_SILENT/, are:
526 <tag><tt/PAM_ESTABLISH_CRED/</tag>
527 Set the credentials for the authentication service,
528 <tag><tt/PAM_DELETE_CRED/</tag>
529 Delete the credentials associated with the authentication service,
530 <tag><tt/PAM_REINITIALIZE_CRED/</tag>
531 Reinitialize the user credentials, and
532 <tag><tt/PAM_REFRESH_CRED/</tag>
533 Extend the lifetime of the user credentials.
537 A successful return is signalled with <tt/PAM_SUCCESS/. Errors that
538 are especially relevant to this function are the following:
541 <tag><tt/PAM_CRED_UNAVAIL/</tag>
542 A module cannot retrieve the user's credentials.
543 <tag><tt/PAM_CRED_EXPIRED/</tag>
544 The user's credentials have expired.
545 <tag><tt/PAM_USER_UNKNOWN/</tag>
546 The user is not known to an authentication module.
547 <tag><tt/PAM_CRED_ERR/</tag>
548 A module was unable to set the credentials of the user.
551 <sect2>Account management
556 extern int pam_acct_mgmt(pam_handle_t *pamh, int flags);
561 This function is typically called after the user has been
562 authenticated. It establishes whether the user's account is healthy.
563 That is to say, whether the user's account is still active and whether
564 the user is permitted to gain access to the system at this time.
565 Valid flags, any one of which, may be logically OR'd with
566 <tt/PAM_SILENT/, and are the same as those applicable to the
567 <tt/flags/ argument of <tt/pam_authenticate/.
570 This function simply calls the corresponding functions of each of the
571 loaded modules, as instructed by the configuration file,
572 <tt>/etc/pam.conf</tt>.
575 The normal response from this function is <tt/PAM_SUCCESS/, however,
576 specific failures are indicated by the following error returns:
579 <tag><tt/PAM_AUTHTOKEN_REQD/</tag>
580 The user <bf/is/ valid but their authentication token has
581 <em/expired/. The correct response to this return-value is to require
582 that the user satisfies the <tt/pam_chauthtok()/ function before
583 obtaining service. It may not be possible for some applications to do
584 this. In such cases, the user should be denied access until such time
585 as they can update their password.
587 <tag><tt/PAM_ACCT_EXPIRED/</tag>
588 The user is no longer permitted access to the system.
589 <tag><tt/PAM_AUTH_ERR/</tag>
590 There was an authentication error.
592 <tag><tt/PAM_PERM_DENIED/</tag>
593 The user is not permitted to gain access at this time.
594 <tag><tt/PAM_USER_UNKNOWN/</tag>
595 The user is not known to a module's account management
600 <sect2>Updating authentication tokens
601 <label id="pam-chauthtok-section">
606 extern int pam_chauthtok(pam_handle_t *pamh, const int flags);
611 This function is used to change the authentication token for a given
612 user (as indicated by the state associated with the handle,
613 <tt/pamh/). The following is a valid but optional flag which may be
614 logically OR'd with <tt/PAM_SILENT/,
617 <tag><tt/PAM_CHANGE_EXPIRED_AUTHTOK/</tag>
618 This argument indicates to the modules that the users
619 authentication token (password) should only be changed if it has
624 Note, if this argument is not passed, the application requires that
625 <em/all/ authentication tokens are to be changed.
628 <tt/PAM_SUCCESS/ is the only successful return value, valid
632 <tag><tt/PAM_AUTHTOK_ERR/</tag>
633 A module was unable to obtain the new authentication token.
635 <tag><tt/PAM_AUTHTOK_RECOVERY_ERR/</tag>
636 A module was unable to obtain the old authentication token.
638 <tag><tt/PAM_AUTHTOK_LOCK_BUSY/</tag>
639 One or more of the modules was unable to change the
640 authentication token since it is currently locked.
642 <tag><tt/PAM_AUTHTOK_DISABLE_AGING/</tag>
643 Authentication token aging has been disabled for at least one
646 <tag><tt/PAM_PERM_DENIED/</tag>
649 <tag><tt/PAM_TRY_AGAIN/</tag>
650 Not all of the modules were in a position to update the
651 authentication token(s). In such a case none of the user's
652 authentication tokens are updated.
654 <tag><tt/PAM_USER_UNKNOWN/</tag>
655 The user is not known to the authentication token changing
660 <sect2>Session initialization
661 <label id="pam-open-session-section">
666 extern int pam_open_session(pam_handle_t *pamh, int flags);
671 This function is used to indicate that an authenticated session has
672 begun. It is used to inform the module that the user is currently in
673 a session. It should be possible for the <bf>Linux-PAM</bf> library
674 to open a session and close the same session (see section <ref
675 id="pam-close-session-section" name="below">) from different
679 Currently, this function simply calls each of the corresponding
680 functions of the loaded modules. The only valid flag is
681 <tt/PAM_SILENT/ and this is, of course, <em/optional/.
684 If any of the <em/required/ loaded modules are unable to open a
685 session for the user, this function will return <tt/PAM_SESSION_ERR/.
687 <sect2>Terminating sessions
688 <label id="pam-close-session-section">
693 extern int pam_close_session(pam_handle_t *pamh, int flags);
698 This function is used to indicate that an authenticated session has
699 ended. It is used to inform the module that the user is exiting a
700 session. It should be possible for the <bf>Linux-PAM</bf> library to
701 open a session and close the same session from different applications.
704 Currently, this function simply calls each of the corresponding
705 functions of the loaded modules. The only valid flag is
706 <tt/PAM_SILENT/ and this is, of course, <em/optional/.
709 If any of the <em/required/ loaded modules are unable to close a
710 session for the user, this function will return <tt/PAM_SESSION_ERR/.
712 <sect2>Setting PAM environment variables
713 <label id="pam-putenv-section">
718 extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
724 Warning, the environment support in <bf/Linux-PAM/ is based solely
725 on a six line email from the developers at Sun. Its interface is
726 likely to be generally correct, however, the details are likely to be
727 changed as more information becomes available.
731 This function attempts to (re)set a <bf/Linux-PAM/ environment
732 variable. The <tt/name_value/ argument is a single <tt/NUL/ terminated
733 string of one of the following forms:
735 <tag>``<tt/NAME=value of variable/''</tag>
737 In this case the environment variable of the given <tt/NAME/ is set to
738 the indicated value: ``<tt/value of variable/''. If this variable is
739 already known, it is overwritten. Otherwise it is added to the
740 <bf/Linux-PAM/ environment.
742 <tag>``<tt/NAME=/''</tag>
744 This function sets the variable to an empty value. It is listed
745 separately to indicate that this is the correct way to achieve such a
748 <tag>``<tt/NAME/''</tag>
750 Without an `<tt/=/' the <tt/pam_putenv()/ function will delete the
751 correspoding variable from the <bf/Linux-PAM/ environment.
756 Success is indicated with a return value of <tt/PAM_SUCCESS/. Failure
757 is indicated by one of the following returns:
760 <tag><tt/PAM_PERM_DENIED/</tag>
761 name given is a <tt/NULL/ pointer
763 <tag><tt/PAM_BAD_ITEM/</tag>
764 variable requested (for deletion) is not currently set
766 <tag><tt/PAM_ABORT/</tag>
767 the <bf/Linux-PAM/ handle, <tt/pamh/, is corrupt
769 <tag><tt/PAM_BUF_ERR/</tag>
770 failed to allocate memory when attempting update
774 <sect2>Getting a PAM environment variable
775 <label id="pam-getenv-section">
780 extern const char *pam_getenv(pam_handle_t *pamh, const char *name);
786 Warning, the environment support in <bf/Linux-PAM/ is based solely
787 on a six-line email from the developers at Sun. Its interface is
788 likely to be generally correct, however, the details are likely to be
789 changed as more information becomes available.
793 Obtain the value of the indicated <bf/Linux-PAM/ environment
794 variable. On error, internal failure or the unavailability of the
795 given variable (unspecified), this function simply returns <tt/NULL/.
797 <sect2>Getting the PAM environment
798 <label id="pam-getenvlist-section">
803 extern const char * const *pam_getenvlist(pam_handle_t *pamh);
809 Warning, the environment support in <bf/Linux-PAM/ is based solely
810 on a six line email from the developers at Sun. Its interface is
811 likely to be generally correct, however, the details are likely to be
812 changed as more information becomes available.
816 This function returns a pointer to the complete <tt/Linux-PAM/
817 environment. It is a pointer to a <em/read-only/ list of
818 <em/read-only/ environment variables. It should be noted that this
819 memory will become invalid after a call to <tt/pam_end()/ (see the
820 section <ref id="pam-end-section" name="above">). If application
821 wishes to make use of this list after such a call, it should first
822 make a copy of all the set variables. (A function that performs such a
823 transcription is to be found in <tt/libpam_misc/.)
825 <sect1>What is expected of an application
827 <sect2>The conversation function
828 <label id="the-conversation-function">
831 An application must provide a ``conversation function''. It is used
832 for direct communication between a loaded module and the application
833 and will typically provide a means for the module to prompt the user
834 for a password etc. . The structure, <tt/pam_conv/, is defined by
835 including <tt><security/pam_appl.h></tt>; to be,
841 int (*conv)(int num_msg,
842 const struct pam_message **msg,
843 struct pam_response **resp,
851 It is initialized by the application before it is passed to the
852 library. The <em/contents/ of this structure are attached to the
853 <tt/*pamh/ handle. The point of this argument is to provide a
854 mechanism for any loaded module to interact directly with the
855 application program. This is why it is called a <em/conversation/
859 When a module calls the referenced <tt/conv()/ function, the argument
860 <tt/*appdata_ptr/ is set to the second element of this structure.
863 The other arguments of a call to <tt/conv()/ concern the information
864 exchanged by module and application. That is to say, <tt/num_msg/
865 holds the length of the array of pointers, <tt/msg/. After a
866 successful return, the pointer <tt/*resp/ points to an array of
867 <tt/pam_response/ structures, holding the application supplied text.
868 Note, <tt/*resp/ is an <tt/struct pam_response/ array and <em/not/ an
872 The message (from the module to the application) passing structure is
873 defined by <tt><security/pam_appl.h></tt> as:
886 Valid choices for <tt/msg_style/ are:
889 <tag><tt/PAM_PROMPT_ECHO_OFF/</tag>
890 Obtain a string without echoing any text
891 <tag><tt/PAM_PROMPT_ECHO_ON/</tag>
892 Obtain a string whilst echoing text
893 <tag><tt/PAM_ERROR_MSG/</tag>
895 <tag><tt/PAM_TEXT_INFO/</tag>
900 The point of having an array of messages is that it becomes possible
901 to pass a number of things to the application in a single call from
902 the module. It can also be convenient for the application that related
903 things come at once: a windows based application can then present a
904 single form with many messages/prompts on at once.
907 The response (from the application to the module) passing structure is
908 defined by including <tt><security/pam_appl.h></tt> as:
911 struct pam_response {
918 Currently, there are no definitions for <tt/resp_retcode/ values; the
919 normal value is <tt/0/.
922 Prior to the 0.59 release of Linux-PAM, the length of the returned
923 <tt/pam_response/ array was equal to the number of <em/prompts/ (types
924 <tt/PAM_PROMPT_ECHO_OFF/ and <tt/PAM_PROMPT_ECHO_ON/) in the
925 <tt/pam_message/ array with which the conversation function was
926 called. This meant that it was not always necessary for the module to
927 <tt/free(3)/ the responses if the conversation function was only used
928 to display some text.
931 Post Linux-PAM-0.59 (and in the interests of compatibility with
932 Sunsoft). The number of resposes is always equal to the <tt/num_msg/
933 conversation function argument. This is slightly easier to program
934 but does require that the response array is <tt/free(3)/'d after every
935 call to the conversation function. The index of the responses
936 corresponds directly to the prompt index in the <tt/pam_message/
940 The maximum length of the <tt/pam_msg.msg/ and <tt/pam_response.resp/
941 character strings is <tt/PAM_MAX_MSG_SIZE/. (This is not enforced by
945 <tt/PAM_SUCCESS/ is the expected return value of this
946 function. However, should an error occur the application should not
947 set <tt/*resp/ but simply return <tt/PAM_CONV_ERR/.
950 Note, if an application wishes to use two conversation functions, it
951 should activate the second with a call to <tt/pam_set_item()/.
954 <bf>Notes:</bf> New item types are being added to the conversation
955 protocol. Currently Linux-PAM supports: <tt>PAM_BINARY_PROMPT</tt>
956 and <tt>PAM_BINARY_MSG</tt>. These two are intended for server-client
957 hidden information exchange and may be used as an interface for
958 maching-machine authentication.
960 <sect1>Programming notes
963 Note, all of the authentication service function calls accept the
964 token <tt/PAM_SILENT/, which instructs the modules to not send
965 messages to the application. This token can be logically OR'd with any
966 one of the permitted tokens specific to the individual function calls.
967 <tt/PAM_SILENT/ does not override the prompting of the user for
968 passwords etc., it only stops informative messages from being
971 <sect>Security issues of <bf>Linux-PAM</bf>
974 A poorly (or maliciously) written application can defeat any
975 <bf/Linux-PAM/ module's authentication mechanisms by simply ignoring
976 it's return values. It is the applications task and responsibility to
977 grant privileges and access to services. The <bf/Linux-PAM/ library
978 simply assumes the responsibility of <em/authenticating/ the user;
979 ascertaining that the user <em/is/ who they say they are. Care should
980 be taken to anticipate all of the documented behavior of the
981 <bf/Linux-PAM/ library functions. A failure to do this will most
982 certainly lead to a future security breach.
984 <sect1>Care about standard library calls
987 In general, writers of authorization-granting applications should
988 assume that each module is likely to call any or <em/all/ `libc'
989 functions. For `libc' functions that return pointers to
990 static/dynamically allocated structures (ie. the library allocates the
991 memory and the user is not expected to `<tt/free()/' it) any module
992 call to this function is likely to corrupt a pointer previously
993 obtained by the application. The application programmer should either
994 re-call such a `libc' function after a call to the <bf/Linux-PAM/
995 library, or copy the structure contents to some safe area of memory
996 before passing control to the <bf/Linux-PAM/ library.
999 Two function classes that fall into this category are
1000 <tt>getpwnam(3)</tt> and <tt>syslog(3)</tt>.
1002 <sect1>Choice of a service name
1005 When picking the <em/service-name/ that corresponds to the first entry
1006 in the <tt>/etc/pam.conf</tt> file, the application programmer should
1007 <bf/avoid/ the temptation of choosing something related to
1008 <tt/argv[0]/. It is a trivial matter for any user to invoke any
1009 application on a system under a different name -- this should not be
1010 permitted to cause a security breach.
1013 To invoke some <tt/target/ application by another name, the user may
1014 symbolically link the target application with the desired name. To be
1015 precise all the user need do is,
1018 ln -s /target/application ./preferred_name
1021 and then <em/run/ <tt>./preferred_name</tt>
1024 By studying the <bf/Linux-PAM/ configuration file,
1025 <tt>/etc/pam.conf</tt>, an attacker can choose the <tt/preferred_name/
1026 to be that of a service enjoying minimal protection; for example a
1027 game which uses <bf/Linux-PAM/ to restrict access to certain hours of
1028 the day. If the service-name were to be linked to the filename under
1029 which the service was invoked, it is clear that the user is
1030 effectively in the position of dictating which authentication scheme
1031 the service uses. Needless to say, this is not a secure situation.
1034 The conclusion is that the application developer should carefully
1035 define the service-name of an application. The safest thing is to make
1036 it a single hard-wired name.
1038 <sect1>The conversation function
1041 Care should be taken to ensure that the <tt/conv()/ function is
1042 robust. Such a function is provided in the library <tt/libpam_misc/
1043 (see <ref id="libpam-misc-section" name="below">).
1045 <sect1>The identity of the user
1048 The <bf/Linux-PAM/ modules will need to determine the identity of the
1049 user who requests a service, and the identity of the user who grants
1050 the service. These two users will seldom be the same. Indeed there
1051 is generally a third user identity to be considered, the new (assumed)
1052 identity of the user once the service is granted.
1055 The need for keeping tabs on these identities is clearly an issue of
1056 security. Basically, the identity of the user requesting a service
1057 should be the current <tt/uid/ (userid) of the running process; the
1058 identity of the privilege granting user is the <tt/euid/ (effective
1059 userid) of the running process; the identity of the user, under whose
1060 name the service will be executed, is given by the contents of the
1061 <tt/PAM_USER/ <tt/pam_get_item(2)/.
1064 In addition the identity of a remote user, requesting the service from
1065 a distant location, will be placed in the <tt/PAM_RUSER/ item.
1067 <sect1>Sufficient resources
1070 Care should be taken to ensure that the proper execution of an
1071 application is not compromised by a lack of system resources. If an
1072 application is unable to open sufficient files to perform its service,
1073 it should fail gracefully, or request additional resources.
1074 Specifically, the quantities manipulated by the <tt/setrlimit(2)/
1075 family of commands should be taken into consideration.
1077 <sect>A library of miscellaneous helper functions
1078 <label id="libpam-misc-section">
1081 To aid the work of the application developer a library of
1082 miscellaneous functions is provided. It is called <tt/libpam_misc/,
1083 and contains functions for allocating memory (securely), a text based
1084 conversation function, and routines for enhancing the standard
1085 PAM-environment variable support.
1090 The functions, structures and macros, made available by this library
1091 can be defined by including <tt><security/pam_misc.h></tt>. It
1092 should be noted that this library is specific to <bf/Linux-PAM/ and is
1093 not referred to in the defining DCE-RFC (see <ref id="bibliography"
1094 name="the bibliography">) below.
1096 <sect1>Functions supplied
1098 <sect2>Safe string duplication
1103 extern char *xstrdup(const char *s)
1106 Return a duplicate copy of the <tt/NUL/ terminated string,
1107 <tt/s/. <tt/NULL/ is returned if there is insufficient memory
1108 available for the duplicate or if <tt/s=NULL/.
1110 <sect2>A text based conversation function
1115 extern int misc_conv(int num_msg, const struct pam_message **msgm,
1116 struct pam_response **response, void *appdata_ptr);
1121 This is a function that will prompt the user with the appropriate
1122 comments and obtain the appropriate inputs as directed by
1123 authentication modules.
1126 In addition to simply slotting into the appropriate <tt/struct
1127 pam_conv/, this function provides some time-out facilities. The
1128 function exports five variables that can be used by an application
1129 programmer to limit the amount of time this conversation function will
1130 spend waiting for the user to type something.
1133 The five variables are as follows:
1135 <tag><tt>extern time_t pam_misc_conv_warn_time;</tt></tag>
1137 This variable contains the <em/time/ (as returned by <tt/time()/) that
1138 the user should be first warned that the clock is ticking. By default
1139 it has the value <tt/0/, which indicates that no such warning will be
1140 given. The application may set its value to sometime in the future,
1141 but this should be done prior to passing control to the <bf/Linux-PAM/
1144 <tag><tt>extern const char *pam_misc_conv_warn_line;</tt></tag>
1146 Used in conjuction with <tt/pam_misc_conv_warn_time/, this variable is
1147 a pointer to the string that will be displayed when it becomes time to
1148 warn the user that the timeout is approaching. Its default value is
1149 ``..\a.Time is running out...\n'', but this can be changed
1150 by the application prior to passing control to <bf/Linux-PAM/.
1152 <tag><tt>extern time_t pam_misc_conv_die_time;</tt></tag>
1154 This variable contains the <em/time/ (as returned by <tt/time()/) that
1155 the conversation will time out. By default it has the value <tt/0/,
1156 which indicates that the conversation function will not timeout. The
1157 application may set its value to sometime in the future, this should
1158 be done prior to passing control to the <bf/Linux-PAM/ library.
1160 <tag><tt>extern const char *pam_misc_conv_die_line;</tt></tag>
1162 Used in conjuction with <tt/pam_misc_conv_die_time/, this variable is
1163 a pointer to the string that will be displayed when the conversation
1164 times out. Its default value is ``..\a.Sorry, your time is
1165 up!\n'', but this can be changed by the application prior to
1166 passing control to <bf/Linux-PAM/.
1168 <tag><tt>extern int pam_misc_conv_died;</tt></tag>
1170 Following a return from the <bf/Linux-PAM/ libraray, the value of this
1171 variable indicates whether the conversation has timed out. A value of
1172 <tt/1/ indicates the time-out occurred.
1174 <tag><tt>extern int (*pam_binary_handler_fn)(const union pam_u_packet_p send,
1175 union pam_u_packet_p *receive);</tt></tag>
1177 This function pointer is initialized to <tt/NULL/ but can be filled
1178 with a function that provides machine-machine (hidden) message
1179 exchange. It is intended for use with hidden authentication protocols
1180 such as RSA or Diffie-Hellman key exchanges. (This is still under
1185 <sect2>Transcribing an environment to that of Linux-PAM
1189 extern int pam_misc_paste_env(pam_handle_t *pamh,
1190 const char * const * user_env);
1194 This function takes the supplied list of environment pointers and
1195 <em/uploads/ its contents to the <bf/Linux-PAM/ environment. Success
1196 is indicated by <tt/PAM_SUCCESS/.
1198 <sect2>Saving the Linux-PAM environment for later use
1202 extern char **pam_misc_copy_env(pam_handle_t *pamh);
1206 This function returns a pointer to a list of environment variables
1207 that are a direct copy of the <bf/Linux-PAM/ environment. The memory
1208 associated with these variables are the responsibility of the
1209 application and should be liberated with a call to
1210 <tt/pam_misc_drop_env()/.
1212 <sect2>Liberating a locally saved environment
1216 extern char **pam_misc_drop_env(char **env);
1220 This function is defined to complement the <tt/pam_misc_copy_env()/
1221 function. It liberates the memory associated with <tt/env/,
1222 <em/overwriting/ with <tt/0/ all memory before <tt/free()/ing it.
1224 <sect2>BSD like Linux-PAM environment variable setting
1228 extern int pam_misc_setenv(pam_handle_t *pamh, const char *name,
1229 const char *value, int readonly);
1233 This function performs a task equivalent to <tt/pam_putenv()/, its
1234 syntax is, however, more like the BSD style function; <tt/setenv()/.
1235 The <tt/name/ and <tt/value/ are concatenated with an ``<tt/=/'' to
1236 form a <tt/name_value/ and passed to <tt/pam_putenv()/. If, however,
1237 the <bf/Linux-PAM/ variable is already set, the replacement will only
1238 be applied if the last argument, <tt/readonly/, is zero.
1240 <sect>Porting legacy applications
1243 The following is extracted from an email. I'll tidy it up later.
1246 The point of PAM is that the application is not supposed to have any
1247 idea how the attatched authentication modules will choose to
1248 authenticate the user. So all they can do is provide a conversation
1249 function that will talk directly to the user(client) on the modules'
1253 Consider the case that you plug a retinal scanner into the login
1254 program. In this situation the user would be prompted: "please look
1255 into the scanner". No username or password would be needed - all this
1256 information could be deduced from the scan and a database lookup. The
1257 point is that the retinal scanner is an ideal task for a "module".
1260 While it is true that a pop-daemon program is designed with the POP
1261 protocol in mind and no-one ever considered attatching a retinal
1262 scanner to it, it is also the case that the "clean" PAM'ification of
1263 such a daemon would allow for the possibility of a scanner module
1264 being be attatched to it. The point being that the "standard"
1265 pop-authentication protocol(s) [which will be needed to satisfy
1266 inflexible/legacy clients] would be supported by inserting an
1267 appropriate pam_qpopper module(s). However, having rewritten popd
1268 once in this way any new protocols can be implemented in-situ.
1271 One simple test of a ported application would be to insert the
1272 <tt/pam_permit/ module and see if the application demands you type a
1273 password... In such a case, <tt/xlock/ would fail to lock the
1274 terminal - or would at best be a screen-saver, ftp would give password
1275 free access to all etc.. Neither of these is a very secure thing to
1276 do, but they do illustrate how much flexibility PAM puts in the hands
1280 The key issue, in doing things correctly, is identifying what is part
1281 of the authentication procedure (how many passwords etc..) the
1282 exchange protocol (prefixes to prompts etc., numbers like 331 in the
1283 case of ftpd) and what is part of the service that the application
1284 delivers. PAM really needs to have total control in the
1285 authentication "proceedure", the conversation function should only
1286 deal with reformatting user prompts and extracting responses from raw
1289 <sect>Glossary of PAM related terms
1292 The following are a list of terms used within this document.
1297 <tag>Authentication token</tag>
1298 Generally, this is a password. However, a user can authenticate
1299 him/herself in a variety of ways. Updating the user's authentication
1300 token thus corresponds to <em>refreshing</em> the object they use to
1301 authenticate themself with the system. The word password is avoided
1302 to keep open the possibility that the authentication involves a
1303 retinal scan or other non-textual mode of challenge/response.
1305 <tag>Credentials</tag>
1306 Having successfully authenticated the user, PAM is able to establish
1307 certain characteristics/attributes of the user. These are termed
1308 <em>credentials</em>. Examples of which are group memberships to
1309 perform privileged tasks with, and <em>tickets</em> in the form of
1310 environment variables etc. . Some user-credentials, such as the
1311 user's UID and GID (plus default group memberships) are not deemed to
1312 be PAM-credentials. It is the responsibility of the application to
1313 grant these directly.
1317 <sect>An example application
1320 To get a flavor of the way a <tt/Linux-PAM/ application is written we
1321 include the following example. It prompts the user for their password
1322 and indicates whether their account is valid on the standard output,
1323 its return code also indicates the success (<tt/0/ for success; <tt/1/
1330 This program was contributed by Shane Watts
1331 [modifications by AGM]
1333 You need to add the following (or equivalent) to the /etc/pam.conf file.
1334 # check authorization
1335 check_user auth required /usr/lib/security/pam_unix_auth.so
1336 check_user account required /usr/lib/security/pam_unix_acct.so
1339 #include <security/pam_appl.h>
1340 #include <security/pam_misc.h>
1343 static struct pam_conv conv = {
1348 int main(int argc, char *argv[])
1350 pam_handle_t *pamh=NULL;
1352 const char *user="nobody";
1359 fprintf(stderr, "Usage: check_user [username]\n");
1363 retval = pam_start("check_user", user, &ero;conv, &ero;pamh);
1365 if (retval == PAM_SUCCESS)
1366 retval = pam_authenticate(pamh, 0); /* is user really user? */
1368 if (retval == PAM_SUCCESS)
1369 retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
1371 /* This is where we have been authorized or not. */
1373 if (retval == PAM_SUCCESS) {
1374 fprintf(stdout, "Authenticated\n");
1376 fprintf(stdout, "Not Authenticated\n");
1379 if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
1381 fprintf(stderr, "check_user: failed to release authenticator\n");
1385 return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
1394 <tag><tt>/usr/include/security/pam_appl.h</tt></tag>
1396 header file for <bf/Linux-PAM/ applications interface
1398 <tag><tt>/usr/include/security/pam_misc.h</tt></tag>
1400 header file for useful library functions for making applications
1403 <tag><tt>/usr/lib/libpam.so.*</tt></tag>
1405 the shared library providing applications with access to
1408 <tag><tt>/etc/pam.conf</tt></tag>
1410 the <bf/Linux-PAM/ configuration file.
1412 <tag><tt>/usr/lib/security/pam_*.so</tt></tag>
1414 the primary location for <bf/Linux-PAM/ dynamically loadable object
1420 <label id="bibliography">
1424 <item>The <bf/Linux-PAM/
1425 <htmlurl url="pam.html" name="System Administrators' Guide">.
1427 <item>The <bf/Linux-PAM/
1428 <htmlurl url="pam_modules.html" name="Module Writers' Guide">.
1430 <item>The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
1431 PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation Request
1432 For Comments 86.0, October 1995.
1439 I intend to put development comments here... like ``at the moment
1440 this isn't actually supported''. At release time what ever is in
1441 this section will be placed in the Bugs section below! :)
1446 <item> <tt/pam_strerror()/ should be internationalized....
1449 Note, the <tt/resp_retcode/ of struct <tt/pam_message/, has no
1450 purpose at the moment. Ideas/suggestions welcome!
1452 <item> more security issues are required....
1456 <sect>Author/acknowledgments
1459 This document was written by Andrew G. Morgan
1460 (morgan@transmeta.com) with many contributions from
1461 <!-- insert credits here -->
1463 an sgml list of people to credit for their contributions to Linux-PAM
1464 $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
1469 Derrick J. Brashear,
1484 Marek Michalkiewicz,
1492 Savochkin Andrey Vladimirovich,
1502 Thanks are also due to Sun Microsystems, especially to Vipin Samar and
1503 Charlie Lai for their advice. At an early stage in the development of
1504 <bf/Linux-PAM/, Sun graciously made the documentation for their
1505 implementation of PAM available. This act greatly accelerated the
1506 development of <bf/Linux-PAM/.
1508 <sect>Bugs/omissions
1511 This manual is hopelessly unfinished. Only a partial list of people is
1512 credited for all the good work they have done.
1514 <sect>Copyright information for this document
1517 Copyright (c) Andrew G. Morgan 1996, 1997. All rights reserved.
1519 Email: <tt><morgan@transmeta.com></tt>
1522 Redistribution and use in source and binary forms, with or without
1523 modification, are permitted provided that the following conditions are
1530 1. Redistributions of source code must retain the above copyright
1531 notice, and the entire permission notice in its entirety,
1532 including the disclaimer of warranties.
1535 2. Redistributions in binary form must reproduce the above copyright
1536 notice, this list of conditions and the following disclaimer in the
1537 documentation and/or other materials provided with the distribution.
1540 3. The name of the author may not be used to endorse or promote
1541 products derived from this software without specific prior
1547 <bf/Alternatively/, this product may be distributed under the terms of
1548 the GNU General Public License (GPL), in which case the provisions of
1549 the GNU GPL are required <bf/instead of/ the above restrictions.
1550 (This clause is necessary due to a potential bad interaction between
1551 the GNU GPL and the restrictions contained in a BSD-style copyright.)
1554 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1555 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1556 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1557 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1558 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1559 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
1560 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1561 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1562 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1563 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1567 <tt>$Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $</tt>