Catch up with the current state of -CURRENT, and discuss the differences

between OpenPAM, Linux-PAM and Solaris PAM in some more detail.  Also add
IDs to most sections and their titles, and an appendix listing a sample
conversation function.

Translators: please leave for later, there's still a lot to do.

Sponsored by:	DARPA, NAI Labs
This commit is contained in:
Dag-Erling Smørgrav 2002-06-07 15:45:24 +00:00
parent 70a78a3610
commit a0e5c66ae0
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=13327
2 changed files with 190 additions and 117 deletions

View file

@ -9,13 +9,16 @@ INSTALL_ONLY_COMPRESSED?=
JADEFLAGS+= -V %generate-article-toc% JADEFLAGS+= -V %generate-article-toc%
SRCS= article.sgml pam_app.c pam_module.c SRCS= article.sgml pam_app.c pam_conv.c pam_module.c
CLEANFILES+= pam_app.c pam_module.c CLEANFILES+= pam_app.c pam_conv.c pam_module.c
pam_app.c: su.c pam_app.c: su.c
sed -e '/^[\/ ]\*/d' ${.ALLSRC} >${.TARGET} sed -e '/^[\/ ]\*/d' ${.ALLSRC} >${.TARGET}
pam_conv.c: converse.c
sed -e '/^[\/ ]\*/d' ${.ALLSRC} >${.TARGET}
pam_module.c: pam_unix.c pam_module.c: pam_unix.c
sed -e '/^[\/ ]\*/d' ${.ALLSRC} >${.TARGET} sed -e '/^[\/ ]\*/d' ${.ALLSRC} >${.TARGET}

View file

@ -76,13 +76,13 @@
At the time of this writing, this specification has not yet been At the time of this writing, this specification has not yet been
adopted as a standard.</para> adopted as a standard.</para>
<para>Although this article focuses on FreeBSD's implementation of <para>Although this article focuses primarily on FreeBSD 5.x,
PAM, which is based on Linux-PAM, most of it should be which uses OpenPAM, it should be equally applicable to FreeBSD
applicable to most other operating systems which implement PAM, 4.x, which uses Linux-PAM, and other operating systems such as
including Solaris.</para> Linux and Solaris.</para>
<section> <section id="pam-trademarks">
<title>Trademarks</title> <title id="pam-trademarks.title">Trademarks</title>
<para>Sun, Sun Microsystems and Solaris are trademarks or <para>Sun, Sun Microsystems and Solaris are trademarks or
registered trademarks of Sun Microsystems, Inc.</para> registered trademarks of Sun Microsystems, Inc.</para>
@ -245,8 +245,8 @@
</glosslist> </glosslist>
</section> </section>
<section> <section id="pam-usage-examples">
<title>Usage examples</title> <title id="pam-usage-examples.title">Usage examples</title>
<para>This section aims to illustrate the meanings of some of <para>This section aims to illustrate the meanings of some of
the terms defined above by way of a handful of simple the terms defined above by way of a handful of simple
@ -342,11 +342,14 @@ Welcome to FreeBSD!
<para>The following is FreeBSD's default policy for <para>The following is FreeBSD's default policy for
<literal>sshd</literal>:</para> <literal>sshd</literal>:</para>
<programlisting>sshd auth required pam_nologin.so no_warn <programlisting>
sshd auth required pam_nologin.so no_warn
sshd auth required pam_unix.so no_warn try_first_pass 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 account required pam_unix.so
sshd session required pam_permit.so sshd session required pam_lastlog.so no_fail
sshd password required pam_permit.so</programlisting> sshd password required pam_permit.so
</programlisting>
<itemizedlist> <itemizedlist>
@ -362,19 +365,21 @@ sshd password required pam_permit.so</programlisting>
</listitem> </listitem>
<listitem> <listitem>
<para><filename>pam_nologin.so</filename>, <para><filename>pam_nologin.so</filename>,
<filename>pam_unix.so</filename> and <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 <filename>pam_permit.so</filename> are modules. It is
clear from this example that clear from this example that
<filename>pam_unix.so</filename> and <filename>pam_unix.so</filename> provides at least two
<filename>pam_permit.so</filename> provide at least two facilities (authentication and account
facilities each.</para> management.)</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</section> </section>
</section> </section>
<section> <section id="pam-conventions">
<title>Conventions</title> <title id="pam-conventions.title">Conventions</title>
<para><!--XXX-->This section has not yet been written.</para> <para><!--XXX-->This section has not yet been written.</para>
</section> </section>
@ -401,17 +406,17 @@ sshd password required pam_permit.so</programlisting>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><function>pam_authenticate</function> <para>&man.pam.authenticate.3; authenticates the
authenticates the applicant, usually by requesting applicant, usually by requesting an authentication
an authentication token and comparing it with a token and comparing it with a value stored in a
value stored in a database or obtained from an database or obtained from an authentication
authentication server.</para> server.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><function>pam_setcred</function> establishes <para>&man.pam.setcred.3; establishes account
account credentials such as user ID, group credentials such as user ID, group membership and
membership and resource limits.</para> resource limits.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -428,8 +433,8 @@ sshd password required pam_permit.so</programlisting>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><function>pam_acct_mgmt</function> verifies that <para>&man.pam.acct.mgmt.3; verifies that the
the requested account is available.</para> requested account is available.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -445,17 +450,17 @@ sshd password required pam_permit.so</programlisting>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><function>pam_open_session</function> performs <para>&man.pam.open.session.3; performs tasks
tasks associated with session set-up: add an entry associated with session set-up: add an entry in the
in the <filename>utmp</filename> and <filename>utmp</filename> and
<filename>wtmp</filename> databases, start an SSH <filename>wtmp</filename> databases, start an SSH
agent, etc.</para> agent, etc.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><function>pam_close_session</function> performs <para>&man.pam.close.session.3; performs tasks
tasks associated with session tear-down: add an associated with session tear-down: add an entry in
entry in the <filename>utmp</filename> and the <filename>utmp</filename> and
<filename>wtmp</filename> databases, stop the SSH <filename>wtmp</filename> databases, stop the SSH
agent, etc.</para> agent, etc.</para>
</listitem> </listitem>
@ -474,10 +479,10 @@ sshd password required pam_permit.so</programlisting>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><function>pam_chauthtok</function> changes the <para>&man.pam.chauthtok.3; changes the authentication
authentication token, optionally verifying that it token, optionally verifying that it is sufficiently
is sufficiently hard to guess, has not been used hard to guess, has not been used previously,
previously, etc.</para> etc.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -486,8 +491,8 @@ sshd password required pam_permit.so</programlisting>
</section> </section>
<section> <section id="pam-modules">
<title>Modules</title> <title id="pam-modules.title">Modules</title>
<para>Modules are a very central concept in PAM; after all, <para>Modules are a very central concept in PAM; after all,
they are the <quote>M</quote> in <quote>PAM</quote>. A PAM they are the <quote>M</quote> in <quote>PAM</quote>. A PAM
@ -497,14 +502,44 @@ sshd password required pam_permit.so</programlisting>
authentication facility, for instance, include the UNIX authentication facility, for instance, include the UNIX
password database, NIS, LDAP and Radius.</para> password database, NIS, LDAP and Radius.</para>
<para>FreeBSD groups all facilities for the same mechanism in <section id="pam-module-naming">
one module called <title id="pam-module-naming.title">Module Naming</title>
<literal>pam_<replaceable>mechanism</replaceable>.so</literal> (e.g.
<literal>pam_unix.so</literal>.) The original PAM <para>FreeBSD implements each mechanism in a single module,
implementation, on the other hand, had separate modules for named
each facility, called <literal>pam_<replaceable>mechanism</replaceable>.so</literal>
<literal>pam_<replaceable>mechanism</replaceable>_<replaceable>facility</replaceable>.so</literal> (for instance, <literal>pam_unix.so</literal> for the Unix
(e.g. <literal>pam_unix_auth.so</literal>.)</para> 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 id="pam-module-versioning">
<title 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're not truly versioned, because the number is a
part of the module name and must be included in the
configuration.</para>
</section>
</section> </section>
<section id="pam-chains-policies"> <section id="pam-chains-policies">
@ -513,7 +548,7 @@ sshd password required pam_permit.so</programlisting>
<para>When a server initiates a PAM transaction, the PAM library <para>When a server initiates a PAM transaction, the PAM library
tries to load a policy for the service specified in the tries to load a policy for the service specified in the
<function>pam_start</function> call. The policy specifies how &man.pam.start.3; call. The policy specifies how
authentication requests should be processed, and is defined in authentication requests should be processed, and is defined in
a configuration file. This is the other central concept in a configuration file. This is the other central concept in
PAM: the possibility for the admin to tune the system security PAM: the possibility for the admin to tune the system security
@ -586,8 +621,8 @@ sshd password required pam_permit.so</programlisting>
in the same chain as different, unrelated modules.</para> in the same chain as different, unrelated modules.</para>
</section> </section>
<section> <section id="pam-transactions">
<title>Transactions</title> <title id="pam-transactions.title">Transactions</title>
<para>The lifecycle of a typical PAM transaction is described <para>The lifecycle of a typical PAM transaction is described
below. Note that if this any of these steps fails, the server below. Note that if this any of these steps fails, the server
@ -604,53 +639,51 @@ sshd password required pam_permit.so</programlisting>
</listitem> </listitem>
<listitem> <listitem>
<para>The server calls <function>pam_start</function> to <para>The server calls &man.pam.start.3; to initialize the
initialize the PAM library and specify its service name PAM library and specify its service name and the target
and the target account, and register a suitable account, and register a suitable conversation
conversation function.</para> function.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The server obtains various information relating to the <para>The server obtains various information relating to the
transaction (such as the applicant's user name and the transaction (such as the applicant's user name and the
name of the host the client runs on) and submits it to PAM name of the host the client runs on) and submits it to PAM
using <function>pam_set_item</function>.</para> using &man.pam.set.item.3;.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The server calls <function>pam_authenticate</function> <para>The server calls &man.pam.authenticate.3; to
to authenticate the applicant.</para> authenticate the applicant.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>The server calls <function>pam_acct_mgmt</function> to <para>The server calls &man.pam.acct.mgmt.3; verify that the
verify that the requested account is available and valid. requested account is available and valid. If the password
The <function>pam_acct_mgmt</function> function will is correct but has expired, &man.pam.acct.mgmt.3; will
return <literal>PAM_NEW_AUTHTOK_REQD</literal> if the return <literal>PAM_NEW_AUTHTOK_REQD</literal> instead of
account's password has expired.</para> <literal>PAM_SUCCESS</literal>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>If the previous step returned <para>If the previous step returned
<literal>PAM_NEW_AUTHTOK_REQD</literal>, the server now <literal>PAM_NEW_AUTHTOK_REQD</literal>, the server now
calls <function>pam_chauthtok</function> to force the calls &man.pam.chauthtok.3; to force the client to change
client to change the authentication token for the the authentication token for the requested account.</para>
requested account.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Now that the applicant has been properly <para>Now that the applicant has been properly
authenticated, the server calls authenticated, the server calls &man.pam.setcred.3; to
<function>pam_setcred</function> to establish the establish the credentials of the requested account. It is
credentials of the requested account. It is able to do able to do this because it acts on behalf of the
this because it acts on behalf of the arbitrator, and arbitrator, and holds the arbitrator's credentials.</para>
holds the arbitrator's credentials.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Once the correct credentials have been established, <para>Once the correct credentials have been established,
the server calls <function>pam_open_session</function> to the server calls &man.pam.open.session.3; to set up the
set up the session.</para> session.</para>
</listitem> </listitem>
<listitem> <listitem>
@ -661,15 +694,14 @@ sshd password required pam_permit.so</programlisting>
<listitem> <listitem>
<para>Once the server is done serving the client, it calls <para>Once the server is done serving the client, it calls
<function>pam_close_session</function> to tear down the &man.pam.close.session.3; to tear down the session.</para>
session.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>Finally, the server calls <function>pam_end</function> <para>Finally, the server calls &man.pam.end.3; to notify
to notify the PAM library that it is done and that it can the PAM library that it is done and that it can release
release whatever resources it has allocated in the course whatever resources it has allocated in the course of the
of the transaction.</para> transaction.</para>
</listitem> </listitem>
</orderedlist> </orderedlist>
</section> </section>
@ -679,7 +711,8 @@ sshd password required pam_permit.so</programlisting>
<title id="pam-config.title">PAM Configuration</title> <title id="pam-config.title">PAM Configuration</title>
<section id="pam-config-file-locations"> <section id="pam-config-file-locations">
<title>Location of configuration files</title> <title id="pam-config-file-locations.title">Location of
configuration files</title>
<para>The traditional PAM configuration file is <para>The traditional PAM configuration file is
<filename>/etc/pam.conf</filename>. This file contains all <filename>/etc/pam.conf</filename>. This file contains all
@ -701,20 +734,20 @@ sshd password required pam_permit.so</programlisting>
service, which serves as a fall-back, should come last. The service, which serves as a fall-back, should come last. The
examples in the original PAM paper grouped configuration lines examples in the original PAM paper grouped configuration lines
by facility, and Solaris' stock <filename>pam.conf</filename> by facility, and Solaris' stock <filename>pam.conf</filename>
still does that, but Linux-PAM (and hence FreeBSD) groups still does that, but FreeBSD's stock configuration groups
configuration lines by service. Either way is fine; either configuration lines by service. Either way is fine; either
way makes equal sense.</para> way makes equal sense.</para>
<para>Linux-PAM offers an alternate configuration mechanism, <para>OpenPAM and Linux-PAM offer an alternate configuration
where policies are contained in separate files, named for the mechanism, where policies are contained in separate files,
service they apply to, in <filename>/etc/pam.d/</filename>, named for the service they apply to, in
with only four fields instead of five&mdash;the service name <filename>/etc/pam.d/</filename>, with only four fields
field is omitted. In FreeBSD 5.0, starting from mid-January instead of five&mdash;the service name field is omitted. This
2002, this is the preferred mechanism. Note, however, that if is the preferred mechanism in FreeBSD 5.x.. Note, however,
<filename>/etc/pam.conf</filename> exists, and contains that if <filename>/etc/pam.conf</filename> exists, and
configuration statements for services which do not have a contains configuration statements for services which do not
specific policy in <filename>/etc/pam.d/</filename>, it will have a specific policy in <filename>/etc/pam.d/</filename>, it
be used as a fall-back for these services.</para> will be used as a fall-back for these services.</para>
<para>The great advantage of <filename>/etc/pam.d/</filename> <para>The great advantage of <filename>/etc/pam.d/</filename>
over <filename>/etc/pam.conf</filename> is that it is possible over <filename>/etc/pam.conf</filename> is that it is possible
@ -729,25 +762,35 @@ sshd password required pam_permit.so</programlisting>
<para>This works because the service name is determined from the <para>This works because the service name is determined from the
file name rather than specified in the policy file, so the file name rather than specified in the policy file, so the
same file can be used for arbitrary services.</para> same file can be used for multiple differently-named
services.</para>
<para>One other advantage is that third-party software can <para>One other advantage is that third-party software can
easily install policies for their services without the need to easily install policies for their services without the need to
edit <filename>/etc/pam.conf</filename>.</para> edit <filename>/etc/pam.conf</filename>. True to the FreeBSD
tradition, OpenPAM will even look for policy files in
<filename>/usr/local/etc/pam.d/</filename> if no configuration
for the requested service is present in
<filename>/etc/pam.d/</filename> or
<filename>/etc/pam.conf</filename>.</para>
<para>Whether you use <filename>/etc/pam.conf</filename> or <para>Finally, whichever configuration mechanism you choose, the
<filename>/etc/pam.d/</filename>, the policy for the special <quote>magic</quote> policy <literal>other</literal> is used
service <literal>other</literal> is used as a fall-back for as a fall-back for any service that does not have its own
any service that does not have its own policy.</para> policy.</para>
</section> </section>
<section> <section id="pam-config-breakdown">
<title>Breakdown of a configuration line</title> <title id="pam-config-breakdown.title">Breakdown of a
configuration line</title>
<para>As explained in <xref linkend="pam-config-file-locations">, <para>As explained in the <link
each line in <filename>/etc/pam.conf</filename> consists of four linkend="pam-config-file-locations"
or more fields: the service name, the facility name, the control endterm="pam-config-file-locations.title"></link> section,
flag, the module name, and zero or more module arguments.</para> 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 <para>The service name is generally (though not always) the name
of the application the statement applies to. If you are of the application the statement applies to. If you are
@ -771,19 +814,21 @@ sshd password required pam_permit.so</programlisting>
describing how to interpret the return code from the module. describing how to interpret the return code from the module.
Linux-PAM supports an alternate syntax that lets you specify Linux-PAM supports an alternate syntax that lets you specify
the action to associate with each possible return code, but the action to associate with each possible return code, but
this should be avoided as it is non-standard and requires very this should be avoided as it is non-standard and closely tied
detailed knowledge of the PAM library to use properly.</para> 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>
<section> <section id="pam-policies">
<title>Policies</title> <title id="pam-policies.title">Policies</title>
<para><!--XXX-->This section has not yet been written.</para> <para><!--XXX-->This section has not yet been written.</para>
</section> </section>
</section> </section>
<section id="pam-modules"> <section id="pam-freebsd-modules">
<title id="pam-modules.title">PAM Modules</title> <title id="pam-freebsd-modules.title">FreeBSD PAM Modules</title>
<para><!--XXX-->This section has not yet been written.</para> <para><!--XXX-->This section has not yet been written.</para>
</section> </section>
@ -815,20 +860,28 @@ sshd password required pam_permit.so</programlisting>
</section> </section>
<appendix id="pam-sample-appl"> <appendix id="pam-sample-appl">
<title id="pam-sample-appl.title">Sample PAM application</title> <title id="pam-sample-appl.title">Sample PAM Application</title>
<para>The following is a minimal implementation of &man.su.1; <para>The following is a minimal implementation of &man.su.1;
using PAM. Note that it uses the Linux-PAM-specific using PAM. Note that it uses the OpenPAM-specific
<function>misc_conv</function> conversation function, which is &man.openpam.ttyconv.3; conversation function, which is
prototyped in <filename prototyped in <filename
class="headerfile">security/pam_misc.h</filename>.</para> class="headerfile">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 the <link
linkend="pam-sample-conv"
endterm="pam-sample-conv.title"></link> appendix is a good
starting point, but should not be used in real-world
applications.</para>
<programlisting><inlinegraphic fileref="pam_app.c" <programlisting><inlinegraphic fileref="pam_app.c"
format="linespecific"></programlisting> format="linespecific"></programlisting>
</appendix> </appendix>
<appendix id="pam-sample-module"> <appendix id="pam-sample-module">
<title id="pam-sample-module.title">Sample PAM module</title> <title id="pam-sample-module.title">Sample PAM Module</title>
<para>The following is a minimal implementation of <para>The following is a minimal implementation of
&man.pam.unix.8;, offering only authentication services. It &man.pam.unix.8;, offering only authentication services. It
@ -841,6 +894,23 @@ sshd password required pam_permit.so</programlisting>
format="linespecific"></programlisting> format="linespecific"></programlisting>
</appendix> </appendix>
<appendix id="pam-sample-conv">
<title 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're 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
convesation function can reasonably get.</para>
<programlisting><inlinegraphic fileref="pam_conv.c"
format="linespecific"></programlisting>
</appendix>
<bibliography id="pam-further"> <bibliography id="pam-further">
<title id="pam-further.title">Further Reading</title> <title id="pam-further.title">Further Reading</title>