|
Packit |
7e982e |
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
Packit |
7e982e |
<book id="adg">
|
|
Packit |
7e982e |
<bookinfo>
|
|
Packit |
7e982e |
<title>The Linux-PAM Application Developers' Guide</title>
|
|
Packit |
7e982e |
<authorgroup>
|
|
Packit |
7e982e |
<author>
|
|
Packit |
7e982e |
<firstname>Andrew G.</firstname>
|
|
Packit |
7e982e |
<surname>Morgan</surname>
|
|
Packit |
7e982e |
<email>morgan@kernel.org</email>
|
|
Packit |
7e982e |
</author>
|
|
Packit |
7e982e |
<author>
|
|
Packit |
7e982e |
<firstname>Thorsten</firstname>
|
|
Packit |
7e982e |
<surname>Kukuk</surname>
|
|
Packit |
7e982e |
<email>kukuk@thkukuk.de</email>
|
|
Packit |
7e982e |
</author>
|
|
Packit |
7e982e |
</authorgroup>
|
|
Packit |
7e982e |
<releaseinfo>Version 1.1.2, 31. August 2010</releaseinfo>
|
|
Packit |
7e982e |
<abstract>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
This manual documents what an application developer needs to know
|
|
Packit |
7e982e |
about the <emphasis remap='B'>Linux-PAM</emphasis> library. It
|
|
Packit |
7e982e |
describes how an application might use the
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> library to authenticate
|
|
Packit |
7e982e |
users. In addition it contains a description of the functions
|
|
Packit |
7e982e |
to be found in <filename>libpam_misc</filename> library, that can
|
|
Packit |
7e982e |
be used in general applications. Finally, it contains some comments
|
|
Packit |
7e982e |
on PAM related security issues for the application developer.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</abstract>
|
|
Packit |
7e982e |
</bookinfo>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id="adg-introduction">
|
|
Packit |
7e982e |
<title>Introduction</title>
|
|
Packit |
7e982e |
<section id="adg-introduction-description">
|
|
Packit |
7e982e |
<title>Description</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
(Pluggable Authentication Modules for Linux) is a library that enables
|
|
Packit |
7e982e |
the local system administrator to choose how individual applications
|
|
Packit |
7e982e |
authenticate users. For an overview of the
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> library see the
|
|
Packit |
7e982e |
<emphasis>Linux-PAM System Administrators' Guide</emphasis>.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
It is the purpose of the <emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
project to liberate the development of privilege granting software
|
|
Packit |
7e982e |
from the development of secure and appropriate authentication schemes.
|
|
Packit |
7e982e |
This is accomplished by providing a documented library of functions
|
|
Packit |
7e982e |
that an application may use for all forms of user authentication
|
|
Packit |
7e982e |
management. This library dynamically loads locally configured
|
|
Packit |
7e982e |
authentication modules that actually perform the authentication tasks.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
From the perspective of an application developer the information
|
|
Packit |
7e982e |
contained in the local configuration of the PAM library should not be
|
|
Packit |
7e982e |
important. Indeed it is intended that an application treat the
|
|
Packit |
7e982e |
functions documented here as a 'black box' that will deal with all
|
|
Packit |
7e982e |
aspects of user authentication. 'All aspects' includes user
|
|
Packit |
7e982e |
verification, account management, session initialization/termination
|
|
Packit |
7e982e |
and also the resetting of passwords
|
|
Packit |
7e982e |
(<emphasis>authentication tokens</emphasis>).
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-introduction-synopsis">
|
|
Packit |
7e982e |
<title>Synopsis</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
For general applications that wish to use the services provided by
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> the following is a summary
|
|
Packit |
7e982e |
of the relevant linking information:
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
#include <security/pam_appl.h>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
cc -o application .... -lpam
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
In addition to <command>libpam</command>, there is a library of
|
|
Packit |
7e982e |
miscellaneous functions that make the job of writing
|
|
Packit |
7e982e |
<emphasis>PAM-aware</emphasis> applications easier (this library is not
|
|
Packit |
7e982e |
covered in the DCE-RFC for PAM and is specific to the Linux-PAM
|
|
Packit |
7e982e |
distribution):
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
#include <security/pam_appl.h>
|
|
Packit |
7e982e |
#include <security/pam_misc.h>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
cc -o application .... -lpam -lpam_misc
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id="adg-overview">
|
|
Packit |
7e982e |
<title>Overview</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Most service-giving applications are restricted. In other words,
|
|
Packit |
7e982e |
their service is not available to all and every prospective client.
|
|
Packit |
7e982e |
Instead, the applying client must jump through a number of hoops to
|
|
Packit |
7e982e |
convince the serving application that they are authorized to obtain
|
|
Packit |
7e982e |
service.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The process of <emphasis>authenticating</emphasis> a client is what
|
|
Packit |
7e982e |
PAM is designed to manage. In addition to authentication, PAM provides
|
|
Packit |
7e982e |
account management, credential management, session management and
|
|
Packit |
7e982e |
authentication-token (password changing) management services. It is
|
|
Packit |
7e982e |
important to realize when writing a PAM based application that these
|
|
Packit |
7e982e |
services are provided in a manner that is
|
|
Packit |
7e982e |
<emphasis remap='B'>transparent</emphasis> to the application. That is
|
|
Packit |
7e982e |
to say, when the application is written, no assumptions can be made
|
|
Packit |
7e982e |
about <emphasis>how</emphasis> the client will be authenticated.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The process of authentication is performed by the PAM library via a
|
|
Packit |
7e982e |
call to <function>pam_authenticate()</function>. The return value
|
|
Packit |
7e982e |
of this function will indicate whether a named client (the
|
|
Packit |
7e982e |
<emphasis>user</emphasis>) has been authenticated. If the PAM library
|
|
Packit |
7e982e |
needs to prompt the user for any information, such as their
|
|
Packit |
7e982e |
<emphasis>name</emphasis> or a <emphasis>password</emphasis>
|
|
Packit |
7e982e |
then it will do so. If the PAM library is configured to authenticate
|
|
Packit |
7e982e |
the user using some silent protocol, it will do this too. (This
|
|
Packit |
7e982e |
latter case might be via some hardware interface for example.)
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
It is important to note that the application must leave all decisions
|
|
Packit |
7e982e |
about when to prompt the user at the discretion of the PAM library.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The PAM library, however, must work equally well for different styles
|
|
Packit |
7e982e |
of application. Some applications, like the familiar
|
|
Packit |
7e982e |
<command>login</command> and <command>passwd</command> are terminal
|
|
Packit |
7e982e |
based applications, exchanges of information with the client in
|
|
Packit |
7e982e |
these cases is as plain text messages. Graphically based applications,
|
|
Packit |
7e982e |
however, have a more sophisticated interface. They generally interact
|
|
Packit |
7e982e |
with the user via specially constructed dialogue boxes. Additionally,
|
|
Packit |
7e982e |
network based services require that text messages exchanged with the
|
|
Packit |
7e982e |
client are specially formatted for automated processing: one such
|
|
Packit |
7e982e |
example is <command>ftpd</command> which prefixes each exchanged
|
|
Packit |
7e982e |
message with a numeric identifier.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The presentation of simple requests to a client is thus something very
|
|
Packit |
7e982e |
dependent on the protocol that the serving application will use. In
|
|
Packit |
7e982e |
spite of the fact that PAM demands that it drives the whole
|
|
Packit |
7e982e |
authentication process, it is not possible to leave such protocol
|
|
Packit |
7e982e |
subtleties up to the PAM library. To overcome this potential problem,
|
|
Packit |
7e982e |
the application provides the PAM library with a
|
|
Packit |
7e982e |
<emphasis>conversation</emphasis> function. This function is called
|
|
Packit |
7e982e |
from <emphasis>within</emphasis> the PAM library and enables the PAM
|
|
Packit |
7e982e |
to directly interact with the client. The sorts of things that this
|
|
Packit |
7e982e |
conversation function must be able to do are prompt the user with
|
|
Packit |
7e982e |
text and/or obtain textual input from the user for processing by the
|
|
Packit |
7e982e |
PAM library. The details of this function are provided in a later
|
|
Packit |
7e982e |
section.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
For example, the conversation function may be called by the PAM
|
|
Packit |
7e982e |
library with a request to prompt the user for a password. Its job is
|
|
Packit |
7e982e |
to reformat the prompt request into a form that the client will
|
|
Packit |
7e982e |
understand. In the case of <command>ftpd</command>, this might involve
|
|
Packit |
7e982e |
prefixing the string with the number <command>331</command> and sending
|
|
Packit |
7e982e |
the request over the network to a connected client. The conversation
|
|
Packit |
7e982e |
function will then obtain any reply and, after extracting the typed
|
|
Packit |
7e982e |
password, will return this string of text to the PAM library. Similar
|
|
Packit |
7e982e |
concerns need to be addressed in the case of an X-based graphical
|
|
Packit |
7e982e |
server.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
There are a number of issues that need to be addressed when one is
|
|
Packit |
7e982e |
porting an existing application to become PAM compliant. A section
|
|
Packit |
7e982e |
below has been devoted to this: Porting legacy applications.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Besides authentication, PAM provides other forms of management.
|
|
Packit |
7e982e |
Session management is provided with calls to
|
|
Packit |
7e982e |
<function>pam_open_session()</function> and
|
|
Packit |
7e982e |
<function>pam_close_session()</function>. What these functions
|
|
Packit |
7e982e |
actually do is up to the local administrator. But typically, they
|
|
Packit |
7e982e |
could be used to log entry and exit from the system or for mounting
|
|
Packit |
7e982e |
and unmounting the user's home directory. If an application provides
|
|
Packit |
7e982e |
continuous service for a period of time, it should probably call
|
|
Packit |
7e982e |
these functions, first open after the user is authenticated and then
|
|
Packit |
7e982e |
close when the service is terminated.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Account management is another area that an application developer
|
|
Packit |
7e982e |
should include with a call to <function>pam_acct_mgmt()</function>.
|
|
Packit |
7e982e |
This call will perform checks on the good health of the user's account
|
|
Packit |
7e982e |
(has it expired etc.). One of the things this function may check is
|
|
Packit |
7e982e |
whether the user's authentication token has expired - in such a case the
|
|
Packit |
7e982e |
application may choose to attempt to update it with a call to
|
|
Packit |
7e982e |
<function>pam_chauthtok()</function>, although some applications
|
|
Packit |
7e982e |
are not suited to this task (<command>ftp</command> for example)
|
|
Packit |
7e982e |
and in this case the application should deny access to the user.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
PAM is also capable of setting and deleting the user's credentials with
|
|
Packit |
7e982e |
the call <function>pam_setcred()</function>. This function should
|
|
Packit |
7e982e |
always be called after the user is authenticated and before service
|
|
Packit |
7e982e |
is offered to the user. By convention, this should be the last call
|
|
Packit |
7e982e |
to the PAM library before the PAM session is opened. What exactly a
|
|
Packit |
7e982e |
credential is, is not well defined. However, some examples are given
|
|
Packit |
7e982e |
in the glossary below.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id="adg-interface">
|
|
Packit |
7e982e |
<title>
|
|
Packit |
7e982e |
The public interface to <emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Firstly, the relevant include file for the
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> library is
|
|
Packit |
7e982e |
<function><security/pam_appl.h></function>.
|
|
Packit |
7e982e |
It contains the definitions for a number of functions. After
|
|
Packit |
7e982e |
listing these functions, we collect some guiding remarks for
|
|
Packit |
7e982e |
programmers.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<section id="adg-interface-by-app-expected">
|
|
Packit |
7e982e |
<title>What can be expected by the application</title>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_start.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_end.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_set_item.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_get_item.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_strerror.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_fail_delay.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_authenticate.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_setcred.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_acct_mgmt.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_chauthtok.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_open_session.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_close_session.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_putenv.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_getenv.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_getenvlist.xml"/>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
<section id="adg-interface-of-app-expected">
|
|
Packit |
7e982e |
<title>What is expected of an application</title>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_conv.xml"/>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
<section id="adg-interface-programming-notes">
|
|
Packit |
7e982e |
<title>Programming notes</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Note, all of the authentication service function calls accept the
|
|
Packit |
7e982e |
token <emphasis remap='B'>PAM_SILENT</emphasis>, which instructs
|
|
Packit |
7e982e |
the modules to not send messages to the application. This token
|
|
Packit |
7e982e |
can be logically OR'd with any one of the permitted tokens specific
|
|
Packit |
7e982e |
to the individual function calls.
|
|
Packit |
7e982e |
<emphasis remap='B'>PAM_SILENT</emphasis> does not override the
|
|
Packit |
7e982e |
prompting of the user for passwords etc., it only stops informative
|
|
Packit |
7e982e |
messages from being generated.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id="adg-security">
|
|
Packit |
7e982e |
<title>
|
|
Packit |
7e982e |
Security issues of <emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
PAM, from the perspective of an application, is a convenient API for
|
|
Packit |
7e982e |
authenticating users. PAM modules generally have no increased
|
|
Packit |
7e982e |
privilege over that possessed by the application that is making use of
|
|
Packit |
7e982e |
it. For this reason, the application must take ultimate responsibility
|
|
Packit |
7e982e |
for protecting the environment in which PAM operates.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
A poorly (or maliciously) written application can defeat any
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> module's authentication
|
|
Packit |
7e982e |
mechanisms by simply ignoring it's return values. It is the
|
|
Packit |
7e982e |
applications task and responsibility to grant privileges and access
|
|
Packit |
7e982e |
to services. The <emphasis remap='B'>Linux-PAM</emphasis> library
|
|
Packit |
7e982e |
simply assumes the responsibility of <emphasis>authenticating</emphasis>
|
|
Packit |
7e982e |
the user; ascertaining that the user <emphasis>is</emphasis> who they
|
|
Packit |
7e982e |
say they are. Care should be taken to anticipate all of the documented
|
|
Packit |
7e982e |
behavior of the <emphasis remap='B'>Linux-PAM</emphasis> library
|
|
Packit |
7e982e |
functions. A failure to do this will most certainly lead to a future
|
|
Packit |
7e982e |
security breach.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-security-library-calls">
|
|
Packit |
7e982e |
<title>Care about standard library calls</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
In general, writers of authorization-granting applications should
|
|
Packit |
7e982e |
assume that each module is likely to call any or
|
|
Packit |
7e982e |
<emphasis>all</emphasis> 'libc' functions. For 'libc' functions
|
|
Packit |
7e982e |
that return pointers to static/dynamically allocated structures
|
|
Packit |
7e982e |
(ie. the library allocates the memory and the user is not expected
|
|
Packit |
7e982e |
to '<function>free()</function>' it) any module call to this
|
|
Packit |
7e982e |
function is likely to corrupt a pointer previously
|
|
Packit |
7e982e |
obtained by the application. The application programmer should
|
|
Packit |
7e982e |
either re-call such a 'libc' function after a call to the
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> library, or copy the
|
|
Packit |
7e982e |
structure contents to some safe area of memory before passing
|
|
Packit |
7e982e |
control to the <emphasis remap='B'>Linux-PAM</emphasis> library.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Two important function classes that fall into this category are
|
|
Packit |
7e982e |
<citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>getpwnam</refentrytitle><manvolnum>3</manvolnum>
|
|
Packit |
7e982e |
</citerefentry> and <citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
|
|
Packit |
7e982e |
</citerefentry>.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-security-service-name">
|
|
Packit |
7e982e |
<title>Choice of a service name</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
When picking the <emphasis>service-name</emphasis> that
|
|
Packit |
7e982e |
corresponds to the first entry in the
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> configuration file,
|
|
Packit |
7e982e |
the application programmer should <emphasis>avoid</emphasis>
|
|
Packit |
7e982e |
the temptation of choosing something related to
|
|
Packit |
7e982e |
<varname>argv[0]</varname>. It is a trivial matter for any user
|
|
Packit |
7e982e |
to invoke any application on a system under a different name and
|
|
Packit |
7e982e |
this should not be permitted to cause a security breach.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
In general, this is always the right advice if the program is
|
|
Packit |
7e982e |
setuid, or otherwise more privileged than the user that invokes
|
|
Packit |
7e982e |
it. In some cases, avoiding this advice is convenient, but as an
|
|
Packit |
7e982e |
author of such an application, you should consider well the ways
|
|
Packit |
7e982e |
in which your program will be installed and used. (Its often the
|
|
Packit |
7e982e |
case that programs are not intended to be setuid, but end up
|
|
Packit |
7e982e |
being installed that way for convenience. If your program falls
|
|
Packit |
7e982e |
into this category, don't fall into the trap of making this mistake.)
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
To invoke some <emphasis>target</emphasis> application by
|
|
Packit |
7e982e |
another name, the user may symbolically link the target application
|
|
Packit |
7e982e |
with the desired name. To be precise all the user need do is,
|
|
Packit |
7e982e |
<command>ln -s /target/application ./preferred_name</command>
|
|
Packit |
7e982e |
and then run <command>./preferred_name</command>.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
By studying the <emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
configuration file(s), an attacker can choose the
|
|
Packit |
7e982e |
<command>preferred_name</command> to be that of a service enjoying
|
|
Packit |
7e982e |
minimal protection; for example a game which uses
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> to restrict access to
|
|
Packit |
7e982e |
certain hours of the day. If the service-name were to be linked
|
|
Packit |
7e982e |
to the filename under which the service was invoked, it
|
|
Packit |
7e982e |
is clear that the user is effectively in the position of
|
|
Packit |
7e982e |
dictating which authentication scheme the service uses. Needless
|
|
Packit |
7e982e |
to say, this is not a secure situation.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The conclusion is that the application developer should carefully
|
|
Packit |
7e982e |
define the service-name of an application. The safest thing is to
|
|
Packit |
7e982e |
make it a single hard-wired name.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-security-conv-function">
|
|
Packit |
7e982e |
<title>The conversation function</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Care should be taken to ensure that the <function>conv()</function>
|
|
Packit |
7e982e |
function is robust. Such a function is provided in the library
|
|
Packit |
7e982e |
<command>libpam_misc</command> (see
|
|
Packit |
7e982e |
<link linkend="adg-libpam-functions">below</link>).
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-security-user-identity">
|
|
Packit |
7e982e |
<title>The identity of the user</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The <emphasis remap='B'>Linux-PAM</emphasis> modules will need
|
|
Packit |
7e982e |
to determine the identity of the user who requests a service,
|
|
Packit |
7e982e |
and the identity of the user who grants the service. These two
|
|
Packit |
7e982e |
users will seldom be the same. Indeed there is generally a third
|
|
Packit |
7e982e |
user identity to be considered, the new (assumed) identity of
|
|
Packit |
7e982e |
the user once the service is granted.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The need for keeping tabs on these identities is clearly an
|
|
Packit |
7e982e |
issue of security. One convention that is actively used by
|
|
Packit |
7e982e |
some modules is that the identity of the user requesting a
|
|
Packit |
7e982e |
service should be the current <emphasis>UID</emphasis>
|
|
Packit |
7e982e |
(user ID) of the running process; the identity of the
|
|
Packit |
7e982e |
privilege granting user is the <emphasis>EUID</emphasis>
|
|
Packit |
7e982e |
(effective user ID) of the running process; the identity of
|
|
Packit |
7e982e |
the user, under whose name the service will be executed, is
|
|
Packit |
7e982e |
given by the contents of the <emphasis>PAM_USER</emphasis>
|
|
Packit |
7e982e |
<citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
|
|
Packit |
7e982e |
</citerefentry>. Note, modules can change the values of
|
|
Packit |
7e982e |
<emphasis>PAM_USER</emphasis> and <emphasis>PAM_RUSER</emphasis>
|
|
Packit |
7e982e |
during any of the <function>pam_*()</function> library calls.
|
|
Packit |
7e982e |
For this reason, the application should take care to use the
|
|
Packit |
7e982e |
<function>pam_get_item()</function> every time it wishes to
|
|
Packit |
7e982e |
establish who the authenticated user is (or will currently be).
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
For network-serving databases and other applications that provide
|
|
Packit |
7e982e |
their own security model (independent of the OS kernel) the above
|
|
Packit |
7e982e |
scheme is insufficient to identify the requesting user.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
A more portable solution to storing the identity of the requesting
|
|
Packit |
7e982e |
user is to use the <emphasis>PAM_RUSER</emphasis> <citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum>
|
|
Packit |
7e982e |
</citerefentry>. The application should supply this value before
|
|
Packit |
7e982e |
attempting to authenticate the user with
|
|
Packit |
7e982e |
<function>pam_authenticate()</function>. How well this name can be
|
|
Packit |
7e982e |
trusted will ultimately be at the discretion of the local
|
|
Packit |
7e982e |
administrator (who configures PAM for your application) and a
|
|
Packit |
7e982e |
selected module may attempt to override the value where it can
|
|
Packit |
7e982e |
obtain more reliable data. If an application is unable to determine
|
|
Packit |
7e982e |
the identity of the requesting entity/user, it should not call
|
|
Packit |
7e982e |
<citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>pam_set_item</refentrytitle><manvolnum>3</manvolnum>
|
|
Packit |
7e982e |
</citerefentry> to set <emphasis>PAM_RUSER</emphasis>.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
In addition to the <emphasis>PAM_RUSER</emphasis> item, the
|
|
Packit |
7e982e |
application should supply the <emphasis>PAM_RHOST</emphasis>
|
|
Packit |
7e982e |
(<emphasis>requesting host</emphasis>) item. As a general rule,
|
|
Packit |
7e982e |
the following convention for its value can be assumed:
|
|
Packit |
7e982e |
NULL = unknown; localhost = invoked directly from the local system;
|
|
Packit |
7e982e |
<emphasis>other.place.xyz</emphasis> = some component of the
|
|
Packit |
7e982e |
user's connection originates from this remote/requesting host. At
|
|
Packit |
7e982e |
present, PAM has no established convention for indicating whether
|
|
Packit |
7e982e |
the application supports a trusted path to communication from
|
|
Packit |
7e982e |
this host.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<section id="adg-security-resources">
|
|
Packit |
7e982e |
<title>Sufficient resources</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Care should be taken to ensure that the proper execution of an
|
|
Packit |
7e982e |
application is not compromised by a lack of system resources. If an
|
|
Packit |
7e982e |
application is unable to open sufficient files to perform its service,
|
|
Packit |
7e982e |
it should fail gracefully, or request additional resources.
|
|
Packit |
7e982e |
Specifically, the quantities manipulated by the <citerefentry>
|
|
Packit |
7e982e |
<refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum>
|
|
Packit |
7e982e |
</citerefentry> family of commands should be taken into consideration.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
This is also true of conversation prompts. The application should not
|
|
Packit |
7e982e |
accept prompts of arbitrary length with out checking for resource
|
|
Packit |
7e982e |
allocation failure and dealing with such extreme conditions gracefully
|
|
Packit |
7e982e |
and in a manner that preserves the PAM API. Such tolerance may be
|
|
Packit |
7e982e |
especially important when attempting to track a malicious adversary.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-libpam_misc'>
|
|
Packit |
7e982e |
<title>A library of miscellaneous helper functions</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
To aid the work of the application developer a library of
|
|
Packit |
7e982e |
miscellaneous functions is provided. It is called
|
|
Packit |
7e982e |
<command>libpam_misc</command>, and contains a text based
|
|
Packit |
7e982e |
conversation function, and routines for enhancing the standard
|
|
Packit |
7e982e |
PAM-environment variable support.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The functions, structures and macros, made available by this
|
|
Packit |
7e982e |
library can be defined by including
|
|
Packit |
7e982e |
<function><security/pam_misc.h></function>. It should be
|
|
Packit |
7e982e |
noted that this library is specific to
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> and is not referred to in
|
|
Packit |
7e982e |
the defining DCE-RFC (see <link linkend="adg-see-also">See also</link>)
|
|
Packit |
7e982e |
below.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<section id='adg-libpam-functions'>
|
|
Packit |
7e982e |
<title>Functions supplied</title>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_misc_conv.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_misc_paste_env.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_misc_drop_env.xml"/>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
href="pam_misc_setenv.xml"/>
|
|
Packit |
7e982e |
</section>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-porting'>
|
|
Packit |
7e982e |
<title>Porting legacy applications</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The point of PAM is that the application is not supposed to
|
|
Packit |
7e982e |
have any idea how the attached authentication modules will choose
|
|
Packit |
7e982e |
to authenticate the user. So all they can do is provide a conversation
|
|
Packit |
7e982e |
function that will talk directly to the user(client) on the modules'
|
|
Packit |
7e982e |
behalf.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Consider the case that you plug a retinal scanner into the login
|
|
Packit |
7e982e |
program. In this situation the user would be prompted: "please look
|
|
Packit |
7e982e |
into the scanner". No username or password would be needed - all this
|
|
Packit |
7e982e |
information could be deduced from the scan and a database lookup. The
|
|
Packit |
7e982e |
point is that the retinal scanner is an ideal task for a "module".
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
While it is true that a pop-daemon program is designed with the POP
|
|
Packit |
7e982e |
protocol in mind and no-one ever considered attaching a retinal
|
|
Packit |
7e982e |
scanner to it, it is also the case that the "clean" PAM'ification of
|
|
Packit |
7e982e |
such a daemon would allow for the possibility of a scanner module
|
|
Packit |
7e982e |
being be attached to it. The point being that the "standard"
|
|
Packit |
7e982e |
pop-authentication protocol(s) [which will be needed to satisfy
|
|
Packit |
7e982e |
inflexible/legacy clients] would be supported by inserting an
|
|
Packit |
7e982e |
appropriate pam_qpopper module(s). However, having rewritten
|
|
Packit |
7e982e |
<command>popd</command> once in this way any new protocols can be
|
|
Packit |
7e982e |
implemented in-situ.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
One simple test of a ported application would be to insert the
|
|
Packit |
7e982e |
<command>pam_permit</command> module and see if the application
|
|
Packit |
7e982e |
demands you type a password... In such a case, <command>xlock</command>
|
|
Packit |
7e982e |
would fail to lock the terminal - or would at best be a screen-saver,
|
|
Packit |
7e982e |
ftp would give password free access to all etc.. Neither of
|
|
Packit |
7e982e |
these is a very secure thing to do, but they do illustrate how
|
|
Packit |
7e982e |
much flexibility PAM puts in the hands of the local admin.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The key issue, in doing things correctly, is identifying what is part
|
|
Packit |
7e982e |
of the authentication procedure (how many passwords etc..) the
|
|
Packit |
7e982e |
exchange protocol (prefixes to prompts etc., numbers like 331 in the
|
|
Packit |
7e982e |
case of ftpd) and what is part of the service that the application
|
|
Packit |
7e982e |
delivers. PAM really needs to have total control in the
|
|
Packit |
7e982e |
authentication "procedure", the conversation function should only
|
|
Packit |
7e982e |
deal with reformatting user prompts and extracting responses from raw
|
|
Packit |
7e982e |
input.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-glossary'>
|
|
Packit |
7e982e |
<title>Glossary of PAM related terms</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The following are a list of terms used within this document.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<variablelist>
|
|
Packit |
7e982e |
<varlistentry>
|
|
Packit |
7e982e |
<term>Authentication token</term>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Generally, this is a password. However, a user can authenticate
|
|
Packit |
7e982e |
him/herself in a variety of ways. Updating the user's
|
|
Packit |
7e982e |
authentication token thus corresponds to
|
|
Packit |
7e982e |
<emphasis>refreshing</emphasis> the object they use to
|
|
Packit |
7e982e |
authenticate themself with the system. The word password is
|
|
Packit |
7e982e |
avoided to keep open the possibility that the authentication
|
|
Packit |
7e982e |
involves a retinal scan or other non-textual mode of
|
|
Packit |
7e982e |
challenge/response.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
</varlistentry>
|
|
Packit |
7e982e |
<varlistentry>
|
|
Packit |
7e982e |
<term>Credentials</term>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Having successfully authenticated the user, PAM is able to
|
|
Packit |
7e982e |
establish certain characteristics/attributes of the user.
|
|
Packit |
7e982e |
These are termed <emphasis>credentials</emphasis>. Examples
|
|
Packit |
7e982e |
of which are group memberships to perform privileged tasks
|
|
Packit |
7e982e |
with, and <emphasis>tickets</emphasis> in the form of
|
|
Packit |
7e982e |
environment variables etc. . Some user-credentials, such as
|
|
Packit |
7e982e |
the user's UID and GID (plus default group memberships) are
|
|
Packit |
7e982e |
not deemed to be PAM-credentials. It is the responsibility
|
|
Packit |
7e982e |
of the application to grant these directly.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
</varlistentry>
|
|
Packit |
7e982e |
</variablelist>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-example'>
|
|
Packit |
7e982e |
<title>An example application</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
To get a flavor of the way a <emphasis remap='B'>Linux-PAM</emphasis>
|
|
Packit |
7e982e |
application is written we include the following example. It prompts
|
|
Packit |
7e982e |
the user for their password and indicates whether their account
|
|
Packit |
7e982e |
is valid on the standard output, its return code also indicates
|
|
Packit |
7e982e |
the success (<returnvalue>0</returnvalue> for success;
|
|
Packit |
7e982e |
<returnvalue>1</returnvalue> for failure).
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
/*
|
|
Packit |
7e982e |
This program was contributed by Shane Watts
|
|
Packit |
7e982e |
[modifications by AGM and kukuk]
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
You need to add the following (or equivalent) to the
|
|
Packit |
7e982e |
/etc/pam.d/check_user file:
|
|
Packit |
7e982e |
# check authorization
|
|
Packit |
7e982e |
auth required pam_unix.so
|
|
Packit |
7e982e |
account required pam_unix.so
|
|
Packit |
7e982e |
*/
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
#include <security/pam_appl.h>
|
|
Packit |
7e982e |
#include <security/pam_misc.h>
|
|
Packit |
7e982e |
#include <stdio.h>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
static struct pam_conv conv = {
|
|
Packit |
7e982e |
misc_conv,
|
|
Packit |
7e982e |
NULL
|
|
Packit |
7e982e |
};
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
int main(int argc, char *argv[])
|
|
Packit |
7e982e |
{
|
|
Packit |
7e982e |
pam_handle_t *pamh=NULL;
|
|
Packit |
7e982e |
int retval;
|
|
Packit |
7e982e |
const char *user="nobody";
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if(argc == 2) {
|
|
Packit |
7e982e |
user = argv[1];
|
|
Packit |
7e982e |
}
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if(argc > 2) {
|
|
Packit |
7e982e |
fprintf(stderr, "Usage: check_user [username]\n");
|
|
Packit |
7e982e |
exit(1);
|
|
Packit |
7e982e |
}
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
retval = pam_start("check_user", user, &conv, &pamh);
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if (retval == PAM_SUCCESS)
|
|
Packit |
7e982e |
retval = pam_authenticate(pamh, 0); /* is user really user? */
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if (retval == PAM_SUCCESS)
|
|
Packit |
7e982e |
retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
/* This is where we have been authorized or not. */
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if (retval == PAM_SUCCESS) {
|
|
Packit |
7e982e |
fprintf(stdout, "Authenticated\n");
|
|
Packit |
7e982e |
} else {
|
|
Packit |
7e982e |
fprintf(stdout, "Not Authenticated\n");
|
|
Packit |
7e982e |
}
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
|
|
Packit |
7e982e |
pamh = NULL;
|
|
Packit |
7e982e |
fprintf(stderr, "check_user: failed to release authenticator\n");
|
|
Packit |
7e982e |
exit(1);
|
|
Packit |
7e982e |
}
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
|
|
Packit |
7e982e |
}
|
|
Packit |
7e982e |
]]>
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-files'>
|
|
Packit |
7e982e |
<title>Files</title>
|
|
Packit |
7e982e |
<variablelist>
|
|
Packit |
7e982e |
<varlistentry>
|
|
Packit |
7e982e |
<term><filename>/usr/include/security/pam_appl.h</filename></term>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Header file with interfaces for
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis> applications.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
</varlistentry>
|
|
Packit |
7e982e |
<varlistentry>
|
|
Packit |
7e982e |
<term><filename>/usr/include/security/pam_misc.h</filename></term>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Header file for useful library functions for making
|
|
Packit |
7e982e |
applications easier to write.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
</varlistentry>
|
|
Packit |
7e982e |
</variablelist>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id="adg-see-also">
|
|
Packit |
7e982e |
<title>See also</title>
|
|
Packit |
7e982e |
<itemizedlist>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The Linux-PAM System Administrators' Guide.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The Linux-PAM Module Writers' Guide.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
<listitem>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
|
|
Packit |
7e982e |
PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation
|
|
Packit |
7e982e |
Request For Comments 86.0, October 1995.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</listitem>
|
|
Packit |
7e982e |
</itemizedlist>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-author'>
|
|
Packit |
7e982e |
<title>Author/acknowledgments</title>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
This document was written by Andrew G. Morgan (morgan@kernel.org)
|
|
Packit |
7e982e |
with many contributions from
|
|
Packit |
7e982e |
Chris Adams, Peter Allgeyer, Tim Baverstock, Tim Berger, Craig S. Bell,
|
|
Packit |
7e982e |
Derrick J. Brashear, Ben Buxton, Seth Chaiklin, Oliver Crow, Chris Dent,
|
|
Packit |
7e982e |
Marc Ewing, Cristian Gafton, Emmanuel Galanos, Brad M. Garcia,
|
|
Packit |
7e982e |
Eric Hester, Roger Hu, Eric Jacksch, Michael K. Johnson, David Kinchlea,
|
|
Packit |
7e982e |
Olaf Kirch, Marcin Korzonek, Thorsten Kukuk, Stephen Langasek,
|
|
Packit |
7e982e |
Nicolai Langfeldt, Elliot Lee, Luke Kenneth Casson Leighton,
|
|
Packit |
7e982e |
Al Longyear, Ingo Luetkebohle, Marek Michalkiewicz, Robert Milkowski,
|
|
Packit |
7e982e |
Aleph One, Martin Pool, Sean Reifschneider, Jan Rekorajski, Erik Troan,
|
|
Packit |
7e982e |
Theodore Ts'o, Jeff Uphoff, Myles Uyema, Savochkin Andrey Vladimirovich,
|
|
Packit |
7e982e |
Ronald Wahl, David Wood, John Wilmes, Joseph S. D. Yao
|
|
Packit |
7e982e |
and Alex O. Yuriev.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Thanks are also due to Sun Microsystems, especially to Vipin Samar and
|
|
Packit |
7e982e |
Charlie Lai for their advice. At an early stage in the development of
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis>, Sun graciously made the
|
|
Packit |
7e982e |
documentation for their implementation of PAM available. This act
|
|
Packit |
7e982e |
greatly accelerated the development of
|
|
Packit |
7e982e |
<emphasis remap='B'>Linux-PAM</emphasis>.
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
<chapter id='adg-copyright'>
|
|
Packit |
7e982e |
<title>Copyright information for this document</title>
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de>
|
|
Packit |
7e982e |
Copyright (c) 1996-2002 Andrew G. Morgan <morgan@kernel.org>
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
7e982e |
modification, are permitted provided that the following conditions are
|
|
Packit |
7e982e |
met:
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
1. Redistributions of source code must retain the above copyright
|
|
Packit |
7e982e |
notice, and the entire permission notice in its entirety,
|
|
Packit |
7e982e |
including the disclaimer of warranties.
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
7e982e |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
7e982e |
documentation and/or other materials provided with the distribution.
|
|
Packit |
7e982e |
|
|
Packit |
7e982e |
3. The name of the author may not be used to endorse or promote
|
|
Packit |
7e982e |
products derived from this software without specific prior
|
|
Packit |
7e982e |
written permission.
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
<para>
|
|
Packit |
7e982e |
Alternatively, this product may be distributed under the terms of
|
|
Packit |
7e982e |
the GNU General Public License (GPL), in which case the provisions
|
|
Packit |
7e982e |
of the GNU GPL are required instead of the above restrictions.
|
|
Packit |
7e982e |
(This clause is necessary due to a potential bad interaction between
|
|
Packit |
7e982e |
the GNU GPL and the restrictions contained in a BSD-style copyright.)
|
|
Packit |
7e982e |
</para>
|
|
Packit |
7e982e |
<programlisting>
|
|
Packit |
7e982e |
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
Packit |
7e982e |
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
Packit |
7e982e |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
Packit |
7e982e |
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
7e982e |
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
Packit |
7e982e |
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
Packit |
7e982e |
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
Packit |
7e982e |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
Packit |
7e982e |
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
Packit |
7e982e |
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
Packit |
7e982e |
</programlisting>
|
|
Packit |
7e982e |
</chapter>
|
|
Packit |
7e982e |
</book>
|