1 <!doctype linuxdoc system>
5 $Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $
7 Copyright (C) Andrew G. Morgan 1996, 1997. All rights reserved.
9 Redistribution and use in source (sgml) and binary (derived) forms,
10 with or without modification, are permitted provided that the
11 following conditions are met:
13 1. Redistributions of source code must retain the above copyright
14 notice, and the entire permission notice in its entirety,
15 including the disclaimer of warranties.
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
21 3. The name of the author may not be used to endorse or promote
22 products derived from this software without specific prior
25 ALTERNATIVELY, this product may be distributed under the terms of the
26 GNU General Public License, in which case the provisions of the GNU
27 GPL are required INSTEAD OF the above restrictions. (This clause is
28 necessary due to a potential bad interaction between the GNU GPL and
29 the restrictions contained in a BSD-style copyright.)
31 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
32 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
37 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
47 <title>The Linux-PAM Application Developers' Guide
48 <author>Andrew G. Morgan, <tt>morgan@linux.kernel.org</tt>
49 <date>DRAFT v0.63 1998/1/18
51 This manual documents what an application developer needs to know
52 about the <bf>Linux-PAM</bf> library. It describes how an application
53 might use the <bf>Linux-PAM</bf> library to authenticate users. In
54 addition it contains a description of the funtions to be found in
55 <tt/libpam_misc/ library, that can be used in general applications.
56 Finally, it contains some comments on PAM related security issues for
57 the application developer.
67 For general applications that wish to use the services provided by
68 <bf/Linux-PAM/ the following is a summary of the relevant linking
72 #include <security/pam_appl.h>
74 cc -o application .... -lpam
79 In addition to <tt/libpam/, there is a library of miscellaneous
80 functions that make the job of writing <em/PAM-aware/ applications
81 easier (this library is not covered in the DCE-RFC for PAM and is
82 specific to the Linux-PAM distribution):
86 #include <security/pam_misc.h>
88 cc -o application .... -lpam -lpam_misc
95 <bf>Linux-PAM</bf> (Pluggable Authentication Modules for Linux) is a
96 library that enables the local system administrator to choose how
97 individual applications authenticate users. For an overview of the
98 <bf>Linux-PAM</bf> library see the <bf/Linux-PAM/ System
99 Administrators' Guide.
102 It is the purpose of the <bf>Linux-PAM</bf> project to liberate the
103 development of privilege granting software from the development of
104 secure and appropriate authentication schemes. This is accomplished
105 by providing a documented library of functions that an application may
106 use for all forms of user authentication management. This library
107 dynamically loads locally configured authentication modules that
108 actually perform the authentication tasks.
111 From the perspective of an application developer the information
112 contained in the local configuration of the PAM library should not be
113 important. Indeed it is intended that an application treat the
114 functions documented here as a ``black box'' that will deal with all
115 aspects of user authentication. ``All aspects'' includes user
116 verification, account management, session initialization/termination
117 and also the resetting of passwords (<em/authentication tokens/).
122 Most service-giving applications are restricted. In other words,
123 their service is not available to all and every prospective client.
124 Instead, the applying client must jump through a number of hoops to
125 convince the serving application that they are authorized to obtain
128 The process of <em/authenticating/ a client is what PAM is designed to
129 manage. In addition to authentication, PAM provides account
130 management, credential management, session management and
131 authentication-token (password changing) management services. It is
132 important to realize when writing a PAM based application that these
133 services are provided in a manner that is <bf>transparent</bf> to the
134 the application. That is to say, when the application is written, no
135 assumptions can be made about <em>how</em> the client will be
139 The process of authentication is performed by the PAM library via a
140 call to <tt>pam_authenticate()</tt>. The return value of this
141 function will indicate whether a named client (the <em>user</em>) has
142 been authenticated. If the PAM library needs to prompt the user for
143 any information, such as their <em>name</em> or a <em>password</em>
144 then it will do so. If the PAM library is configured to authenticate
145 the user using some silent protocol, it will do this too. (This
146 latter case might be via some hardware interface for example.)
149 It is important to note that the application must leave all decisions
150 about when to prompt the user at the discretion of the PAM library.
153 The PAM library, however, must work equally well for different styles
154 of application. Some applications, like the familiar <tt>login</tt>
155 and <tt>passwd</tt> are terminal based applications, exchanges of
156 information with the client in these cases is as plain text messages.
157 Graphically based applications, however, have a more sophisticated
158 interface. They generally interact with the user via specially
159 constructed dialogue boxes. Additionally, network based services
160 require that text messages exchanged with the client are specially
161 formatted for automated processing: one such example is <tt>ftpd</tt>
162 which prefixes each exchanged message with a numeric identifier.
165 The presentation of simple requests to a client is thus something very
166 dependent on the protocol that the serving application will use. In
167 spite of the fact that PAM demands that it drives the whole
168 authentication process, it is not possible to leave such protocol
169 subtleties up to the PAM library. To overcome this potential problem,
170 the application provides the PAM library with a <em>conversation</em>
171 function. This function is called from <bf>within</bf> the PAM
172 library and enables the PAM to directly interact with the client. The
173 sorts of things that this conversation function must be able to do are
174 prompt the user with text and/or obtain textual input from the user
175 for processing by the PAM library. The details of this function are
176 provided in a later section.
179 For example, the conversation function may be called by the PAM library
180 with a request to prompt the user for a password. Its job is to
181 reformat the prompt request into a form that the client will
182 understand. In the case of <tt>ftpd</tt>, this will involve prefixing
183 the string with the number <tt>331</tt> and sending the request over
184 the network to a connected client. The conversation function will
185 then obtain any reply and, after extracting the typed password, will
186 return this string of text to the PAM library. Similar concerns need
187 to be addressed in the case of an X-based graphical server.
190 There are a number of issues that need to be addressed when one is
191 porting an existing application to become PAM compliant. A section
192 below has been devoted to this: Porting legacy applications.
195 Besides authentication, PAM provides other forms of management.
196 Session management is provided with calls to
197 <tt>pam_open_session()</tt> and <tt>pam_close_session()</tt>. What
198 these functions actually do is up to the local administrator. But
199 typically, they could be used to log entry and exit from the system or
200 for mounting and unmounting the user's home directory. If an
201 application provides continuous service for a period of time, it
202 should probably call these functions, first open after the user is
203 authenticated and then close when the service is terminated.
206 Account management is another area that an application developer
207 should include with a call to <tt/pam_acct_mgmt()/. This call will
208 perform checks on the good health of the user's account (has it
209 expired etc.). One of the things this function may check is whether
210 the user's authentication token has expired - in such a case the
211 application may choose to attempt to update it with a call to
212 <tt/pam_chauthtok()/, although some applications are not suited to
213 this task (<em>ftp</em> for example) and in this case the application
214 should deny access to the user.
217 PAM is also capable of setting and deleting the users credentials with
218 the call <tt>pam_setcred()</tt>. This function should always be
219 called after the user is authenticated and before service is offered
220 to the user. By convention, this should be the last call to the PAM
221 library before service is given to the user. What exactly a
222 credential is, is not well defined. However, some examples are given
223 in the glossary below.
225 <sect>The public interface to <bf>Linux-PAM</bf>
228 Firstly, the relevant include file for the <bf>Linux-PAM</bf> library
229 is <tt><security/pam_appl.h></tt>. It contains the definitions
230 for a number of functions. After listing these functions, we collect
231 some guiding remarks for programmers.
233 <sect1>What can be expected by the application
236 Here we document those functions in the <bf/Linux-PAM/ library that
237 may be called from an application.
239 <sect2>Initialization of Linux-PAM
240 <label id="pam-start-section">
245 extern int pam_start(const char *service_name, const char *user,
246 const struct pam_conv *pam_conversation,
247 pam_handle_t **pamh);
252 This is the first of the <bf>Linux-PAM</bf> functions that must be
253 called by an application. It initializes the interface and reads the
254 system configuration file, <tt>/etc/pam.conf</tt> (see the
255 <bf/Linux-PAM/ System Administrators' Guide). Following a successful
256 return (<tt/PAM_SUCCESS/) the contents of <tt/*pamh/ is a handle that
257 provides continuity for successive calls to the <bf/Linux-PAM/
258 library. The arguments expected by <tt/pam_start/ are as follows: the
259 <tt/service_name/ of the program, the <tt/user/name of the individual
260 to be authenticated, a pointer to an application-supplied
261 <tt/pam_conv/ structure and a pointer to a <tt/pam_handle_t/
265 The <tt>pam_conv</tt> structure is discussed more fully in the section
266 <ref id="the-conversation-function" name="below">. The
267 <tt>pam_handle_t</tt> is a <em>blind</em> structure and the
268 application should not attempt to probe it directly for information.
269 Instead the <bf>Linux-PAM</bf> library provides the functions
270 <tt>pam_set_item</tt> and <tt>pam_get_item</tt>. These functions are
273 <sect2>Termination of the library
274 <label id="pam-end-section">
279 extern int pam_end(pam_handle_t *pamh, int pam_status);
284 This function is the last function an application should call in the
285 <bf>Linux-PAM</bf> library. Upon return the handle <tt/pamh/ is no
286 longer valid and all memory associated with it will be invalid (likely
287 to cause a segmentation fault if accessed).
290 Under normal conditions the argument <tt/pam_status/ has the value
291 PAM_SUCCESS, but in the event of an unsuccessful service application
292 the approprite <bf/Linux-PAM/ error-return value should be used
294 attempt its purpose is to be passed as an argument to the
295 module specific function <tt/cleanup()/ (see the <bf/Linux-PAM/
296 <htmlurl url="pam_modules.html" name="Module Developers' Guide">).
298 <sect2>Setting PAM items
299 <label id="pam-set-item-section">
304 extern int pam_set_item(pam_handle_t *pamh, int item_type,
309 <p>This function is used to (re)set the value of one of the following
313 <tag><tt/PAM_SERVICE/</tag>
316 <tag><tt/PAM_USER/</tag>
319 <tag><tt/PAM_TTY/</tag>
320 The terminal name: prefixed by <tt>/dev/</tt> if it is a
321 device file; for graphical, X-based, applications the value for this
322 item should be the <tt/$DISPLAY/ variable.
324 <tag><tt/PAM_RHOST/</tag>
327 <tag><tt/PAM_CONV/</tag>
328 The conversation structure (see section <ref
329 id="the-conversation-function" name="below">)
331 <tag><tt/PAM_RUSER/</tag>
334 <tag><tt/PAM_USER_PROMPT/</tag>
335 The string used when prompting for a user's name. The default
336 value for this string is ``Please enter username: ''.
341 For all <tt/item_type/s, other than <tt/PAM_CONV/, <tt/item/ is a
342 pointer to a <tt><NUL></tt> terminated character string. In the
343 case of <tt/PAM_CONV/, <tt/item/ points to an initialized
344 <tt/pam_conv/ structure (see section <ref
345 id="the-conversation-function" name="below">).
348 A successful call to this function returns <tt/PAM_SUCCESS/. However,
349 the application should expect one of the following errors:
353 <tag><tt/PAM_PERM_DENIED/</tag>
354 An attempt was made to replace the conversation structure with
356 <tag><tt/PAM_BUF_ERR/</tag>
357 The function ran out of memory making a copy of the item.
358 <tag><tt/PAM_BAD_ITEM/</tag>
359 The application attempted to set an undefined item.
362 <sect2>Getting PAM items
363 <label id="pam-get-item-section">
368 extern int pam_get_item(const pam_handle_t *pamh, int item_type,
374 This function is used to obtain the value of the indicated
375 <tt/item_type/. Upon successful return, <tt/*item/ contains a pointer
376 to the value of the corresponding item. Note, this is a pointer to
377 the <em/actual/ data and should <em/not/ be <tt/free()/'ed or
378 over-written! A successful call is signaled by a return value of
379 <tt/PAM_SUCCESS/. If an attempt is made to get an undefined item,
380 <tt/PAM_BAD_ITEM/ is returned.
382 <sect2>Understanding errors
383 <label id="pam-strerror-section">
388 extern const char *pam_strerror(pam_handle_t *pamh, int errnum);
393 This function returns some text describing the <bf>Linux-PAM</bf>
394 error associated with the argument <tt/errnum/. If the error is not
395 recognized ``<tt/Unknown Linux-PAM error/'' is returned.
397 <sect2>Planning for delays
402 extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec);
407 This function is offered by <bf/Linux-PAM/ to facilitate time delays
408 following a failed call to <tt/pam_authenticate()/ and before control
409 is returned to the application. When using this function the
410 application programmer should check if it is available with,
413 #ifdef HAVE_PAM_FAIL_DELAY
415 #endif /* HAVE_PAM_FAIL_DELAY */
421 Generally, an application requests that a user is authenticated by
422 <bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or
423 <tt/pam_chauthtok()/. These functions calls each of the <em/stacked/
424 authentication modules listed in the <tt>/etc/pam.conf</tt> file. As
425 directed by this file, one of more of the modules may fail causing the
426 <tt/pam_...()/ call to return an error. It is desirable for there to
427 also be a pause before the application continues. The principal reason
428 for such a delay is security: a delay acts to discourage <em/brute
429 force/ dictionary attacks primarily, but also helps hinder
430 <em/timed/ (covert channel) attacks.
433 The <tt/pam_fail_delay()/ function provides the mechanism by which an
434 application or module can suggest a minimum delay (of <tt/micro_sec/
435 <em/micro-seconds/). <bf/Linux-PAM/ keeps a record of the longest time
436 requested with this function. Should <tt/pam_authenticate()/ fail,
437 the failing return to the application is delayed by an amount of time
438 randomly distributed (by up to 25%) about this longest value.
441 Independent of success, the delay time is reset to its zero default
442 value when <bf/Linux-PAM/ returns control to the application.
444 <sect2>Authenticating the user
449 extern int pam_authenticate(pam_handle_t *pamh, int flags);
454 This function serves as an interface to the authentication mechanisms
455 of the loaded modules. The single <em/optional/ flag, which may be
456 logically OR'd with <tt/PAM_SILENT/, takes the following value,
460 <tag><tt/PAM_DISALLOW_NULL_AUTHTOK/</tag>
461 Instruct the authentication modules to return
462 <tt/PAM_AUTH_ERR/ if the user does not have a registered
463 authorization token---it is set to <tt/NULL/ in the system database.
467 The value returned by this function is one of the following:
471 <tag><tt/PAM_AUTH_ERR/</tag>
472 The user was not authenticated
473 <tag><tt/PAM_CRED_INSUFFICIENT/</tag>
474 For some reason the application does not have sufficient
475 credentials to authenticate the user.
476 <tag><tt/PAM_AUTHINFO_UNAVAIL/</tag>
477 The modules were not able to access the authentication
478 information. This might be due to a network or hardware failure etc.
479 <tag><tt/PAM_USER_UNKNOWN/</tag>
480 The supplied username is not known to the authentication
482 <tag><tt/PAM_MAXTRIES/</tag>
483 One or more of the authentication modules has reached its
484 limit of tries authenticating the user. Do not try again.
489 If one or more of the authentication modules fails to load, for
490 whatever reason, this function will return <tt/PAM_ABORT/.
492 <sect2>Setting user credentials
493 <label id="pam-setcred-section">
498 extern int pam_setcred(pam_handle_t *pamh, int flags);
503 This function is used to set the module-specific credentials of the
504 user. It is usually called after the user has been authenticated,
505 after the account management function has been called and after a
506 session has been opened for the user.
509 A credential is something that the user possesses. It is some
510 property, such as a <em>Kerberos</em> ticket, or a supplementary group
511 membership that make up the uniqueness of a given user. On a Linux
512 (or UN*X system) the user's <tt>UID</tt> and <tt>GID</tt>'s are
513 credentials too. However, it has been decided that these properties
514 (along with the default supplementary groups of which the user is a
515 member) are credentials that should be set directly by the application
519 This function simply calls the <tt/pam_sm_setcred/ functions of each
520 of the loaded modules. Valid <tt/flags/, any one of which, may be
521 logically OR'd with <tt/PAM_SILENT/, are:
524 <tag><tt/PAM_ESTABLISH_CRED/</tag>
525 Set the credentials for the authentication service,
526 <tag><tt/PAM_DELETE_CRED/</tag>
527 Delete the credentials associated with the authentication service,
528 <tag><tt/PAM_REINITIALIZE_CRED/</tag>
529 Reinitialize the user credentials, and
530 <tag><tt/PAM_REFRESH_CRED/</tag>
531 Extend the lifetime of the user credentials.
535 A successful return is signalled with <tt/PAM_SUCCESS/. Errors that
536 are especially relevant to this function are the following:
539 <tag><tt/PAM_CRED_UNAVAIL/</tag>
540 A module cannot retrieve the user's credentials.
541 <tag><tt/PAM_CRED_EXPIRED/</tag>
542 The user's credentials have expired.
543 <tag><tt/PAM_USER_UNKNOWN/</tag>
544 The user is not known to an authentication module.
545 <tag><tt/PAM_CRED_ERR/</tag>
546 A module was unable to set the credentials of the user.
549 <sect2>Account management
554 extern int pam_acct_mgmt(pam_handle_t *pamh, int flags);
559 This function is typically called after the user has been
560 authenticated. It establishes whether the user's account is healthy.
561 That is to say, whether the user's account is still active and whether
562 the user is permitted to gain access to the system at this time.
563 Valid flags, any one of which, may be logically OR'd with
564 <tt/PAM_SILENT/, and are the same as those applicable to the
565 <tt/flags/ argument of <tt/pam_authenticate/.
568 This function simply calls the corresponding functions of each of the
569 loaded modules, as instructed by the configuration file,
570 <tt>/etc/pam.conf</tt>.
573 The normal response from this function is <tt/PAM_SUCCESS/, however,
574 specific failures are indicated by the following error returns:
577 <tag><tt/PAM_AUTHTOKEN_REQD/</tag>
578 The user <bf/is/ valid but their authentication token has
579 <em/expired/. The correct response to this return-value is to require
580 that the user satisfies the <tt/pam_chauthtok()/ function before
581 obtaining service. It may not be possible for some applications to do
582 this. In such cases, the user should be denied access until such time
583 as they can update their password.
585 <tag><tt/PAM_ACCT_EXPIRED/</tag>
586 The user is no longer permitted access to the system.
587 <tag><tt/PAM_AUTH_ERR/</tag>
588 There was an authentication error.
590 <tag><tt/PAM_PERM_DENIED/</tag>
591 The user is not permitted to gain access at this time.
592 <tag><tt/PAM_USER_UNKNOWN/</tag>
593 The user is not known to a module's account management
598 <sect2>Updating authentication tokens
599 <label id="pam-chauthtok-section">
604 extern int pam_chauthtok(pam_handle_t *pamh, const int flags);
609 This function is used to change the authentication token for a given
610 user (as indicated by the state associated with the handle,
611 <tt/pamh/). The following is a valid but optional flag which may be
612 logically OR'd with <tt/PAM_SILENT/,
615 <tag><tt/PAM_CHANGE_EXPIRED_AUTHTOK/</tag>
616 This argument indicates to the modules that the users
617 authentication token (password) should only be changed if it has
622 Note, if this argument is not passed, the application requires that
623 <em/all/ authentication tokens are to be changed.
626 <tt/PAM_SUCCESS/ is the only successful return value, valid
630 <tag><tt/PAM_AUTHTOK_ERR/</tag>
631 A module was unable to obtain the new authentication token.
633 <tag><tt/PAM_AUTHTOK_RECOVERY_ERR/</tag>
634 A module was unable to obtain the old authentication token.
636 <tag><tt/PAM_AUTHTOK_LOCK_BUSY/</tag>
637 One or more of the modules was unable to change the
638 authentication token since it is currently locked.
640 <tag><tt/PAM_AUTHTOK_DISABLE_AGING/</tag>
641 Authentication token aging has been disabled for at least one
644 <tag><tt/PAM_PERM_DENIED/</tag>
647 <tag><tt/PAM_TRY_AGAIN/</tag>
648 Not all of the modules were in a position to update the
649 authentication token(s). In such a case none of the user's
650 authentication tokens are updated.
652 <tag><tt/PAM_USER_UNKNOWN/</tag>
653 The user is not known to the authentication token changing
658 <sect2>Session initialization
659 <label id="pam-open-session-section">
664 extern int pam_open_session(pam_handle_t *pamh, int flags);
669 This function is used to indicate that an authenticated session has
670 begun. It is used to inform the module that the user is currently in
671 a session. It should be possible for the <bf>Linux-PAM</bf> library
672 to open a session and close the same session (see section <ref
673 id="pam-close-session-section" name="below">) from different
677 Currently, this function simply calls each of the corresponding
678 functions of the loaded modules. The only valid flag is
679 <tt/PAM_SILENT/ and this is, of course, <em/optional/.
682 If any of the <em/required/ loaded modules are unable to open a
683 session for the user, this function will return <tt/PAM_SESSION_ERR/.
685 <sect2>Terminating sessions
686 <label id="pam-close-session-section">
691 extern int pam_close_session(pam_handle_t *pamh, int flags);
696 This function is used to indicate that an authenticated session has
697 ended. It is used to inform the module that the user is exiting a
698 session. It should be possible for the <bf>Linux-PAM</bf> library to
699 open a session and close the same session from different applications.
702 Currently, this function simply calls each of the corresponding
703 functions of the loaded modules. The only valid flag is
704 <tt/PAM_SILENT/ and this is, of course, <em/optional/.
707 If any of the <em/required/ loaded modules are unable to close a
708 session for the user, this function will return <tt/PAM_SESSION_ERR/.
710 <sect2>Setting PAM environment variables
711 <label id="pam-putenv-section">
716 extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
722 Warning, the environment support in <bf/Linux-PAM/ is based solely
723 on a six line email from the developers at Sun. Its interface is
724 likely to be generally correct, however, the details are likely to be
725 changed as more information becomes available.
729 This function attempts to (re)set a <bf/Linux-PAM/ environment
730 variable. The <tt/name_value/ argument is a single <tt/NUL/ terminated
731 string of one of the following forms:
733 <tag>``<tt/NAME=value of variable/''</tag>
735 In this case the environment variable of the given <tt/NAME/ is set to
736 the indicated value: ``<tt/value of variable/''. If this variable is
737 already known, it is overwritten. Otherwise it is added to the
738 <bf/Linux-PAM/ environment.
740 <tag>``<tt/NAME=/''</tag>
742 This function sets the variable to an empty value. It is listed
743 separately to indicate that this is the correct way to achieve such a
746 <tag>``<tt/NAME/''</tag>
748 Without an `<tt/=/' the <tt/pam_putenv()/ function will delete the
749 correspoding variable from the <bf/Linux-PAM/ environment.
754 Success is indicated with a return value of <tt/PAM_SUCCESS/. Failure
755 is indicated by one of the following returns:
758 <tag><tt/PAM_PERM_DENIED/</tag>
759 name given is a <tt/NULL/ pointer
761 <tag><tt/PAM_BAD_ITEM/</tag>
762 variable requested (for deletion) is not currently set
764 <tag><tt/PAM_ABORT/</tag>
765 the <bf/Linux-PAM/ handle, <tt/pamh/, is corrupt
767 <tag><tt/PAM_BUF_ERR/</tag>
768 failed to allocate memory when attempting update
772 <sect2>Getting a PAM environment variable
773 <label id="pam-getenv-section">
778 extern const char *pam_getenv(pam_handle_t *pamh, const char *name);
784 Warning, the environment support in <bf/Linux-PAM/ is based solely
785 on a six-line email from the developers at Sun. Its interface is
786 likely to be generally correct, however, the details are likely to be
787 changed as more information becomes available.
791 Obtain the value of the indicated <bf/Linux-PAM/ environment
792 variable. On error, internal failure or the unavailability of the
793 given variable (unspecified), this function simply returns <tt/NULL/.
795 <sect2>Getting the PAM environment
796 <label id="pam-getenvlist-section">
801 extern const char * const *pam_getenvlist(pam_handle_t *pamh);
807 Warning, the environment support in <bf/Linux-PAM/ is based solely
808 on a six line email from the developers at Sun. Its interface is
809 likely to be generally correct, however, the details are likely to be
810 changed as more information becomes available.
814 This function returns a pointer to the complete <tt/Linux-PAM/
815 environment. It is a pointer to a <em/read-only/ list of
816 <em/read-only/ environment variables. It should be noted that this
817 memory will become invalid after a call to <tt/pam_end()/ (see the
818 section <ref id="pam-end-section" name="above">). If application
819 wishes to make use of this list after such a call, it should first
820 make a copy of all the set variables. (A function that performs such a
821 transcription is to be found in <tt/libpam_misc/.)
823 <sect1>What is expected of an application
825 <sect2>The conversation function
826 <label id="the-conversation-function">
829 An application must provide a ``conversation function''. It is used
830 for direct communication between a loaded module and the application
831 and will typically provide a means for the module to prompt the user
832 for a password etc. . The structure, <tt/pam_conv/, is defined by
833 including <tt><security/pam_appl.h></tt>; to be,
839 int (*conv)(int num_msg,
840 const struct pam_message **msg,
841 struct pam_response **resp,
849 It is initialized by the application before it is passed to the
850 library. The <em/contents/ of this structure are attached to the
851 <tt/*pamh/ handle. The point of this argument is to provide a
852 mechanism for any loaded module to interact directly with the
853 application program. This is why it is called a <em/conversation/
857 When a module calls the referenced <tt/conv()/ function, the argument
858 <tt/*appdata_ptr/ is set to the second element of this structure.
861 The other arguments of a call to <tt/conv()/ concern the information
862 exchanged by module and application. That is to say, <tt/num_msg/
863 holds the length of the array of pointers, <tt/msg/. After a
864 successful return, the pointer <tt/*resp/ points to an array of
865 <tt/pam_response/ structures, holding the application supplied text.
866 Note, <tt/*resp/ is an <tt/struct pam_response/ array and <em/not/ an
870 The message (from the module to the application) passing structure is
871 defined by <tt><security/pam_appl.h></tt> as:
884 Valid choices for <tt/msg_style/ are:
887 <tag><tt/PAM_PROMPT_ECHO_OFF/</tag>
888 Obtain a string without echoing any text
889 <tag><tt/PAM_PROMPT_ECHO_ON/</tag>
890 Obtain a string whilst echoing text
891 <tag><tt/PAM_ERROR_MSG/</tag>
893 <tag><tt/PAM_TEXT_INFO/</tag>
898 The point of having an array of messages is that it becomes possible
899 to pass a number of things to the application in a single call from
900 the module. It can also be convenient for the application that related
901 things come at once: a windows based application can then present a
902 single form with many messages/prompts on at once.
905 The response (from the application to the module) passing structure is
906 defined by including <tt><security/pam_appl.h></tt> as:
909 struct pam_response {
916 Currently, there are no definitions for <tt/resp_retcode/ values; the
917 normal value is <tt/0/.
920 Prior to the 0.59 release of Linux-PAM, the length of the returned
921 <tt/pam_response/ array was equal to the number of <em/prompts/ (types
922 <tt/PAM_PROMPT_ECHO_OFF/ and <tt/PAM_PROMPT_ECHO_ON/) in the
923 <tt/pam_message/ array with which the conversation function was
924 called. This meant that it was not always necessary for the module to
925 <tt/free(3)/ the responses if the conversation function was only used
926 to display some text.
929 Post Linux-PAM-0.59 (and in the interests of compatibility with
930 Sunsoft). The number of resposes is always equal to the <tt/num_msg/
931 conversation function argument. This is slightly easier to program
932 but does require that the response array is <tt/free(3)/'d after every
933 call to the conversation function. The index of the responses
934 corresponds directly to the prompt index in the <tt/pam_message/
938 The maximum length of the <tt/pam_msg.msg/ and <tt/pam_response.resp/
939 character strings is <tt/PAM_MAX_MSG_SIZE/. (This is not enforced by
943 <tt/PAM_SUCCESS/ is the expected return value of this
944 function. However, should an error occur the application should not
945 set <tt/*resp/ but simply return <tt/PAM_CONV_ERR/.
948 Note, if an application wishes to use two conversation functions, it
949 should activate the second with a call to <tt/pam_set_item()/.
952 <bf>Notes:</bf> New item types are being added to the conversation
953 protocol. Currently Linux-PAM supports: <tt>PAM_BINARY_PROMPT</tt>
954 and <tt>PAM_BINARY_MSG</tt>. These two are intended for server-client
955 hidden information exchange and may be used as an interface for
956 maching-machine authentication.
958 <sect1>Programming notes
961 Note, all of the authentication service function calls accept the
962 token <tt/PAM_SILENT/, which instructs the modules to not send
963 messages to the application. This token can be logically OR'd with any
964 one of the permitted tokens specific to the individual function calls.
965 <tt/PAM_SILENT/ does not override the prompting of the user for
966 passwords etc., it only stops informative messages from being
969 <sect>Security issues of <bf>Linux-PAM</bf>
972 A poorly (or maliciously) written application can defeat any
973 <bf/Linux-PAM/ module's authentication mechanisms by simply ignoring
974 it's return values. It is the applications task and responsibility to
975 grant privileges and access to services. The <bf/Linux-PAM/ library
976 simply assumes the responsibility of <em/authenticating/ the user;
977 ascertaining that the user <em/is/ who they say they are. Care should
978 be taken to anticipate all of the documented behavior of the
979 <bf/Linux-PAM/ library functions. A failure to do this will most
980 certainly lead to a future security breach.
982 <sect1>Care about standard library calls
985 In general, writers of authorization-granting applications should
986 assume that each module is likely to call any or <em/all/ `libc'
987 functions. For `libc' functions that return pointers to
988 static/dynamically allocated structures (ie. the library allocates the
989 memory and the user is not expected to `<tt/free()/' it) any module
990 call to this function is likely to corrupt a pointer previously
991 obtained by the application. The application programmer should either
992 re-call such a `libc' function after a call to the <bf/Linux-PAM/
993 library, or copy the structure contents to some safe area of memory
994 before passing control to the <bf/Linux-PAM/ library.
997 Two function classes that fall into this category are
998 <tt>getpwnam(3)</tt> and <tt>syslog(3)</tt>.
1000 <sect1>Choice of a service name
1003 When picking the <em/service-name/ that corresponds to the first entry
1004 in the <tt>/etc/pam.conf</tt> file, the application programmer should
1005 <bf/avoid/ the temptation of choosing something related to
1006 <tt/argv[0]/. It is a trivial matter for any user to invoke any
1007 application on a system under a different name -- this should not be
1008 permitted to cause a security breach.
1011 To invoke some <tt/target/ application by another name, the user may
1012 symbolically link the target application with the desired name. To be
1013 precise all the user need do is,
1016 ln -s /target/application ./preferred_name
1019 and then <em/run/ <tt>./preferred_name</tt>
1022 By studying the <bf/Linux-PAM/ configuration file,
1023 <tt>/etc/pam.conf</tt>, an attacker can choose the <tt/preferred_name/
1024 to be that of a service enjoying minimal protection; for example a
1025 game which uses <bf/Linux-PAM/ to restrict access to certain hours of
1026 the day. If the service-name were to be linked to the filename under
1027 which the service was invoked, it is clear that the user is
1028 effectively in the position of dictating which authentication scheme
1029 the service uses. Needless to say, this is not a secure situation.
1032 The conclusion is that the application developer should carefully
1033 define the service-name of an application. The safest thing is to make
1034 it a single hard-wired name.
1036 <sect1>The conversation function
1039 Care should be taken to ensure that the <tt/conv()/ function is
1040 robust. Such a function is provided in the library <tt/libpam_misc/
1041 (see <ref id="libpam-misc-section" name="below">).
1043 <sect1>The identity of the user
1046 The <bf/Linux-PAM/ modules will need to determine the identity of the
1047 user who requests a service, and the identity of the user who grants
1048 the service. These two users will seldom be the same. Indeed there
1049 is generally a third user identity to be considered, the new (assumed)
1050 identity of the user once the service is granted.
1053 The need for keeping tabs on these identities is clearly an issue of
1054 security. Basically, the identity of the user requesting a service
1055 should be the current <tt/uid/ (userid) of the running process; the
1056 identity of the privilege granting user is the <tt/euid/ (effective
1057 userid) of the running process; the identity of the user, under whose
1058 name the service will be executed, is given by the contents of the
1059 <tt/PAM_USER/ <tt/pam_get_item(2)/.
1062 In addition the identity of a remote user, requesting the service from
1063 a distant location, will be placed in the <tt/PAM_RUSER/ item.
1065 <sect1>Sufficient resources
1068 Care should be taken to ensure that the proper execution of an
1069 application is not compromised by a lack of system resources. If an
1070 application is unable to open sufficient files to perform its service,
1071 it should fail gracefully, or request additional resources.
1072 Specifically, the quantities manipulated by the <tt/setrlimit(2)/
1073 family of commands should be taken into consideration.
1075 <sect>A library of miscellaneous helper functions
1076 <label id="libpam-misc-section">
1079 To aid the work of the application developer a library of
1080 miscellaneous functions is provided. It is called <tt/libpam_misc/,
1081 and contains functions for allocating memory (securely), a text based
1082 conversation function, and routines for enhancing the standard
1083 PAM-environment variable support.
1088 The functions, structures and macros, made available by this library
1089 can be defined by including <tt><security/pam_misc.h></tt>. It
1090 should be noted that this library is specific to <bf/Linux-PAM/ and is
1091 not referred to in the defining DCE-RFC (see <ref id="bibliography"
1092 name="the bibliography">) below.
1094 <sect1>Functions supplied
1096 <sect2>Safe string duplication
1101 extern char *xstrdup(const char *s)
1104 Return a duplicate copy of the <tt/NUL/ terminated string,
1105 <tt/s/. <tt/NULL/ is returned if there is insufficient memory
1106 available for the duplicate or if <tt/s=NULL/.
1108 <sect2>A text based conversation function
1113 extern int misc_conv(int num_msg, const struct pam_message **msgm,
1114 struct pam_response **response, void *appdata_ptr);
1119 This is a function that will prompt the user with the appropriate
1120 comments and obtain the appropriate inputs as directed by
1121 authentication modules.
1124 In addition to simply slotting into the appropriate <tt/struct
1125 pam_conv/, this function provides some time-out facilities. The
1126 function exports five variables that can be used by an application
1127 programmer to limit the amount of time this conversation function will
1128 spend waiting for the user to type something.
1131 The five variables are as follows:
1133 <tag><tt>extern time_t pam_misc_conv_warn_time;</tt></tag>
1135 This variable contains the <em/time/ (as returned by <tt/time()/) that
1136 the user should be first warned that the clock is ticking. By default
1137 it has the value <tt/0/, which indicates that no such warning will be
1138 given. The application may set its value to sometime in the future,
1139 but this should be done prior to passing control to the <bf/Linux-PAM/
1142 <tag><tt>extern const char *pam_misc_conv_warn_line;</tt></tag>
1144 Used in conjuction with <tt/pam_misc_conv_warn_time/, this variable is
1145 a pointer to the string that will be displayed when it becomes time to
1146 warn the user that the timeout is approaching. Its default value is
1147 ``..\a.Time is running out...\n'', but this can be changed
1148 by the application prior to passing control to <bf/Linux-PAM/.
1150 <tag><tt>extern time_t pam_misc_conv_die_time;</tt></tag>
1152 This variable contains the <em/time/ (as returned by <tt/time()/) that
1153 the conversation will time out. By default it has the value <tt/0/,
1154 which indicates that the conversation function will not timeout. The
1155 application may set its value to sometime in the future, this should
1156 be done prior to passing control to the <bf/Linux-PAM/ library.
1158 <tag><tt>extern const char *pam_misc_conv_die_line;</tt></tag>
1160 Used in conjuction with <tt/pam_misc_conv_die_time/, this variable is
1161 a pointer to the string that will be displayed when the conversation
1162 times out. Its default value is ``..\a.Sorry, your time is
1163 up!\n'', but this can be changed by the application prior to
1164 passing control to <bf/Linux-PAM/.
1166 <tag><tt>extern int pam_misc_conv_died;</tt></tag>
1168 Following a return from the <bf/Linux-PAM/ libraray, the value of this
1169 variable indicates whether the conversation has timed out. A value of
1170 <tt/1/ indicates the time-out occurred.
1172 <tag><tt>extern int (*pam_binary_handler_fn)(const union pam_u_packet_p send,
1173 union pam_u_packet_p *receive);</tt></tag>
1175 This function pointer is initialized to <tt/NULL/ but can be filled
1176 with a function that provides machine-machine (hidden) message
1177 exchange. It is intended for use with hidden authentication protocols
1178 such as RSA or Diffie-Hellman key exchanges. (This is still under
1183 <sect2>Transcribing an environment to that of Linux-PAM
1187 extern int pam_misc_paste_env(pam_handle_t *pamh,
1188 const char * const * user_env);
1192 This function takes the supplied list of environment pointers and
1193 <em/uploads/ its contents to the <bf/Linux-PAM/ environment. Success
1194 is indicated by <tt/PAM_SUCCESS/.
1196 <sect2>Saving the Linux-PAM environment for later use
1200 extern char **pam_misc_copy_env(pam_handle_t *pamh);
1204 This function returns a pointer to a list of environment variables
1205 that are a direct copy of the <bf/Linux-PAM/ environment. The memory
1206 associated with these variables are the responsibility of the
1207 application and should be liberated with a call to
1208 <tt/pam_misc_drop_env()/.
1210 <sect2>Liberating a locally saved environment
1214 extern char **pam_misc_drop_env(char **env);
1218 This function is defined to complement the <tt/pam_misc_copy_env()/
1219 function. It liberates the memory associated with <tt/env/,
1220 <em/overwriting/ with <tt/0/ all memory before <tt/free()/ing it.
1222 <sect2>BSD like Linux-PAM environment variable setting
1226 extern int pam_misc_setenv(pam_handle_t *pamh, const char *name,
1227 const char *value, int readonly);
1231 This function performs a task equivalent to <tt/pam_putenv()/, its
1232 syntax is, however, more like the BSD style function; <tt/setenv()/.
1233 The <tt/name/ and <tt/value/ are concatenated with an ``<tt/=/'' to
1234 form a <tt/name_value/ and passed to <tt/pam_putenv()/. If, however,
1235 the <bf/Linux-PAM/ variable is already set, the replacement will only
1236 be applied if the last argument, <tt/readonly/, is zero.
1238 <sect>Porting legacy applications
1241 The following is extracted from an email. I'll tidy it up later.
1244 The point of PAM is that the application is not supposed to have any
1245 idea how the attatched authentication modules will choose to
1246 authenticate the user. So all they can do is provide a conversation
1247 function that will talk directly to the user(client) on the modules'
1251 Consider the case that you plug a retinal scanner into the login
1252 program. In this situation the user would be prompted: "please look
1253 into the scanner". No username or password would be needed - all this
1254 information could be deduced from the scan and a database lookup. The
1255 point is that the retinal scanner is an ideal task for a "module".
1258 While it is true that a pop-daemon program is designed with the POP
1259 protocol in mind and no-one ever considered attatching a retinal
1260 scanner to it, it is also the case that the "clean" PAM'ification of
1261 such a daemon would allow for the possibility of a scanner module
1262 being be attatched to it. The point being that the "standard"
1263 pop-authentication protocol(s) [which will be needed to satisfy
1264 inflexible/legacy clients] would be supported by inserting an
1265 appropriate pam_qpopper module(s). However, having rewritten popd
1266 once in this way any new protocols can be implemented in-situ.
1269 One simple test of a ported application would be to insert the
1270 <tt/pam_permit/ module and see if the application demands you type a
1271 password... In such a case, <tt/xlock/ would fail to lock the
1272 terminal - or would at best be a screen-saver, ftp would give password
1273 free access to all etc.. Neither of these is a very secure thing to
1274 do, but they do illustrate how much flexibility PAM puts in the hands
1278 The key issue, in doing things correctly, is identifying what is part
1279 of the authentication procedure (how many passwords etc..) the
1280 exchange protocol (prefixes to prompts etc., numbers like 331 in the
1281 case of ftpd) and what is part of the service that the application
1282 delivers. PAM really needs to have total control in the
1283 authentication "proceedure", the conversation function should only
1284 deal with reformatting user prompts and extracting responses from raw
1287 <sect>Glossary of PAM related terms
1290 The following are a list of terms used within this document.
1295 <tag>Authentication token</tag>
1296 Generally, this is a password. However, a user can authenticate
1297 him/herself in a variety of ways. Updating the user's authentication
1298 token thus corresponds to <em>refreshing</em> the object they use to
1299 authenticate themself with the system. The word password is avoided
1300 to keep open the possibility that the authentication involves a
1301 retinal scan or other non-textual mode of challenge/response.
1303 <tag>Credentials</tag>
1304 Having successfully authenticated the user, PAM is able to establish
1305 certain characteristics/attributes of the user. These are termed
1306 <em>credentials</em>. Examples of which are group memberships to
1307 perform privileged tasks with, and <em>tickets</em> in the form of
1308 environment variables etc. . Some user-credentials, such as the
1309 user's UID and GID (plus default group memberships) are not deemed to
1310 be PAM-credentials. It is the responsibility of the application to
1311 grant these directly.
1315 <sect>An example application
1318 To get a flavor of the way a <tt/Linux-PAM/ application is written we
1319 include the following example. It prompts the user for their password
1320 and indicates whether their account is valid on the standard output,
1321 its return code also indicates the success (<tt/0/ for success; <tt/1/
1328 This program was contributed by Shane Watts
1329 [modifications by AGM]
1331 You need to add the following (or equivalent) to the /etc/pam.conf file.
1332 # check authorization
1333 check_user auth required /usr/lib/security/pam_unix_auth.so
1334 check_user account required /usr/lib/security/pam_unix_acct.so
1337 #include <security/pam_appl.h>
1338 #include <security/pam_misc.h>
1341 static struct pam_conv conv = {
1346 int main(int argc, char *argv[])
1348 pam_handle_t *pamh=NULL;
1350 const char *user="nobody";
1357 fprintf(stderr, "Usage: check_user [username]\n");
1361 retval = pam_start("check_user", user, &ero;conv, &ero;pamh);
1363 if (retval == PAM_SUCCESS)
1364 retval = pam_authenticate(pamh, 0); /* is user really user? */
1366 if (retval == PAM_SUCCESS)
1367 retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
1369 /* This is where we have been authorized or not. */
1371 if (retval == PAM_SUCCESS) {
1372 fprintf(stdout, "Authenticated\n");
1374 fprintf(stdout, "Not Authenticated\n");
1377 if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
1379 fprintf(stderr, "check_user: failed to release authenticator\n");
1383 return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
1392 <tag><tt>/usr/include/security/pam_appl.h</tt></tag>
1394 header file for <bf/Linux-PAM/ applications interface
1396 <tag><tt>/usr/include/security/pam_misc.h</tt></tag>
1398 header file for useful library functions for making applications
1401 <tag><tt>/usr/lib/libpam.so.*</tt></tag>
1403 the shared library providing applications with access to
1406 <tag><tt>/etc/pam.conf</tt></tag>
1408 the <bf/Linux-PAM/ configuration file.
1410 <tag><tt>/usr/lib/security/pam_*.so</tt></tag>
1412 the primary location for <bf/Linux-PAM/ dynamically loadable object
1418 <label id="bibliography">
1422 <item>The <bf/Linux-PAM/
1423 <htmlurl url="pam.html" name="System Administrators' Guide">.
1425 <item>The <bf/Linux-PAM/
1426 <htmlurl url="pam_modules.html" name="Module Writers' Guide">.
1428 <item>The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
1429 PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation Request
1430 For Comments 86.0, October 1995.
1437 I intend to put development comments here... like ``at the moment
1438 this isn't actually supported''. At release time what ever is in
1439 this section will be placed in the Bugs section below! :)
1444 <item> <tt/pam_strerror()/ should be internationalized....
1447 Note, the <tt/resp_retcode/ of struct <tt/pam_message/, has no
1448 purpose at the moment. Ideas/suggestions welcome!
1450 <item> more security issues are required....
1454 <sect>Author/acknowledgments
1457 This document was written by Andrew G. Morgan
1458 (morgan@transmeta.com) with many contributions from
1459 <!-- insert credits here -->
1461 an sgml list of people to credit for their contributions to Linux-PAM
1462 $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
1467 Derrick J. Brashear,
1482 Marek Michalkiewicz,
1490 Savochkin Andrey Vladimirovich,
1500 Thanks are also due to Sun Microsystems, especially to Vipin Samar and
1501 Charlie Lai for their advice. At an early stage in the development of
1502 <bf/Linux-PAM/, Sun graciously made the documentation for their
1503 implementation of PAM available. This act greatly accelerated the
1504 development of <bf/Linux-PAM/.
1506 <sect>Bugs/omissions
1509 This manual is hopelessly unfinished. Only a partial list of people is
1510 credited for all the good work they have done.
1512 <sect>Copyright information for this document
1515 Copyright (c) Andrew G. Morgan 1996, 1997. All rights reserved.
1517 Email: <tt><morgan@transmeta.com></tt>
1520 Redistribution and use in source and binary forms, with or without
1521 modification, are permitted provided that the following conditions are
1528 1. Redistributions of source code must retain the above copyright
1529 notice, and the entire permission notice in its entirety,
1530 including the disclaimer of warranties.
1533 2. Redistributions in binary form must reproduce the above copyright
1534 notice, this list of conditions and the following disclaimer in the
1535 documentation and/or other materials provided with the distribution.
1538 3. The name of the author may not be used to endorse or promote
1539 products derived from this software without specific prior
1545 <bf/Alternatively/, this product may be distributed under the terms of
1546 the GNU General Public License (GPL), in which case the provisions of
1547 the GNU GPL are required <bf/instead of/ the above restrictions.
1548 (This clause is necessary due to a potential bad interaction between
1549 the GNU GPL and the restrictions contained in a BSD-style copyright.)
1552 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1553 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1554 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1555 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1556 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1557 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
1558 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1559 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1560 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1561 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1565 <tt>$Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $</tt>