diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 12:01:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 12:01:37 +0000 |
commit | de848d9e9146434817c65d74d1d0313e9d729462 (patch) | |
tree | dcbd0efb229b17f696f7195671f05b354b4f70fc /doc/mwg/Linux-PAM_MWG.xml | |
parent | Initial commit. (diff) | |
download | pam-de848d9e9146434817c65d74d1d0313e9d729462.tar.xz pam-de848d9e9146434817c65d74d1d0313e9d729462.zip |
Adding upstream version 1.4.0.upstream/1.4.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/mwg/Linux-PAM_MWG.xml')
-rw-r--r-- | doc/mwg/Linux-PAM_MWG.xml | 632 |
1 files changed, 632 insertions, 0 deletions
diff --git a/doc/mwg/Linux-PAM_MWG.xml b/doc/mwg/Linux-PAM_MWG.xml new file mode 100644 index 0000000..3022538 --- /dev/null +++ b/doc/mwg/Linux-PAM_MWG.xml @@ -0,0 +1,632 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" + "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> +<book id="mwg"> + <bookinfo> + <title>The Linux-PAM Module Writers' Guide</title> + <authorgroup> + <author> + <firstname>Andrew G.</firstname> + <surname>Morgan</surname> + <email>morgan@kernel.org</email> + </author> + <author> + <firstname>Thorsten</firstname> + <surname>Kukuk</surname> + <email>kukuk@thkukuk.de</email> + </author> + </authorgroup> + <releaseinfo>Version 1.1.2, 31. August 2010</releaseinfo> + <abstract> + <para> + This manual documents what a programmer needs to know in order + to write a module that conforms to the + <emphasis remap='B'>Linux-PAM</emphasis> standard.It also + discusses some security issues from the point of view of the + module programmer. + </para> + </abstract> + </bookinfo> + + <chapter id="mwg-introduction"> + <title>Introduction</title> + <section id="mwg-introduction-description"> + <title>Description</title> + <para> + <emphasis remap='B'>Linux-PAM</emphasis> (Pluggable Authentication + Modules for Linux) is a library that enables the local system + administrator to choose how individual applications authenticate + users. For an overview of the + <emphasis remap='B'>Linux-PAM</emphasis> library see the + <emphasis>Linux-PAM System Administrators' Guide</emphasis>. + </para> + <para> + A <emphasis remap='B'>Linux-PAM</emphasis> module is a single + executable binary file that can be loaded by the + <emphasis remap='B'>Linux-PAM</emphasis> interface library. + This PAM library is configured locally with a system file, + <filename>/etc/pam.conf</filename>, to authenticate a user + request via the locally available authentication modules. The + modules themselves will usually be located in the directory + <filename>/lib/security</filename> (or + <filename>/lib64/security</filename>, depending on the architecture) + and take the form of dynamically loadable object files (see + <citerefentry> + <refentrytitle>dlopen</refentrytitle><manvolnum>3</manvolnum> + </citerefentry>. Alternatively, the modules can be statically + linked into the <emphasis remap='B'>Linux-PAM</emphasis> library; + this is mostly to allow <emphasis remap='B'>Linux-PAM</emphasis> to + be used on platforms without dynamic linking available, but this is + a <emphasis>deprecated</emphasis> functionality. It is the + <emphasis remap='B'>Linux-PAM</emphasis> interface that is called + by an application and it is the responsibility of the library to + locate, load and call the appropriate functions in a + <emphasis remap='B'>Linux-PAM</emphasis>-module. + </para> + <para> + Except for the immediate purpose of interacting with the user + (entering a password etc..) the module should never call the + application directly. This exception requires a "conversation + mechanism" which is documented below. + </para> + </section> + + <section id="mwg-introduction-synopsis"> + <title>Synopsis</title> + <programlisting> +#include <security/pam_modules.h> + +gcc -fPIC -c pam_module.c +gcc -shared -o pam_module.so pam_module.o -lpam + </programlisting> + </section> + </chapter> + + <chapter id="mwg-expected-by-module"> + <title>What can be expected by the module</title> + <para> + Here we list the interface that the conventions that all + <emphasis remap='B'>Linux-PAM</emphasis> modules must adhere to. + </para> + <section id="mwg-expected-by-module-item"> + <title> + Getting and setting <emphasis>PAM_ITEM</emphasis>s and + <emphasis>data</emphasis> + </title> + <para> + First, we cover what the module should expect from the + <emphasis remap='B'>Linux-PAM</emphasis> library and a + <emphasis remap='B'>Linux-PAM</emphasis> aware application. + Essentially this is the <filename>libpam.*</filename> library. + </para> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_set_data.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_get_data.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_set_item.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_get_item.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_get_user.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_conv.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_putenv.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_getenv.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_getenvlist.xml"/> + </section> + <section id="mwg-expected-by-module-other"> + <title> + Other functions provided by <filename>libpam</filename> + </title> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_strerror.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_fail_delay.xml"/> + </section> + </chapter> + + <chapter id="mwg-expected-of-module"> + <title>What is expected of a module</title> + <para> + The module must supply a sub-set of the six functions listed + below. Together they define the function of a + <emphasis remap='B'>Linux-PAM module</emphasis>. Module developers + are strongly urged to read the comments on security that follow + this list. + </para> + <section id="mwg-expected-of-module-overview"> + <title>Overview</title> + <para> + The six module functions are grouped into four independent + management groups. These groups are as follows: + <emphasis>authentication</emphasis>, <emphasis>account</emphasis>, + <emphasis>session</emphasis> and <emphasis>password</emphasis>. + To be properly defined, a module must define all functions within + at least one of these groups. A single module may contain the + necessary functions for <emphasis>all</emphasis> four groups. + </para> + <section id="mwg-expected-of-module-overview-1"> + <title>Functional independence</title> + <para> + The independence of the four groups of service a module can + offer means that the module should allow for the possibility + that any one of these four services may legitimately be called + in any order. Thus, the module writer should consider the + appropriateness of performing a service without the prior + success of some other part of the module. + </para> + <para> + As an informative example, consider the possibility that an + application applies to change a user's authentication token, + without having first requested that + <emphasis remap='B'>Linux-PAM</emphasis> authenticate the + user. In some cases this may be deemed appropriate: when + <command>root</command> wants to change the authentication + token of some lesser user. In other cases it may not be + appropriate: when <command>joe</command> maliciously wants + to reset <command>alice</command>'s password; or when anyone + other than the user themself wishes to reset their + <emphasis>KERBEROS</emphasis> authentication token. A policy + for this action should be defined by any reasonable + authentication scheme, the module writer should consider + this when implementing a given module. + </para> + </section> + <section id="mwg-expected-of-module-overview-2"> + <title>Minimizing administration problems</title> + <para> + To avoid system administration problems and the poor + construction of a <filename>/etc/pam.conf</filename> file, + the module developer may define all six of the following + functions. For those functions that would not be called, + the module should return <errorname>PAM_SERVICE_ERR</errorname> + and write an appropriate message to the system log. When + this action is deemed inappropriate, the function would + simply return <errorname>PAM_IGNORE</errorname>. + </para> + </section> + <section id="mwg-expected-of-module-overview-3"> + <title>Arguments supplied to the module</title> + <para> + The <parameter>flags</parameter> argument of each of + the following functions can be logically OR'd with + <parameter>PAM_SILENT</parameter>, which is used to inform the + module to not pass any <emphasis>text</emphasis> (errors or + warnings) application. + </para> + <para> + The <parameter>argc</parameter> and <parameter>argv</parameter> + arguments are taken from the line appropriate to this + module---that is, with the <emphasis>service_name</emphasis> + matching that of the application---in the configuration file + (see the <emphasis remap='B'>Linux-PAM</emphasis> + System Administrators' Guide). Together these two parameters + provide the number of arguments and an array of pointers to + the individual argument tokens. This will be familiar to C + programmers as the ubiquitous method of passing command arguments + to the function <function>main()</function>. Note, however, that + the first argument (<parameter>argv[0]</parameter>) is a true + argument and <emphasis>not</emphasis> the name of the module. + </para> + </section> + </section> + <section id="mwg-expected-of-module-auth"> + <title>Authentication management</title> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_authenticate.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_setcred.xml"/> + </section> + <section id="mwg-expected-of-module-acct"> + <title>Account management</title> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_acct_mgmt.xml"/> + </section> + <section id="mwg-expected-of-module-session"> + <title>Session management</title> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_open_session.xml"/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_close_session.xml"/> + </section> + <section id="mwg-expected-of-module-chauthtok"> + <title>Authentication token management</title> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" + href="pam_sm_chauthtok.xml"/> + </section> + </chapter> + + <chapter id="mwg-see-options"> + <title>Generic optional arguments</title> + <para> + Here we list the generic arguments that all modules can expect to + be passed. They are not mandatory, and their absence should be + accepted without comment by the module. + </para> + <variablelist> + <varlistentry> + <term>debug</term> + <listitem> + <para> + Use the <citerefentry> + <refentrytitle>pam_syslog</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> call to log debugging information to the system + log files. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>use_first_pass</term> + <listitem> + <para> + The module should not prompt the user for a password. + Instead, it should obtain the previously typed password + (by a call to <function>pam_get_item()</function> for the + <parameter>PAM_AUTHTOK</parameter> item), and use that. If + that doesn't work, then the user will not be authenticated. + (This option is intended for <command>auth</command> and + <command>passwd</command> modules only). + </para> + </listitem> + </varlistentry> + </variablelist> + </chapter> + + <chapter id="mwg-see-programming"> + <title>Programming notes</title> + <para> + Here we collect some pointers for the module writer to bear in mind + when writing/developing a <emphasis remap='B'>Linux-PAM</emphasis> + compatible module. + </para> + + <section id="mwg-see-programming-sec"> + <title>Security issues for module creation</title> + <section id="mwg-see-programming-sec-res"> + <title>Sufficient resources</title> + <para> + Care should be taken to ensure that the proper execution + of a module is not compromised by a lack of system resources. + If a module is unable to open sufficient files to perform its + task, it should fail gracefully, or request additional resources. + Specifically, the quantities manipulated by the <citerefentry> + <refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum> + </citerefentry> family of commands should be taken into + consideration. + </para> + </section> + <section id="mwg-see-programming-sec-who"> + <title>Who´s who?</title> + <para> + Generally, the module may wish to establish the identity of + the user requesting a service. This may not be the same as + the username returned by <function>pam_get_user()</function>. + Indeed, that is only going to be the name of the user under + whose identity the service will be given. This is not + necessarily the user that requests the service. + </para> + <para> + In other words, user X runs a program that is setuid-Y, it + grants the user to have the permissions of Z. A specific example + of this sort of service request is the <command>su</command> + program: user <command>joe</command> executes + <command>su</command> to become the user <command>jane</command>. + In this situation X=<command>joe</command>, Y=<command>root</command> + and Z=<command>jane</command>. Clearly, it is important that + the module does not confuse these different users and grant an + inappropriate level of privilege. + </para> + <para> + The following is the convention to be adhered to when juggling + user-identities. + </para> + <itemizedlist> + <listitem> + <para> + X, the identity of the user invoking the service request. + This is the user identifier; returned by the function + <citerefentry> + <refentrytitle>getuid</refentrytitle><manvolnum>2</manvolnum> + </citerefentry>. + </para> + </listitem> + <listitem> + <para> + Y, the privileged identity of the application used to + grant the requested service. This is the + <emphasis>effective</emphasis> user identifier; + returned by the function <citerefentry> + <refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum> + </citerefentry>. + </para> + </listitem> + <listitem> + <para> + Z, the user under whose identity the service will be granted. + This is the username returned by + <function>pam_get_user()</function> and also stored in the + <emphasis remap='B'>Linux-PAM</emphasis> item, + <emphasis>PAM_USER</emphasis>. + </para> + </listitem> + <listitem> + <para> + <emphasis remap='B'>Linux-PAM</emphasis> has a place for + an additional user identity that a module may care to make + use of. This is the <emphasis>PAM_RUSER</emphasis> item. + Generally, network sensitive modules/applications may wish + to set/read this item to establish the identity of the user + requesting a service from a remote location. + </para> + </listitem> + </itemizedlist> + <para> + Note, if a module wishes to modify the identity of either the + <emphasis>uid</emphasis> or <emphasis>euid</emphasis> of the + running process, it should take care to restore the original + values prior to returning control to the + <emphasis remap='B'>Linux-PAM</emphasis> library. + </para> + </section> + <section id="mwg-see-programming-sec-conv"> + <title>Using the conversation function</title> + <para> + Prior to calling the conversation function, the module should + reset the contents of the pointer that will return the applications + response. This is a good idea since the application may fail + to fill the pointer and the module should be in a position to + notice! + </para> + <para> + The module should be prepared for a failure from the + conversation. The generic error would be + <emphasis>PAM_CONV_ERR</emphasis>, but anything other than + <emphasis>PAM_SUCCESS</emphasis> should be treated as + indicating failure. + </para> + </section> + <section id="mwg-see-programming-sec-token"> + <title>Authentication tokens</title> + <para> + To ensure that the authentication tokens are not left lying + around the items, <emphasis>PAM_AUTHTOK</emphasis> and + <emphasis>PAM_OLDAUTHTOK</emphasis>, are not available to + the application: they are defined in + <filename><security/pam_modules.h></filename>. This + is ostensibly for security reasons, but a maliciously + programmed application will always have access to all memory + of the process, so it is only superficially enforced. As a + general rule the module should overwrite authentication tokens + as soon as they are no longer needed. Especially before + <function>free()</function>'ing them. The + <emphasis remap='B'>Linux-PAM</emphasis> library is + required to do this when either of these authentication + token items are (re)set. + </para> + <para> + Not to dwell too little on this concern; should the module + store the authentication tokens either as (automatic) function + variables or using <function>pam_[gs]et_data()</function> the + associated memory should be over-written explicitly before it + is released. In the case of the latter storage mechanism, the + associated <function>cleanup()</function> function should + explicitly overwrite the <varname>*data</varname> before + <function>free()</function>'ing it: for example, + <programlisting> +/* + * An example cleanup() function for releasing memory that was used to + * store a password. + */ + +int cleanup(pam_handle_t *pamh, void *data, int error_status) +{ + char *xx; + + if ((xx = data)) { + while (*xx) + *xx++ = '\0'; + free(data); + } + return PAM_SUCCESS; +} + </programlisting> + </para> + </section> + </section> + <section id="mwg-see-programming-syslog"> + <title>Use of <citerefentry> + <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> + </citerefentry></title> + <para> + Only rarely should error information be directed to the user. + Usually, this is to be limited to + <quote><emphasis>sorry you cannot login now</emphasis></quote> + type messages. Information concerning errors in the configuration + file, <filename>/etc/pam.conf</filename>, or due to some system + failure encountered by the module, should be written to + <citerefentry> + <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> with <emphasis>facility-type</emphasis> + <emphasis remap='B'>LOG_AUTHPRIV</emphasis>. + </para> + <para> + With a few exceptions, the level of logging is, at the discretion + of the module developer. Here is the recommended usage of different + logging levels: + </para> + <itemizedlist> + <listitem> + <para> + As a general rule, errors encountered by a module should be + logged at the <emphasis>LOG_ERR</emphasis> level. However, + information regarding an unrecognized argument, passed to a + module from an entry in the <filename>/etc/pam.conf</filename> + file, is <emphasis>required</emphasis> to be logged at the + <emphasis>LOG_ERR</emphasis> level. + </para> + </listitem> + <listitem> + <para> + Debugging information, as activated by the + <command>debug</command> argument to the module in + <filename>/etc/pam.conf</filename>, should be logged + at the <emphasis>LOG_DEBUG</emphasis> level. + </para> + </listitem> + <listitem> + <para> + If a module discovers that its personal configuration + file or some system file it uses for information is + corrupted or somehow unusable, it should indicate this + by logging messages at level, <emphasis>LOG_ALERT</emphasis>. + </para> + </listitem> + <listitem> + <para> + Shortages of system resources, such as a failure to + manipulate a file or <function>malloc()</function> failures + should be logged at level <emphasis>LOG_CRIT</emphasis>. + </para> + </listitem> + <listitem> + <para> + Authentication failures, associated with an incorrectly + typed password should be logged at level, + <emphasis>LOG_NOTICE</emphasis>. + </para> + </listitem> + </itemizedlist> + </section> + <section id="mwg-see-programming-libs"> + <title>Modules that require system libraries</title> + <para> + Writing a module is much like writing an application. You + have to provide the "conventional hooks" for it to work + correctly, like <function>pam_sm_authenticate()</function> + etc., which would correspond to the <function>main()</function> + function in a normal function. + </para> + <para> + Typically, the author may want to link against some standard system + libraries. As when one compiles a normal program, this can be + done for modules too: you simply append the + <parameter>-l</parameter><emphasis>XXX</emphasis> arguments + for the desired libraries when you create the shared module object. + To make sure a module is linked to the + <command>libwhatever.so</command> library + when it is <function>dlopen()</function>ed, try: + <programlisting> +% gcc -shared -o pam_module.so pam_module.o -lwhatever + </programlisting> + </para> + </section> + </chapter> + + <chapter id="mwg-example"> + <title>An example module</title> + <para> + At some point, we may include a fully commented example of a module in + this document. For now, please look at the modules directory of the + <emphasis remap='B'>Linux-PAM</emphasis> sources. + </para> + </chapter> + + <chapter id="mwg-see-also"> + <title>See also</title> + <itemizedlist> + <listitem> + <para> + The Linux-PAM System Administrators' Guide. + </para> + </listitem> + <listitem> + <para> + The Linux-PAM Application Developers' Guide. + </para> + </listitem> + <listitem> + <para> + The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH + PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation + Request For Comments 86.0, October 1995. + </para> + </listitem> + </itemizedlist> + </chapter> + + <chapter id='mwg-author'> + <title>Author/acknowledgments</title> + <para> + This document was written by Andrew G. Morgan (morgan@kernel.org) + with many contributions from + Chris Adams, Peter Allgeyer, Tim Baverstock, Tim Berger, Craig S. Bell, + Derrick J. Brashear, Ben Buxton, Seth Chaiklin, Oliver Crow, Chris Dent, + Marc Ewing, Cristian Gafton, Emmanuel Galanos, Brad M. Garcia, + Eric Hester, Roger Hu, Eric Jacksch, Michael K. Johnson, David Kinchlea, + Olaf Kirch, Marcin Korzonek, Thorsten Kukuk, Stephen Langasek, + Nicolai Langfeldt, Elliot Lee, Luke Kenneth Casson Leighton, + Al Longyear, Ingo Luetkebohle, Marek Michalkiewicz, Robert Milkowski, + Aleph One, Martin Pool, Sean Reifschneider, Jan Rekorajski, Erik Troan, + Theodore Ts'o, Jeff Uphoff, Myles Uyema, Savochkin Andrey Vladimirovich, + Ronald Wahl, David Wood, John Wilmes, Joseph S. D. Yao + and Alex O. Yuriev. + </para> + <para> + Thanks are also due to Sun Microsystems, especially to Vipin Samar and + Charlie Lai for their advice. At an early stage in the development of + <emphasis remap='B'>Linux-PAM</emphasis>, Sun graciously made the + documentation for their implementation of PAM available. This act + greatly accelerated the development of + <emphasis remap='B'>Linux-PAM</emphasis>. + </para> + </chapter> + + <chapter id='mwg-copyright'> + <title>Copyright information for this document</title> + <programlisting> +Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> +Copyright (c) 1996-2002 Andrew G. Morgan <morgan@kernel.org> + </programlisting> + <para> + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + </para> + <programlisting> +1. Redistributions of source code must retain the above copyright + notice, and the entire permission notice in its entirety, + including the disclaimer of warranties. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + </programlisting> + <para> + Alternatively, this product may be distributed under the terms of + the GNU General Public License (GPL), in which case the provisions + of the GNU GPL are required instead of the above restrictions. + (This clause is necessary due to a potential bad interaction between + the GNU GPL and the restrictions contained in a BSD-style copyright.) + </para> + <programlisting> +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + </programlisting> + </chapter> +</book> |