]> granicus.if.org Git - linux-pam/blob - doc/adg/Linux-PAM_ADG.xml
Relevant BUGIDs:
[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 1.1, 16. June 2009</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 functions
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-user-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         (user ID) of the running process; the identity of the
399         privilege granting user is the <emphasis>EUID</emphasis>
400         (effective user ID) 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 manner 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_misc</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
524       <command>popd</command> once in this way any new protocols can be
525       implemented in-situ.
526     </para>
527     <para>
528       One simple test of a ported application would be to insert the
529       <command>pam_permit</command> module and see if the application
530       demands you type a password...  In such a case, <command>xlock</command>
531       would fail to lock the terminal - or would at best be a screen-saver,
532       ftp would give password free access to all etc..  Neither of
533       these is a very secure thing to do, but they do illustrate how
534       much flexibility PAM puts in the hands of the local admin.
535     </para>
536     <para>
537       The key issue, in doing things correctly, is identifying what is part
538       of the authentication procedure (how many passwords etc..) the
539       exchange protocol (prefixes to prompts etc., numbers like 331 in the
540       case of ftpd) and what is part of the service that the application
541       delivers.  PAM really needs to have total control in the
542       authentication "procedure", the conversation function should only
543       deal with reformatting user prompts and extracting responses from raw
544       input.
545     </para>
546   </chapter>
547
548   <chapter id='adg-glossary'>
549     <title>Glossary of PAM related terms</title>
550     <para>
551       The following are a list of terms used within this document.
552     </para>
553     <variablelist>
554       <varlistentry>
555         <term>Authentication token</term>
556         <listitem>
557           <para>
558             Generally, this is a password. However, a user can authenticate
559             him/herself in a variety of ways. Updating the user's
560             authentication token thus corresponds to
561             <emphasis>refreshing</emphasis> the object they use to
562             authenticate themself with the system. The word password is
563             avoided to keep open the possibility that the authentication
564             involves a retinal scan or other non-textual mode of
565             challenge/response.
566           </para>
567         </listitem>
568       </varlistentry>
569       <varlistentry>
570         <term>Credentials</term>
571         <listitem>
572           <para>
573             Having successfully authenticated the user, PAM is able to
574             establish certain characteristics/attributes of the user.
575             These are termed <emphasis>credentials</emphasis>. Examples
576             of which are group memberships to perform privileged tasks
577             with, and <emphasis>tickets</emphasis> in the form of
578             environment variables etc. . Some user-credentials, such as
579             the user's UID and GID (plus default group memberships) are
580             not deemed to be PAM-credentials. It is the responsibility
581             of the application to grant these directly.
582           </para>
583         </listitem>
584       </varlistentry>
585     </variablelist>
586   </chapter>
587
588   <chapter id='adg-example'>
589     <title>An example application</title>
590     <para>
591       To get a flavor of the way a <emphasis remap='B'>Linux-PAM</emphasis>
592       application is written we include the following example. It prompts
593       the user for their password and indicates whether their account
594       is valid on the standard output, its return code also indicates
595       the success (<returnvalue>0</returnvalue> for success;
596       <returnvalue>1</returnvalue> for failure).
597     </para>
598     <programlisting><![CDATA[
599 /*
600   This program was contributed by Shane Watts
601   [modifications by AGM and kukuk]
602
603   You need to add the following (or equivalent) to the
604   /etc/pam.d/check_user file:
605   # check authorization
606   auth       required     pam_unix.so
607   account    required     pam_unix.so
608  */
609
610 #include <security/pam_appl.h>
611 #include <security/pam_misc.h>
612 #include <stdio.h>
613
614 static struct pam_conv conv = {
615     misc_conv,
616     NULL
617 };
618
619 int main(int argc, char *argv[])
620 {
621     pam_handle_t *pamh=NULL;
622     int retval;
623     const char *user="nobody";
624
625     if(argc == 2) {
626         user = argv[1];
627     }
628
629     if(argc > 2) {
630         fprintf(stderr, "Usage: check_user [username]\n");
631         exit(1);
632     }
633
634     retval = pam_start("check_user", user, &conv, &pamh);
635
636     if (retval == PAM_SUCCESS)
637         retval = pam_authenticate(pamh, 0);    /* is user really user? */
638
639     if (retval == PAM_SUCCESS)
640         retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
641
642     /* This is where we have been authorized or not. */
643
644     if (retval == PAM_SUCCESS) {
645         fprintf(stdout, "Authenticated\n");
646     } else {
647         fprintf(stdout, "Not Authenticated\n");
648     }
649
650     if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
651         pamh = NULL;
652         fprintf(stderr, "check_user: failed to release authenticator\n");
653         exit(1);
654     }
655
656     return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
657 }
658 ]]>
659     </programlisting>
660   </chapter>
661
662   <chapter id='adg-files'>
663     <title>Files</title>
664     <variablelist>
665       <varlistentry>
666         <term><filename>/usr/include/security/pam_appl.h</filename></term>
667         <listitem>
668           <para>
669             Header file with interfaces for
670             <emphasis remap='B'>Linux-PAM</emphasis> applications.
671            </para>
672         </listitem>
673       </varlistentry>
674       <varlistentry>
675         <term><filename>/usr/include/security/pam_misc.h</filename></term>
676         <listitem>
677           <para>
678             Header file for useful library functions for making
679             applications easier to write.
680           </para>
681         </listitem>
682       </varlistentry>
683     </variablelist>
684   </chapter>
685
686   <chapter id="adg-see-also">
687     <title>See also</title>
688     <itemizedlist>
689       <listitem>
690         <para>
691           The Linux-PAM System Administrators' Guide.
692         </para>
693       </listitem>
694       <listitem>
695         <para>
696           The Linux-PAM Module Writers' Guide.
697         </para>
698       </listitem>
699       <listitem>
700         <para>
701           The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
702           PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation
703           Request For Comments 86.0, October 1995.
704         </para>
705       </listitem>
706     </itemizedlist>
707   </chapter>
708
709   <chapter id='adg-author'>
710     <title>Author/acknowledgments</title>
711     <para>
712       This document was written by Andrew G. Morgan (morgan@kernel.org)
713       with many contributions from
714       Chris Adams, Peter Allgeyer, Tim Baverstock, Tim Berger, Craig S. Bell,
715       Derrick J. Brashear, Ben Buxton, Seth Chaiklin, Oliver Crow, Chris Dent,
716       Marc Ewing, Cristian Gafton, Emmanuel Galanos, Brad M. Garcia,
717       Eric Hester, Roger Hu, Eric Jacksch, Michael K. Johnson, David Kinchlea,
718       Olaf Kirch, Marcin Korzonek, Thorsten Kukuk, Stephen Langasek,
719       Nicolai Langfeldt, Elliot Lee, Luke Kenneth Casson Leighton,
720       Al Longyear, Ingo Luetkebohle, Marek Michalkiewicz, Robert Milkowski,
721       Aleph One, Martin Pool, Sean Reifschneider, Jan Rekorajski, Erik Troan,
722       Theodore Ts'o, Jeff Uphoff, Myles Uyema, Savochkin Andrey Vladimirovich,
723       Ronald Wahl, David Wood, John Wilmes, Joseph S. D. Yao
724       and Alex O. Yuriev.
725     </para>
726     <para>
727       Thanks are also due to Sun Microsystems, especially to Vipin Samar and
728       Charlie Lai for their advice. At an early stage in the development of
729       <emphasis remap='B'>Linux-PAM</emphasis>, Sun graciously made the
730       documentation for their implementation of PAM available. This act
731       greatly accelerated the development of
732       <emphasis remap='B'>Linux-PAM</emphasis>.
733     </para>
734   </chapter>
735
736   <chapter id='adg-copyright'>
737     <title>Copyright information for this document</title>
738     <programlisting>
739 Copyright (c) 2006 Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
740 Copyright (c) 1996-2002 Andrew G. Morgan &lt;morgan@kernel.org&gt;
741     </programlisting>
742     <para>
743       Redistribution and use in source and binary forms, with or without
744       modification, are permitted provided that the following conditions are
745       met:
746     </para>
747     <programlisting>
748 1. Redistributions of source code must retain the above copyright
749    notice, and the entire permission notice in its entirety,
750    including the disclaimer of warranties.
751
752 2. Redistributions in binary form must reproduce the above copyright
753    notice, this list of conditions and the following disclaimer in the
754    documentation and/or other materials provided with the distribution.
755
756 3. The name of the author may not be used to endorse or promote
757    products derived from this software without specific prior
758    written permission.
759     </programlisting>
760     <para>
761       Alternatively, this product may be distributed under the terms of
762       the GNU General Public License (GPL), in which case the provisions
763       of the GNU GPL are required instead of the above restrictions.
764       (This clause is necessary due to a potential bad interaction between
765       the GNU GPL and the restrictions contained in a BSD-style copyright.)
766     </para>
767     <programlisting>
768 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
769 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
770 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
771 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
772 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
773 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
774 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
775 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
776 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
777 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
778     </programlisting>
779   </chapter>
780 </book>