]> granicus.if.org Git - linux-pam/blob - doc/adg/Linux-PAM_ADG.xml
Relevant BUGIDs: 1822779
[linux-pam] / doc / adg / Linux-PAM_ADG.xml
1 <?xml version='1.0' encoding='UTF-8'?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3         "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
4 <book id="adg">
5   <bookinfo>
6     <title>The Linux-PAM Application Developers' Guide</title>
7     <authorgroup>
8       <author>
9         <firstname>Andrew G.</firstname>
10         <surname>Morgan</surname>
11         <email>morgan@kernel.org</email>
12       </author>
13       <author>
14         <firstname>Thorsten</firstname>
15         <surname>Kukuk</surname>
16         <email>kukuk@thkukuk.de</email>
17       </author>
18     </authorgroup>
19     <releaseinfo>Version 0.99.6.0, 5. August 2006</releaseinfo>
20     <abstract>
21       <para>
22         This manual documents what an application developer needs to know
23         about the <emphasis remap='B'>Linux-PAM</emphasis> library. It
24         describes how an application might use the
25         <emphasis remap='B'>Linux-PAM</emphasis> library to authenticate
26         users. In addition it contains a description of the funtions
27         to be found in <filename>libpam_misc</filename> library, that can
28         be used in general applications. Finally, it contains some comments
29         on PAM related security issues for the application developer.
30       </para>
31     </abstract>
32   </bookinfo>
33
34   <chapter id="adg-introduction">
35     <title>Introduction</title>
36     <section id="adg-introduction-description">
37       <title>Description</title>
38       <para>
39         <emphasis remap='B'>Linux-PAM</emphasis>
40         (Pluggable Authentication Modules for Linux) is a library that enables
41         the local system administrator to choose how individual applications
42         authenticate users. For an overview of the
43         <emphasis remap='B'>Linux-PAM</emphasis> library see the
44         <emphasis>Linux-PAM System Administrators' Guide</emphasis>.
45       </para>
46       <para>
47         It is the purpose of the <emphasis remap='B'>Linux-PAM</emphasis>
48         project to liberate the development of privilege granting software
49         from the development of secure and appropriate authentication schemes.
50         This is accomplished by providing a documented library of functions
51         that an application may use for all forms of user authentication
52         management. This library dynamically loads locally configured
53         authentication modules that actually perform the authentication tasks.
54       </para>
55       <para>
56         From the perspective of an application developer the information
57         contained in the local configuration of the PAM library should not be
58         important. Indeed it is intended that an application treat the
59         functions documented here as a 'black box' that will deal with all
60         aspects of user authentication. 'All aspects' includes user
61         verification, account management, session initialization/termination
62         and also the resetting of passwords
63         (<emphasis>authentication tokens</emphasis>).
64       </para>
65     </section>
66
67     <section id="adg-introduction-synopsis">
68       <title>Synopsis</title>
69       <para>
70         For general applications that wish to use the services provided by
71         <emphasis remap='B'>Linux-PAM</emphasis> the following is a summary
72         of the relevant linking information:
73         <programlisting>
74 #include &lt;security/pam_appl.h&gt;
75
76 cc -o application .... -lpam
77         </programlisting>
78       </para>
79       <para>
80         In addition to <command>libpam</command>, there is a library of
81         miscellaneous functions that make the job of writing
82         <emphasis>PAM-aware</emphasis> applications easier (this library is not
83         covered in the DCE-RFC for PAM and is specific to the Linux-PAM
84         distribution):
85         <programlisting>
86 #include &lt;security/pam_appl.h&gt;
87 #include &lt;security/pam_misc.h&gt;
88
89 cc -o application .... -lpam -lpam_misc
90         </programlisting>
91       </para>
92     </section>
93   </chapter>
94
95   <chapter id="adg-overview">
96     <title>Overview</title>
97     <para>
98       Most service-giving applications are restricted. In other words,
99       their service is not available to all and every prospective client.
100       Instead, the applying client must jump through a number of hoops to
101       convince the serving application that they are authorized to obtain
102       service.
103     </para>
104     <para>
105       The process of <emphasis>authenticating</emphasis> a client is what
106       PAM is designed to manage. In addition to authentication, PAM provides
107       account management, credential management, session management and
108       authentication-token (password changing) management services.  It is
109       important to realize when writing a PAM based application that these
110       services are provided in a manner that is
111       <emphasis remap='B'>transparent</emphasis> to the application. That is
112       to say, when the application is written, no assumptions can be made
113       about <emphasis>how</emphasis> the client will be authenticated.
114     </para>
115     <para>
116       The process of authentication is performed by the PAM library via a
117       call to <function>pam_authenticate()</function>. The return value
118       of this function will indicate whether a named client (the
119       <emphasis>user</emphasis>) has been authenticated. If the PAM library
120       needs to prompt the user for any information, such as their
121       <emphasis>name</emphasis> or a <emphasis>password</emphasis>
122       then it will do so. If the PAM library is configured to authenticate
123       the user using some silent protocol, it will do this too. (This
124       latter case might be via some hardware interface for example.)
125     </para>
126     <para>
127       It is important to note that the application must leave all decisions
128       about when to prompt the user at the discretion of the PAM library.
129     </para>
130     <para>
131       The PAM library, however, must work equally well for different styles
132       of application. Some applications, like the familiar
133       <command>login</command> and <command>passwd</command> are terminal
134       based applications, exchanges of information with the client in
135       these cases is as plain text messages. Graphically based applications,
136       however, have a more sophisticated interface. They generally interact
137       with the user via specially constructed dialogue boxes. Additionally,
138       network based services require that text messages exchanged with the
139       client are specially formatted for automated processing: one such
140       example is <command>ftpd</command> which prefixes each exchanged
141       message with a numeric identifier.
142     </para>
143     <para>
144       The presentation of simple requests to a client is thus something very
145       dependent on the protocol that the serving application will use. In
146       spite of the fact that PAM demands that it drives the whole
147       authentication process, it is not possible to leave such protocol
148       subtleties up to the PAM library.  To overcome this potential problem,
149       the application provides the PAM library with a
150       <emphasis>conversation</emphasis> function.  This function is called
151       from <emphasis>within</emphasis> the PAM library and enables the PAM
152       to directly interact with the client. The sorts of things that this
153       conversation function must be able to do are prompt the user with
154       text and/or obtain textual input from the user for processing by the
155       PAM library. The details of this function are provided in a later
156       section.
157     </para>
158     <para>
159       For example, the conversation function may be called by the PAM
160       library with a request to prompt the user for a password. Its job is
161       to reformat the prompt request into a form that the client will
162       understand. In the case of <command>ftpd</command>, this might involve
163       prefixing the string with the number <command>331</command> and sending
164       the request over the network to a connected client. The conversation
165       function will then obtain any reply and, after extracting the typed
166       password, will return this string of text to the PAM library. Similar
167       concerns need to be addressed in the case of an X-based graphical
168       server.
169     </para>
170     <para>
171       There are a number of issues that need to be addressed when one is
172       porting an existing application to become PAM compliant. A section
173       below has been devoted to this: Porting legacy applications.
174     </para>
175     <para>
176       Besides authentication, PAM provides other forms of management.
177       Session management is provided with calls to
178       <function>pam_open_session()</function> and
179       <function>pam_close_session()</function>. What these functions
180       actually do is up to the local administrator. But typically, they
181       could be used to log entry and exit from the system or for mounting
182       and unmounting the user's home directory. If an application provides
183       continuous service for a period of time, it should probably call
184       these functions, first open after the user is authenticated and then
185       close when the service is terminated.
186     </para>
187     <para>
188       Account management is another area that an application developer
189       should include with a call to <function>pam_acct_mgmt()</function>.
190       This call will perform checks on the good health of the user's account
191       (has it expired etc.). One of the things this function may check is
192       whether the user's authentication token has expired - in such a case the
193       application may choose to attempt to update it with a call to
194       <function>pam_chauthtok()</function>, although some applications
195       are not suited to this task (<command>ftp</command> for example)
196       and in this case the application should deny access to the user.
197     </para>
198     <para>
199       PAM is also capable of setting and deleting the users credentials with
200       the call <function>pam_setcred()</function>. This function should
201       always be called after the user is authenticated and before service
202       is offered to the user. By convention, this should be the last call
203       to the PAM library before the PAM session is opened. What exactly a
204       credential is, is not well defined. However, some examples are given
205       in the glossary below.
206     </para>
207   </chapter>
208
209   <chapter id="adg-interface">
210     <title>
211       The public interface to <emphasis remap='B'>Linux-PAM</emphasis>
212     </title>
213     <para>
214       Firstly, the relevant include file for the
215       <emphasis remap='B'>Linux-PAM</emphasis> library is
216       <function>&lt;security/pam_appl.h&gt;</function>.
217       It contains the definitions for a number of functions. After
218       listing these functions, we collect some guiding remarks for
219       programmers.
220     </para>
221     <section id="adg-interface-by-app-expected">
222       <title>What can be expected by the application</title>
223       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
224        href="pam_start.xml"/>
225       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
226        href="pam_end.xml"/>
227       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
228        href="pam_set_item.xml"/>
229       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
230        href="pam_get_item.xml"/>
231       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
232        href="pam_strerror.xml"/>
233       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
234        href="pam_fail_delay.xml"/>
235       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
236        href="pam_authenticate.xml"/>
237       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
238        href="pam_setcred.xml"/>
239       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
240        href="pam_acct_mgmt.xml"/>
241       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
242        href="pam_chauthtok.xml"/>
243       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
244        href="pam_open_session.xml"/>
245       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
246        href="pam_close_session.xml"/>
247       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
248        href="pam_putenv.xml"/>
249       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
250        href="pam_getenv.xml"/>
251       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
252        href="pam_getenvlist.xml"/>
253     </section>
254     <section id="adg-interface-of-app-expected">
255       <title>What is expected of an application</title>
256       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
257        href="pam_conv.xml"/>
258     </section>
259     <section id="adg-interface-programming-notes">
260       <title>Programming notes</title>
261       <para>
262         Note, all of the authentication service function calls accept the
263         token <emphasis remap='B'>PAM_SILENT</emphasis>, which instructs
264         the modules to not send messages to the application. This token
265         can be logically OR'd with any one of the permitted tokens specific
266         to the individual function calls.
267         <emphasis remap='B'>PAM_SILENT</emphasis> does not override the
268         prompting of the user for passwords etc., it only stops informative
269         messages from being generated.
270       </para>
271     </section>
272   </chapter>
273
274   <chapter id="adg-security">
275     <title>
276       Security issues of <emphasis remap='B'>Linux-PAM</emphasis>
277     </title>
278     <para>
279       PAM, from the perspective of an application, is a convenient API for
280       authenticating users. PAM modules generally have no increased
281       privilege over that possessed by the application that is making use of
282       it. For this reason, the application must take ultimate responsibility
283       for protecting the environment in which PAM operates.
284     </para>
285     <para>
286       A poorly (or maliciously) written application can defeat any
287       <emphasis remap='B'>Linux-PAM</emphasis> module's authentication
288       mechanisms by simply ignoring it's return values. It is the
289       applications task and responsibility to grant privileges and access
290       to services.  The <emphasis remap='B'>Linux-PAM</emphasis> library
291       simply assumes the responsibility of <emphasis>authenticating</emphasis>
292       the user; ascertaining that the user <emphasis>is</emphasis> who they
293       say they are. Care should be taken to anticipate all of the documented
294       behavior of the <emphasis remap='B'>Linux-PAM</emphasis> library
295       functions. A failure to do this will most certainly lead to a future
296       security breach.
297     </para>
298
299     <section id="adg-security-library-calls">
300       <title>Care about standard library calls</title>
301       <para>
302         In general, writers of authorization-granting applications should
303         assume that each module is likely to call any or
304         <emphasis>all</emphasis> 'libc' functions. For 'libc' functions
305         that return pointers to static/dynamically allocated structures
306         (ie. the library allocates the memory and the user is not expected
307         to '<function>free()</function>' it) any module call to this
308         function is likely to corrupt a pointer previously
309         obtained by the application. The application programmer should
310         either re-call such a 'libc' function after a call to the
311         <emphasis remap='B'>Linux-PAM</emphasis> library, or copy the
312         structure contents to some safe area of memory before passing
313         control to the <emphasis remap='B'>Linux-PAM</emphasis> library.
314       </para>
315       <para>
316         Two important function classes that fall into this category are
317         <citerefentry>
318           <refentrytitle>getpwnam</refentrytitle><manvolnum>3</manvolnum>
319         </citerefentry> and <citerefentry>
320           <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
321         </citerefentry>.
322       </para>
323     </section>
324
325     <section id="adg-security-service-name">
326       <title>Choice of a service name</title>
327       <para>
328         When picking the <emphasis>service-name</emphasis> that
329         corresponds to the first entry in the
330         <emphasis remap='B'>Linux-PAM</emphasis> configuration file,
331         the application programmer should <emphasis>avoid</emphasis>
332         the temptation of choosing something related to
333         <varname>argv[0]</varname>. It is a trivial matter for any user
334         to invoke any application on a system under a different name and
335         this should not be permitted to cause a security breach.
336       </para>
337       <para>
338         In general, this is always the right advice if the program is
339         setuid, or otherwise more privileged than the user that invokes
340         it. In some cases, avoiding this advice is convenient, but as an
341         author of such an application, you should consider well the ways
342         in which your program will be installed and used. (Its often the
343         case that programs are not intended to be setuid, but end up
344         being installed that way for convenience. If your program falls
345         into this category, don't fall into the trap of making this mistake.)
346       </para>
347       <para>
348         To invoke some <emphasis>target</emphasis> application by
349         another name, the user may symbolically link the target application
350         with the desired name. To be precise all the user need do is,
351         <command>ln -s /target/application ./preferred_name</command>
352         and then run <command>./preferred_name</command>.
353       </para>
354       <para>
355         By studying the <emphasis remap='B'>Linux-PAM</emphasis>
356         configuration file(s), an attacker can choose the
357         <command>preferred_name</command> to be that of a service enjoying
358         minimal protection; for example a game which uses
359         <emphasis remap='B'>Linux-PAM</emphasis> to restrict access to
360         certain hours of the day.  If the service-name were to be linked
361         to the filename under which the service was invoked, it
362         is clear that the user is effectively in the position of
363         dictating which authentication scheme the service uses. Needless
364         to say, this is not a secure situation.
365       </para>
366       <para>
367         The conclusion is that the application developer should carefully
368         define the service-name of an application. The safest thing is to
369         make it a single hard-wired name.
370       </para>
371     </section>
372
373     <section id="adg-security-conv-function">
374       <title>The conversation function</title>
375       <para>
376         Care should be taken to ensure that the <function>conv()</function>
377         function is robust. Such a function is provided in the library
378         <command>libpam_misc</command> (see
379         <link linkend="adg-libpam-functions">below</link>).
380       </para>
381     </section>
382
383     <section id="adg-security-usre-identity">
384       <title>The identity of the user</title>
385       <para>
386         The <emphasis remap='B'>Linux-PAM</emphasis> modules will need
387         to determine the identity of the user who requests a service,
388         and the identity of the user who grants the service. These two
389         users will seldom be the same. Indeed there is generally a third
390         user identity to be considered, the new (assumed) identity of
391         the user once the service is granted.
392       </para>
393       <para>
394         The need for keeping tabs on these identities is clearly an
395         issue of security. One convention that is actively used by
396         some modules is that the identity of the user requesting a
397         service should be the current <emphasis>UID</emphasis>
398         (userid) of the running process; the identity of the
399         privilege granting user is the <emphasis>EUID</emphasis>
400         (effective userid) of the running process; the identity of
401         the user, under whose name the service will be executed, is
402         given by the contents of the <emphasis>PAM_USER</emphasis>
403         <citerefentry>
404           <refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
405         </citerefentry>. Note, modules can change the values of
406         <emphasis>PAM_USER</emphasis> and <emphasis>PAM_RUSER</emphasis>
407         during any of the <function>pam_*()</function> library calls.
408         For this reason, the application should take care to use the
409         <function>pam_get_item()</function> every time it wishes to
410         establish who the authenticated user is (or will currently be).
411       </para>
412       <para>
413         For network-serving databases and other applications that provide
414         their own security model (independent of the OS kernel) the above
415         scheme is insufficient to identify the requesting user.
416       </para>
417       <para>
418         A more portable solution to storing the identity of the requesting
419         user is to use the <emphasis>PAM_RUSER</emphasis> <citerefentry>
420         <refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
421         </citerefentry>. The application should supply this value before
422         attempting to authenticate the user with
423         <function>pam_authenticate()</function>. How well this name can be
424         trusted will ultimately be at the discretion of the local
425         administrator (who configures PAM for your application) and a
426         selected module may attempt to override the value where it can
427         obtain more reliable data. If an application is unable to determine
428         the identity of the requesting entity/user, it should not call
429         <citerefentry>
430           <refentrytitle>pam_set_item</refentrytitle><manvolnum>3</manvolnum>
431         </citerefentry> to set <emphasis>PAM_RUSER</emphasis>.
432       </para>
433       <para>
434         In addition to the <emphasis>PAM_RUSER</emphasis> item, the
435         application should supply the <emphasis>PAM_RHOST</emphasis>
436         (<emphasis>requesting host</emphasis>) item. As a general rule,
437         the following convention for its value can be assumed:
438         NULL = unknown; localhost = invoked directly from the local system;
439         <emphasis>other.place.xyz</emphasis> = some component of the
440         user's connection originates from this remote/requesting host. At
441         present, PAM has no established convention for indicating whether
442         the application supports a trusted path to communication from
443         this host.
444       </para>
445     </section>
446
447     <section id="adg-security-resources">
448       <title>Sufficient resources</title>
449       <para>
450         Care should be taken to ensure that the proper execution of an
451         application is not compromised by a lack of system resources. If an
452         application is unable to open sufficient files to perform its service,
453         it should fail gracefully, or request additional resources.
454         Specifically, the quantities manipulated by the <citerefentry>
455         <refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum>
456       </citerefentry> family of commands should be taken into consideration.
457       </para>
458       <para>
459         This is also true of conversation prompts. The application should not
460         accept prompts of arbitrary length with out checking for resource
461         allocation failure and dealing with such extreme conditions gracefully
462         and in a mannor that preserves the PAM API. Such tolerance may be
463         especially important when attempting to track a malicious adversary.
464       </para>
465     </section>
466   </chapter>
467
468   <chapter id='adg-libpam_misc'>
469     <title>A library of miscellaneous helper functions</title>
470     <para>
471       To aid the work of the application developer a library of
472       miscellaneous functions is provided.  It is called
473       <command>libpam_miscy</command>, and contains a text based
474       conversation function, and routines for enhancing the standard
475       PAM-environment variable support.
476     </para>
477     <para>
478       The functions, structures and macros, made available by this
479       library can be defined by including
480       <function>&lt;security/pam_misc.h&gt;</function>. It should be
481       noted that this library is specific to
482       <emphasis remap='B'>Linux-PAM</emphasis> and is not referred to in
483       the defining DCE-RFC (see <link linkend="adg-see-also">See also</link>)
484       below.
485     </para>
486     <section id='adg-libpam-functions'>
487       <title>Functions supplied</title>
488       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
489        href="pam_misc_conv.xml"/>
490       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
491        href="pam_misc_paste_env.xml"/>
492       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
493        href="pam_misc_drop_env.xml"/>
494       <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
495        href="pam_misc_setenv.xml"/>
496     </section>
497   </chapter>
498
499   <chapter id='adg-porting'>
500     <title>Porting legacy applications</title>
501     <para>
502       The point of PAM is that the application is not supposed to
503       have any idea how the attached authentication modules will choose
504       to authenticate the user. So all they can do is provide a conversation
505       function that will talk directly to the user(client) on the modules'
506       behalf.
507     </para>
508     <para>
509       Consider the case that you plug a retinal scanner into the login
510       program. In this situation the user would be prompted: "please look
511       into the scanner". No username or password would be needed - all this
512       information could be deduced from the scan and a database lookup. The
513       point is that the retinal scanner is an ideal task for a "module".
514     </para>
515     <para>
516       While it is true that a pop-daemon program is designed with the POP
517       protocol in mind and no-one ever considered attaching a retinal
518       scanner to it, it is also the case that the "clean" PAM'ification of
519       such a daemon would allow for the possibility of a scanner module
520       being be attached to it. The point being that the "standard"
521       pop-authentication protocol(s) [which will be needed to satisfy
522       inflexible/legacy clients] would be supported by inserting an
523       appropriate pam_qpopper module(s).  However, having rewritten popd
524       once in this way any new protocols can be implemented in-situ.
525     </para>
526     <para>
527       One simple test of a ported application would be to insert the
528       <command>pam_permit</command> module and see if the application
529       demands you type a password...  In such a case, <command>xlock</command>
530       would fail to lock the terminal - or would at best be a screen-saver,
531       ftp would give password free access to all etc..  Neither of
532       these is a very secure thing to do, but they do illustrate how
533       much flexibility PAM puts in the hands of the local admin.
534     </para>
535     <para>
536       The key issue, in doing things correctly, is identifying what is part
537       of the authentication procedure (how many passwords etc..) the
538       exchange protocol (prefixes to prompts etc., numbers like 331 in the
539       case of ftpd) and what is part of the service that the application
540       delivers.  PAM really needs to have total control in the
541       authentication "procedure", the conversation function should only
542       deal with reformatting user prompts and extracting responses from raw
543       input.
544     </para>
545   </chapter>
546
547   <chapter id='adg-glossary'>
548     <title>Glossary of PAM related terms</title>
549     <para>
550       The following are a list of terms used within this document.
551     </para>
552     <variablelist>
553       <varlistentry>
554         <term>Authentication token</term>
555         <listitem>
556           <para>
557             Generally, this is a password. However, a user can authenticate
558             him/herself in a variety of ways. Updating the user's
559             authentication token thus corresponds to
560             <emphasis>refreshing</emphasis> the object they use to
561             authenticate themself with the system. The word password is
562             avoided to keep open the possibility that the authentication
563             involves a retinal scan or other non-textual mode of
564             challenge/response.
565           </para>
566         </listitem>
567       </varlistentry>
568       <varlistentry>
569         <term>Credentials</term>
570         <listitem>
571           <para>
572             Having successfully authenticated the user, PAM is able to
573             establish certain characteristics/attributes of the user.
574             These are termed <emphasis>credentials</emphasis>. Examples
575             of which are group memberships to perform privileged tasks
576             with, and <emphasis>tickets</emphasis> in the form of
577             environment variables etc. . Some user-credentials, such as
578             the user's UID and GID (plus default group memberships) are
579             not deemed to be PAM-credentials. It is the responsibility
580             of the application to grant these directly.
581           </para>
582         </listitem>
583       </varlistentry>
584     </variablelist>
585   </chapter>
586
587   <chapter id='adg-example'>
588     <title>An example application</title>
589     <para>
590       To get a flavor of the way a <emphasis remap='B'>Linux-PAM</emphasis>
591       application is written we include the following example. It prompts
592       the user for their password and indicates whether their account
593       is valid on the standard output, its return code also indicates
594       the success (<returnvalue>0</returnvalue> for success;
595       <returnvalue>1</returnvalue> for failure).
596     </para>
597     <programlisting><![CDATA[
598 /*
599   This program was contributed by Shane Watts
600   [modifications by AGM and kukuk]
601
602   You need to add the following (or equivalent) to the
603   /etc/pam.d/check_user file:
604   # check authorization
605   auth       required     pam_unix.so
606   account    required     pam_unix.so
607  */
608
609 #include <security/pam_appl.h>
610 #include <security/pam_misc.h>
611 #include <stdio.h>
612
613 static struct pam_conv conv = {
614     misc_conv,
615     NULL
616 };
617
618 int main(int argc, char *argv[])
619 {
620     pam_handle_t *pamh=NULL;
621     int retval;
622     const char *user="nobody";
623
624     if(argc == 2) {
625         user = argv[1];
626     }
627
628     if(argc > 2) {
629         fprintf(stderr, "Usage: check_user [username]\n");
630         exit(1);
631     }
632
633     retval = pam_start("check_user", user, &conv, &pamh);
634
635     if (retval == PAM_SUCCESS)
636         retval = pam_authenticate(pamh, 0);    /* is user really user? */
637
638     if (retval == PAM_SUCCESS)
639         retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
640
641     /* This is where we have been authorized or not. */
642
643     if (retval == PAM_SUCCESS) {
644         fprintf(stdout, "Authenticated\n");
645     } else {
646         fprintf(stdout, "Not Authenticated\n");
647     }
648
649     if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
650         pamh = NULL;
651         fprintf(stderr, "check_user: failed to release authenticator\n");
652         exit(1);
653     }
654
655     return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
656 }
657 ]]>
658     </programlisting>
659   </chapter>
660
661   <chapter id='adg-files'>
662     <title>Files</title>
663     <variablelist>
664       <varlistentry>
665         <term><filename>/usr/include/security/pam_appl.h</filename></term>
666         <listitem>
667           <para>
668             Header file with interfaces for
669             <emphasis remap='B'>Linux-PAM</emphasis> applications.
670            </para>
671         </listitem>
672       </varlistentry>
673       <varlistentry>
674         <term><filename>/usr/include/security/pam_misc.h</filename></term>
675         <listitem>
676           <para>
677             Header file for useful library functions for making
678             applications easier to write.
679           </para>
680         </listitem>
681       </varlistentry>
682     </variablelist>
683   </chapter>
684
685   <chapter id="adg-see-also">
686     <title>See also</title>
687     <itemizedlist>
688       <listitem>
689         <para>
690           The Linux-PAM System Administrators' Guide.
691         </para>
692       </listitem>
693       <listitem>
694         <para>
695           The Linux-PAM Module Writers' Guide.
696         </para>
697       </listitem>
698       <listitem>
699         <para>
700           The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
701           PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation
702           Request For Comments 86.0, October 1995.
703         </para>
704       </listitem>
705     </itemizedlist>
706   </chapter>
707
708   <chapter id='adg-author'>
709     <title>Author/acknowledgments</title>
710     <para>
711       This document was written by Andrew G. Morgan (morgan@kernel.org)
712       with many contributions from
713       Chris Adams, Peter Allgeyer, Tim Baverstock, Tim Berger, Craig S. Bell,
714       Derrick J. Brashear, Ben Buxton, Seth Chaiklin, Oliver Crow, Chris Dent,
715       Marc Ewing, Cristian Gafton, Emmanuel Galanos, Brad M. Garcia,
716       Eric Hester, Roger Hu, Eric Jacksch, Michael K. Johnson, David Kinchlea,
717       Olaf Kirch, Marcin Korzonek, Thorsten Kukuk, Stephen Langasek,
718       Nicolai Langfeldt, Elliot Lee, Luke Kenneth Casson Leighton,
719       Al Longyear, Ingo Luetkebohle, Marek Michalkiewicz, Robert Milkowski,
720       Aleph One, Martin Pool, Sean Reifschneider, Jan Rekorajski, Erik Troan,
721       Theodore Ts'o, Jeff Uphoff, Myles Uyema, Savochkin Andrey Vladimirovich,
722       Ronald Wahl, David Wood, John Wilmes, Joseph S. D. Yao
723       and Alex O. Yuriev.
724     </para>
725     <para>
726       Thanks are also due to Sun Microsystems, especially to Vipin Samar and
727       Charlie Lai for their advice. At an early stage in the development of
728       <emphasis remap='B'>Linux-PAM</emphasis>, Sun graciously made the
729       documentation for their implementation of PAM available. This act
730       greatly accelerated the development of
731       <emphasis remap='B'>Linux-PAM</emphasis>.
732     </para>
733   </chapter>
734
735   <chapter id='adg-copyright'>
736     <title>Copyright information for this document</title>
737     <programlisting>
738 Copyright (c) 2006 Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
739 Copyright (c) 1996-2002 Andrew G. Morgan &lt;morgan@kernel.org&gt;
740     </programlisting>
741     <para>
742       Redistribution and use in source and binary forms, with or without
743       modification, are permitted provided that the following conditions are
744       met:
745     </para>
746     <programlisting>
747 1. Redistributions of source code must retain the above copyright
748    notice, and the entire permission notice in its entirety,
749    including the disclaimer of warranties.
750
751 2. Redistributions in binary form must reproduce the above copyright
752    notice, this list of conditions and the following disclaimer in the
753    documentation and/or other materials provided with the distribution.
754
755 3. The name of the author may not be used to endorse or promote
756    products derived from this software without specific prior
757    written permission.
758     </programlisting>
759     <para>
760       Alternatively, this product may be distributed under the terms of
761       the GNU General Public License (GPL), in which case the provisions
762       of the GNU GPL are required instead of the above restrictions.
763       (This clause is necessary due to a potential bad interaction between
764       the GNU GPL and the restrictions contained in a BSD-style copyright.)
765     </para>
766     <programlisting>
767 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
768 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
769 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
770 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
771 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
772 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
773 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
774 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
775 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
776 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
777     </programlisting>
778   </chapter>
779 </book>