pam-afs-session 2.6
(PAM module for AFS PAGs and tokens)
Written by Russ Allbery <eagle@eyrie.org>
Copyright 2015 Russ Allbery <eagle@eyrie.org>. Copyright 2005, 2006,
2007, 2008, 2010, 2011 The Board of Trustees of the Leland Stanford
Junior University. This software is distributed under a BSD-style
license. Plese see the section LICENSE below for more information.
BLURB
pam-afs-session is a PAM module intended for use with a Kerberos PAM
module to obtain an AFS PAG and AFS tokens on login. It puts every new
session in a PAG regardless of whether it was authenticated with
Kerberos and either uses Heimdal's libkafs or runs a configurable
external program to obtain tokens. It supports using Heimdal's libkafs
or OpenAFS's libkopenafs for the AFS interface and falls back to an
internal implementation if libkafs isn't available.
DESCRIPTION
pam-afs-session is a PAM module that isolates each login in a separate
AFS PAG (so that they will not trample on each other's AFS tokens) and
supports either running an external program to obtain AFS tokens from a
Kerberos ticket cache or using Heimdal's libkafs library. It does not
obtain tickets itself and must be used in conjunction with a Kerberos
PAM module to obtain tokens (setting up PAGs can be done without any
Kerberos implementations). It provides only the setcred and session PAM
functions.
There are two ways this module can obtain tokens:
* If you have Heimdal's libkafs library available, the module can call
libkafs's krb5_afslog function to obtain tokens directly. If you are
using Heimdal and obtaining tokens from Kerberos tickets, this is the
recommended configuration, since it means the PAM module doesn't have
to fork an external process. If built with Heimdal's libkafs, this
will be the default unless program is set in the module
configuration.
* Otherwise, the module will run an arbitrary external program to
obtain tokens. This is the most flexible option, works with MIT
Kerberos in conjunction with the aklog program from OpenAFS or the
afslog program from Heimdal, and can support programs that obtain AFS
tokens via some means other than a Kerberos ticket cache created on
login.
For the AFS system call layer, pam-afs-session supports linking with the
Heimdal libkafs library or OpenAFS's libkopenafs library. As a
fallback, and to support a low-dependency build, it also comes with a
simple AFS system call implementation for Linux, Mac OS X, Solaris, or
platforms that use syscall to call AFS functions. It can also link with
the older OpenAFS libraries when libkopenafs isn't available.
The module can optionally be linked with Kerberos libraries to obtain
configuration information from krb5.conf, to support the kdestroy
option, and to use libkafs's functions for obtaining tokens.
This module does not support getting tokens for the rmtsys AFS network
redirection interface (generally used with the NFS translator).
pam-afs-session is primarily tested on Linux. I rely on reports from
users to ensure it continues working on other platforms. Please let me
know if any problems you run into.
REQUIREMENTS
The PAM implementations on Linux, Solaris, Mac OS X, HP-UX, and AIX are
supported, although the module is primarily tested on Linux and only
lightly tested (and not at all by me personally) on the other platforms.
Use on platforms with other PAM implementations, such as IRIX or the
*BSDs, will require more porting and will not currently work. Patches
are welcome.
The module is written in C and should hopefully build on any system with
an adequate PAM library that Libtool supports.
Either Heimdal's libkafs or OpenAFS's libkopenafs are the preferred ways
of making AFS system calls. If neither are present during compile time,
pam-afs-session will attempt to fall back on a built-in AFS system call
layer. To use the built-in AFS system call interface on Linux, Mac OS
X, and Solaris 11, the system must run a new enough version of OpenAFS
or Arla to support AFS system calls through ioctl on a file in /proc or
/dev. On other systems with a simple system call interface, configure
must be able to find the AFS header afs/param.h in order to get the
system call numbers for that platform. On AIX and IRIX, configure will
attempt to locate the necessary OpenAFS libraries for lsetpag (either
libafsauthent or libsys) but will not support deleting tokens at the end
of a session.
The module can optionally use Heimdal's libkafs library to obtain tokens
as well as create the PAG. If you are using Heimdal and obtaining
tokens from Kerberos tickets, this is the recommended configuration,
since it means that the PAM module doesn't have to fork an external
process. For other users, an external aklog program that obtains tokens
is necessary (and not provided by this module).
To obtain configuration information from krb5.conf and to support the
kdestroy option, either MIT Kerberos or Heimdal are required.
Testing the module requires a system with AFS installed and working so
that the PAG creation and manipulation can be tested. Running the
complete test suite also requires that you have an existing ticket cache
and working aklog program. Those portions of the test suite will be
skipped if AFS or a Kerberos ticket cache do not appear to be available.
To run the POD test suite, you must have the Perl 5.006 or later and the
modules Test::More and Test::Pod installed. Test::More comes with Perl
5.8 or later. Test::Pod is available from CPAN and currently must be
installed separately, but the POD tests will be skipped without
interfering with the rest of the tests if it's not installed.
To check spelling in the POD documentation, Pod::Spell (available from
CPAN) and either aspell or ispell with the american dictionary are also
required. The user's path is searched for aspell or ispell and aspell
is preferred. Spelling tests are disabled by default since spelling
dictionaries differ too much between systems. To enable those tests,
set RRA_MAINTAINER_TESTS to a true value.
To bootstrap from a Git checkout, or if you change the Automake files
and need to regenerate Makefile.in, you will need Automake 1.11 or
later. For bootstrap or if you change configure.ac or any of the m4
files it includes and need to regenerate configure or config.h.in, you
will need Autoconf 2.64 or later. Perl is also required to generate the
manual pages from a fresh Git checkout.
COMPILING AND INSTALLING
To build the module, just run:
./configure
make
Kerberos support is enabled by default if configure can find Kerberos
libraries. If your Kerberos libraries aren't installed in a location
found by your compiler by default and krb5-config isn't on your PATH,
use the --with-krb5=PATH option to configure. The Kerberos libraries
will then be expected in PATH/lib and the headers in PATH/include.
To specify a particular krb5-config script to use, either set the
KRB5_CONFIG environment variable or pass it to configure like:
./configure KRB5_CONFIG=/path/to/krb5-config
To not use krb5-config and force library probing even if there is a
krb5-config script on your path, set KRB5_CONFIG to a nonexistent path:
./configure KRB5_CONFIG=/nonexistent
To disable Kerberos support, even if you have Kerberos libraries
available, pass --without-krb5 to configure.
By default, the first aklog program found on the PATH will be compiled
into the module as the default aklog program to run. This can be
overridden by the program PAM option. To specify an explicit path to
aklog, use:
./configure --with-aklog=/path/to/aklog
instead.
To install the module into /usr/local/lib/security and the man page into
/usr/local/share/man/man5, run:
make install
You can change the installation locations with the --prefix, --mandir,
and --libdir options to configure. The module will normally be
installed in a subdirectory of $libdir named security, but if --prefix
is set to /usr (rather than /usr/local, the default), the module will be
installed in /lib/security (or /lib32/security or /lib64/security if
they exist) to match the default PAM configuration. Alternately, you
can simply copy pam_afs_session.so to whatever directory you use for PAM
modules. On Solaris, you will need to make the module executable.
By default, if libkafs or libkopenafs are available, pam-afs-session
will use them in preference to its own system call implementation. If
for some reason you want to build pam-afs-session without a dependency
on those libraries even though you have them installed, pass the
--without-libkafs flag to configure.
If you are building this module without libkafs on a platform other than
Linux, configure needs to find the AFS header afs/param.h. If this is
not in the normal include path, pass the --with-afs-headers option to
configure to point the compiler at the correct path. For example, if
your AFS headers are in /usr/afsws/include, run:
./configure --with-afs-headers=/usr/afsws/include
instead.
You can pass the --enable-reduced-depends flag to configure to try to
minimize the shared library dependencies encoded in the binaries. This
omits from the link line all the libraries included solely because
libkafs or the Kerberos libraries depend on them and instead links the
programs only against libraries whose APIs are called directly. This
will only work with shared libraries and will only work on platforms
where shared libraries properly encode their own dependencies (such as
Linux). It is intended primarily for building packages for Linux
distributions to avoid encoding unnecessary shared library dependencies
that make shared library migrations more difficult. If none of the
above made any sense to you, don't bother with this flag.
TESTING
pam-afs-session comes with a test suite, which you can run after
building pam-afs-session with:
make check
If a test case fails, please run the that individual test case with
verbose output using:
tests/runtests -o <name-of-test>
and send me the output when reporting the problem.
CONFIGURING
Just installing the module does not enable it or change anything about
your system authentication configuration. You have to add the module to
your PAM configuration, generally in the session group and possibly in
the auth group as well. See the platform-specific instructions below.
On all platforms, options can be put after the module name in the PAM
configuration file. This is useful if you don't have Kerberos libraries
available or if you want different configurations for different
services.
If Kerberos support was enabled, configuration options may also be put
in the krb5.conf file used by your Kerberos libraries (usually
/etc/krb5.conf or /usr/local/etc/krb5.conf) instead or in addition to
the PAM configuration. See the man page for more details. This is
recommended for general system configuration, since the krb5.conf
configuration syntax is a little nicer and more flexible.
See the files in the examples directory for examples of PAM
configuration for various operating systems. Contributions for
additional operating systems are welcome.
Linux
To use it in conjunction with pam_krb5 on a Debian system, put something
like:
auth [success=ok default=1] pam_krb5.so
auth [default=done] pam_afs_session.so program=/usr/bin/aklog
auth required pam_unix.so try_first_pass nullok_secure
in /etc/pam.d/common-auth and something like:
session optional pam_krb5.so
session required pam_afs_session.so program=/usr/bin/aklog
in /etc/pam.d/common-session. The program= setting is optional if
/usr/bin/aklog was in your path when the module was compiled or was
specified via the --with-aklog option to configure.
You may want to stack your Kerberos PAM module and the Unix module
differently, but note that this module should always run after the
Kerberos PAM module. If there is no ticket cache available in the PAM
environment, it will succeed silently.
On Red Hat systems, modify /etc/pam.d/system-auth instead; it contains
all of the configuration for the different stacks.
Be aware that the pam_keyinit module can have a bad interaction with
this module. pam_keyinit initializes a new kernel keyring and will
remove the keyring created by pam_afs_session to represent your PAG and
hold your tokens. pam_afs_session will attempt to detect this and add
the PAG and tokens back, but to do so it must run after pam_keyinit in
the session stack. To be safe, you may want to remove this PAM module
unless you're using it.
Note that this is not an authentication module and will always return
PAM_SUCCESS to any authentication attempt, so never make this module
sufficient in your authentication stack. It's only listed as an auth
module because it provides a pam_setcred implementation and some
programs need to call pam_setcred rather than pam_open_session (screen
savers, for instance, to refresh credentials).
Solaris
Solaris doesn't support the [] keywords that Linux PAM does, so if you
want to mark the Kerberos PAM module as sufficient and fall back on the
Unix module only if it fails, you won't be able to easily run
pam_afs_session in the auth group. For most applications, this isn't a
problem; running pam_afs_session only from the session group with
something like:
other session required /usr/local/lib/security/pam_afs_session.so
minimum_uid=100 retain_after_close
(all on one line) in /etc/pam.conf will be sufficient. Make sure this
line is after the Kerberos PAM module's session call.
However, note that login and dtlogin, at least under Solaris 10,
apparently call pam_open_session before pam_setcred, and the
open_session function of the native Kerberos PAM module doesn't set up
the ticket cache. This means that calling pam_afs_session only in the
session group won't work, since it will be called before the setcred
function of the Kerberos PAM module and hence won't have a ticket cache
available yet. There are two possible solutions: replace the native
Kerberos PAM module with another module, such as:
http://www.eyrie.org/~eagle/software/pam-krb5/
that does the same thing in open_session as in setcred, or also call
pam_afs_session from the auth group:
login auth required /usr/local/lib/security/pam_afs_session.so
minimum_uid=100
after the Kerberos PAM module (and likewise for dtlogin). This means
that you cannot use sufficient in the auth group for the Kerberos PAM
module, since that will then abort the group before pam_afs_session
runs.
See the man page for pam.conf on Solaris for more configuration
information.
HP-UX
HP-UX configuration is very similar to Solaris. Something like:
dtaction session required /usr/lib/security/pam_afs_session.so
dtlogin session required /usr/lib/security/pam_afs_session.so
login session required /usr/lib/security/pam_afs_session.so
OTHER session required /usr/lib/security/pam_afs_session.so
will use pam-afs-session for most login sessions.
Mac OS X
For Mac OS X, PAM isn't used for system login and is therefore mostly
useful for remote ssh. To use this module with sshd, add it to the
session group of the sshd PAM configuration, and it will then obtain
tokens with forwarded tickets via GSS-API or tickets obtained via
KerberosAuthentication.
Note that PAGs are not supported on Mac OS X, so you will need to add
the "nopag" parameter to the PAM configuration for this module. Note
also that while the latest Mac OS X ssh daemon supports GSS-API
authentication, it apparently doesn't make the forwarded tickets
available to the PAM stack, so pam-afs-session cannot properly set up
tokens during GSS-API login.
IMPLEMENTATION NOTES
pam-afs-session supports three basic usage patterns: creating a new
session using either pam_open_session or pam_setcred(PAM_ESTABLISH_CRED)
(or both), closing a session with pam_close_session or
pam_setcred(PAM_DELETE_CRED), and refreshing credentials with
pam_setcred(PAM_REINITIALIZE_CRED). In general, the same behavior
occurs whether using the pam_*_session interface or the pam_setcred
interface, since some PAM-using programs call one and some call the
other. In all cases, pam-afs-session will log an error and then
successfully exit if AFS doesn't appear to be running (checked with the
k_hasafs interface).
pam-afs-session stores a PAM data key named "pam_afs_session" once it
has successfully created a PAG and a token. If this key is present in
the PAM data when pam_open_session or pam_setcred with the
PAM_ESTABLISH_CRED flag is called, it will successfully do nothing to
keep from doing duplicate work. Otherwise, it will always create a PAG
and then will either call krb5_afslog or run an external program to
obtain tokens provided that the environment variable KRB5CCNAME is set
in the PAM environment.
If libkafs was found and used at compile time and if krb5_afslog is
available, the default is to run krb5_afslog to obtain tokens.
Otherwise, the default is to run whatever aklog program was found at
compile time. If program is set explicitly in the configuration,
pam-afs-session will always run that program rather than calling
krb5_afslog.
When pam_close_session or pam_setcred(PAM_DELETE_CRED) is called,
pam-afs-session will destroy the user's tokens only if the PAM data key
"pam_afs_session" is present (meaning that pam-afs-session previously
obtained tokens). This check is present to avoid deleting tokens when
session initialization failed, since in that case no new PAG may have
been created and we may be deleting tokens that are not ours to delete.
pam_setcred(PAM_REINITIALIZE_CRED) is treated similarly to the opening
of a new session except that no PAG is created. Instead, only the
program to obtain tokens is run, provided that KRB5CCNAME is set in the
PAM environment. This interface is used by programs such as screen
savers and lockers to refresh a user's credentials.
pam-afs-session requires that the user (obtained via pam_get_user)
exists in the local passwd file or equivalent (using getpwnam). If
running an external program, the program is run under that user's UID
and primary GID. If calling krb5_afslog, that user's UID is used for
the "AFS ID" field in the tokens display (which is entirely cosmetic).
HOMEPAGE AND SOURCE REPOSITORY
The pam-afs-session web page at:
http://www.eyrie.org/~eagle/software/pam-afs-session/
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
pam-afs-session is maintained using Git. You can access the current
source by cloning the repository at:
git://git.eyrie.org/afs/pam-afs-session.git
or view the repository via the web at:
http://git.eyrie.org/?p=afs/pam-afs-session.git
HISTORY AND ACKNOWLEDGEMENTS
Some of the ideas behind this PAM module (although not the code) are
taken from the libpam-openafs-session Debian package written by Sam
Hartman and the pam_afs2 module written by Douglas Engert. Thanks to
both of them for their previous work. Any errors in this implementation
are mine.
The Linux system call layer was based on inspection of the code in
OpenAFS and on discussions with Jeffrey Hutzelman on how best to
implement an AFS system call layer and on how the pieces work. I
couldn't have written this code without his explanations.
Thanks to Douglas Engert for an initial code review, for Solaris
porting, for suggesting the always_aklog and aklog_homedir options, and
for catching various other problems and missing features.
Thanks to Sean O'Malley for additional Solaris porting information and
for testing with the Sun C compiler.
Thanks to Joe Buehler for porting and testing on HP-UX.
Thanks to Markus Moeller for multiple patches and suggestions for
improved portability for pam-krb5, from which this module has also
benefitted.
LICENSE
The pam-afs-session package as a whole is covered by the following
copyright statement and license:
Copyright 2015 Russ Allbery <eagle@eyrie.org>
Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
The Board of Trustees of the Leland Stanford Junior University
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
All individual files without an explicit exception below are released
under this license. Some files may have additional copyright holders as
noted in those files. There is detailed information about the licensing
of each file in the LICENSE file in this distribution.
Some files in this distribution are individually released under
different licenses, all of which are compatible with the above general
package license but which may require preservation of additional
notices. All required notices are preserved in the LICENSE file. Each
file intended for copying into other software packages contains a
copyright and license notice at the top or bottom of the file. Please
take note of any attribution and notice requirements specified in that
license.