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