<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
%man;
]>

<!--
  - Copyright (c) 2001,2002 Networks Associates Technologies, Inc.
  - All rights reserved.
  -
  - This software was developed for the FreeBSD Project by ThinkSec AS and
  - NAI Labs, the Security Research Division of Network Associates, Inc.
  - under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
  - DARPA CHATS research program.
  -
  - Redistribution and use in source and binary forms, with or without
  - modification, are permitted provided that the following conditions
  - are met:
  - 1. Redistributions of source code must retain the above copyright
  -    notice, this list of conditions and the following disclaimer.
  - 2. Redistributions in binary form must reproduce the above copyright
  -    notice, this list of conditions and the following disclaimer in the
  -    documentation and/or other materials provided with the distribution.
  - 3. The name of the author may not be used to endorse or promote
  -    products derived from this software without specific prior written
  -    permission.
  -
  - THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  - ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  - SUCH DAMAGE.
  -->

<article>
  <articleinfo>
    <title>Pluggable Authentication Modules</title>

    <pubdate>$FreeBSD$</pubdate>

    <abstract>
      <para>This article describes the underlying principles and
        mechanisms of the Pluggable Authentication Modules (PAM)
        library, and explains how to configure PAM, how to integrate
        PAM into applications, and how to write PAM modules.</para>
    </abstract>

    <authorgroup>
      <author>
	<firstname>Dag-Erling</firstname>
	<surname>Sm&oslash;rgrav</surname>
	<contrib>Contributed by </contrib>
      </author>
    </authorgroup>
  </articleinfo>

  <section id="pam-intro">
    <title id="pam-intro.title">Introduction</title>

    <para>The Pluggable Authentication Modules (PAM) library is a
      generalized API for authentication-related services which allows
      a system administrator to add new authentication methods simply
      by installing new PAM modules, and to modify authentication
      policies by editing configuration files.</para>

    <para>PAM was defined and developed in 1995 by Vipin Samar and
      Charlie Lai of Sun Microsystems, and has not changed much since.
      In 1997, the Open Group published the X/Open Single Sign-on
      (XSSO) preliminary specification, which standardized the PAM API
      and added extensions for single (or rather integrated) sign-on.
      At the time of this writing, this specification has not yet been
      adopted as a standard.</para>

    <para>Although this article focuses on FreeBSD's implementation of
      PAM, which is based on Linux-PAM, most of it should be
      applicable to most other operating systems which implement PAM,
      including Solaris.</para>

    <section>
      <title>Trademarks</title>

      <para>Sun, Sun Microsystems and Solaris are trademarks or
        registered trademarks of Sun Microsystems, Inc.</para>

      <para>UNIX and The Open Group are trademarks or registered
        trademarks of The Open Group.</para>

      <para>All other brand or product names mentioned in this
        document may be trademarks or registered trademarks of their
        respective owners.</para>
    </section>
  </section>

  <section id="pam-terms">
    <title id="pam-terms.title">Terms and conventions</title>

    <section id="pam-definitions">
      <title id="pam-definitions.title">Definitions</title>

      <para>The terminology surrounding PAM is rather confused.
        Neither Samar and Lai's original paper nor the XSSO
        specification made any attempt at formally defining terms for
        the various actors and entities involved in PAM, and the terms
        that they do use (but do not define) are sometimes misleading
        and ambiguous.  The first attempt at establishing a consistent
        and unambiguous terminology was a whitepaper written by Andrew
        G. Morgan (author of Linux-PAM) in 1999.  While Morgan's
        choice of terminology was a huge leap forward, it is in this
        author's opinion by no means perfect.  What follows is an
        attempt, heavily inspired by Morgan, to define precise and
        unambiguous terms for all actors and entities involved in
        PAM.</para>

      <glosslist>
        <glossentry>
          <glossterm>account</glossterm>
	  <glossdef>
	    <para>The set of credentials the applicant is requesting
	      from the arbitrator.</para>
	  </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>applicant</glossterm>
	  <glossdef>
	    <para>The user or entity requesting authentication.</para>
          </glossdef>
        </glossentry>

        <glossentry>
          <glossterm>arbitrator</glossterm>
	  <glossdef>
	    <para>The user or entity who has the privileges necessary
	      to verify the applicant's credentials and the authority
	      to grant or deny the request.</para>
	  </glossdef>
        </glossentry>

	<glossentry>
	  <glossterm>chain</glossterm>
	  <glossdef>
	    <para>A sequence of modules that will be invoked in
	      response to a PAM request.  The chain includes
	      information about the order in which to invoke the
	      modules, what arguments to pass to them, and how to
	      interpret the results.</para>
	  </glossdef>
	</glossentry>

        <glossentry>
          <glossterm>client</glossterm>
	  <glossdef>
	    <para>The application responsible for initiating an
	      authentication request on behalf of the applicant and
	      for obtaining the necessary authentication information
	      from him.</para>
	  </glossdef>
        </glossentry>

	<glossentry>
	  <glossterm>facility</glossterm>
	  <glossdef>
	    <para>One of the four basic groups of functionality
	      provided by PAM: authentication, account management,
	      session management and authentication token
	      update.</para>
	  </glossdef>
	</glossentry>

	<glossentry>
	  <glossterm>module</glossterm>
	  <glossdef>
	    <para>A collection of one or more related functions
	      implementing a particular authentication facility,
	      gathered into a single (normally dynamically loadable)
	      binary file and identified by a single name.</para>
	  </glossdef>
	</glossentry>

	<glossentry>
	  <glossterm>policy</glossterm>
	  <glossdef>
	    <para>The complete set of configuration statements
	      describing how to handle PAM requests for a particular
	      service.  A policy normally consists of four chains, one
	      for each facility, though some services do not use all
	      four facilities.</para>
	  </glossdef>
	</glossentry>

        <glossentry>
          <glossterm>server</glossterm>
	  <glossdef>
	    <para>The application acting on behalf of the arbitrator
	      to converse with the client, retrieve authentication
	      information, verify the applicant's credentials and
	      grant or deny requests.</para>
	  </glossdef>
        </glossentry>

	<glossentry>
	  <glossterm>service</glossterm>
	  <glossdef>
	    <para>A class of servers providing similar or related
	      functionality and requiring similar authentication.  PAM
	      policies are defined on a per-service basis, so all
	      servers that claim the same service name will be subject
	      to the same policy.</para>
	  </glossdef>
	</glossentry>

	<glossentry>
	  <glossterm>session</glossterm>
	  <glossdef>
	    <para>The context within which service is rendered to the
	      applicant by the server.  One of PAM's four facilities,
	      session management, is concerned exclusively with
	      setting up and tearing down this context.</para>
	  </glossdef>
	</glossentry>

	<glossentry>
	  <glossterm>token</glossterm>
	  <glossdef>
	    <para>A chunk of information associated with the account,
	      such as a password or passphrase, which the applicant
	      must provide to prove his identity.</para>
	  </glossdef>
	</glossentry>

	<glossentry>
	  <glossterm>transaction</glossterm>
	  <glossdef>
	    <para>A sequence of requests from the same applicant to
	      the same instance of the same server, beginning with
	      authentication and session set-up and ending with
	      session tear-down.</para>
	  </glossdef>
	</glossentry>
      </glosslist>
    </section>

    <section>
      <title>Usage examples</title>

      <para>This section aims to illustrate the meanings of some of
        the terms defined above by way of a handful of simple
        examples.</para>

      <section>
        <title>Client and server are one</title>

	<para>This simple example shows <literal>alice</literal>
	  &man.su.1;'ing to <literal>root</literal>.</para>

<screen>&prompt.user; <userinput>whoami</userinput>
alice
&prompt.user; <userinput>ls -l `which su`</userinput>
-r-sr-xr-x  1 root  wheel  10744 Dec  6 19:06 /usr/bin/su
&prompt.user; <userinput>su -</userinput>
Password: <userinput>xi3kiune</userinput>
&prompt.root; whoami
root
</screen>

	<itemizedlist>
	  <listitem>
	    <para>The applicant is <literal>alice</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>The account is <literal>root</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>The &man.su.1; process is both client and
	      server.</para>
	  </listitem>
	  <listitem>
	    <para>The authentication token is
	    <literal>xi3kiune</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>The arbitrator is <literal>root</literal>, which is
	      why &man.su.1; is setuid <literal>root</literal>.</para>
	  </listitem>
	</itemizedlist>
      </section>

      <section>
        <title>Client and server are separate</title>

	<para>The example below shows <literal>eve</literal> try to
	  initiate an &man.ssh.1; connection to
	  <literal>login.example.com</literal>, ask to log in as
	  <literal>bob</literal>, and succeed.  Bob should have chosen
	  a better password!</para>

<screen>&prompt.user; <userinput>whoami</userinput>
eve
&prompt.user; <userinput>ssh bob@login.example.com</userinput>
bob@login.example.com's password: <userinput>god</userinput>
Last login: Thu Oct 11 09:52:57 2001 from 192.168.0.1
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
        The Regents of the University of California.  All rights reserved.
FreeBSD 4.4-STABLE (LOGIN) #4: Tue Nov 27 18:10:34 PST 2001

Welcome to FreeBSD!
&prompt.user;</screen>

	<itemizedlist>
	  <listitem>
	    <para>The applicant is <literal>eve</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>The client is Eve's &man.ssh.1; process.</para>
	  </listitem>
	  <listitem>
	    <para>The server is the &man.sshd.8; process on
	      <literal>login.example.com</literal></para>
	  </listitem>
	  <listitem>
	    <para>The account is <literal>bob</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>The authentication token is
	    <literal>god</literal>.</para>
	  </listitem>
	  <listitem>
	    <para>Although this is not shown in this example, the
	      arbitrator is <literal>root</literal>.</para>
	  </listitem>
	</itemizedlist>
      </section>

      <section>
        <title>Sample policy</title>

	<para>The following is FreeBSD's default policy for
	  <literal>sshd</literal>:</para>

<programlisting>sshd    auth    required        pam_nologin.so  no_warn
sshd    auth    required        pam_unix.so     no_warn try_first_pass
sshd    account required        pam_unix.so
sshd    session required        pam_permit.so
sshd    password required       pam_permit.so</programlisting>


	<itemizedlist>
	  <listitem>
            <para>This policy applies to the <literal>sshd</literal>
              service (which is not necessarily restricted to the
              &man.sshd.8; server.)</para>
	  </listitem>
	  <listitem>
	    <para><literal>auth</literal>, <literal>account</literal>,
	      <literal>session</literal> and
	      <literal>password</literal> are facilities.</para>
	  </listitem>
	  <listitem>
	    <para><filename>pam_nologin.so</filename>,
	      <filename>pam_unix.so</filename> and
	      <filename>pam_permit.so</filename> are modules.  It is
	      clear from this example that
	      <filename>pam_unix.so</filename> and
	      <filename>pam_permit.so</filename> provide at least two
	      facilities each.</para>
	  </listitem>
	</itemizedlist>
      </section>
    </section>

    <section>
      <title>Conventions</title>

      <para><!--XXX-->This section has not yet been written.</para>
    </section>
  </section>

  <section id="pam-essentials">
    <title id="pam-essentials.title">PAM Essentials</title>

    <section id="pam-facilities-primitives">
      <title id="pam-facilities-primitives.title">Facilities and
        primitives</title>

      <para>The PAM API offers six different authentication primitives
        grouped in four facilities, which are described below.</para>

      <variablelist>
        <varlistentry>
	  <term><literal>auth</literal></term>
	  <listitem>
	    <para><emphasis>Authentication.</emphasis> This facility
	      concerns itself with authenticating the applicant and
	      establishing the account credentials.  It provides two
	      primitives:</para>

	    <itemizedlist>
	      <listitem>
	        <para><function>pam_authenticate</function>
	          authenticates the applicant, usually by requesting
	          an authentication token and comparing it with a
	          value stored in a database or obtained from an
	          authentication server.</para>
	      </listitem>

	      <listitem>
	        <para><function>pam_setcred</function> establishes
	          account credentials such as user ID, group
	          membership and resource limits.</para>
	      </listitem>
	    </itemizedlist>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>account</literal></term>
	  <listitem>
	    <para><emphasis>Account management.</emphasis> This
	      facility handles non-authentication-related issues of
	      account availability, such as access restrictions based
	      on the time of day or the server's work load.  It
	      provides a single primitive:</para>

	    <itemizedlist>
	      <listitem>
	        <para><function>pam_acct_mgmt</function> verifies that
	          the requested account is available.</para>
	      </listitem>
	    </itemizedlist>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>session</literal></term>
	  <listitem>
	    <para><emphasis>Session management.</emphasis> This
	      facility handles tasks associated with session set-up
	      and tear-down, such as login accounting.  It provides
	      two primitives:</para>

	    <itemizedlist>
	      <listitem>
	        <para><function>pam_open_session</function> performs
	          tasks associated with session set-up: add an entry
	          in the <filename>utmp</filename> and
	          <filename>wtmp</filename> databases, start an SSH
	          agent, etc.</para>
	      </listitem>

	      <listitem>
	        <para><function>pam_close_session</function> performs
	          tasks associated with session tear-down: add an
	          entry in the <filename>utmp</filename> and
	          <filename>wtmp</filename> databases, stop the SSH
	          agent, etc.</para>
	      </listitem>
	    </itemizedlist>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>password</literal></term>
	  <listitem>
	    <para><emphasis>Password management.</emphasis> This
	      facility is used to change the authentication token
	      associated with an account, either because it has
	      expired or because the user wishes to change it.  It
	      provides a single primitive:</para>

	    <itemizedlist>
	      <listitem>
	        <para><function>pam_chauthtok</function> changes the
	          authentication token, optionally verifying that it
	          is sufficiently hard to guess, has not been used
	          previously, etc.</para>
	      </listitem>
	    </itemizedlist>
	  </listitem>
	</varlistentry>
      </variablelist>

    </section>

    <section>
      <title>Modules</title>

      <para>Modules are a very central concept in PAM; after all,
        they are the <quote>M</quote> in <quote>PAM</quote>.  A PAM
        module is a self-contained piece of program code that
        implements the primitives in one or more facilities for one
        particular mechanism; possible mechanisms for the
        authentication facility, for instance, include the UNIX
        password database, NIS, LDAP and Radius.</para>

      <para>FreeBSD groups all facilities for the same mechanism in
        one module called
	<literal>pam_<replaceable>mechanism</replaceable>.so</literal> (e.g.
	<literal>pam_unix.so</literal>.)  The original PAM
        implementation, on the other hand, had separate modules for
        each facility, called
        <literal>pam_<replaceable>mechanism</replaceable>_<replaceable>facility</replaceable>.so</literal>
	(e.g. <literal>pam_unix_auth.so</literal>.)</para>
    </section>

    <section id="pam-chains-policies">
      <title id="pam-chains-policies.title">Chains and
        policies</title>

      <para>When a server initiates a PAM transaction, the PAM library
        tries to load a policy for the service specified in the
        <function>pam_start</function> call.  The policy specifies how
        authentication requests should be processed, and is defined in
        a configuration file.  This is the other central concept in
        PAM: the possibility for the admin to tune the system security
        policy (in the wider sense of the word) simply by editing a
        text file.</para>

      <para>A policy consists of four chains, one for each of the four
        PAM facilities.  Each chain is a sequence of configuration
        statements, each specifying a module to invoke, some
        (optional) parameters to pass to the module, and a control
        flag that describes how to interpret the return code from the
        module.</para>

      <para>Understanding the control flags is essential to
        understanding PAM configuration files.  There are four
        different control flags:</para>

      <variablelist>
        <varlistentry>
	  <term><literal>required</literal></term>
	  <listitem>
	    <para>Success is required, but the chain continues no
	      matter what this module returns, so that later modules
	      can override it.</para>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>requisite</literal></term>
	  <listitem>
	    <para>A negative result from this module will immediately
	      terminate the chain and deny the request.</para>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>sufficient</literal></term>
	  <listitem>
	    <para>A positive result from this module will immediately
	      terminate the chain and grant the request.  On failure,
	      the chain continues.</para>
	  </listitem>
	</varlistentry>

        <varlistentry>
	  <term><literal>optional</literal></term>
	  <listitem>
	    <para>A negative result from this module will be
	      ignored.</para>
	  </listitem>
	</varlistentry>
      </variablelist>

      <para>When a server invokes one of the six PAM primitives, PAM
        retrieves the chain for the facility the primitive belongs to,
        and invokes each of the modules listed in the chain, in the
        order they are listed, until it reaches the end, or determines
        that no further processing is necessary (either because a
        <literal>sufficient</literal> module succeeded, or because a
        <literal>requisite</literal> module failed.)  The request is
        granted if and only if at least one module was invoked, and
        all non-optional modules succeeded.</para>

      <para>Note that it is possible, though not very common, to have
        the same module listed several times in the same chain.  For
        instance, a module that looks up user names and passwords in a
        directory server could be invoked multiple times with
        different parameters specifying different directory servers to
        contact.  PAM treat different occurrences of the same module
        in the same chain as different, unrelated modules.</para>
    </section>

    <section>
      <title>Transactions</title>

      <para>The lifecycle of a typical PAM transaction is described
        below.  Note that if this any of these steps fails, the server
        should report a suitable error message to the client and abort
        the transaction.</para>

      <orderedlist>
        <listitem>
	  <para>If necessary, the server obtains arbitrator
	    credentials through a mechanism independent of
	    PAM&mdash;most commonly by virtue of having been started
	    by <literal>root</literal>, or of being setuid
	    <literal>root</literal>.</para>
	</listitem>

        <listitem>
	  <para>The server calls <function>pam_start</function> to
	    initialize the PAM library and specify its service name
	    and the target account, and register a suitable
	    conversation function.</para>
	</listitem>

	<listitem>
	  <para>The server obtains various information relating to the
	    transaction (such as the applicant's user name and the
	    name of the host the client runs on) and submits it to PAM
	    using <function>pam_set_item</function>.</para>
	</listitem>

	<listitem>
	  <para>The server calls <function>pam_authenticate</function>
	    to authenticate the applicant.</para>
	</listitem>

	<listitem>
	  <para>The server calls <function>pam_acct_mgmt</function> to
	    verify that the requested account is available and valid.
	    The <function>pam_acct_mgmt</function> function will
	    return <literal>PAM_NEW_AUTHTOK_REQD</literal> if the
	    account's password has expired.</para>
	</listitem>

	<listitem>
	  <para>If the previous step returned
	    <literal>PAM_NEW_AUTHTOK_REQD</literal>, the server now
	    calls <function>pam_chauthtok</function> to force the
	    client to change the authentication token for the
	    requested account.</para>
	</listitem>

	<listitem>
	  <para>Now that the applicant has been properly
	    authenticated, the server calls
	    <function>pam_setcred</function> to establish the
	    credentials of the requested account.  It is able to do
	    this because it acts on behalf of the arbitrator, and
	    holds the arbitrator's credentials.</para>
	</listitem>

	<listitem>
	  <para>Once the correct credentials have been established,
	    the server calls <function>pam_open_session</function> to
	    set up the session.</para>
	</listitem>

	<listitem>
	  <para>The server now performs whatever service the client
	    requested&mdash;for instance, provide the applicant with a
	    shell.</para>
	</listitem>

	<listitem>
	  <para>Once the server is done serving the client, it calls
	    <function>pam_close_session</function> to tear down the
	    session.</para>
	</listitem>

	<listitem>
	  <para>Finally, the server calls <function>pam_end</function>
	    to notify the PAM library that it is done and that it can
	    release whatever resources it has allocated in the course
	    of the transaction.</para>
	</listitem>
      </orderedlist>
    </section>
  </section>

  <section id="pam-config">
    <title id="pam-config.title">PAM Configuration</title>

    <section id="pam-config-file-locations">
      <title>Location of configuration files</title>

      <para>The traditional PAM configuration file is
        <filename>/etc/pam.conf</filename>.  This file contains all
        the PAM policies for your system.  Each line of the file
        describes one step in a chain, as shown below:</para>

<programlisting>login   auth    required        pam_nologin.so  no_warn</programlisting>

      <para>The fields are, in order: service name, facility name,
        control flag, module name, and module arguments.  Any
        additional fields are interpreted as additional module
        arguments.</para>

      <para>A separate chain is constructed for each service /
        facility pair, so while the order in which lines for the same
        service and facility appear is significant, the order in which
        the individual services and facilities are listed is
        not&mdash;except that entries for the <literal>other</literal>
        service, which serves as a fall-back, should come last.  The
        examples in the original PAM paper grouped configuration lines
        by facility, and Solaris' stock <filename>pam.conf</filename>
        still does that, but Linux-PAM (and hence FreeBSD) groups
        configuration lines by service.  Either way is fine; either
        way makes equal sense.</para>

      <para>Linux-PAM offers an alternate configuration mechanism,
        where policies are contained in separate files, named for the
        service they apply to, in <filename>/etc/pam.d/</filename>,
        with only four fields instead of five&mdash;the service name
        field is omitted.  In FreeBSD 5.0, starting from mid-January
        2002, this is the preferred mechanism.  Note, however, that if
        <filename>/etc/pam.conf</filename> exists, and contains
        configuration statements for services which do not have a
        specific policy in <filename>/etc/pam.d/</filename>, it will
        be used as a fall-back for these services.</para>

      <para>The great advantage of <filename>/etc/pam.d/</filename>
        over <filename>/etc/pam.conf</filename> is that it is possible
        to use the same policy for multiple services by linking each
        service name to a same policy file.  For instance, to use the
        same policy for the <literal>su</literal> and
        <literal>sudo</literal> services, one could do as
        follows:</para>

<screen>&prompt.root; <userinput>cd /etc/pam.d</userinput>
&prompt.root; <userinput>ln -s su sudo</userinput></screen>

      <para>This works because the service name is determined from the
        file name rather than specified in the policy file, so the
        same file can be used for arbitrary services.</para>

      <para>One other advantage is that third-party software can
        easily install policies for their services without the need to
        edit <filename>/etc/pam.conf</filename>.</para>

      <para>Whether you use <filename>/etc/pam.conf</filename> or
        <filename>/etc/pam.d/</filename>, the policy for the special
        service <literal>other</literal> is used as a fall-back for
        any service that does not have its own policy.</para>
    </section>

    <section>
      <title>Breakdown of a configuration line</title>

      <para>As explained in <xref linkend="pam-config-file-locations">,
	each line in <filename>/etc/pam.conf</filename> consists of four
	or more fields: the service name, the facility name, the control
	flag, the module name, and zero or more module arguments.</para>

      <para>The service name is generally (though not always) the name
        of the application the statement applies to.  If you are
        unsure, refer to the individual application's documentation to
        determine what service name it uses.</para>

      <para>Note that if you use <filename>/etc/pam.d/</filename>
        instead of <filename>/etc/pam.conf</filename>, the service
        name is specified by the name of the policy file, and omitted
        from the actual configuration lines, which then start with the
        facility name.</para>

      <para>The facility is one of the four facility keywords
        described in the <link linkend="pam-facilities-primitives"
        endterm="pam-facilities-primitives.title"></link>
        section.</para>

      <para>Likewise, the control flag is one of the four keywords
        described in the <link linkend="pam-chains-policies"
        endterm="pam-chains-policies.title"></link> section,
        describing how to interpret the return code from the module.
        Linux-PAM supports an alternate syntax that lets you specify
        the action to associate with each possible return code, but
        this should be avoided as it is non-standard and requires very
        detailed knowledge of the PAM library to use properly.</para>
    </section>

    <section>
      <title>Policies</title>

      <para><!--XXX-->This section has not yet been written.</para>
    </section>
  </section>

  <section id="pam-modules">
    <title id="pam-modules.title">PAM Modules</title>

    <para><!--XXX-->This section has not yet been written.</para>
  </section>

  <section id="pam-appl-prog">
    <title id="pam-appl-prog.title">PAM Application Programming</title>

    <para><!--XXX-->This section has not yet been written.</para>

    <!--
    
      Note that while the original PAM paper includes a sample PAM
      application that calls pam_open_session() before pam_setcred(),
      the Linux-PAM documentation states that pam_setcred() must be
      called first, which makes more sense.

      Also note that the example in the paper calls setgid(),
      initgroups() and setuid() itself rather than rely on
      pam_setcred() to do it.
      
      -->
    
  </section>

  <section id="pam-module-prog">
    <title id="pam-module-prog.title">PAM Module Programming</title>

    <para><!--XXX-->This section has not yet been written.</para>
  </section>

  <appendix id="pam-sample-appl">
    <title id="pam-sample-appl.title">Sample PAM application</title>

    <para>The following is a minimal implementation of &man.su.1;
      using PAM.  Note that it uses the Linux-PAM-specific
      <function>misc_conv</function> conversation function, which is
      prototyped in <filename
      class="headerfile">security/pam_misc.h</filename>.</para>
    
<programlisting><inlinegraphic fileref="pam_app.c"
  format="linespecific"></programlisting>
  </appendix>

  <appendix id="pam-sample-module">
    <title id="pam-sample-module.title">Sample PAM module</title>

    <para><!--XXX-->This section has not yet been written.</para>
  </appendix>

  <bibliography id="pam-further">
    <title id="pam-further.title">Further Reading</title>

    <abstract>
      <para>This is a list of documents relevant to PAM and related
        issues.  It is by no means complete.</para>
    </abstract>

    <bibliodiv>
      <title>Papers</title>

      <biblioentry>
	<title><ulink
	  url="http://www.sun.com/software/solaris/pam/pam.external.pdf">
	  Making Login Services Independent of Authentication
	  Technologies</ulink></title>

	<authorgroup>
	  <author>
	    <surname>Samar</surname>

	    <firstname>Vipin</firstname>
	  </author>

	  <author>
	    <surname>Lai</surname>

	    <firstname>Charlie</firstname>
	  </author>
	</authorgroup>

	<orgname>Sun Microsystems</orgname>

	<!-- the original PAM whitepaper from Sun -->
      </biblioentry>

      <biblioentry>
	<title><ulink
	  url="http://www.opengroup.org/pubs/catalog/p702.htm">X/Open
	  Single Sign-on Preliminary Specification</ulink></title>

	<orgname>The Open Group</orgname>

	<isbn>1-85912-144-6</isbn>

	<pubdate>June 1997</pubdate>

	<!-- (Open Group members can get the PDF, others will have
	to register to download the text version or buy the paper
	version) -->
      </biblioentry>

      <biblioentry>
	<title><ulink
	  url="http://www.kernel.org/pub/linux/libs/pam/pre/doc/current-draft.txt">
	  Pluggable Authentication Modules</ulink></title>

	<author>
	  <surname>Morgan</surname>

	  <firstname>Andrew</firstname>

	  <othername>G.</othername>
	</author>

	<pubdate>October 6, 1999</pubdate>
      </biblioentry>
    </bibliodiv>

    <bibliodiv>
      <title>User Manuals</title>

      <biblioentry>
	<title><ulink
	  url="http://www.sun.com/software/solaris/pam/pam.admin.pdf">PAM
	  Administration</ulink></title>
	<orgname>Sun Microsystems</orgname>

	<!-- an introduction to configuring and using PAM, from Sun
	-->
      </biblioentry>
    </bibliodiv>

    <bibliodiv>
      <title>Related Web pages</title>

      <biblioentry>
	<title><ulink url="http://openpam.sourceforge.net/">OpenPAM at
	  Source Forge</ulink></title>

	<author>
	  <lastname>Sm&oslash;rgrav</lastname>

	  <firstname>Dag-Erling</firstname>
	</author>
      </biblioentry>
    </bibliodiv>
  </bibliography>
</article>
