Blame doc/adg/Linux-PAM_ADG.xml

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>