849972189ce30f2866af0f51d6d4c04d777ffaf6
[dragonfly.git] / contrib / libpam / doc / pam_modules.sgml
1 <!doctype linuxdoc system>
2
3 <!--
4
5  $Id: pam_modules.sgml,v 1.19 1997/04/05 06:49:14 morgan Exp morgan $
6  $FreeBSD: src/contrib/libpam/doc/pam_modules.sgml,v 1.1.1.1.6.2 2001/06/11 15:28:10 markm Exp $
7  $DragonFly: src/contrib/libpam/doc/Attic/pam_modules.sgml,v 1.2 2003/06/17 04:24:02 dillon Exp $
8
9     Copyright (c) Andrew G. Morgan 1996, 1997.  All rights reserved.
10
11         ** some sections, in this document, were contributed by other
12         ** authors. They carry individual copyrights.
13
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions are
16 met:
17
18 1. Redistributions of source code must retain the above copyright
19    notice, and the entire permission notice in its entirety,
20    including the disclaimer of warranties.
21
22 2. Redistributions in binary form must reproduce the above copyright
23    notice, this list of conditions and the following disclaimer in the
24    documentation and/or other materials provided with the distribution.
25
26 3. The name of the author may not be used to endorse or promote
27    products derived from this software without specific prior
28    written permission.
29
30 ALTERNATIVELY, this product may be distributed under the terms of the
31 GNU General Public License, in which case the provisions of the GNU
32 GPL are required INSTEAD OF the above restrictions.  (This clause is
33 necessary due to a potential bad interaction between the GNU GPL and
34 the restrictions contained in a BSD-style copyright.)
35
36 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
40 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
41 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
42 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
45 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
46 DAMAGE.
47
48  -->
49
50 <article>
51
52 <title>The Linux-PAM Module Writers' Guide
53 <author>Andrew G. Morgan, <tt>morgan@transmeta.com</tt>
54 <date>DRAFT v0.59 1997/10/17
55 <abstract>
56 This manual documents what a programmer needs to know in order to
57 write a module that conforms to the <bf/Linux-PAM/ standard. It also
58 discusses some security issues from the point of view of the module
59 programmer.
60 </abstract>
61
62 <toc>
63
64 <sect>Introduction
65
66 <sect1> Synopsis
67 <p>
68 <tscreen>
69 <verb>
70 #include <security/pam_modules.h>
71
72 gcc -fPIC -c pam_module-name.c
73 ld -x --shared -o pam_module-name.so pam_module-name.o -lpam
74 </verb>
75 </tscreen>
76
77 <sect1> Description
78
79 <p>
80 <bf/Linux-PAM/ (Pluggable Authentication Modules for Linux) is a
81 library that enables the local system administrator to choose how
82 individual applications authenticate users.  For an overview of the
83 <bf/Linux-PAM/ library see the <bf/Linux-PAM/ System Administrators'
84 Guide.
85
86 <p>
87 A <bf/Linux-PAM/ module is a single executable binary file that can be
88 loaded by the <bf/Linux-PAM/ interface library. This PAM library is
89 configured locally with a system file, <tt>/etc/pam.conf</tt>, to
90 authenticate a user request via the locally available authentication
91 modules. The modules themselves will usually be located in the
92 directory <tt>/usr/lib/security</tt> and take the form of dynamically
93 loadable object files (see dlopen(3)). Alternatively, the modules can
94 be statically linked into the <bf/Linux-PAM/ library; this is mostly to
95 allow <bf/Linux-PAM/ to be used on platforms without dynamic linking
96 available, but the two forms can be used together.  It is the
97 <bf/Linux-PAM/ interface that is called by an application and it is
98 the responsibility of the library to locate, load and call the
99 appropriate functions in a <bf/Linux-PAM/-module.
100
101 <p>
102 Except for the immediate purpose of interacting with the user
103 (entering a password etc..) the module should never call the
104 application directly. This exception requires a "conversation
105 mechanism" which is documented below.
106
107 <sect>What can be expected by the module
108
109 <p>
110 Here we list the interface that the conventions that all
111 <bf/Linux-PAM/ modules must adhere to.
112
113 <sect1>Getting and setting <tt/PAM_ITEM/s and <em/data/
114
115 <p>
116 First, we cover what the module should expect from the <bf/Linux-PAM/
117 library and a <bf/Linux-PAM/ <em/aware/ application. Essesntially this
118 is the <tt/libpam.*/ library.
119
120 <sect2>
121 Setting data
122
123 <p>
124 Synopsis:
125 <tscreen>
126 <verb>
127 extern int pam_set_data(pam_handle_t *pamh
128                         , const char *module_data_name
129                         , void *data
130                         , void (*cleanup)(pam_handle_t *pamh
131                                           , void *data
132                                           , int error_status)
133                         );
134 </verb>
135 </tscreen>
136
137 <p>
138 The modules may be dynamically loadable objects. In general such files
139 should not contain <tt/static/ variables. This and the subsequent
140 function provide a mechanism for a module to associate some data with
141 the handle <tt/pamh/. Typically a module will call the
142 <tt/pam_set_data()/ function to register some data under a (hopefully)
143 unique <tt/module_data_name/. The data is available for use by other
144 modules too but <em/not/ by an application.
145
146 <p>
147 The function <tt/cleanup()/ is associated with the <tt/data/ and, if
148 non-<tt/NULL/, it is called when this data is over-written or
149 following a call to <tt/pam_end()/ (see the Linux-PAM Application
150 Developers' Guide).
151
152 <p>
153 The <tt/error_status/ argument is used to indicate to the module the
154 sort of action it is to take in cleaning this data item. As an
155 example, Kerberos creates a ticket file during the authentication
156 phase, this file might be associated with a data item. When
157 <tt/pam_end()/ is called by the module, the <tt/error_status/
158 carries the return value of the <tt/pam_authenticate()/ or other
159 <tt/libpam/ function as appropriate. Based on this value the Kerberos
160 module may choose to delete the ticket file (<em/authentication
161 failure/) or leave it in place.
162
163 <p>
164 (*This paragraph is currently under advisement with Sun*) The
165 <tt/error_status/ may have been logically OR'd with either of the
166 following two values:
167
168 <p>
169 <descrip>
170 <tag><tt/PAM_DATA_REPLACE/</tag>
171         When a data item is being replaced (through a second call to
172 <tt/pam_set_data()/) this mask is used is used. Otherwise, the call is
173 assumed to be from <tt/pam_end()/.
174
175 <tag><tt/PAM_DATA_SILENT/</tag>
176         Which indicates that the process would prefer to perform the
177 <tt/cleanup()/ quietly. That is, discourages logging/messages to the
178 user.
179
180 </descrip>
181
182
183 <sect2>
184 Getting data
185
186 <p>
187 Synopsis:
188 <tscreen>
189 <verb>
190 extern int pam_get_data(const pam_handle_t *pamh
191                         , const char *module_data_name
192                         , const void **data
193                         );
194 </verb>
195 </tscreen>
196
197 <p>
198 This function together with the previous one provides a method of
199 associating module-specific data with the handle <tt/pamh/. A
200 successful call to <tt/pam_get_data/ will result in <tt/*data/
201 pointing to the data associated with the <tt/module_data_name/. Note,
202 this data is <em/not/ a copy and should be treated as <em/constant/
203 by the module.
204
205 <p>
206 Note, if there is an entry but it has the value <tt/NULL/, then this
207 call returns <tt/PAM_NO_MODULE_DATA/.
208
209 <sect2>
210 Setting items
211
212 <p>
213 Synopsis:
214 <tscreen>
215 <verb>
216 extern int pam_set_item(pam_handle_t *pamh
217                         , int item_type
218                         , const void *item
219                         );
220 </verb>
221 </tscreen>
222
223 <p>
224 This function is used to (re)set the value of one of the
225 <tt/item_type/s.  The reader is urged to read the entry for this
226 function in the <bf/Linux-PAM/ application developers' manual.
227
228 <p>
229 In addition to the <tt/item/s listed there, the module can set the
230 following two <tt/item_type/s:
231
232 <p>
233 <descrip>
234 <tag><tt/PAM_AUTHTOK/</tag>
235
236 The authentication token (password). This token should be ignored by
237 all module functions besides <tt/pam_sm_authenticate()/ and
238 <tt/pam_sm_chauthtok()/. In the former function it is used to pass the
239 most recent authentication token from one stacked module to
240 another. In the latter function the token is used for another
241 purpose. It contains the currently active authentication token.
242
243 <tag><tt/PAM_OLDAUTHTOK/</tag>
244
245 The old authentication token. This token should be ignored by all
246 module functions except <tt/pam_sm_chauthtok()/.
247
248 </descrip>
249
250 <p>
251 Both of these items are reset before returning to the application.
252 When resetting these items, the <bf/Linux-PAM/ library first writes
253 <tt/0/'s to the current tokens and then <tt/free()/'s the associated
254 memory.
255
256 <p>
257 The return values for this function are listed in the 
258 <bf>Linux-PAM</bf> Application Developers' Guide.
259
260 <sect2>
261 Getting items
262
263 <p>
264 Synopsis:
265 <tscreen>
266 <verb>
267 extern int pam_get_item(const pam_handle_t *pamh
268                         , int item_type
269                         , const void **item
270                         );
271 </verb>
272 </tscreen>
273
274 <p>
275 This function is used to obtain the value of the specified
276 <tt/item_type/. It is better documented in the <bf/Linux-PAM/
277 Application Developers' Guide. However, there are three things worth
278 stressing here:
279 <itemize>
280
281 <item>
282 Generally, if the module wishes to obtain the name of the user, it
283 should not use this function, but instead perform a call to
284 <tt/pam_get_user()/ (see section <ref id="pam-get-user"
285 name="below">).
286
287 <item>
288 The module is additionally privileged to read the authentication
289 tokens, <tt/PAM_AUTHTOK/ and <tt/PAM_OLDAUTHTOK/ (see the section
290 above on <tt/pam_set_data()/).
291
292 <item>
293 The module should <em/not/ <tt/free()/ or alter the data pointed to by
294 <tt/*item/ after a successful return from <tt/pam_get_item()/. This
295 pointer points directly at the data contained within the <tt/*pamh/
296 structure.  Should a module require that a change is made to the this
297 <tt/ITEM/ it should make the appropriate call to <tt/pam_set_item()/.
298 </itemize>
299
300 <sect2>The <em/conversation/ mechanism
301
302 <p>
303 Following the call <tt>pam_get_item(pamh,PAM_CONV,&amp;item)</tt>, the
304 pointer <tt/item/ points to a <em/conversation/-function that provides
305 limited but direct access to the application.  The purpose of this
306 function is to allow the module to prompt the user for their password
307 and pass other information in a manner consistent with the
308 application. For example, an X-windows based program might pop up a
309 dialog box to report a login failure. Just as the application should
310 not be concerned with the method of authentication, so the module
311 should not dictate the manner in which input (output) is
312 obtained from (presented to) to the user.
313
314 <p>
315 The reader is strongly urged to read the more complete description of
316 the <tt/pam_conv/ structure, written from the perspective of the
317 application developer, in the <bf/Linux-PAM/ Application Developers'
318 Guide.
319
320 <p>
321 The <tt/pam_response/ structure returned after a call to the
322 <tt/pam_conv/ function must be <tt/free()/'d by the module. Since the
323 call to the conversation function originates from the module, it is
324 clear that either this <tt/pam_response/ structure could be either
325 statically or dynamically (using <tt/malloc()/ etc.) allocated within
326 the application. Repeated calls to the conversation function would
327 likely overwrite static memory, so it is required that for a
328 successful return from the conversation function the memory for the
329 response structure is dynamically allocated by the application with
330 one of the <tt/malloc()/ family of commands and <em/must/ be
331 <tt/free()/'d by the module.
332
333 <p>
334 If the <tt/pam_conv/ mechanism is used to enter authentication tokens,
335 the module should either pass the result to the <tt/pam_set_item()/
336 library function, or copy it itself. In such a case, once the token
337 has been stored (by one of these methods or another one), the memory
338 returned by the application should be overwritten with <tt/0/'s, and
339 then <tt/free()/'d.
340
341 <p>
342 The return values for this function are listed in the 
343 <bf>Linux-PAM</bf> Application Developers' Guide.
344
345 <sect2>Getting the name of a user<label id="pam-get-user">
346
347 <p>
348 Synopsis:
349 <tscreen>
350 <verb>
351 extern int pam_get_user(pam_handle_t *pamh
352                         , const char **user
353                         , const char *prompt
354                         );
355 </verb>
356 </tscreen>
357
358 <p>
359 This is a <bf/Linux-PAM/ library function that returns the
360 (prospective) name of the user. To determine the username it does the
361 following things, in this order:
362 <itemize>
363
364 <item> checks what <tt/pam_get_item(pamh, PAM_USER, ... );/ would have
365 returned. If this is not <tt/NULL/ this is what it returns. Otherwise,
366
367 <item> obtains a username from the application via the <tt/pam_conv/
368 mechanism, it prompts the user with the first non-<tt/NULL/ string in
369 the following list:
370 <itemize>
371
372 <item> The <tt/prompt/ argument passed to the function
373 <item> What is returned by <tt/pam_get_item(pamh,PAM_USER_PROMPT, ... );/
374 <item> The default prompt: ``Please enter username: ''
375
376 </itemize>
377 </itemize>
378
379 <p>
380 By whatever means the username is obtained, a pointer to it is
381 returned as the contents of <tt/*user/. Note, this memory should
382 <em/not/ be <tt/free()/'d by the module. Instead, it will be liberated
383 on the next call to <tt/pam_get_user()/, or by <tt/pam_end()/ when the
384 application ends its interaction with <bf/Linux-PAM/.
385
386 <p>
387 Also, in addition, it should be noted that this function sets the
388 <tt/PAM_USER/ item that is associated with the <tt/pam_[gs]et_item()/
389 function.
390
391 <sect2>Setting a Linux-PAM environment variable
392
393 <p>
394 Synopsis:
395 <tscreen>
396 <verb>
397 extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
398 </verb>
399 </tscreen>
400
401 <p>
402 <bf/Linux-PAM/ (0.54+) comes equipped with a series of functions for
403 maintaining a set of <em/environment/ variables. The environment is
404 initialized by the call to <tt/pam_start()/ and is <bf/erased/ with a
405 call to <tt/pam_end()/.  This <em/environment/ is associated with the
406 <tt/pam_handle_t/ pointer returned by the former call.
407
408 <p>
409 The default environment is all but empty. It contains a single
410 <tt/NULL/ pointer, which is always required to terminate the
411 variable-list.  The <tt/pam_putenv()/ function can be used to add a
412 new environment variable, replace an existing one, or delete an old
413 one.
414
415 <p>
416 <itemize>
417 <item>Adding/replacing a variable<newline>
418
419 To add or overwrite a <bf/Linux-PAM/ environment variable the value of
420 the argument <tt/name_value/, should be of the following form:
421 <tscreen>
422 <verb>
423 name_value="VARIABLE=VALUE OF VARIABLE"
424 </verb>
425 </tscreen>
426 Here, <tt/VARIABLE/ is the environment variable's name and what
427 follows the `<tt/=/' is its (new) value. (Note, that <tt/"VARIABLE="/
428 is a valid value for <tt/name_value/, indicating that the variable is
429 set to <tt/""/.)
430
431 <item> Deleting a variable<newline>
432
433 To delete a <bf/Linux-PAM/ environment variable the value of
434 the argument <tt/name_value/, should be of the following form:
435 <tscreen>
436 <verb>
437 name_value="VARIABLE"
438 </verb>
439 </tscreen>
440 Here, <tt/VARIABLE/ is the environment variable's name and the absence
441 of an `<tt/=/' indicates that the variable should be removed.
442
443 </itemize>
444
445 <p>
446 In all cases <tt/PAM_SUCCESS/ indicates success.
447
448 <sect2>Getting a Linux-PAM environment variable
449
450 <p>
451 Synopsis:
452 <tscreen>
453 <verb>
454 extern const char *pam_getenv(pam_handle_t *pamh, const char *name);
455 </verb>
456 </tscreen>
457
458 <p>
459 This function can be used to return the value of the given
460 variable. If the returned value is <tt/NULL/, the variable is not
461 known.
462
463 <sect2>Listing the Linux-PAM environment
464
465 <p>
466 Synopsis:
467 <tscreen>
468 <verb>
469 extern char * const *pam_getenvlist(pam_handle_t *pamh);
470 </verb>
471 </tscreen>
472
473 <p>
474 This function returns a pointer to the entire <bf/Linux-PAM/
475 environment array.  At first sight the <em/type/ of the returned data
476 may appear a little confusing.  It is basically a <em/read-only/ array
477 of character pointers, that lists the <tt/NULL/ terminated list of
478 environment variables set so far.
479
480 <p>
481 Although, this is not a concern for the module programmer, we mention
482 here that an application should be careful to copy this entire array
483 before executing <tt/pam_end()/ otherwise all the variable information
484 will be lost. (There are functions in <tt/libpam_misc/ for this
485 purpose: <tt/pam_misc_copy_env()/ and <tt/pam_misc_drop_env()/.)
486
487 <sect1>Other functions provided by <tt/libpam/
488
489 <sect2>Understanding errors
490
491 <p>
492 <itemize>
493
494 <item>
495 <tt>extern const char *pam_strerror(pam_handle_t *pamh, int errnum);</tt>
496
497 <p>
498 This function returns some text describing the <bf/Linux-PAM/ error
499 associated with the argument <tt/errnum/.  If the error is not
500 recognized <tt/``Unknown Linux-PAM error''/ is returned.
501
502 </itemize>
503
504 <sect2>Planning for delays
505
506 <p>
507 <itemize>
508
509 <item>
510 <tt>extern int pam_fail_delay(pam_handle_t *pamh, unsigned int
511 micro_sec)</tt>
512
513 <p>
514 This function is offered by <bf/Linux-PAM/ to facilitate time delays
515 following a failed call to <tt/pam_authenticate()/ and before control
516 is returned to the application. When using this function the module
517 programmer should check if it is available with,
518 <tscreen>
519 <verb>
520 #ifdef HAVE_PAM_FAIL_DELAY
521     ....
522 #endif /* HAVE_PAM_FAIL_DELAY */
523 </verb>
524 </tscreen>
525
526 <p>
527 Generally, an application requests that a user is authenticated by
528 <bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or
529 <tt/pam_chauthtok()/.  These functions calls each of the <em/stacked/
530 authentication modules listed in the <tt>/etc/pam.conf</tt> file.  As
531 directed by this file, one of more of the modules may fail causing the
532 <tt/pam_...()/ call to return an error.  It is desirable for there to
533 also be a pause before the application continues. The principal reason
534 for such a delay is security: a delay acts to discourage <em/brute
535 force/ dictionary attacks primarily, but also helps hinder
536 <em/timed/ (covert channel) attacks.
537
538 <p>
539 The <tt/pam_fail_delay()/ function provides the mechanism by which an
540 application or module can suggest a minimum delay (of <tt/micro_sec/
541 <em/micro-seconds/). <bf/Linux-PAM/ keeps a record of the longest time
542 requested with this function. Should <tt/pam_authenticate()/ fail,
543 the failing return to the application is delayed by an amount of time
544 randomly distributed (by up to 25%) about this longest value.
545
546 <p>
547 Independent of success, the delay time is reset to its zero default
548 value when <bf/Linux-PAM/ returns control to the application.
549
550 </itemize>
551
552 <sect>What is expected of a module
553
554 <p>
555 The module must supply a sub-set of the six functions listed
556 below. Together they define the function of a <bf/Linux-PAM
557 module/. Module developers are strongly urged to read the comments on
558 security that follow this list.
559
560 <sect1> Overview
561
562 <p>
563 The six module functions are grouped into four independent management
564 groups. These groups are as follows: <em/authentication/,
565 <em/account/, <em/session/ and <em/password/. To be properly defined,
566 a module must define all functions within at least one of these
567 groups. A single module may contain the necessary functions for
568 <em/all/ four groups.
569
570 <sect2> Functional independence
571
572 <p>
573 The independence of the four groups of service a module can offer
574 means that the module should allow for the possibility that any one of
575 these four services may legitimately be called in any order. Thus, the
576 module writer should consider the appropriateness of performing a
577 service without the prior success of some other part of the module.
578
579 <p>
580 As an informative example, consider the possibility that an
581 application applies to change a user's authentication token, without
582 having first requested that <bf/Linux-PAM/ authenticate the user. In
583 some cases this may be deemed appropriate: when <tt/root/ wants to
584 change the authentication token of some lesser user. In other cases it
585 may not be appropriate: when <tt/joe/ maliciously wants to reset
586 <tt/alice/'s password; or when anyone other than the user themself
587 wishes to reset their <em/KERBEROS/ authentication token. A policy for
588 this action should be defined by any reasonable authentication scheme,
589 the module writer should consider this when implementing a given
590 module.
591
592 <sect2> Minimizing administration problems
593
594 <p>
595 To avoid system administration problems and the poor construction of a
596 <tt>/etc/pam.conf</tt> file, the module developer may define all
597 six of the following functions. For those functions that would not be
598 called, the module should return <tt/PAM_SERVICE_ERR/ and write an
599 appropriate message to the system log. When this action is deemed
600 inappropriate, the function would simply return <tt/PAM_IGNORE/.
601
602 <sect2> Arguments supplied to the module
603
604 <p>
605 The <tt/flags/ argument of each of the following functions can be
606 logically OR'd with <tt/PAM_SILENT/, which is used to inform the
607 module to not pass any <em/text/ (errors or warnings) to the
608 application.
609
610 <p>
611 The <tt/argc/ and <tt/argv/ arguments are taken from the line
612 appropriate to this module---that is, with the <em/service_name/
613 matching that of the application---in the configuration file (see the
614 <bf/Linux-PAM/ System Administrators' Guide). Together these two
615 parameters provide the number of arguments and an array of pointers to
616 the individual argument tokens. This will be familiar to C programmers
617 as the ubiquitous method of passing command arguments to the function
618 <tt/main()/. Note, however, that the first argument (<tt/argv[0]/) is
619 a true argument and <bf/not/ the name of the module.
620
621 <sect1> Authentication management
622
623 <p>
624 To be correctly initialized, <tt/PAM_SM_AUTH/ must be <tt/#define/'d
625 prior to including <tt>&lt;security/pam_modules.h&gt;</tt>. This will
626 ensure that the prototypes for static modules are properly declared.
627
628 <p>
629 <itemize>
630
631 <item>
632 <tt>PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
633 int argc, const char **argv);</tt>
634
635 <p>
636 This function performs the task of authenticating the user. 
637
638 <p>
639 The <tt/flags/ argument can be a logically OR'd with <tt/PAM_SILENT/
640 and optionally take the following value:
641
642 <p><descrip>
643 <tag><tt/PAM_DISALLOW_NULL_AUTHTOK/</tag>
644         return <tt/PAM_AUTH_ERR/ if the database of authentication
645 tokens for this authentication mechanism has a <tt/NULL/ entry for the
646 user. Without this flag, such a <tt/NULL/ token will lead to a success
647 without the user being prompted.
648 </descrip>
649
650 <p>
651 Besides <tt/PAM_SUCCESS/ return values that can be sent by this
652 function are one of the following:
653
654 <descrip>
655
656 <tag><tt/PAM_AUTH_ERR/</tag>
657         The user was not authenticated
658 <tag><tt/PAM_CRED_INSUFFICIENT/</tag>
659         For some reason the application does not have sufficient
660 credentials to authenticate the user.
661 <tag><tt/PAM_AUTHINFO_UNAVAIL/</tag>
662         The modules were not able to access the authentication
663 information. This might be due to a network or hardware failure etc.
664 <tag><tt/PAM_USER_UNKNOWN/</tag>
665         The supplied username is not known to the authentication
666 service
667 <tag><tt/PAM_MAXTRIES/</tag>
668         One or more of the authentication modules has reached its
669 limit of tries authenticating the user. Do not try again.
670
671 </descrip>
672
673 <item>
674 <tt>PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int
675 argc, const char **argv);</tt>
676
677 <p>
678 This function performs the task of altering the credentials of the
679 user with respect to the corresponding authorization
680 scheme. Generally, an authentication module may have access to more
681 information about a user than their authentication token. This
682 function is used to append such information to the application. It
683 should only be called <em/after/ the user has been authenticated.
684
685 <p>
686 Permitted flags, one of which, may be logically OR'd with
687 <tt/PAM_SILENT/ are,
688
689 <p><descrip>
690 <tag><tt/PAM_ESTABLISH_CRED/</tag>
691         Set the credentials for the authentication service,
692 <tag><tt/PAM_DELETE_CRED/</tag>
693         Delete the credentials associated with the authentication service,
694 <tag><tt/PAM_REINITIALIZE_CRED/</tag>
695         Reinitialize the user credentials, and
696 <tag><tt/PAM_REFRESH_CRED/</tag>
697         Extend the lifetime of the user credentials.
698 </descrip>
699
700 <p>
701 Besides <tt/PAM_SUCCESS/, the module may return one of the following
702 errors:
703
704 <p><descrip>
705 <tag><tt/PAM_CRED_UNAVAIL/</tag>
706         This module cannot retrieve the user's credentials.
707 <tag><tt/PAM_CRED_EXPIRED/</tag>
708         The user's credentials have expired.
709 <tag><tt/PAM_USER_UNKNOWN/</tag>
710         The user is not known to this authentication module.
711 <tag><tt/PAM_CRED_ERR/</tag>
712         This module was unable to set the credentials of the user.
713 </descrip>
714
715 </itemize>
716
717 <sect1> Account management
718
719 <p>
720 To be correctly initialized, <tt/PAM_SM_ACCOUNT/ must be
721 <tt/#define/'d prior to including <tt>&lt;security/pam_modules.h&gt;</tt>.
722 This will ensure that the prototype for a static module is properly
723 declared.
724
725 <p>
726 <itemize>
727
728 <item>
729 <tt>PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int
730 argc, const char **argv);</tt>
731
732 <p>
733 This function performs the task of establishing whether the user is
734 permitted to gain access at this time. It should be understood that
735 the user has previously been validated by an authentication
736 module. This function checks for other things. Such things might be:
737 the time of day or the date, the terminal line, remote
738 hostname, etc. .
739
740 <p>
741 This function may also determine things like the expiration on
742 passwords, and respond that the user change it before continuing.
743
744 <p>
745 Valid flags, which may be logically OR'd with <tt/PAM_SILENT/, are the
746 same as those applicable to the <tt/flags/ argument of
747 <tt/pam_sm_authenticate/.
748
749 <p>
750 This function may return one of the following errors,
751
752 <descrip>
753
754 <tag><tt/PAM_ACCT_EXPIRED/</tag>
755         The user is no longer permitted access to the system.
756 <tag><tt/PAM_AUTH_ERR/</tag>
757         There was an authentication error.
758 <tag><tt/PAM_AUTHTOKEN_REQD/</tag>
759         The user's authentication token has expired. Before calling
760 this function again the application will arrange for a new one to be
761 given. This will likely result in a call to <tt/pam_sm_chauthtok()/.
762 <tag><tt/PAM_USER_UNKNOWN/</tag>
763         The user is not known to the module's account management
764 component.
765         
766 </descrip>
767
768 </itemize>
769
770 <sect1> Session management
771
772 <p>
773 To be correctly initialized, <tt/PAM_SM_SESSION/ must be
774 <tt/#define/'d prior to including
775 <tt>&lt;security/pam_modules.h&gt;</tt>.  This will ensure that the
776 prototypes for static modules are properly declared.
777
778 <p>
779 The following two functions are defined to handle the
780 initialization/termination of a session. For example, at the beginning
781 of a session the module may wish to log a message with the system
782 regarding the user. Similarly, at the end of the session the module
783 would inform the system that the user's session has ended.
784
785 <p>
786 It should be possible for sessions to be opened by one application and
787 closed by another. This either requires that the module uses only
788 information obtained from <tt/pam_get_item()/, or that information
789 regarding the session is stored in some way by the operating system
790 (in a file for example).
791
792 <p>
793 <itemize>
794
795 <item>
796 <tt>PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int
797 argc, const char **argv);</tt>
798
799 <p>
800 This function is called to commence a session. The only valid, but
801 optional, flag is <tt/PAM_SILENT/.
802
803 <p>
804 As a return value, <tt/PAM_SUCCESS/ signals success and
805 <tt/PAM_SESSION_ERR/ failure.
806
807 <item>
808 <tt>PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int
809 argc, const char **argv);</tt>
810
811 <p>
812 This function is called to terminate a session. The only valid, but
813 optional, flag is <tt/PAM_SILENT/.
814
815 <p>
816 As a return value, <tt/PAM_SUCCESS/ signals success and
817 <tt/PAM_SESSION_ERR/ failure.
818
819 </itemize>
820
821 <sect1> Password management
822
823 <p>
824 To be correctly initialized, <tt/PAM_SM_PASSWORD/ must be
825 <tt/#define/'d prior to including <tt>&lt;security/pam_modules.h&gt;</tt>.
826 This will ensure that the prototype for a static module is properly
827 declared.
828
829 <p>
830 <itemize>
831
832 <item>
833 <tt>PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int
834 argc, const char **argv);</tt>
835
836 <p>
837 This function is used to (re-)set the authentication token of the
838 user. A valid flag, which may be logically OR'd with <tt/PAM_SILENT/,
839 can be built from the following list,
840
841 <descrip>
842 <tag><tt/PAM_CHANGE_EXPIRED_AUTHTOK/</tag>
843         This argument indicates to the module that the users
844 authentication token (password) should only be changed if it has
845 expired. This flag is optional and <em/must/ be combined with one of
846 the following two flags. Note, however, the following two options are
847 <em/mutually exclusive/.
848
849 <tag><tt/PAM_PRELIM_CHECK/</tag>
850         This indicates that the modules are being probed as to their
851 ready status for altering the user's authentication token. If the
852 module requires access to another system over some network it should
853 attempt to verify it can connect to this system on receiving this
854 flag. If a module cannot establish it is ready to update the user's
855 authentication token it should return <tt/PAM_TRY_AGAIN/, this
856 information will be passed back to the application.
857
858 <tag><tt/PAM_UPDATE_AUTHTOK/</tag>
859         This informs the module that this is the call it should change
860 the authorization tokens. If the flag is logically OR'd with
861 <tt/PAM_CHANGE_EXPIRED_AUTHTOK/, the token is only changed if it has
862 actually expired.
863
864 </descrip>
865
866 <p>
867 Note, the <bf/Linux-PAM/ library calls this function twice in
868 succession. The first time with <tt/PAM_PRELIM_CHECK/ and then, if the
869 module does not return <tt/PAM_TRY_AGAIN/, subsequently with
870 <tt/PAM_UPDATE_AUTHTOK/. It is only on the second call that the
871 authorization token is (possibly) changed.
872
873 <p>
874 <tt/PAM_SUCCESS/ is the only successful return value, valid
875 error-returns are:
876
877 <descrip>
878 <tag><tt/PAM_AUTHTOK_ERR/</tag>
879         The module was unable to obtain the new authentication token.
880         
881 <tag><tt/PAM_AUTHTOK_RECOVERY_ERR/</tag>
882         The module was unable to obtain the old authentication token.
883
884 <tag><tt/PAM_AUTHTOK_LOCK_BUSY/</tag>
885         Cannot change the authentication token since it is currently
886 locked.
887         
888 <tag><tt/PAM_AUTHTOK_DISABLE_AGING/</tag>
889         Authentication token aging has been disabled.
890
891 <tag><tt/PAM_PERM_DENIED/</tag>
892         Permission denied.
893
894 <tag><tt/PAM_TRY_AGAIN/</tag>
895         Preliminary check was unsuccessful. Signals an immediate return
896 to the application is desired.
897
898 <tag><tt/PAM_USER_UNKNOWN/</tag>
899         The user is not known to the authentication token changing
900 service.
901
902 </descrip>
903
904 </itemize>
905
906 <sect>Generic optional arguments
907
908 <p>
909 Here we list the generic arguments that all modules can expect to
910 be passed. They are not mandatory, and their absence should be
911 accepted without comment by the module.
912
913 <p>
914 <descrip>
915 <tag><tt/debug/</tag>
916
917 Use the <tt/syslog(3)/ call to log debugging information to the system
918 log files.
919
920 <tag><tt/no_warn/</tag>
921
922 Instruct module to not give warning messages to the application.
923
924 <tag><tt/use_first_pass/</tag>
925
926 The module should not prompt the user for a password. Instead, it
927 should obtain the previously typed password (by a call to
928 <tt/pam_get_item()/ for the <tt/PAM_AUTHTOK/ item), and use that. If
929 that doesn't work, then the user will not be authenticated. (This
930 option is intended for <tt/auth/ and <tt/passwd/ modules only).
931
932 <tag><tt/try_first_pass/</tag>
933
934 The module should attempt authentication with the previously typed
935 password (by a call to <tt/pam_get_item()/ for the <tt/PAM_AUTHTOK/
936 item). If that doesn't work, then the user is prompted for a
937 password. (This option is intended for <tt/auth/ modules only).
938
939 <tag><tt/use_mapped_pass/</tag>
940
941 <bf/WARNING:/ coding this functionality may cause the module writer to
942 break <em/local/ encryption laws. For example, in the U.S. there are
943 restrictions on the export computer code that is capable of strong
944 encryption.  It has not been established whether this option is
945 affected by this law, but one might reasonably assume that it does
946 until told otherwise.  For this reason, this option is not supported
947 by any of the modules distributed with <bf/Linux-PAM/.
948
949 The intended function of this argument, however, is that the module
950 should take the existing authentication token from a previously
951 invoked module and use it as a key to retrieve the authentication
952 token for this module. For example, the module might create a strong
953 hash of the <tt/PAM_AUTHTOK/ item (established by a previously
954 executed module). Then, with logical-exclusive-or, use the result as a
955 <em/key/ to safely store/retrieve the authentication token for this
956 module in/from a local file <em/etc/. .
957
958 </descrip>
959
960 <sect>Programming notes
961
962 <p>
963 Here we collect some pointers for the module writer to bear in mind
964 when writing/developing a <bf/Linux-PAM/ compatible module.
965
966 <sect1>Security issues for module creation
967
968 <sect2>Sufficient resources
969
970 <p>
971 Care should be taken to ensure that the proper execution of a module
972 is not compromised by a lack of system resources.  If a module is
973 unable to open sufficient files to perform its task, it should fail
974 gracefully, or request additional resources.  Specifically, the
975 quantities manipulated by the <tt/setrlimit(2)/ family of commands
976 should be taken into consideration.
977
978 <sect2>Who's who?
979
980 <p>
981 Generally, the module may wish to establish the identity of the user
982 requesting a service.  This may not be the same as the username
983 returned by <tt/pam_get_user()/. Indeed, that is only going to be the
984 name of the user under whose identity the service will be given.  This
985 is not necessarily the user that requests the service.
986
987 <p>
988 In other words, user X runs a program that is setuid-Y, it grants the
989 user to have the permissions of Z.  A specific example of this sort of
990 service request is the <em/su/ program: user <tt/joe/ executes
991 <em/su/ to become the user <em/jane/.  In this situation X=<tt/joe/,
992 Y=<tt/root/ and Z=<tt/jane/.  Clearly, it is important that the module
993 does not confuse these different users and grant an inappropriate
994 level of privilege.
995
996 <p>
997 The following is the convention to be adhered to when juggling
998 user-identities.
999
1000 <p>
1001 <itemize>
1002 <item>X, the identity of the user invoking the service request.
1003 This is the user identifier; returned by the function <tt/getuid(2)/.
1004
1005 <item>Y, the privileged identity of the application used to grant the
1006 requested service.  This is the <em/effective/ user identifier;
1007 returned by the function <tt/geteuid(2)/.
1008
1009 <item>Z, the user under whose identity the service will be granted.
1010 This is the username returned by <tt/pam_get_user(2)/ and also stored
1011 in the <bf/Linux-PAM/ item, <tt/PAM_USER/.
1012
1013 <item><bf/Linux-PAM/ has a place for an additional user identity that
1014 a module may care to make use of. This is the <tt/PAM_RUSER/ item.
1015 Generally, network sensitive modules/applications may wish to set/read
1016 this item to establish the identity of the user requesting a service
1017 from a remote location.
1018
1019 </itemize>
1020
1021 <p>
1022 Note, if a module wishes to modify the identity of either the <tt/uid/
1023 or <tt/euid/ of the running process, it should take care to restore
1024 the original values prior to returning control to the <bf/Linux-PAM/
1025 library.
1026
1027 <sect2>Using the conversation function
1028 <p>
1029 Prior to calling the conversation function, the module should reset
1030 the contents of the pointer that will return the applications
1031 response.  This is a good idea since the application may fail to fill
1032 the pointer and the module should be in a position to notice!
1033
1034 <p>
1035 The module should be prepared for a failure from the conversation. The
1036 generic error would be <tt/PAM_CONV_ERR/, but anything other than
1037 <tt/PAM_SUCCESS/ should be treated as indicating failure.
1038
1039 <sect2>Authentication tokens
1040
1041 <p>
1042 To ensure that the authentication tokens are not left lying around the
1043 items, <tt/PAM_AUTHTOK/ and <tt/PAM_OLDAUTHTOK/, are not available to
1044 the application: they are defined in
1045 <tt>&lt;security/pam_modules.h&gt;</tt>. This is ostensibly for
1046 security reasons, but a maliciously programmed application will always
1047 have access to all memory of the process, so it is only superficially
1048 enforced.  As a general rule the module should overwrite
1049 authentication tokens as soon as they are no longer needed.
1050 Especially before <tt/free()/'ing them. The <bf/Linux-PAM/ library is
1051 required to do this when either of these authentication token items
1052 are (re)set.
1053
1054 <p>
1055 Not to dwell too little on this concern; should the module store the
1056 authentication tokens either as (automatic) function variables or
1057 using <tt/pam_[gs]et_data()/ the associated memory should be
1058 over-written explicitly before it is released. In the case of the
1059 latter storage mechanism, the associated <tt/cleanup()/ function
1060 should explicitly overwrite the <tt/*data/ before <tt/free()/'ing it:
1061 for example,
1062
1063 <tscreen>
1064 <verb>
1065 /*
1066  * An example cleanup() function for releasing memory that was used to
1067  * store a password. 
1068  */
1069
1070 int cleanup(pam_handle_t *pamh, void *data, int error_status)
1071 {
1072     char *xx;
1073
1074     if ((xx = data)) {
1075         while (*xx)
1076             *xx++ = '\0';
1077         free(data);
1078     }
1079     return PAM_SUCCESS;
1080 }
1081 </verb>
1082 </tscreen>
1083
1084 <sect1>Use of <tt/syslog(3)/
1085
1086 <p>
1087 Only rarely should error information be directed to the user. Usually,
1088 this is to be limited to ``<em/sorry you cannot login now/'' type
1089 messages. Information concerning errors in the configuration file,
1090 <tt>/etc/pam.conf</tt>, or due to some system failure encountered by
1091 the module, should be written to <tt/syslog(3)/ with
1092 <em/facility-type/ <tt/LOG_AUTHPRIV/.
1093
1094 <p>
1095 With a few exceptions, the level of logging is, at the discretion of
1096 the module developer. Here is the recommended usage of different
1097 logging levels:
1098
1099 <p>
1100 <itemize>
1101
1102 <item>
1103 As a general rule, errors encountered by a module should be logged at
1104 the <tt/LOG_ERR/ level. However, information regarding an unrecognized
1105 argument, passed to a module from an entry in the
1106 <tt>/etc/pam.conf</tt> file, is <bf/required/ to be logged at the
1107 <tt/LOG_ERR/ level.
1108
1109 <item>
1110 Debugging information, as activated by the <tt/debug/ argument to the
1111 module in <tt>/etc/pam.conf</tt>, should be logged at the
1112 <tt/LOG_DEBUG/ level.
1113
1114 <item>
1115 If a module discovers that its personal configuration file or some
1116 system file it uses for information is corrupted or somehow unusable,
1117 it should indicate this by logging messages at level, <tt/LOG_ALERT/.
1118
1119 <item>
1120 Shortages of system resources, such as a failure to manipulate a file
1121 or <tt/malloc()/ failures should be logged at level <tt/LOG_CRIT/.
1122
1123 <item>
1124 Authentication failures, associated with an incorrectly typed password
1125 should be logged at level, <tt/LOG_NOTICE/.
1126
1127 </itemize>
1128
1129 <sect1> Modules that require system libraries
1130
1131 <p>
1132 Writing a module is much like writing an application. You have to
1133 provide the "conventional hooks" for it to work correctly, like
1134 <tt>pam_sm_authenticate()</tt> etc., which would correspond to the
1135 <tt/main()/ function in a normal function.
1136
1137 <p>
1138 Typically, the author may want to link against some standard system
1139 libraries. As when one compiles a normal program, this can be done for
1140 modules too: you simply append the <tt>-l</tt><em>XXX</em> arguments
1141 for the desired libraries when you create the shared module object. To
1142 make sure a module is linked to the <tt>lib<em>whatever</em>.so</tt>
1143 library when it is <tt>dlopen()</tt>ed, try:
1144 <tscreen>
1145 <verb>
1146 % gcc -shared -Xlinker -x -o pam_module.so pam_module.o -lwhatever
1147 </verb>
1148 </tscreen>
1149
1150 <sect1> Added requirements for <em/statically/ loaded modules.
1151
1152 <!--
1153         Copyright (C) Michael K. Johnson 1996.
1154         Last modified:  AGM 1996/5/31.
1155  -->
1156
1157 <p>
1158 Modules may be statically linked into libpam. This should be true of
1159 all the modules distributed with the basic <bf/Linux-PAM/
1160 distribution.  To be statically linked, a module needs to export
1161 information about the functions it contains in a manner that does not
1162 clash with other modules.
1163
1164 The extra code necessary to build a static module should be delimited
1165 with <tt/#ifdef PAM_STATIC/ and <tt/#endif/. The static code should do
1166 the following:
1167 <itemize>
1168 <item> Define a single structure, <tt/struct pam_module/, called
1169 <tt>_pam_<it>modname</it>_modstruct</tt>, where
1170 <tt><it>modname</it></tt> is the name of the module <bf/as used in the
1171 filesystem/ but without the leading directory name (generally
1172 <tt>/usr/lib/security/</tt> or the suffix (generally <tt/.so/).
1173
1174 </itemize>
1175
1176 <p>
1177 As a simple example, consider the following module code which defines
1178 a module that can be compiled to be <em/static/ or <em/dynamic/:
1179
1180 <p>
1181 <tscreen>
1182 <verb>
1183 #include <stdio.h>                                    /* for NULL define */
1184
1185 #define PAM_SM_PASSWORD         /* the only pam_sm_... function declared */
1186 #include <security/pam_modules.h>
1187
1188 PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
1189                                 int argc, const char **argv)
1190 {
1191      return PAM_SUCCESS;
1192 }
1193
1194 #ifdef PAM_STATIC             /* for the case that this module is static */
1195
1196 struct pam_module _pam_modname_modstruct = {       /* static module data */
1197      "pam_modname",
1198      NULL,
1199      NULL,
1200      NULL,
1201      NULL,
1202      NULL,
1203      pam_sm_chauthtok,
1204 };
1205
1206 #endif                                                 /* end PAM_STATIC */
1207 </verb>
1208 </tscreen>
1209
1210 <p>
1211 To be linked with <em/libpam/, staticly-linked modules must be built
1212 from within the <tt>Linux-PAM-X.YY/modules/</tt> subdirectory of the
1213 <bf/Linux-PAM/ source directory as part of a normal build of the
1214 <bf/Linux-PAM/ system.
1215
1216 The <em/Makefile/, for the module in question, must execute the
1217 <tt/register_static/ shell script that is located in the
1218 <tt>Linux-PAM-X.YY/modules/</tt> subdirectory. This is to ensure that
1219 the module is properly registered with <em/libpam/.
1220
1221 The <bf/two/ manditory arguments to <tt/register_static/ are the
1222 title, and the pathname of the object file containing the module's
1223 code. The pathname is specified relative to the
1224 <tt>Linux-PAM-X.YY/modules</tt> directory. The pathname may be an
1225 empty string---this is for the case that a single object file needs to
1226 register more than one <tt/struct pam_module/. In such a case, exactly
1227 one call to <tt/register_static/ must indicate the object file.
1228
1229 <p>
1230 Here is an example; a line in the <em/Makefile/ might look like this:
1231 <tscreen>
1232 <verb>
1233 register:
1234 ifdef STATIC
1235         (cd ..; ./register_static pam_modname pam_modname/pam_modname.o)
1236 endif
1237 </verb>
1238 </tscreen>
1239
1240 For some further examples, see the <tt>modules</tt> subdirectory of
1241 the current <bf/Linux-PAM/ distribution.
1242
1243 <p>
1244 <sect>An example module file
1245
1246 <p>
1247 <em>
1248 perhaps this should point to a place in the file structure!?
1249 </em>
1250
1251 <sect>Files
1252
1253 <p><descrip>
1254
1255 <tag><tt>/usr/lib/libpam.so.*</tt></tag>
1256
1257 the shared library providing applications with access to
1258 <bf/Linux-PAM/.
1259
1260 <tag><tt>/etc/pam.conf</tt></tag>
1261
1262 the <bf/Linux-PAM/ configuration file.
1263
1264 <tag><tt>/usr/lib/security/pam_*.so</tt></tag>
1265
1266 the primary location for <bf/Linux-PAM/ dynamically loadable object
1267 files; the modules.
1268
1269 </descrip>
1270
1271 <sect>See also
1272
1273 <p><itemize>
1274 <item>The <bf/Linux-PAM/ System Administrators' Guide.
1275 <item>The <bf/Linux-PAM/ Application Writers' Guide.
1276 <item>
1277 V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH PLUGGABLE
1278 AUTHENTICATION MODULES'', Open Software Foundation Request For
1279 Comments 86.0, October 1995.
1280 </itemize>
1281
1282 <sect>Notes
1283
1284 <p>
1285 I intend to put development comments here... like ``at the moment
1286 this isn't actually supported''. At release time what ever is in
1287 this section will be placed in the Bugs section below! :)
1288
1289 <p>
1290 <itemize>
1291 <item>
1292 Perhaps we should keep a registry of data-names as used by
1293 <tt/pam_[gs]et_data()/ so there are no unintentional problems due to
1294 conflicts?
1295
1296 <item>
1297 <tt/pam_strerror()/ should be internationalized....
1298
1299 <item>
1300 There has been some debate about whether <tt/initgroups()/ should be
1301 in an application or in a module. It was settled by Sun who stated
1302 that initgroups is an action of the <em/application/. The modules are
1303 permitted to add additional groups, however.
1304
1305 <item>
1306 Refinements/futher suggestions to <tt/syslog(3)/ usage by modules are
1307 needed.
1308
1309 </itemize>
1310
1311 <sect>Author/acknowledgments
1312
1313 <p>
1314 This document was written by Andrew G. Morgan
1315 (<tt/morgan@transmeta.com/) with many contributions from
1316 <!-- insert credits here -->
1317 <!--
1318  an sgml list of people to credit for their contributions to Linux-PAM
1319   -->
1320 <!--
1321  an sgml list of people to credit for their contributions to Linux-PAM
1322  $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
1323   -->
1324 Peter Allgeyer,
1325 Tim Baverstock,
1326 Craig S. Bell,
1327 Derrick J. Brashear,
1328 Ben Buxton,
1329 Oliver Crow,
1330 Chris Dent,
1331 Marc Ewing,
1332 Cristian Gafton,
1333 Eric Hester,
1334 Roger Hu,
1335 Eric Jacksch,
1336 Michael K. Johnson,
1337 David Kinchlea,
1338 Nicolai Langfeldt,
1339 Elliot Lee,
1340 Al Longyear,
1341 Ingo Luetkebohle,
1342 Marek Michalkiewicz,
1343 Aleph One,
1344 Martin Pool,
1345 Sean Reifschneider,
1346 Erik Troan,
1347 Theodore Ts'o,
1348 Jeff Uphoff,
1349 Myles Uyema,
1350 Savochkin Andrey Vladimirovich,
1351 Ronald Wahl,
1352 David Wood,
1353 John Wilmes,
1354 Joseph S. D. Yao
1355 and
1356 Alex O.  Yuriev.
1357
1358 <p>
1359 Thanks are also due to Sun Microsystems, especially to Vipin Samar and
1360 Charlie Lai for their advice. At an early stage in the development of
1361 <bf/Linux-PAM/, Sun graciously made the documentation for their
1362 implementation of PAM available. This act greatly accelerated the
1363 development of <bf/Linux-PAM/.
1364
1365 <sect>Bugs/omissions
1366
1367 <p>
1368 Few PAM modules currently exist. Few PAM-aware applications exist.
1369 This document is hopelessly unfinished. Only a partial list of people is
1370 credited for all the good work they have done.
1371
1372 <sect>Copyright information for this document
1373
1374 <p>
1375 Copyright (c) Andrew G. Morgan 1996, 1997.  All rights reserved.
1376 <newline>
1377 Email: <tt>&lt;morgan@transmeta.com&gt;</tt>
1378
1379 <p>
1380 Redistribution and use in source and binary forms, with or without
1381 modification, are permitted provided that the following conditions are
1382 met:
1383
1384 <p>
1385 <itemize>
1386
1387 <item>
1388 1. Redistributions of source code must retain the above copyright
1389    notice, and the entire permission notice in its entirety,
1390    including the disclaimer of warranties.
1391
1392 <item>
1393 2. Redistributions in binary form must reproduce the above copyright
1394    notice, this list of conditions and the following disclaimer in the
1395    documentation and/or other materials provided with the distribution.
1396
1397 <item>
1398 3. The name of the author may not be used to endorse or promote
1399    products derived from this software without specific prior
1400    written permission.
1401
1402 </itemize>
1403
1404 <p>
1405 <bf/Alternatively/, this product may be distributed under the terms of
1406 the GNU General Public License (GPL), in which case the provisions of
1407 the GNU GPL are required <bf/instead of/ the above restrictions.
1408 (This clause is necessary due to a potential bad interaction between
1409 the GNU GPL and the restrictions contained in a BSD-style copyright.)
1410
1411 <p>
1412 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1413 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1414 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1415 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1416 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1417 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
1418 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1419 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1420 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1421 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1422 DAMAGE.
1423
1424 <p>
1425 <tt>$Id: pam_modules.sgml,v 1.19 1997/04/05 06:49:14 morgan Exp morgan $</tt>
1426
1427 </article>