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