1326 lines
49 KiB
XML
1326 lines
49 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
|
|
"http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
|
|
<!--
|
|
- Copyright (c) 2001-2003 Networks Associates Technology, Inc.
|
|
- All rights reserved.
|
|
-
|
|
- This software was developed for the FreeBSD Project by ThinkSec AS and
|
|
- Network Associates Laboratories, 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 xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
|
|
<info><title>Pluggable Authentication Modules</title>
|
|
|
|
|
|
<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>
|
|
|
|
<copyright>
|
|
<year>2001</year>
|
|
<year>2002</year>
|
|
<year>2003</year>
|
|
<holder>Networks Associates Technology, Inc.</holder>
|
|
</copyright>
|
|
|
|
<authorgroup>
|
|
<author><personname><firstname>Dag-Erling</firstname><surname>Smørgrav</surname></personname><contrib>Contributed by </contrib></author>
|
|
</authorgroup>
|
|
|
|
<legalnotice xml:id="pam-legalnotice">
|
|
<para>This article was written for the FreeBSD Project by
|
|
ThinkSec AS and Network Associates Laboratories, the Security
|
|
Research Division of Network Associates, Inc. under
|
|
DARPA/SPAWAR contract N66001-01-C-8035 (<quote>CBOSS</quote>),
|
|
as part of the DARPA CHATS research program.</para>
|
|
</legalnotice>
|
|
|
|
<legalnotice xml:id="trademarks" role="trademarks">
|
|
&tm-attrib.freebsd;
|
|
&tm-attrib.linux;
|
|
&tm-attrib.opengroup;
|
|
&tm-attrib.sun;
|
|
&tm-attrib.general;
|
|
</legalnotice>
|
|
|
|
<releaseinfo>$FreeBSD$</releaseinfo>
|
|
</info>
|
|
|
|
<section xml:id="pam-intro">
|
|
<title xml: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 primarily on FreeBSD 5.x,
|
|
which uses OpenPAM, it should be equally applicable to FreeBSD
|
|
4.x, which uses Linux-PAM, and other operating systems such as
|
|
Linux and &solaris;.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-terms">
|
|
<title xml:id="pam-terms.title">Terms and conventions</title>
|
|
|
|
<section xml:id="pam-definitions">
|
|
<title xml: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 xml:id="pam-usage-examples">
|
|
<title xml:id="pam-usage-examples.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_login_access.so
|
|
sshd account required pam_unix.so
|
|
sshd session required pam_lastlog.so no_fail
|
|
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>,
|
|
<filename>pam_login_access.so</filename>,
|
|
<filename>pam_lastlog.so</filename> and
|
|
<filename>pam_permit.so</filename> are modules. It is
|
|
clear from this example that
|
|
<filename>pam_unix.so</filename> provides at least two
|
|
facilities (authentication and account
|
|
management.)</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
</section>
|
|
|
|
<!--
|
|
<section id="pam-conventions">
|
|
<title id="pam-conventions.title">Conventions</title>
|
|
|
|
<para>This section has not yet been written.</para>
|
|
</section>
|
|
-->
|
|
</section>
|
|
|
|
<section xml:id="pam-essentials">
|
|
<title xml:id="pam-essentials.title">PAM Essentials</title>
|
|
|
|
<section xml:id="pam-facilities-primitives">
|
|
<title xml: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>&man.pam.authenticate.3; 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>&man.pam.setcred.3; 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>&man.pam.acct.mgmt.3; 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>&man.pam.open.session.3; 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>&man.pam.close.session.3; 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>&man.pam.chauthtok.3; 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 xml:id="pam-modules">
|
|
<title xml:id="pam-modules.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>
|
|
|
|
<section xml:id="pam-module-naming">
|
|
<title xml:id="pam-module-naming.title">Module Naming</title>
|
|
|
|
<para>FreeBSD implements each mechanism in a single module,
|
|
named
|
|
<literal>pam_<replaceable>mechanism</replaceable>.so</literal>
|
|
(for instance, <literal>pam_unix.so</literal> for the &unix;
|
|
mechanism.) Other implementations sometimes have separate
|
|
modules for separate facilities, and include the facility
|
|
name as well as the mechanism name in the module name. To
|
|
name one example, &solaris; has a
|
|
<literal>pam_dial_auth.so.1</literal> module which is
|
|
commonly used to authenticate dialup users.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-module-versioning">
|
|
<title xml:id="pam-module-versioning.title">Module Versioning</title>
|
|
|
|
<para>FreeBSD's original PAM implementation, based on
|
|
Linux-PAM, did not use version numbers for PAM modules.
|
|
This would commonly cause problems with legacy applications,
|
|
which might be linked against older versions of the system
|
|
libraries, as there was no way to load a matching version of
|
|
the required modules.</para>
|
|
|
|
<para>OpenPAM, on the other hand, looks for modules that have
|
|
the same version number as the PAM library (currently 2),
|
|
and only falls back to an unversioned module if no versioned
|
|
module could be loaded. Thus legacy modules can be provided
|
|
for legacy applications, while allowing new (or newly built)
|
|
applications to take advantage of the most recent
|
|
modules.</para>
|
|
|
|
<para>Although &solaris; PAM modules commonly have a version
|
|
number, they are not truly versioned, because the number is a
|
|
part of the module name and must be included in the
|
|
configuration.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section xml:id="pam-chains-policies">
|
|
<title xml: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
|
|
&man.pam.start.3; 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>binding</literal></term>
|
|
<listitem>
|
|
<para>If the module succeeds and no earlier module in the
|
|
chain has failed, the chain is immediately terminated
|
|
and the request is granted. If the module fails, the
|
|
rest of the chain is executed, but the request is
|
|
ultimately denied.</para>
|
|
|
|
<para>This control flag was introduced by Sun in &solaris; 9
|
|
(&sunos; 5.9), and is also supported by OpenPAM.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>required</literal></term>
|
|
<listitem>
|
|
<para>If the module succeeds, the rest of the chain is
|
|
executed, and the request is granted unless some other
|
|
module fails. If the module fails, the rest of the
|
|
chain is also executed, but the request is ultimately
|
|
denied.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>requisite</literal></term>
|
|
<listitem>
|
|
<para>If the module succeeds, the rest of the chain is
|
|
executed, and the request is granted unless some other
|
|
module fails. If the module fails, the chain is
|
|
immediately terminated and the request is denied.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>sufficient</literal></term>
|
|
<listitem>
|
|
<para>If the module succeeds and no earlier module in the
|
|
chain has failed, the chain is immediately terminated
|
|
and the request is granted. If the module fails, the
|
|
module is ignored and the rest of the chain is
|
|
executed.</para>
|
|
|
|
<para>As the semantics of this flag may be somewhat
|
|
confusing, especially when it is used for the last
|
|
module in a chain, it is recommended that the
|
|
<literal>binding</literal> control flag be used instead
|
|
if the implementation supports it.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>optional</literal></term>
|
|
<listitem>
|
|
<para>The module is executed, but its result is ignored.
|
|
If all modules in a chain are marked
|
|
<literal>optional</literal>, all requests will always be
|
|
granted.</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>binding</literal> or
|
|
<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 xml:id="pam-transactions">
|
|
<title xml:id="pam-transactions.title">Transactions</title>
|
|
|
|
<para>The lifecycle of a typical PAM transaction is described
|
|
below. Note that if 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—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 &man.pam.start.3; 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 &man.pam.set.item.3;.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The server calls &man.pam.authenticate.3; to
|
|
authenticate the applicant.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The server calls &man.pam.acct.mgmt.3; to verify that the
|
|
requested account is available and valid. If the password
|
|
is correct but has expired, &man.pam.acct.mgmt.3; will
|
|
return <literal>PAM_NEW_AUTHTOK_REQD</literal> instead of
|
|
<literal>PAM_SUCCESS</literal>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If the previous step returned
|
|
<literal>PAM_NEW_AUTHTOK_REQD</literal>, the server now
|
|
calls &man.pam.chauthtok.3; 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 &man.pam.setcred.3; 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 &man.pam.open.session.3; to set up the
|
|
session.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The server now performs whatever service the client
|
|
requested—for instance, provide the applicant with a
|
|
shell.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Once the server is done serving the client, it calls
|
|
&man.pam.close.session.3; to tear down the session.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Finally, the server calls &man.pam.end.3; 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 xml:id="pam-config">
|
|
<title xml:id="pam-config.title">PAM Configuration</title>
|
|
|
|
<section xml:id="pam-config-file">
|
|
<title xml:id="pam-config-file.title">PAM policy files</title>
|
|
|
|
<section xml:id="pam-config-pam.conf">
|
|
<title xml:id="pam-config-pam.conf.title">The
|
|
<filename>/etc/pam.conf</filename> file</title>
|
|
|
|
<para>The traditional PAM policy 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. The examples in the original PAM paper grouped
|
|
configuration lines by facility, and the &solaris; stock
|
|
<filename>pam.conf</filename> still does that, but FreeBSD's
|
|
stock configuration groups configuration lines by service.
|
|
Either way is fine; either way makes equal sense.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-config-pam.d">
|
|
<title xml:id="pam-config-pam.d.title">The
|
|
<filename>/etc/pam.d</filename> directory</title>
|
|
|
|
<para>OpenPAM and Linux-PAM support an alternate configuration
|
|
mechanism, which is the preferred mechanism in FreeBSD. In
|
|
this scheme, each policy is contained in a separate file
|
|
bearing the name of the service it applies to. These files
|
|
are stored in <filename>/etc/pam.d/</filename>.</para>
|
|
|
|
<para>These per-service policy files have only four fields
|
|
instead of <filename>pam.conf</filename>'s five: the service
|
|
name field is omitted. Thus, instead of the sample
|
|
<filename>pam.conf</filename> line from the previous
|
|
section, one would have the following line in
|
|
<filename>/etc/pam.d/login</filename>:</para>
|
|
|
|
<programlisting>auth required pam_nologin.so no_warn</programlisting>
|
|
|
|
<para>As a consequence of this simplified syntax, 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 multiple differently-named
|
|
services.</para>
|
|
|
|
<para>Since each service's policy is stored in a separate
|
|
file, the <filename>pam.d</filename> mechanism also makes it
|
|
very easy to install additional policies for third-party
|
|
software packages.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-config-file-order">
|
|
<title xml:id="pam-config-file-order.title">The policy search
|
|
order</title>
|
|
|
|
<para>As we have seen above, PAM policies can be found in a
|
|
number of places. What happens if policies for the same
|
|
service exist in multiple places?</para>
|
|
|
|
<para>It is essential to understand that PAM's configuration
|
|
system is centered on chains.<!-- XXX --></para>
|
|
|
|
</section>
|
|
</section>
|
|
|
|
<section xml:id="pam-config-breakdown">
|
|
<title xml:id="pam-config-breakdown.title">Breakdown of a
|
|
configuration line</title>
|
|
|
|
<para>As explained in <xref linkend="pam-config-file"/>, 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 <xref linkend="pam-facilities-primitives"/>.</para>
|
|
|
|
<para>Likewise, the control flag is one of the four keywords
|
|
described in <xref linkend="pam-chains-policies"/>,
|
|
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 closely tied
|
|
in with the way Linux-PAM dispatches service calls (which
|
|
differs greatly from the way &solaris; and OpenPAM do it.)
|
|
Unsurprisingly, OpenPAM does not support this syntax.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-policies">
|
|
<title xml:id="pam-policies.title">Policies</title>
|
|
|
|
<para>To configure PAM correctly, it is essential to understand
|
|
how policies are interpreted.</para>
|
|
|
|
<para>When an application calls &man.pam.start.3;, the PAM
|
|
library loads the policy for the specified service and
|
|
constructs four module chains (one for each facility.) If one
|
|
or more of these chains are empty, the corresponding chains
|
|
from the policy for the <literal>other</literal> service are
|
|
substituted.</para>
|
|
|
|
<para>When the application later calls one of the six PAM
|
|
primitives, the PAM library retrieves the chain for the
|
|
corresponding facility and calls the appropriate service
|
|
function in each module listed in the chain, in the order in
|
|
which they were listed in the configuration. After each call
|
|
to a service function, the module type and the error code
|
|
returned by the service function are used to determine what
|
|
happens next. With a few exceptions, which we discuss below,
|
|
the following table applies:</para>
|
|
|
|
<table>
|
|
<title>PAM chain execution summary</title>
|
|
<tgroup cols="4">
|
|
<colspec colwidth="1*" colname="type"/>
|
|
<colspec colwidth="1*" colname="success"/>
|
|
<colspec colwidth="1*" colname="ignore"/>
|
|
<colspec colwidth="1*" colname="other"/>
|
|
<thead>
|
|
<row>
|
|
<entry colname="type"/>
|
|
<entry colname="success"><literal>PAM_SUCCESS</literal></entry>
|
|
<entry colname="ignore"><literal>PAM_IGNORE</literal></entry>
|
|
<entry colname="other"><literal>other</literal></entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="type">binding</entry>
|
|
<entry colname="success">if (!fail) break;</entry>
|
|
<entry colname="ignore">-</entry>
|
|
<entry colname="other">fail = true;</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="type">required</entry>
|
|
<entry colname="success">-</entry>
|
|
<entry colname="ignore">-</entry>
|
|
<entry colname="other">fail = true;</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="type">requisite</entry>
|
|
<entry colname="success">-</entry>
|
|
<entry colname="ignore">-</entry>
|
|
<entry colname="other">fail = true; break;</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="type">sufficient</entry>
|
|
<entry colname="success">if (!fail) break;</entry>
|
|
<entry colname="ignore">-</entry>
|
|
<entry colname="other">-</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="type">optional</entry>
|
|
<entry colname="success">-</entry>
|
|
<entry colname="ignore">-</entry>
|
|
<entry colname="other">-</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>If <varname>fail</varname> is true at the end of a chain,
|
|
or when a <quote>break</quote> is reached, the dispatcher
|
|
returns the error code returned by the first module that
|
|
failed. Otherwise, it returns
|
|
<literal>PAM_SUCCESS</literal>.</para>
|
|
|
|
<para>The first exception of note is that the error code
|
|
<literal>PAM_NEW_AUTHTOK_REQD</literal> is treated like a
|
|
success, except that if no module failed, and at least one
|
|
module returned <literal>PAM_NEW_AUTHTOK_REQD</literal>, the
|
|
dispatcher will return
|
|
<literal>PAM_NEW_AUTHTOK_REQD</literal>.</para>
|
|
|
|
<para>The second exception is that &man.pam.setcred.3; treats
|
|
<literal>binding</literal> and
|
|
<literal>sufficient</literal> modules as if they were
|
|
<literal>required</literal>.</para>
|
|
|
|
<para>The third and final exception is that
|
|
&man.pam.chauthtok.3; runs the entire chain twice (once for
|
|
preliminary checks and once to actually set the password), and
|
|
in the preliminary phase it treats
|
|
<literal>binding</literal> and
|
|
<literal>sufficient</literal> modules as if they were
|
|
<literal>required</literal>.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section xml:id="pam-freebsd-modules">
|
|
<title xml:id="pam-freebsd-modules.title">FreeBSD PAM Modules</title>
|
|
|
|
<section xml:id="pam-modules-deny">
|
|
<title xml:id="pam-modules-deny.title">&man.pam.deny.8;</title>
|
|
|
|
<para>The &man.pam.deny.8; module is one of the simplest modules
|
|
available; it responds to any request with
|
|
<literal>PAM_AUTH_ERR</literal>. It is useful for quickly
|
|
disabling a service (add it to the top of every chain), or for
|
|
terminating chains of <literal>sufficient</literal>
|
|
modules.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-echo">
|
|
<title xml:id="pam-modules-echo.title">&man.pam.echo.8;</title>
|
|
|
|
<para>The &man.pam.echo.8; module simply passes its arguments to
|
|
the conversation function as a
|
|
<literal>PAM_TEXT_INFO</literal> message. It is mostly useful
|
|
for debugging, but can also serve to display messages such as
|
|
<quote>Unauthorized access will be prosecuted</quote> before
|
|
starting the authentication procedure.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-exec">
|
|
<title xml:id="pam-modules-exec.title">&man.pam.exec.8;</title>
|
|
|
|
<para>The &man.pam.exec.8; module takes its first argument to be
|
|
the name of a program to execute, and the remaining arguments
|
|
are passed to that program as command-line arguments. One
|
|
possible application is to use it to run a program at login
|
|
time which mounts the user's home directory.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-ftpusers">
|
|
<title xml:id="pam-modules-ftpusers.title">&man.pam.ftpusers.8;</title>
|
|
|
|
<para>The &man.pam.ftpusers.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-group">
|
|
<title xml:id="pam-modules-group.title">&man.pam.group.8;</title>
|
|
|
|
<para>The &man.pam.group.8; module accepts or rejects applicants
|
|
on the basis of their membership in a particular file group
|
|
(normally <literal>wheel</literal> for &man.su.1;). It is
|
|
primarily intended for maintaining the traditional behavior
|
|
of BSD &man.su.1;, but has many other uses, such as excluding
|
|
certain groups of users from a particular service.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-guest">
|
|
<title xml:id="pam-modules-guest.title">&man.pam.guest.8;</title>
|
|
|
|
<para>The &man.pam.guest.8; module allows guest logins using
|
|
fixed login names. Various requirements can be placed on the
|
|
password, but the default behavior is to allow any password
|
|
as long as the login name is that of a guest account. The
|
|
&man.pam.guest.8; module can easily be used to implement
|
|
anonymous FTP logins.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-krb5">
|
|
<title xml:id="pam-modules-krb5.title">&man.pam.krb5.8;</title>
|
|
|
|
<para>The &man.pam.krb5.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-ksu">
|
|
<title xml:id="pam-modules-ksu.title">&man.pam.ksu.8;</title>
|
|
|
|
<para>The &man.pam.ksu.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-lastlog">
|
|
<title xml:id="pam-modules-lastlog.title">&man.pam.lastlog.8;</title>
|
|
|
|
<para>The &man.pam.lastlog.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-login-access">
|
|
<title xml:id="pam-modules-login-access.title">&man.pam.login.access.8;</title>
|
|
|
|
<para>The &man.pam.login.access.8; module provides an
|
|
implementation of the account management primitive which
|
|
enforces the login restrictions specified in the
|
|
&man.login.access.5; table.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-nologin">
|
|
<title xml:id="pam-modules-nologin.title">&man.pam.nologin.8;</title>
|
|
|
|
<para>The &man.pam.nologin.8; module refuses non-root logins
|
|
when <filename>/var/run/nologin</filename> exists. This file
|
|
is normally created by &man.shutdown.8; when less than five
|
|
minutes remain until the scheduled shutdown time.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-opie">
|
|
<title xml:id="pam-modules-opie.title">&man.pam.opie.8;</title>
|
|
|
|
<para>The &man.pam.opie.8; module implements the &man.opie.4;
|
|
authentication method. The &man.opie.4; system is a
|
|
challenge-response mechanism where the response to each
|
|
challenge is a direct function of the challenge and a
|
|
passphrase, so the response can be easily computed <quote>just
|
|
in time</quote> by anyone possessing the passphrase,
|
|
eliminating the need for password lists. Moreover, since
|
|
&man.opie.4; never reuses a challenge that has been correctly
|
|
answered, it is not vulnerable to replay attacks.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-opieaccess">
|
|
<title xml:id="pam-modules-opieaccess.title">&man.pam.opieaccess.8;</title>
|
|
|
|
<para>The &man.pam.opieaccess.8; module is a companion module to
|
|
&man.pam.opie.8;. Its purpose is to enforce the restrictions
|
|
codified in &man.opieaccess.5;, which regulate the conditions
|
|
under which a user who would normally authenticate herself
|
|
using &man.opie.4; is allowed to use alternate methods. This
|
|
is most often used to prohibit the use of password
|
|
authentication from untrusted hosts.</para>
|
|
|
|
<para>In order to be effective, the &man.pam.opieaccess.8;
|
|
module must be listed as <literal>requisite</literal>
|
|
immediately after a <literal>sufficient</literal> entry for
|
|
&man.pam.opie.8;, and before any other modules, in the
|
|
<literal>auth</literal> chain.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-passwdqc">
|
|
<title xml:id="pam-modules-passwdqc.title">&man.pam.passwdqc.8;</title>
|
|
|
|
<para>The &man.pam.passwdqc.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-permit">
|
|
<title xml:id="pam-modules-permit.title">&man.pam.permit.8;</title>
|
|
|
|
<para>The &man.pam.permit.8; module is one of the simplest
|
|
modules available; it responds to any request with
|
|
<literal>PAM_SUCCESS</literal>. It is useful as a placeholder
|
|
for services where one or more chains would otherwise be
|
|
empty.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-radius">
|
|
<title xml:id="pam-modules-radius.title">&man.pam.radius.8;</title>
|
|
|
|
<para>The &man.pam.radius.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-rhosts">
|
|
<title xml:id="pam-modules-rhosts.title">&man.pam.rhosts.8;</title>
|
|
|
|
<para>The &man.pam.rhosts.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-rootok">
|
|
<title xml:id="pam-modules-rootok.title">&man.pam.rootok.8;</title>
|
|
|
|
<para>The &man.pam.rootok.8; module reports success if and only
|
|
if the real user id of the process calling it (which is
|
|
assumed to be run by the applicant) is 0. This is useful for
|
|
non-networked services such as &man.su.1; or &man.passwd.1;,
|
|
to which the <literal>root</literal> should have automatic
|
|
access.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-securetty">
|
|
<title xml:id="pam-modules-securetty.title">&man.pam.securetty.8;</title>
|
|
|
|
<para>The &man.pam.securetty.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-self">
|
|
<title xml:id="pam-modules-self.title">&man.pam.self.8;</title>
|
|
|
|
<para>The &man.pam.self.8; module reports success if and only if
|
|
the names of the applicant matches that of the target account.
|
|
It is most useful for non-networked services such as
|
|
&man.su.1;, where the identity of the applicant can be easily
|
|
verified.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-ssh">
|
|
<title xml:id="pam-modules-ssh.title">&man.pam.ssh.8;</title>
|
|
|
|
<para>The &man.pam.ssh.8; module provides both authentication
|
|
and session services. The authentication service allows users
|
|
who have passphrase-protected SSH secret keys in their
|
|
<filename>~/.ssh</filename> directory to authenticate
|
|
themselves by typing their passphrase. The session service
|
|
starts &man.ssh-agent.1; and preloads it with the keys that
|
|
were decrypted in the authentication phase. This feature is
|
|
particularly useful for local logins, whether in X (using
|
|
&man.xdm.1; or another PAM-aware X login manager) or at the
|
|
console.</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-tacplus">
|
|
<title xml:id="pam-modules-tacplus.title">&man.pam.tacplus.8;</title>
|
|
|
|
<para>The &man.pam.tacplus.8; module</para>
|
|
</section>
|
|
|
|
<section xml:id="pam-modules-unix">
|
|
<title xml:id="pam-modules-unix.title">&man.pam.unix.8;</title>
|
|
|
|
<para>The &man.pam.unix.8; module implements traditional &unix;
|
|
password authentication, using &man.getpwnam.3; to obtain the
|
|
target account's password and compare it with the one provided
|
|
by the applicant. It also provides account management
|
|
services (enforcing account and password expiration times) and
|
|
password-changing services. This is probably the single most
|
|
useful module, as the great majority of admins will want to
|
|
maintain historical behavior for at least some
|
|
services.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section xml:id="pam-appl-prog">
|
|
<title xml: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 xml:id="pam-module-prog">
|
|
<title xml:id="pam-module-prog.title">PAM Module Programming</title>
|
|
|
|
<para><!--XXX-->This section has not yet been written.</para>
|
|
</section>
|
|
|
|
<appendix xml:id="pam-sample-appl">
|
|
<title xml: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 OpenPAM-specific
|
|
&man.openpam.ttyconv.3; conversation function, which is
|
|
prototyped in <filename>security/openpam.h</filename>. If you wish
|
|
build this application on a system with a different PAM library,
|
|
you will have to provide your own conversation function. A
|
|
robust conversation function is surprisingly difficult to
|
|
implement; the one presented in <xref linkend="pam-sample-conv"/> is a good
|
|
starting point, but should not be used in real-world
|
|
applications.</para>
|
|
|
|
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="su.c" parse="text"/></programlisting>
|
|
</appendix>
|
|
|
|
<appendix xml:id="pam-sample-module">
|
|
<title xml:id="pam-sample-module.title">Sample PAM Module</title>
|
|
|
|
<para>The following is a minimal implementation of
|
|
&man.pam.unix.8;, offering only authentication services. It
|
|
should build and run with most PAM implementations, but takes
|
|
advantage of OpenPAM extensions if available: note the use of
|
|
&man.pam.get.authtok.3;, which enormously simplifies prompting
|
|
the user for a password.</para>
|
|
|
|
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.c" parse="text"/></programlisting>
|
|
</appendix>
|
|
|
|
<appendix xml:id="pam-sample-conv">
|
|
<title xml:id="pam-sample-conv.title">Sample PAM Conversation
|
|
Function</title>
|
|
|
|
<para>The conversation function presented below is a greatly
|
|
simplified version of OpenPAM's &man.openpam.ttyconv.3;. It is
|
|
fully functional, and should give the reader a good idea of how
|
|
a conversation function should behave, but it is far too simple
|
|
for real-world use. Even if you are not using OpenPAM, feel free
|
|
to download the source code and adapt &man.openpam.ttyconv.3; to
|
|
your uses; we believe it to be as robust as a tty-oriented
|
|
conversation function can reasonably get.</para>
|
|
|
|
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="converse.c" parse="text"/></programlisting>
|
|
</appendix>
|
|
|
|
<bibliography xml:id="pam-further">
|
|
<info><title xml: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>
|
|
</info>
|
|
|
|
<bibliodiv>
|
|
<title>Papers</title>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://www.sun.com/software/solaris/pam/pam.external.pdf">
|
|
Making Login Services Independent of Authentication
|
|
Technologies</link></citetitle>
|
|
<authorgroup>
|
|
<author><personname><surname>Samar</surname><firstname>Vipin</firstname></personname></author>
|
|
<author><personname><surname>Lai</surname><firstname>Charlie</firstname></personname></author>
|
|
</authorgroup>
|
|
<orgname>Sun Microsystems</orgname>
|
|
</biblioentry>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://www.opengroup.org/pubs/catalog/p702.htm">X/Open
|
|
Single Sign-on Preliminary Specification</link></citetitle>
|
|
<orgname>The Open Group</orgname>
|
|
<biblioid class="isbn">1-85912-144-6</biblioid>
|
|
<pubdate>June 1997</pubdate>
|
|
</biblioentry>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://www.kernel.org/pub/linux/libs/pam/pre/doc/current-draft.txt">
|
|
Pluggable Authentication Modules</link></citetitle>
|
|
<author><personname><surname>Morgan</surname><firstname>Andrew</firstname><othername role="mi">G.</othername></personname></author>
|
|
<pubdate>1999-10-06</pubdate>
|
|
</biblioentry>
|
|
</bibliodiv>
|
|
|
|
<bibliodiv>
|
|
<title>User Manuals</title>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://www.sun.com/software/solaris/pam/pam.admin.pdf">PAM
|
|
Administration</link></citetitle>
|
|
<orgname>Sun Microsystems</orgname>
|
|
</biblioentry>
|
|
</bibliodiv>
|
|
|
|
<bibliodiv>
|
|
<title>Related Web pages</title>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://openpam.sourceforge.net/">OpenPAM homepage</link></citetitle>
|
|
<author><personname><surname>Smørgrav</surname><firstname>Dag-Erling</firstname></personname></author>
|
|
<orgname>ThinkSec AS</orgname>
|
|
</biblioentry>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://www.kernel.org/pub/linux/libs/pam/">Linux-PAM homepage</link></citetitle>
|
|
<author><personname><surname>Morgan</surname><firstname>Andrew</firstname><othername role="mi">G.</othername></personname></author>
|
|
</biblioentry>
|
|
|
|
<biblioentry>
|
|
<citetitle><link xlink:href="http://wwws.sun.com/software/solaris/pam/">Solaris PAM homepage</link></citetitle>
|
|
<orgname>Sun Microsystems</orgname>
|
|
</biblioentry>
|
|
</bibliodiv>
|
|
</bibliography>
|
|
</article>
|