~ubuntu-branches/ubuntu/breezy/pam/breezy

« back to all changes in this revision

Viewing changes to Linux-PAM/doc/pam_modules.sgml

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2004-06-28 14:28:08 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040628142808-adikk7vtfg3pzcjw
Tags: 0.76-22
* Add uploaders
* Document location of repository
* Fix options containing arguments in pam_unix, Closes: #254904

Show diffs side-by-side

added added

removed removed

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