This commit was generated by cvs2svn to compensate for changes in r41220,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
jdp 1998-11-18 01:16:21 +00:00
commit b0d9083974
225 changed files with 41922 additions and 0 deletions

1091
contrib/libpam/CHANGELOG Normal file

File diff suppressed because it is too large Load Diff

41
contrib/libpam/Copyright Normal file
View File

@ -0,0 +1,41 @@
Unless otherwise *explicitly* stated the following text describes the
licensed conditions under which the contents of this Linux-PAM release
may be distributed:
-------------------------------------------------------------------------
Redistribution and use in source and binary forms of Linux-PAM, with
or without modification, are permitted provided that the following
conditions are met:
1. Redistributions of source code must retain any existing copyright
notice, and this entire permission notice in its entirety,
including the disclaimer of warranties.
2. Redistributions in binary form must reproduce all prior and current
copyright notices, this list of conditions, and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name of any author may not be used to endorse or promote
products derived from this software without their specific prior
written permission.
ALTERNATIVELY, this product may be distributed under the terms of the
GNU General Public License, in which case the provisions of the GNU
GPL are required INSTEAD OF the above restrictions. (This clause is
necessary due to a potential conflict between the GNU GPL and the
restrictions contained in a BSD-style copyright.)
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(S) 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
DAMAGE.
-------------------------------------------------------------------------

282
contrib/libpam/Makefile Normal file
View File

@ -0,0 +1,282 @@
##
## $Id: Makefile,v 1.31 1997/04/05 07:04:25 morgan Exp morgan $
##
## $Log: Makefile,v $
##
##
# major and minor numbers of this release
MAJOR_REL=0
MINOR_REL=65
DEBUG_REL=no
#DEBUG_REL=yes
# this should be the name of this directory
RELNAME = Linux-PAM-$(MAJOR_REL).$(MINOR_REL)
# this is the name of the archive file
DISTFILE = $(RELNAME).tar.gz
# define this to indicate to subdirectories that they are part of the
# full source tree.
FULL_LINUX_PAM_SOURCE_TREE=yes
export FULL_LINUX_PAM_SOURCE_TREE
DYNLOAD="dl"
DYNTYPE="so"
# Comment out either line to disable that type of linking for *modules only*
# Both at once is a legal configuration!
DYNAMIC=-DPAM_DYNAMIC
#STATIC=-DPAM_STATIC
# Comment out these lines to disable building dynamic/static libpam.*
DYNAMIC_LIBPAM=yes
#STATIC_LIBPAM=yes
# All combinations of the above four variable definitions are legal,
# however, not defining either dynamic or static modules and yet
# creating a some flavor of LIBPAM will make an authentication library
# that always fails!
# Here we indicate which libraries are present on the local system
# they control the building of some modules in this distribution
# Note, these definitions are all "export"ed below...
HAVE_PWDBLIB=no
HAVE_CRACKLIB=no
HAVE_AFSLIBS=no
HAVE_KRBLIBS=no
# NB. The following is the generic defines for compilation.
# They can be overridden in the default.defs file below
#
WARNINGS = -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
-Wpointer-arith -Wcast-qual -Wcast-align \
-Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
-Wnested-externs -Winline -Wshadow -pedantic
PIC=-fPIC
# Mode to install shared libraries with
SHLIBMODE=644
#
# Conditional defines..
#
ifdef DYNAMIC
# need the dynamic library functions
LIBDL=-l$(DYNLOAD)
ifdef STATIC_LIBPAM
# needed because pam_xxx() fn's are now in statically linked library
RDYNAMIC = -rdynamic
endif
endif
# Here we include the defines for the preferred operating system
# these include things like CC, CFLAGS and destination directories
# etc.. By default, this is a symbolic link to one of the .defs files
# the .../defs/ directory. Please take a moment to check that you are
# using the correct one.
include default.defs
# to turn on the fprintf(stderr, ..) debugging lines throughout the
# distribution uncomment this line
#EXTRAS += -DDEBUG
# For serious memory allocation tracing uncomment the following
#MEMORY_DEBUG=-DMEMORY_DEBUG
#######################################################################
# The pam_unix module in this file will not work on NIS based systems.#
#######################################################################
# ////////////////////////////////////////////////////
# // You should not modify anything below this line //
# ////////////////////////////////////////////////////
# the sub-directories to make things in
DIRS = modules libpam conf libpam_misc examples
#
# basic defines
#
INCLUDEDIR=-I$(shell pwd)/include
PAMLIB=-L$(shell pwd)/libpam
PAMMISCLIB=-L$(shell pwd)/libpam_misc
ifeq ($(DEBUG_REL),yes)
PAMLIB += -lpamd
PAMMISCLIB += -lpamd_misc
else
PAMLIB += -lpam
PAMMISCLIB += -lpam_misc
endif
# This is Linux-PAM and not a version from Sun etc..
# [Note, this does not describe the operating system you are using
# only that you are compiling the "Linux" (read FREE) implementation
# of Pluggable Authentication Modules.
EXTRAS += -DLINUX_PAM
#
# build composite defines
#
LOADLIBES = $(PAMLIB) $(RDYNAMIC) $(PAMMISCLIB) $(LIBDL) $(ULIBS)
CFLAGS += $(EXTRAS) $(MEMORY_DEBUG) $(WARNINGS) $(INCLUDEDIR) $(PIC)
ifneq ($(strip $(OS)),)
CFLAGS += -D$(OS)
endif
ifneq ($(strip $(ARCH)),)
CFLAGS += -D$(ARCH)
endif
#
# export the libraries-available info; the modules should know how
# to deal with this...
#
export HAVE_PWDBLIB
export HAVE_CRACKLIB
export HAVE_AFSLIBS
export HAVE_KRBLIBS
#
# generic exports
#
export MAJOR_REL # the major release of this distribution
export MINOR_REL # the minor release of this distribution
export DEBUG_REL # for installing a debugging version of PAM
export OS # operating system
export ARCH # architecture
export CC # the C compiler
export INSTALL # to do instalations with
export MKDIR # to ensure directories exist
export CFLAGS # CC flags used to compile everything
export LD_D # build a shared object file (module)
export LD_L # build a shared library (e.g. libpam)
export USESONAME # does shlib link command require soname option
export SOSWITCH # shlib lib soname switch name
export NEEDSONAME # does shared library link need versioned lib
export LD # build a generic library
export LDCONFIG # rebuild the shared libraries
export AR # build a static library
export RANLIB # reorder a static library
export LOADLIBES # libraries needed for application linking
export PAMLIB # where to find the local libpam.xx file
export DYNTYPE # which suffix is used for libraries
export SHLIBMODE # file mode for shared objects
#
# where to install things
#
export FAKEROOT # for package maintainers
#
export PREFIX # basic prefix for all other directories
export SUPLEMENTED # where to store module helper binaries
export LIBDIR # where libpam and libpam_misc go
export SECUREDIR # where the modules will be placed
export INCLUDED # where to store pam---.h files
export CONFIGED # where pam.conf and pam.d/ go
export SCONFIGED # where modules' config files go
#
# Conditional exporting ( ... these go on for a while... )
#
ifdef DYNAMIC
export DYNAMIC
endif
ifdef STATIC
export STATIC
endif
ifdef DYNAMIC_LIBPAM
export DYNAMIC_LIBPAM
endif
ifdef STATIC_LIBPAM
export STATIC_LIBPAM
endif
ifdef MEMORY_DEBUG
export MEMORY_DEBUG
endif
##
## the rules
##
all: .freezemake
@for i in $(DIRS) ; do \
$(MAKE) -C $$i all ; \
if [ $$? -ne 0 ]; then break ; fi ; \
done
.freezemake:
# Do nothing
.old_freezemake: Makefile
@touch .freezemake
@echo "*WARNING*: If you are running a system that is dependent"
@echo " on PAM to work. DO NOT make sterile NOR make remove."
@echo " These options will delete the PAM files on your system"
@echo " and make it unusable!"
@echo ""
@echo "If you are in any doubt, just do 'make all' (or just"
@echo "'make'). It is likely that this is the SAFEST thing to do...."
@exit 1
install:
@for i in $(DIRS) ; do \
$(MAKE) -C $$i install ; \
if [ $$? -ne 0 ]; then break ; fi ; \
done
install ./doc/man/*.3 $(PREFIX)/man/man3/
install ./doc/man/*.8 $(PREFIX)/man/man8/
sterile: .freezemake
@$(MAKE) remove
@$(MAKE) extraclean
remove: .freezemake
@for i in $(DIRS) ; do \
$(MAKE) -C $$i remove ; \
done
clean:
@rm -f *~ core
@for i in $(DIRS) ; do \
$(MAKE) -C $$i clean ; \
done
extraclean:
@for i in $(DIRS) doc; do \
$(MAKE) -C $$i extraclean ; \
done
check:
@$(MAKE) -C conf check
RCScheck:
@$(MAKE) -C conf RCScheck
# this can be used to see what hasn't been check'd into RCS
open:
@find . \( -type f -a -perm 644 \) -print
release:
@egrep '^DEBUG\_REL\=yes' Makefile|grep -v grep > /dev/null ;\
if [ $$? -eq 0 ]; then \
echo "You should first set DEBUG_REL to no" ; exit 1 ; fi
$(MAKE) extraclean
rm -f .freezemake
touch .filelist .RCSlist
chmod 600 .filelist .RCSlist
cd .. ; find $(RELNAME) \! -type d -print | fgrep -v RCS | fgrep -v 'conf/.md5sum' > $(RELNAME)/.filelist
cd .. ; find $(RELNAME) -type f -print | fgrep RCS | fgrep -v 'conf/.RCSsum' > $(RELNAME)/.RCSlist
chmod 400 .filelist .RCSlist
$(MAKE) check
$(MAKE) RCScheck
(cat .filelist ; echo $(RELNAME)/conf/.md5sum) | (cd .. ; tar -cz -f$(DISTFILE) -T-)
(cat .RCSlist ; echo $(RELNAME)/conf/.RCSsum) | (cd .. ; tar -cz -fRCS+$(DISTFILE) -T-)

167
contrib/libpam/README Normal file
View File

@ -0,0 +1,167 @@
#
# $Id: README,v 1.14 1997/04/05 07:04:46 morgan Exp $
#
Hello!
Thanks for downloading Linux-PAM-0.65.
--------------------------------------------------------------------
Before you begin:
* This distribution requires GNU's Make
* It requires GNU's C-compiler: gcc (and 'ld')
* it also requires the GNU shell: bash
* some of the modules require the presence of libpwdb see redhat
* two modules have some need for libcrack too..
--------------------------------------------------------------------
[
Zeroth (optional) thing to do: check the detatched "pgp" signature for
this distribution file, it should be signed by
Type Bits/KeyID Date User ID
pub 1024/2A398175 1996/11/17 Andrew G. Morgan <morgan@linux.kernel.org>
]
First thing to do (I assume you have successfully unpacked it!) is to
run:
make check [ requires md5sum to be present ]
This will also check that the distribution has arrived intact. [
Later, If you change some things, running this command from this
directory will show you what files you have altered. ]
If you choose to get and install the RCS files that accompany this
release, you may also run
make RCScheck
from this directory.
Next, you should check the symbolic link
.../Linux-PAM-X.YY/default.defs
points to the file that best describes your system. The various *.defs
files that are included in this distribution are to be found in the
directory:
.../Linux-PAM-X.YY/defs/
This should configure the distribution to compile on your system. The
default is the version I use for maintaining the distribution. [If you
don't find one that suits your needs, please try to create one, email
it to me and I will include it in a future release.]
If you are running an ELF based Linux system you should be able to
compile the distribution straight from the box. If you are running an
a.out based system, then some of the functionality of Linux-PAM will
be unavailable to you. Instead, you must switch the DYNAMIC variables
*off* in your "defs" file: comment out the DYNAMIC and DYNAMIC_LIBPAM
defines and uncomment the STATIC and STATIC_LIBPAM defines. NOTE, for
ELF based systems, almost any combination of these four definitions is
legal... If you have ELF, I recommend the default however.
Second, try to compile it. Use the following command in *this*
directory:
make
[ or 'make all' if you prefer ]. The first time you type make, it is
likely to complain. This is to remind you to remove any libraries from
previous versions of the distribution that are likely to confuse this
make... Type 'make' again.
Before you do the third thing. You should think about whether you want
the default configuration scripts to be installed or not. If you have
a working PAM based system you probably do *not* want this.. Whatever,
before Linux-PAM installs the default scripts you will be prompted as
to whether it is a good idea. Be sure to say NO if you are worried!
** You have been warned. **
Third, to install the stuff you need to be root. Do the following:
su -c "make install"
If everything has worked as intended there should now be
some executables in ./bin/
some filters for pam_filter in /usr/sbin/pam_filter/
some configuration files:
/etc/pam.conf
/etc/security/*.conf
libpam_misc.a (static library) in /usr/lib/
In addition:
if dynamically linked:
libpam.so.XXX (shared library) in /usr/lib/
libpam_misc.so.XXX (shared library) in /usr/lib/
pam_*.so (modules) in /usr/lib/security/
if statically linked:
libpam.a (static library) in /usr/lib/
[These are the default directories that I use. Your own system may
differ as specified in your XXX.defs file.]
NOTES:
* The documentation, what there is of it, is in ./doc. I am only
including the sgml format source-files. But try to make .ps files
available from the above http address. To locally use these sgml files
you should have linuxdoc-sgml installed. Sorry, but I'm conserving net
bandwidth by only including sources!
* The source for each module is to be found in ./modules/XXX. If you
want to add a new one, make a directory like XXX for it. Add the name
(XXX) to MODDIRS in ./modules/Makefile and hopefully it will become
part of the overall make. Note, the Makefile in ./modules/ is now
smart enough to check if the directory is there before it changes into
it; If you want to start working on a module, send me its name and I
will add it to the "official" Makefile.. This way, you should be able
to insert your developing module into any new release, and not have to
worry at first about letting it out to the public. This may also give
other people some idea about whether a module is currently being
worked on or not.
* Currently, you have to 'make' binaries from this directory. 'make
clean', however, works in any directory that has a Makefile.
* Also, you can 'make remove' (as root) from *this* directory and it
will delete the various installed files dotted around the system. THIS
IS A VERY BAD IDEA IF YOUR SYSTEM DEPENDS ON PAM TO WORK!!!
* 'make sterile' does 'make remove' and then 'make extraclean', this
might be required if you are alternating your choice of
STATIC(_LIBPAM) and DYNAMIC(_LIBPAM) compilation. SEE COMMENT IN
UPPERCASE IN PARAGRAPH ABOVE!!!!
Best wishes
Andrew Morgan
Email bugs/comments to: the Linux-PAM list <pam-list@redhat.com>
or me <morgan@linux.kernel.org>
To see about joining the mailing list, send the following email:
--------------------------------
To: pam-list-request@redhat.com
Subject: help
<empty text>
--------------------------------
Additionally, some Linux-PAM files have been known to be found at one
or more of the following places (they are not always the most up to
date...):
http://www.redhat.com/linux-info/pam/
ftp://bach.cis.temple.edu/pub/People/Alex/private/PAM
ftp://ftp.redhat.com/pub/misc/
ftp://linux.nrao.edu/pub/linux/ALPHA/PAM/
ftp://tsx-11.mit.edu/pub/linux/ALPHA/PAM/

59
contrib/libpam/TODO Normal file
View File

@ -0,0 +1,59 @@
$Id: TODO,v 1.10 1997/02/15 19:30:51 morgan Exp morgan $
Here are some things to think about if you are interested in
contributing to the Linux-PAM effort.
1. If you have a suggestion mail the pam-list!
2. TODO: Comments
----- --------
[modules]
pam_time should log an error if it denies access.
pam_smartcard?? It has already started to happen. (Alex Yuriev has a
smart-card module...)
pam_floppy?? A alternative login mechanism might involve
authenticating with a personal specially
formatted floppy!? (got to make some use of
all those strange Linux incompatible floppies
I keep getting from ISPs ;^)
pam_??? If you are interested in another type of
authentication method--just make a module!
If you want it registered/some help, email the
list.
[misc]
SVGA & X-conv Currently, libpam-misc contains a text-only
conversation function. A graphical one,
for X or SVGA would be very welcome,
[Ben Buxton is working on an X one (as of
1996/12/1)] applications like xlock
etc.. would benefit from this.
Issues that need to be resolved:
--------------------------------
- can we support the use_mapped_pass flag without running into problems
with ITAR rules? [this problem is likely to mutate. The DCE-RFC
people are considering the addition of a mapping module type - one
that other modules can use to safely store passwords...]
- anyone know where someone to email for FREE legal advice/support?
-----------
Comments to <pam-list@redhat.com>
(administrative requests to <pam-list-request@redhat.com> use
Subject: help
<empty_message>
)
-----------
Andrew Morgan <morgan@linux.kernel.org>.
http://linux.kernel.org/pub/linux/libs/pam/index.html

39
contrib/libpam/bin/README Normal file
View File

@ -0,0 +1,39 @@
##
# $Id: README,v 1.6 1997/02/15 19:21:08 morgan Exp $
##
# $Log: README,v $
# Revision 1.6 1997/02/15 19:21:08 morgan
# fixed email
#
# Revision 1.5 1996/08/09 05:29:43 morgan
# trimmed in line with the removal of applications from the distribution
#
#
##
(now we are getting networked apps, be careful to try and test on a
securely isolated system!)
N=2 <-- blank xsh
Following a 'make install' (which should be done as root) in the
parent directory this directory will contain $N binaries. The source
for these programs is in ../examples. They are various short programs
to use and otherwise test-drive the Linux-PAM libraries/modules with.
These programs grant no privileges, but they give an idea of how well
the modules are working.
blank is new as of Linux-PAM-0.21. If you are writing/modifying an
application it might be a place to start...
xsh is new as of Linux-PAM-0.31, it is identical to blank, but invokes
/bin/sh if the user is authenticated.
[other apps are to be found in SimplePAMApps and many more on Red
Hat's server.. http://www.redhat.com/]
Best wishes
Andrew
(morgan@parc.power.net)

View File

@ -0,0 +1,60 @@
#
# $Id: Makefile,v 1.8 1997/04/05 06:59:33 morgan Exp $
#
# $Log: Makefile,v $
# Revision 1.8 1997/04/05 06:59:33 morgan
# fakeroot and $(MAKE)
#
# Revision 1.7 1997/02/15 15:53:51 morgan
# added lines to make pam_conv1
#
# Revision 1.6 1996/11/10 19:48:09 morgan
# fix for systems that have not installed bash in /bin/
#
# Revision 1.5 1996/03/16 22:21:26 morgan
# added 'make remove' option
#
# Revision 1.4 1996/03/10 21:01:47 morgan
# added .ignore_age flag file
#
# Revision 1.3 1996/03/10 17:41:28 morgan
# make RCScheck check for the presence of the executable before running
# it!
#
# Revision 1.2 1996/03/10 17:16:42 morgan
# added md5RCS/ RCScheck entry
#
#
dummy:
@echo "*** This is not a top level Makefile!"
##########################################################
all:
$(MAKE) -C pam_conv1 all
install: $(FAKEROOT)$(CONFIGED)/pam.conf
$(MAKE) -C pam_conv1 install
$(FAKEROOT)$(CONFIGED)/pam.conf: ./pam.conf
bash -f ./install_conf
remove:
rm -f $(FAKEROOT)$(CONFIGED)/pam.conf
$(MAKE) -C pam_conv1 remove
check:
bash -f ./md5itall
RCScheck:
if [ -x ./md5RCS ]; then bash -f ./md5RCS ; fi
lclean:
rm -f core *~ .ignore_age
clean: lclean
$(MAKE) -C pam_conv1 clean
extraclean: lclean
$(MAKE) -C pam_conv1 extraclean

178
contrib/libpam/conf/install Executable file
View File

@ -0,0 +1,178 @@
#!/bin/sh
#
# [This file was lifted from an X distribution. There was no explicit
# copyright in the file, but the following text was associated with it.
# should anyone from the X Consortium wish to alter the following
# text. Please email <morgan@parc.power.net> Thanks. ]
#
# --------------------------
# The X Consortium maintains and distributes the X Window System and
# related software and documentation in coordinated releases. A release
# consists of two distinct parts:
#
# 1) Specifications and Sample implementations of X Consortium
# standards, and
#
# 2) software and documentation contributed by the general X Consortium
# community.
#
# The timing and contents of a release are determined by the Consortium
# staff based on the needs and desires of the Members and the advice of
# the Advisory Board, tempered by the resource constraints of the
# Consortium.
#
# Members have access to all X Consortium produced software and
# documentation prior to release to the public. Each Member can receive
# pre-releases and public releases at no charge. In addition, Members
# have access to software and documentation while it is under
# development, and can periodically request snapshots of the development
# system at no charge.
#
# The X Consortium also maintains an electronic mail system for
# reporting problems with X Consortium produced software and
# documentation. Members have access to all bug reports, as well as all
# software patches as they are incrementally developed by the Consortium
# staff between releases.
#
# In general, all materials included in X Consortium releases are
# copyrighted and contain permission notices granting unrestricted use,
# sales and redistribution rights provided that the copyrights and the
# permission notices are left intact. All materials are provided "as
# is," without express or implied warranty.
# --------------------------
#
# This accepts bsd-style install arguments and makes the appropriate calls
# to the System V install.
#
flags=""
dst=""
src=""
dostrip=""
owner=""
mode=""
while [ x$1 != x ]; do
case $1 in
-c) shift
continue;;
-m) flags="$flags $1 $2 "
mode="$2"
shift
shift
continue;;
-o) flags="$flags -u $2 "
owner="$2"
shift
shift
continue;;
-g) flags="$flags $1 $2 "
shift
shift
continue;;
-s) dostrip="strip"
shift
continue;;
*) if [ x$src = x ]
then
src=$1
else
dst=$1
fi
shift
continue;;
esac
done
case "$mode" in
"")
;;
*)
case "$owner" in
"")
flags="$flags -u root"
;;
esac
;;
esac
if [ x$src = x ]
then
echo "$0: no input file specified"
exit 1
fi
if [ x$dst = x ]
then
echo "$0: no destination specified"
exit 1
fi
# set up some variable to be used later
rmcmd=""
srcdir="."
# if the destination isn't a directory we'll need to copy it first
if [ ! -d $dst ]
then
dstbase=`basename $dst`
cp $src /tmp/$dstbase
rmcmd="rm -f /tmp/$dstbase"
src=$dstbase
srcdir=/tmp
dst="`echo $dst | sed 's,^\(.*\)/.*$,\1,'`"
if [ x$dst = x ]
then
dst="."
fi
fi
# If the src file has a directory, copy it to /tmp to make install happy
srcbase=`basename $src`
if [ "$src" != "$srcbase" -a "$src" != "./$srcbase" ]
then
cp $src /tmp/$srcbase
src=$srcbase
srcdir=/tmp
rmcmd="rm -f /tmp/$srcbase"
fi
# do the actual install
if [ -f /usr/sbin/install ]
then
installcmd=/usr/sbin/install
elif [ -f /etc/install ]
then
installcmd=/etc/install
else
installcmd=install
fi
# This rm is commented out because some people want to be able to
# install through symbolic links. Uncomment it if it offends you.
rm -f $dst/$srcbase
(cd $srcdir ; $installcmd -f $dst $flags $src)
if [ x$dostrip = xstrip ]
then
strip $dst/$srcbase
fi
# and clean up
$rmcmd
exit

View File

@ -0,0 +1,36 @@
#!/bin/bash
CONFILE="$FAKEROOT"$CONFIGED/pam.conf
IGNORE_AGE=./.ignore_age
CONF=./pam.conf
echo
if [ -f "$IGNORE_AGE" ]; then
echo "you don't want to be bothered with the age of your $CONFILE file"
yes="n"
elif [ ! -f "$CONFILE" ] || [ "$CONF" -nt "$CONFILE" ]; then
if [ -f "$CONFILE" ]; then
echo "\
An older Linux-PAM configuration file already exists ($CONFILE)"
WRITE=overwrite
fi
echo -n "\
Do you wish to copy the $CONF file in this distribution
to $CONFILE ? (y/n) [n] "
read yes
else
yes=n
fi
if [ "$yes" = "y" ]; then
echo " copying $CONF to $CONFILE"
cp $CONF $CONFILE
else
touch "$IGNORE_AGE"
echo " Skipping $CONF installation"
fi
echo
exit 0

45
contrib/libpam/conf/md5itall Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
#
# $Id$
#
# $Log$
#
# Created by Andrew G. Morgan (morgan@parc.power.net)
#
MD5SUM=md5sum
CHKFILE1=./.md5sum
CHKFILE2=./.md5sum-new
which $MD5SUM > /dev/null
result=$?
if [ -x "$MD5SUM" ] || [ $result -eq 0 ]; then
rm -f $CHKFILE2
echo -n "computing md5 checksums."
for x in `cat ../.filelist` ; do
(cd ../.. ; $MD5SUM $x) >> $CHKFILE2
echo -n "."
done
echo
if [ -f "$CHKFILE1" ]; then
echo "\
---> Note, since the last \`make check', the following file(s) have changed:
==========================================================================="
diff $CHKFILE1 $CHKFILE2
if [ $? -eq 0 ]; then
echo "\
--------------------------- Nothing has changed ---------------------------"
fi
echo "\
==========================================================================="
fi
rm -f "$CHKFILE1"
mv "$CHKFILE2" "$CHKFILE1"
chmod 400 "$CHKFILE1"
else
echo "\
Please install \`$MD5SUM'.
[It is used to check the integrity of this distribution]
---> no check done."
fi

50
contrib/libpam/conf/mkdirp Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
#
# this is a wrapper for difficult mkdir programs...
#
for d in $*
do
if [ ! -d $d ]; then
mkdir -p $d
if [ $? -ne 0 ]; then exit $? ; fi
fi
done
exit 0
##########################################################################
# if your mkdir does not support the -p option delete the above lines and
# use what follows:
--------------------
#!/bin/sh
#VERBOSE=yes
Cwd=`pwd`
for d in $*
do
if [ "`echo $d|cut -c1`" != "/" ]; then
x=`pwd`/$d
else
x=$d
fi
x="`echo $x|sed -e 'yX/X X'`"
cd /
for s in $x
do
if [ -d $s ]; then
if [ -n "$VERBOSE" ]; then echo -n "[$s/]"; fi
cd $s
else
mkdir $s
if [ $? -ne 0 ]; then exit $? ; fi
if [ -n "$VERBOSE" ]; then echo -n "$s/"; fi
cd $s
fi
done
if [ -n "$VERBOSE" ]; then echo ; fi
cd $Cwd
done
exit 0

View File

@ -0,0 +1,126 @@
# ---------------------------------------------------------------------------#
# /etc/pam.conf #
# #
# Last modified by Andrew G. Morgan <morgan@parc.power.net> #
# ---------------------------------------------------------------------------#
# $Id: pam.conf,v 1.18 1997/02/15 20:20:20 morgan Exp morgan $
# ---------------------------------------------------------------------------#
# serv. module ctrl module [path] ...[args..] #
# name type flag #
# ---------------------------------------------------------------------------#
#
# The PAM configuration file for the `chfn' service
#
chfn auth required pam_pwdb.so
chfn account required pam_pwdb.so
chfn password required pam_cracklib.so retry=3
chfn password required pam_pwdb.so shadow md5 use_authtok
#
# The PAM configuration file for the `chsh' service
#
chsh auth required pam_pwdb.so
chsh account required pam_pwdb.so
chsh password required pam_cracklib.so retry=3
chsh password required pam_pwdb.so shadow md5 use_authtok
#
# The PAM configuration file for the `ftp' service
#
ftp auth requisite pam_listfile.so \
item=user sense=deny file=/etc/ftpusers onerr=succeed
ftp auth requisite pam_shells.so
ftp auth required pam_pwdb.so
ftp account required pam_pwdb.so
#
# The PAM configuration file for the `imap' service
#
imap auth required pam_pwdb.so
imap account required pam_pwdb.so
#
# The PAM configuration file for the `login' service
#
login auth requisite pam_securetty.so
login auth required pam_pwdb.so
login auth optional pam_group.so
login account requisite pam_time.so
login account required pam_pwdb.so
login password required pam_cracklib.so retry=3
login password required pam_pwdb.so shadow md5 use_authtok
login session required pam_pwdb.so
#
# The PAM configuration file for the `netatalk' service
#
netatalk auth required pam_pwdb.so
netatalk account required pam_pwdb.so
#
# The PAM configuration file for the `other' service
#
other auth required pam_deny.so
other auth required pam_warn.so
other account required pam_deny.so
other password required pam_deny.so
other password required pam_warn.so
other session required pam_deny.so
#
# The PAM configuration file for the `passwd' service
#
passwd password requisite pam_cracklib.so retry=3
passwd password required pam_pwdb.so shadow md5 use_authtok
#
# The PAM configuration file for the `rexec' service
#
rexec auth requisite pam_securetty.so
rexec auth requisite pam_nologin.so
rexec auth sufficient pam_rhosts_auth.so
rexec auth required pam_pwdb.so
rexec account required pam_pwdb.so
rexec session required pam_pwdb.so
rexec session required pam_limits.so
#
# The PAM configuration file for the `rlogin' service
# this application passes control to `login' if it fails
#
rlogin auth requisite pam_securetty.so
rlogin auth requisite pam_nologin.so
rlogin auth required pam_rhosts_auth.so
rlogin account required pam_pwdb.so
rlogin password required pam_cracklib.so retry=3
rlogin password required pam_pwdb.so shadow md5 use_authtok
rlogin session required pam_pwdb.so
rlogin session required pam_limits.so
#
# The PAM configuration file for the `rsh' service
#
rsh auth requisite pam_securetty.so
rsh auth requisite pam_nologin.so
rsh auth sufficient pam_rhosts_auth.so
rsh auth required pam_pwdb.so
rsh account required pam_pwdb.so
rsh session required pam_pwdb.so
rsh session required pam_limits.so
#
# The PAM configuration file for the `samba' service
#
samba auth required pam_pwdb.so
samba account required pam_pwdb.so
#
# The PAM configuration file for the `su' service
#
su auth required pam_wheel.so
su auth sufficient pam_rootok.so
su auth required pam_pwdb.so
su account required pam_pwdb.so
su session required pam_pwdb.so
#
# The PAM configuration file for the `vlock' service
#
vlock auth required pam_pwdb.so
#
# The PAM configuration file for the `xdm' service
#
xdm auth required pam_pwdb.so
xdm account required pam_pwdb.so
#
# The PAM configuration file for the `xlock' service
#
xlock auth required pam_pwdb.so

View File

@ -0,0 +1,41 @@
#
#
ifeq ($(OS),solaris)
clean:
@echo not available in Solaris
all:
@echo not available in Solaris
install:
@echo not available in Solaris
else
all: pam_conv1
pam_conv1: pam_conv.tab.c lex.yy.c
$(CC) -o pam_conv1 pam_conv.tab.c -lfl
pam_conv.tab.c: pam_conv.y lex.yy.c
bison pam_conv.y
lex.yy.c: pam_conv.lex
flex pam_conv.lex
lclean:
rm -f core pam_conv1 lex.yy.c pam_conv.tab.c *.o *~
rm -rf ./pam.d pam_conv.output
clean: lclean
install: pam_conv1
cp -f ./pam_conv1 ../../bin
endif
remove:
rm -f ../../bin/pam_conv1
extraclean: remove clean

View File

@ -0,0 +1,10 @@
$Id: README,v 1.1 1997/02/15 15:50:50 morgan Exp $
This directory contains a untility to convert pam.conf files to a pam.d/
tree. The conversion program takes pam.conf from the standard input and
creates the pam.d/ directory in the current directory.
The program will fail if ./pam.d/ already exists.
Andrew Morgan, February 1997

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
%{
/*
* $Id: pam_conv.lex,v 1.1 1997/01/23 05:35:50 morgan Exp $
*
* Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
*
* This file is covered by the Linux-PAM License (which should be
* distributed with this file.)
*/
const static char lexid[]=
"$Id: pam_conv.lex,v 1.1 1997/01/23 05:35:50 morgan Exp $\n"
"Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>\n";
extern int current_line;
%}
%%
"#"[^\n]* ; /* skip comments (sorry) */
"\\\n" {
++current_line;
}
([^\n\t ]|[\\][^\n])+ {
return TOK;
}
[ \t]+ ; /* Ignore */
<<EOF>> {
return EOFILE;
}
[\n] {
++current_line;
return NL;
}
%%

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
%{
/*
* $Id: pam_conv.y,v 1.3 1997/02/15 15:50:50 morgan Exp morgan $
*
* Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
*
* This file is covered by the Linux-PAM License (which should be
* distributed with this file.)
*/
const static char bisonid[]=
"$Id: pam_conv.y,v 1.3 1997/02/15 15:50:50 morgan Exp morgan $\n"
"Copyright (c) Andrew G. Morgan 1997-8 <morgan@linux.kernel.org>\n";
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
int current_line=1;
extern char *yytext;
/* XXX - later we'll change this to be the specific conf file(s) */
#define newpamf stderr
#define PAM_D "./pam.d"
#define PAM_D_MODE 0755
#define PAM_D_MAGIC_HEADER \
"#%PAM-1.0\n" \
"#[For version 1.0 syntax, the above header is optional]\n"
#define PAM_D_FILE_FMT PAM_D "/%s"
const char *old_to_new_ctrl_flag(const char *old);
void yyerror(const char *format, ...);
%}
%union {
int def;
char *string;
}
%token NL EOFILE TOK
%type <string> tok path tokenls
%start complete
%%
complete
:
| complete NL
| complete line
| complete EOFILE {
return 0;
}
;
line
: tok tok tok path tokenls NL {
char *filename;
FILE *conf;
int i;
/* make sure we have lower case */
for (i=0; $1[i]; ++i) {
$1[i] = tolower($1[i]);
}
/* $1 = service-name */
yyerror("Appending to " PAM_D "/%s", $1);
filename = malloc(strlen($1) + sizeof(PAM_D) + 6);
sprintf(filename, PAM_D_FILE_FMT, $1);
conf = fopen(filename, "r");
if (conf == NULL) {
/* new file */
conf = fopen(filename, "w");
if (conf != NULL) {
fprintf(conf, PAM_D_MAGIC_HEADER);
fprintf(conf,
"#\n"
"# The PAM configuration file for the `%s' service\n"
"#\n", $1);
}
} else {
fclose(conf);
conf = fopen(filename, "a");
}
if (conf == NULL) {
yyerror("trouble opening %s - aborting", filename);
exit(1);
}
free(filename);
/* $2 = module-type */
fprintf(conf, "%-10s", $2);
free($2);
/* $3 = required etc. */
{
const char *trans;
trans = old_to_new_ctrl_flag($3);
free($3);
fprintf(conf, " %-10s", trans);
}
/* $4 = module-path */
fprintf(conf, " %s", $4);
free($4);
/* $5 = arguments */
if ($5 != NULL) {
fprintf(conf, " \\\n\t\t%s", $5);
free($5);
}
/* end line */
fprintf(conf, "\n");
fclose(conf);
}
| error NL {
yyerror("malformed line");
}
;
tokenls
: {
$$=NULL;
}
| tokenls tok {
int len;
if ($1) {
len = strlen($1) + strlen($2) + 2;
$$ = malloc(len);
sprintf($$,"%s %s",$1,$2);
free($1);
free($2);
} else {
$$ = $2;
}
}
;
path
: TOK {
/* XXX - this could be used to check if file present */
$$ = strdup(yytext);
}
tok
: TOK {
$$ = strdup(yytext);
}
%%
#include "lex.yy.c"
const char *old_to_new_ctrl_flag(const char *old)
{
static const char *clist[] = {
"requisite",
"required",
"sufficient",
"optional",
NULL,
};
int i;
for (i=0; clist[i]; ++i) {
if (strcasecmp(clist[i], old) == 0) {
break;
}
}
return clist[i];
}
void yyerror(const char *format, ...)
{
va_list args;
fprintf(stderr, "line %d: ", current_line);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
}
void main()
{
if (mkdir(PAM_D, PAM_D_MODE) != 0) {
yyerror(PAM_D " already exists.. aborting");
exit(1);
}
yyparse();
}

View File

@ -0,0 +1,36 @@
##
# HPUX defs contributed by Derrick J Brashear <shadow@dementia.org>
##
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the default version. Please look in .../defs/ for your
# preferred OS/vendor.
OS=hpux9
ARCH=hpux
CC=gcc
INSTALL=install
MKDIR=mkdir -p
CFLAGS=-g -DPAM_SHL -DHAVE_UTMP_H
ULIBS=
LD=ld
LD_D=$(LD) -b
LD_L=$(LD) -b
USESONAME=no
NEEDSONAME=no
LDCONFIG=:
AR=ar -cr
RANLIB=ranlib
FAKEROOT=
PREFIX=/usr
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security
DYNLOAD="dld"
DYNTYPE="sl"
SHLIBMODE=755

View File

@ -0,0 +1,32 @@
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the default version. Please look in .../defs/ for your
# preferred OS/vendor.
OS=linux
ARCH=`uname -m | sed 's/^i?86/i386/'`
CC=gcc
INSTALL=install
MKDIR=mkdir -p
CFLAGS=-O7 -pipe -g
ULIBS=#-lefence
LD=ld
LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
SOSWITCH=-soname
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
AR=ar -cr
RANLIB=ranlib
FAKEROOT=
PREFIX=/usr
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security
NSLLIB=-lnsl

View File

@ -0,0 +1,35 @@
##
# defs for Andrew's debugging version (which is a modified Red Hat
# box)
##
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the version used for Red Hat Linux.
OS=linux
ARCH=i386
CC=gcc
INSTALL=install
MKDIR=mkdir -p
CFLAGS=$(RPM_OPT_FLAGS) -pipe -g
ULIBS=
#-lefence
LD=ld
LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
SOSWITCH=-soname
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
AR=ar -cr
RANLIB=ranlib
FAKEROOT=$(RPM_BUILD_ROOT)
PREFIX=
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security.d
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security

View File

@ -0,0 +1,34 @@
##
# defs for Red Hat Linux
# Michael K. Johnson <johnsonm@redhat.com>
##
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the version used for Red Hat Linux.
OS=linux
ARCH=$(shell rpm --showrc | grep 'build arch' | sed 's/^.*: //g')
CC=gcc
INSTALL=install
MKDIR=mkdir -p
CFLAGS=$(RPM_OPT_FLAGS) -pipe -g
ULIBS=#-lefence
LD=ld
LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
SOSWITCH=-soname
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
AR=ar -cr
RANLIB=ranlib
FAKEROOT=$(RPM_BUILD_ROOT)
PREFIX=
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security

View File

@ -0,0 +1,48 @@
##
# Solaris defs contributed by Josh Wilmes <josh@makita.jpl.nasa.gov>
##
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the default version. Please look in .../defs/ for your
# preferred OS/vendor.
# Please note that the linker used must be the GNU ld, not the native Sun
# linker. It is fairly common for the gnu linker (/usr/ccs/bin/ld) to be
# configured as the default linker for gcc. To tell gcc to use the
# gnu linker, you need to set the GCC_EXEC_PREFIX environment variable
# to point at the directory where the gnu linker is installed. Here's
# what I do:
# $ mkdir /tmp/foo
# $ ln -s /path/to/gnu/ld /tmp/foo/ld
# $ export GCC_EXEC_PREFIX=/tmp/foo/
# $ export PATH=/tmp/foo:$PATH
OS=solaris
ARCH=sun
CC=cc
INSTALL=install
MKDIR=mkdir -p
WARNINGS = -D_POSIX_SOURCE
PIC=-KPIC
CFLAGS=-g -D__EXTENSIONS__ -Dsolaris
ULIBS=
LD=ld
LD_L=$(LD) -G
LD_D=$(LD_L)
RDYNAMIC=
USESONAME=yes
SOSWITCH=-h
NEEDSONAME=no
LDCONFIG=echo
AR=ar -cr
RANLIB=ranlib
FAKEROOT=
PREFIX=/usr
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security

View File

@ -0,0 +1,37 @@
##
# SunOS defs contributed by Derrick J Brashear <shadow@dementia.org>
##
# this file indicates the compiler and the various hardware/OS dependent
# flags for installation. It also defines the various destinations of
# installed files on the system.
#
# This file is the SunOS version. Please look in .../defs/ for your
# preferred OS/vendor.
OS=sunos
ARCH=sun
CC=gcc
INSTALL=install
MKDIR=mkdir -p
CFLAGS=-O2 -pipe -g -D__EXTENSIONS__
ULIBS=
LD_D=gcc -shared -Xlinker -x
LD=ld
LD_L=$(LD)
USESONAME=no
NEEDSONAME=yes
LDCONFIG=/usr/etc/ldconfig
AR=ar cr
RANLIB=ranlib
FAKEROOT=
PREFIX=/usr
SUPLEMENTED=$(PREFIX)/sbin
LIBDIR=$(PREFIX)/lib
SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security
WARNINGS= -ansi -Wall -Wwrite-strings \
-Wpointer-arith -Wcast-qual -Wcast-align \
-Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
-Wnested-externs -Winline -Wshadow

View File

@ -0,0 +1,37 @@
<!--
an sgml list of people to credit for their contributions to Linux-PAM
$Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
-->
Peter Allgeyer,
Tim Baverstock,
Craig S. Bell,
Derrick J. Brashear,
Ben Buxton,
Oliver Crow,
Chris Dent,
Marc Ewing,
Cristian Gafton,
Eric Hester,
Roger Hu,
Eric Jacksch,
Michael K. Johnson,
David Kinchlea,
Nicolai Langfeldt,
Elliot Lee,
Al Longyear,
Ingo Luetkebohle,
Marek Michalkiewicz,
Aleph One,
Martin Pool,
Sean Reifschneider,
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.

View File

@ -0,0 +1,77 @@
### $Id: Makefile,v 1.9 1997/01/04 21:55:52 morgan Exp $
TXTER=sgml2txt
HTMLER=sgml2html
# older distributions use, sgml2ps
PSER=sgml2latex -p
FILES=pam pam_appl pam_modules
FSRCS=pam.sgml pam_appl.sgml pam_modules.sgml
TEXTS=txts/pam.txt txts/pam_appl.txt txts/pam_modules.txt
HTMLS=html/pam.html html/pam_appl.html html/pam_modules.html
PSFILES=ps/pam.ps ps/pam_appl.ps ps/pam_modules.ps
MODULES=$(shell ls modules/*.sgml)
#######################################################
dummy:
@echo "Making the documentation..."
@make all
all: htmls texts postscript
htmls: $(HTMLS)
$(HTMLS) : $(FSRCS)
@for i in $(FILES) ; do \
if [ ! -f "html/$$i.html" ] || [ "$$i.sgml" -nt "html/$$i.html" ]; \
then \
cd html ; $(HTMLER) ../$$i ; \
if [ $$? -ne 0 ]; then exit 1 ; fi ; \
cd .. ; \
fi ; \
done
texts: $(TEXTS)
$(TEXTS) : $(FSRCS)
@for i in $(FILES) ; do \
if [ ! -f "txts/$$i.txt" ] \
|| [ "$$i.sgml" -nt "txts/$$i.txt" ]; then \
cd txts ; $(TXTER) ../$$i ; cd .. ; \
fi ; \
done
postscript: $(PSFILES)
$(PSFILES): $(FSRCS)
@for i in $(FILES) ; do \
if [ ! -f "ps/$$i.ps" ] || [ "$$i.sgml" -nt "ps/$$i.ps" ]; then \
cd ps ; $(PSER) ../$$i ; cd .. ; \
fi ; \
done
pam.sgml: pam_source.sgml MODULES-SGML
@sed -e '/^<!\-\- insert\-file MODULES\-SGML \-\->/r MODULES-SGML' pam_source.sgml > pam.sgml
MODULES-SGML: $(MODULES)
@echo 'Building module text from files in modules/*.sgml'
@rm -f MODULES-SGML
@echo '<!-- modules included:' > MODULES-SGML
@ls modules/*.sgml >> MODULES-SGML
@echo ' and that is all -->' >> MODULES-SGML
@cat modules/*.sgml >> MODULES-SGML
extraclean: clean
clean:
rm -f *~ *.bak
rm -f html/pam*.html
rm -f man/*~
rm -f $(TEXTS)
rm -f $(PSFILES)
rm -f MODULES-SGML pam.sgml

16
contrib/libpam/doc/NOTES Normal file
View File

@ -0,0 +1,16 @@
Things to be added:
@ modules:
@ application:
use of
'user' = user to become,
'uid' = user requesting service
'euid' = privilege of current process.
@ sysadmin:
included modules:
behavior
non-included modules:
behavior/pointers.

View File

@ -0,0 +1,23 @@
+----------------+
| application: X |
+----------------+ / +----------+ +================+
| authentication-[---->--\--] Linux- |--<--| /etc/pam.conf |
| + [----<--/--] PAM | |================|
|[conversation()][--+ \ | | | X auth .. a.so |
+----------------+ | / +-n--n-----+ | X auth .. b.so |
| | | __| | | _____/
| service user | A | | |____,-----'
| | | V A
+----------------+ +------|-----|---------+ -----+------+
+---u-----u----+ | | |
| auth.... |--[ a ]--[ b ]--[ c ]
+--------------+
| acct.... |--[ b ]--[ d ]
+--------------+
| password |--[ b ]--[ c ]
+--------------+
| session |--[ e ]--[ c ]
+--------------+

View File

@ -0,0 +1,21 @@
<HTML>
<HEAD>
<TITLE>Linux-PAM - Pluggable Authentication Modules for Linux</TITLE>
</HEAD>
<BODY>
<p>
Here is the documentation for Linux-PAM. As you will see it is
currently not complete. However, in order of decreasing length:
<ul>
<li> <a href="pam.html">The System Administrators' Guide</a>
<li> <a href="pam_modules.html">The Module Writers' Manual</a>
<li> <a href="pam_appl.html">The Application developers' Manual</a>
</ul>
<hr>
<p>
REVISION: <tt>$Id: index.html,v 1.4 1996/11/21 06:51:01 morgan Exp $</tt>
</BODY>

View File

@ -0,0 +1,279 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam.8,v 1.2 1997/02/15 18:37:27 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@linux.kernel.org>
.TH PAM 8 "1997 Feb 9" "Linux-PAM 0.56" "Linux-PAM Manual"
.SH NAME
Linux-PAM \- Pluggable Authentication Modules for Linux
.SH SYNOPSIS
.B /etc/pam.conf
.sp 2
.SH DESCRIPTION
This manual is intended to offer a quick introduction to
.BR Linux-PAM ". "
For more information the reader is directed to the
.BR "Linux-PAM system administrators' guide".
.sp
.BR Linux-PAM
Is a system of libraries that handle the authentication tasks of
applications (services) on the system. The library provides a stable
general interface (Application Programming Interface - API) that
privilege granting programs (such as
.BR login "(1) "
and
.BR su "(1)) "
defer to to perform standard authentication tasks.
.sp
The principal feature of the PAM approach is that the nature of the
authentication is dynamically configurable. In other words, the
system administrator is free to choose how individual
service-providing applications will authenticate users. This dynamic
configuration is set by the contents of the single
.BR Linux-PAM
configuration file
.BR /etc/pam.conf "."
Alternatively, the configuration can be set by individual
configuration files located in the
.B /etc/pam.d/
directory.
.IB "The presence of this directory will cause " Linux-PAM " to ignore"
.BI /etc/pam.conf "."
.sp
From the point of view of the system administrator, for whom this
manual is provided, it is not of primary importance to understand the
internal behavior of the
.BR Linux-PAM
library. The important point to recognize is that the configuration
file(s)
.I define
the connection between applications
.BR "" "(" services ")"
and the pluggable authentication modules
.BR "" "(" PAM "s)"
that perform the actual authentication tasks.
.sp
.BR Linux-PAM
separates the tasks of
.I authentication
into four independent management groups:
.BR "account" " management; "
.BR "auth" "entication management; "
.BR "password" " management; "
and
.BR "session" " management."
(We highlight the abbreviations used for these groups in the
configuration file.)
.sp
Simply put, these groups take care of different aspects of a typical
user's request for a restricted service:
.sp
.BR account " - "
provide account verification types of service: has the user's password
expired?; is this user permitted access to the requested service?
.br
.BR auth "entication - "
establish the user is who they claim to be. Typically this is via some
challenge-response request that the user must satisfy: if you are who
you claim to be please enter your password. Not all authentications
are of this type, there exist hardware based authentication schemes
(such as the use of smart-cards and biometric devices), with suitable
modules, these may be substituted seamlessly for more standard
approaches to authentication - such is the flexibility of
.BR Linux-PAM "."
.br
.BR password " - "
this group's responsibility is the task of updating authentication
mechanisms. Typically, such services are strongly coupled to those of
the
.BR auth
group. Some authentication mechanisms lend themselves well to being
updated with such a function. Standard UN*X password-based access is
the obvious example: please enter a replacement password.
.br
.BR session " - "
this group of tasks cover things that should be done prior to a
service being given and after it is withdrawn. Such tasks include the
maintenance of audit trails and the mounting of the user's home
directory. The
.BR session
management group is important as it provides both an opening and
closing hook for modules to affect the services available to a user.
.SH The configuration file(s)
When a
.BR Linux-PAM
aware privilege granting application is started, it activates its
attachment to the PAM-API. This activation performs a number of
tasks, the most important being the reading of the configuration file(s):
.BR /etc/pam.conf "."
Alternatively, this may be the contents of the
.BR /etc/pam.d/
directory.
These files list the
.BR PAM "s"
that will do the authentication tasks required by this service, and
the appropriate behavior of the PAM-API in the event that individual
.BR PAM "s "
fail.
.sp
The syntax of the
.B /etc/pam.conf
configuration file is as follows. The file is made
up of a list of rules, each rule is typically placed on a single line,
but may be extended with an escaped end of line: `\\<LF>'. Comments
are preceded with `#' marks and extend to the next end of line.
.sp
The format of each rule is a space separated collection of tokens, the
first three being case-insensitive:
.sp
.br
.BR " service type control module-path module-arguments"
.sp
The syntax of files contained in the
.B /etc/pam.d/
directory, are identical except for the absence of any
.I service
field. In this case, the
.I service
is the name of the file in the
.B /etc/pam.d/
directory. This filename must be in lower case.
.sp
An important feature of
.BR Linux-PAM ", "
is that a number of rules may be
.I stacked
to combine the services of a number of PAMs for a given authentication
task.
.sp
The
.BR service
is typically the familiar name of the corresponding application:
.BR login
and
.BR su
are good examples. The
.BR service "-name, " other ", "
is reserved for giving
.I default
rules. Only lines that mention the current service (or in the absence
of such, the
.BR other
entries) will be associated with the given service-application.
.sp
The
.BR type
is the management group that the rule corresponds to. It is used to
specify which of the management groups the subsequent module is to
be associated with. Valid entries are:
.BR account "; "
.BR auth "; "
.BR password "; "
and
.BR session "."
The meaning of each of these tokens was explained above.
.sp
The third field,
.BR control ", "
indicates the behavior of the PAM-API should the module fail to
succeed in its authentication task. Valid
.BR control
values are:
.BR requisite
- failure of such a PAM results in the immediate termination of the
authentication process;
.BR required
- failure of such a PAM will ultimately lead to the PAM-API returning
failure but only after the remaining
.I stacked
modules (for this
.BR service
and
.BR type ")"
have been invoked;
.BR sufficient
- success of such a module is enough to satisfy the authentication
requirements of the stack of modules (if a prior
.BR required
module has failed the success of this one is
.IR ignored "); "
.BR optional
- the success or failure of this module is only important if it is the
only module in the stack associated with this
.BR service "+" type "."
.sp
.BR module-path
- this is the full filename of the PAM to be used by the application
.sp
.BR module-arguments
- these are a space separated list of tokens that can be used to
modify the specific behavior of the given PAM. Such arguments will be
documented for each individual module.
.SH "FILES"
.BR /etc/pam.conf " - the configuration file"
.br
.BR /etc/pam.d/ " - the"
.BR Linux-PAM
configuration directory. If this directory is present, the
.B /etc/pam.conf
file is ignored.
.br
.BR /usr/lib/libpam.so.X " - the dynamic library"
.br
.BR /usr/lib/security/*.so " - the PAMs
.sp
Note, to conform to the Linux File-system standard, the libraries and
modules in your system may be located in
.BR /lib " and " /lib/security
respectively.
.SH ERRORS
Typically errors generated by the
.BR Linux-PAM
system of libraries, will be written to
.BR syslog "(3)."
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.br
Contains additional features, currently under consideration by the
DCE-RFC committee.
.SH BUGS
.sp 2
None known.
.SH "SEE ALSO"
The three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1 @@
.so man8/pam.8

View File

@ -0,0 +1 @@
.so man8/pam.8

View File

@ -0,0 +1,91 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_authenticate.3,v 1.2 1997/02/15 18:39:59 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
.TH PAM_AUTHENTICATE 3 "1996 Dec 9" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
pam_authenticate \- authenticate a user
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.sp
.BI "int pam_authenticate(pam_handle_t " *pamh ", int " flags ");"
.sp 2
.SH DESCRIPTION
.B pam_authenticate
.br
Use this function to authenticate an applicant user. It is linked
.I dynamically
to the authentication modules by
.BR Linux-PAM ". "
It is the task of these module to perform such an authentication. The
specific nature of the authentication is not the concern of the
application.
.br
Following successful completion, the
.BR name
of the authenticated user will be present in the
.BR Linux-PAM
item
.BR PAM_USER ". "
This item may be recovered with a call to
.BR pam_get_item "(3)."
.br
The application developer should note that the modules may request
that the user enter their username via the conversation mechanism (see
.BR pam_start "(3))."
Should this be the case, the user-prompt string can be set via
the
.BR PAM_USER_PROMPT
item (see
.BR pam_set_item "(3))."
.SH "RETURN VALUE"
On success
.BR PAM_SUCCESS
is returned. All other returns should be considered
authentication failures and will be
.I delayed
by an amount specified with prior calls to
.BR pam_fail_delay "(3). "
Specific failures that demand special attention are the following:
.TP
.B PAM_ABORT
the application should exit immediately. Of course,
.BR pam_end "(3)"
should be called first.
.TP
.B PAM_MAXTRIES
the application has tried too many times to authenticate the
user, authentication should not be attempted again.
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_start "(3), "
.BR pam_get_item "(3) "
.BR pam_fail_delay "(3) "
and
.BR pam_strerror "(3). "
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,101 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_chauthtok.3,v 1.2 1997/02/15 18:42:23 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_CHAUTHTOK 3 "1997 Jan 4" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
pam_chauthtok \- updating authentication tokens
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.sp
.BI "int pam_chauthtok(pam_handle_t " *pamh ", int " flags ");"
.sp 2
.SH DESCRIPTION
.B pam_chauthtok
.br
Use this function to rejuvenate the authentication tokens (passwords
etc.) of an applicant user.
.br
Note, the application should not pre-authenticate the user, as this is
performed (if required) by the
.BR Linux-PAM
framework.
.br
The
.I flags
argument can
.I optionally
take the value,
.BR PAM_CHANGE_EXPIRED_AUTHTOK "."
In such cases the framework is only required to update those
authentication tokens that have expired. Without this argument, the
framework will attempt to obtain new tokens for all configured
authentication mechanisms. The details of the types and number of such
schemes should not concern the calling application.
.SH RETURN VALUE
A successful return from this function will be indicated with
.BR PAM_SUCCESS "."
.br
Specific errors of special interest when calling this function are
.br
.BR PAM_AUTHTOK_ERROR
- a valid new token was not obtained
.br
.BR PAM_AUTHTOK_RECOVERY_ERR
- old authentication token was not available
.br
.BR PAM_AUTHTOK_LOCK_BUSY
- a resource needed to update the token was locked (try again later)
.br
.BR PAM_AUTHTOK_DISABLE_AGING
- one or more of the authentication modules does not honor
authentication token aging
.br
.BR PAM_TRY_AGAIN
- one or more authentication mechanism is not prepared to update a
token at this time
.br
In general other return values may be returned. They should be treated
as indicating failure.
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_start "(3), "
.BR pam_authenticate "(3), "
.BR pam_setcred "(3), "
.BR pam_get_item "(3), "
.BR pam_strerror "(3) "
and
.BR pam "(8)."
.br
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1 @@
.so man3/pam_open_session.3

View File

@ -0,0 +1 @@
.so man3/pam_start.3

View File

@ -0,0 +1,130 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_fail_delay.3,v 1.2 1997/02/15 18:47:46 morgan Exp morgan $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_FAIL_DELAY 3 "1997 Jan 12" "Linux-PAM 0.56" "Programmers' Manual"
.SH NAME
pam_fail_delay \- request a delay on failure
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.br
or,
.br
.B #include <security/pam_modules.h>
.sp
.BI "int pam_fail_delay(pam_handle_t " "*pamh" ", unsigned int " "usec" ");"
.sp 2
.SH DESCRIPTION
.br
It is often possible to attack an authentication scheme by exploiting
the time it takes the scheme to deny access to an applicant user. In
cases of
.I short
timeouts, it may prove possible to attempt a
.I brute force
dictionary attack -- with an automated process, the attacker tries all
possible passwords to gain access to the system. In other cases,
where individual failures can take measurable amounts of time
(indicating the nature of the failure), an attacker can obtain useful
information about the authentication process. These latter attacks
make use of procedural delays that constitute a
.I covert channel
of useful information.
.br
To minimize the effectiveness of such attacks, it is desirable to
introduce a random delay in a failed authentication process.
.B Linux-PAM
provides such a facility. The delay occurs upon failure of the
.BR pam_authenticate "(3) "
and
.BR pam_chauthtok "(3) "
functions. It occurs
.I after
all authentication modules have been called, but
.I before
control is returned to the service application.
.br
The function,
.BR pam_fail_delay "(3),"
is used to specify a required minimum for the length of the
failure-delay; the
.I usec
argument. This function can be called by the service application
and/or the authentication modules, both may have an interest in
delaying a reapplication for service by the user. The length of the
delay is computed at the time it is required. Its length is
pseudo-gausianly distributed about the
.I maximum
requested value; the resultant delay will differ by as much as 25% of
this maximum requested value (both up and down).
.br
On return from
.BR pam_authenticate "(3) or " pam_chauthtok "(3),"
independent of success or failure, the new requested delay is reset to
its default value: zero.
.SH EXAMPLE
.br
For example, a
.B login
application may require a failure delay of roughly 3 seconds. It will
contain the following code:
.sp
.br
.B " pam_fail_delay(pamh, 3000000 /* micro-seconds */ );"
.br
.B " pam_authenticate(pamh, 0);"
.sp
.br
if the modules do not request a delay, the failure delay will be
between 2.25 and 3.75 seconds.
.br
However, the modules, invoked in the authentication process, may
also request delays:
.sp
.br
.RB " (module #1) " "pam_fail_delay(pamh, 2000000);"
.sp
.br
.RB " (module #2) " "pam_fail_delay(pamh, 4000000);"
.sp
.br
in this case, it is the largest requested value that is used to
compute the actual failed delay: here between 3 and 5 seconds.
.SH "RETURN VALUE"
Following a successful call to
.BR pam_fail_delay "(3), " PAM_SUCCESS
is returned. All other returns should be considered serious failures.
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
Under consideration by the X/Open group for future inclusion in the
PAM RFC. 1996/1/10
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_start "(3), "
.BR pam_get_item "(3) "
and
.BR pam_strerror "(3). "
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,99 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_open_session.3,v 1.2 1997/02/15 18:49:02 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_OPEN_SESSION 3 "1997 Jan 4" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
pam_open/close_session \- PAM session management
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.sp
.BI "int pam_open_session(pam_handle_t " *pamh ", int " flags ");"
.sp
.BI "int pam_close_session(pam_handle_t " *pamh ", int " flags ");"
.sp 2
.SH DESCRIPTION
PAM provides management-hooks for the initialization and termination
of a session.
.TP
.B pam_open_session
.br
Use this function to signal that an authenticated user session has
begun. It should be called only after the user is properly identified
and (where necessary) has been granted their credentials with
.BR pam_authenticate "(3)"
and
.BR pam_setcred "(3)"
respectively.
.br
Some types of functions associated with session
initialization are logging for the purposes of system-audit and
mounting directories (the user's home directory for example). These
should not concern the application. It should be noted that the
.I effective
uid,
.BR geteuid "(2),"
of the application should be of sufficient privilege to perform such
tasks.
.TP
.B pam_close_session
.br
Use this function to signal that a user session has
terminated. In general this function may not need to be located in the
same application as the initialization function,
.BR pam_open_session "."
.br
Typically, this function will undo the actions of
.BR pam_open_session "."
That is, log audit information concerning the end of the user session
or unmount the user's home directory. Apart from having sufficient
privilege the details of the session termination should not concern
the calling application. It is good programming practice, however, to
cease acting on behalf of the user on returning from this call.
.SH RETURN VALUE
A successful return from the session management functions will be
indicated with
.BR PAM_SUCCESS "."
.br
The specific error indicating a failure to open or close a session is
.BR PAM_SESSION_ERR "."
In general other return values may be returned. They should be treated
as indicating failure.
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
OSF-RFC 86.0, October 1995.
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_start "(3), "
.BR pam_authenticate "(3), "
.BR pam_setcred "(3), "
.BR pam_get_item "(3), "
.BR pam_strerror "(3) "
and
.BR pam "(3)."
.br
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,79 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_setcred.3,v 1.2 1997/02/15 18:50:49 morgan Exp morgan $
.\" Copyright (c) Andrew G. Morgan 1996,1997 <morgan@parc.power.net>
.TH PAM_SETCRED 3 "1997 July 6" "Linux-PAM 0.58" "App. Programmers' Manual"
.SH NAME
pam_setcred \- set the credentials for the user
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.sp
.BI "int pam_setcred(pam_handle_t " *pamh ", int " flags ");"
.sp 2
.SH DESCRIPTION
.B pam_setcred
This function is used to establish, maintain and delete the
credentials of a user. It should be called after a user has been
authenticated and before a session is opened for the user (with
.BR pam_open_session "(3))."
It should be noted that credentials come in many forms. Examples
include: group memberships; ticket-files; and Linux-PAM environment
variables. For this reason, it is important that the basic identity
of the user is established, by the application, prior to a call to
this function. For example, the default
.BR Linux-PAM
environment variables should be set and also
.BR initgroups "(2) "
(or equivalent) should have been performed.
.SH "VALID FLAGS"
.TP
.BR PAM_ESTABLISH_CRED
initialize the credentials for the user.
.TP
.BR PAM_DELETE_CRED
delete the user's credentials.
.TP
.BR PAM_REINITIALIZE_CRED
delete and then initialize the user's credentials.
.TP
.BR PAM_REFRESH_CRED
extend the lifetime of the existing credentials.
.SH "RETURN VALUE"
On success
.BR PAM_SUCCESS
is returned, all other return values should be treated as errors.
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_authenticate "(3), "
.BR pam_strerror "(3)"
and
.BR pam_open_session "(3). "
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,98 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: pam_start.3,v 1.2 1997/02/15 18:51:54 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
.TH PAM_START 3 "1997 Feb 15" "Linux-PAM 0.56" "Application Programmers' Manual"
.SH NAME
pam_start, pam_end \- activating Linux-PAM
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.sp
.BI "int pam_start(const char " *service ", const char " *user ", const struct pam_conv " *conv ", pam_handle_t " **pamh_p ");"
.sp
.BI "int pam_end(pam_handle_t " *pamh ", int " pam_status ");"
.sp 2
.SH DESCRIPTION
.TP
.B pam_start
Initialize the
.I Linux-PAM
library. Identifying the application with a particular
.IR service
name. The
.IR user "name"
can take the value
.IR NULL ", "
if not known at the time the interface is initialized. The
conversation structure is passed to the library via the
.IR conv
argument. (For a complete description of this and other structures
the reader is directed to the more verbose
.IR Linux-PAM
application developers' guide). Upon successful initialization, an
opaque pointer-handle for future access to the library is returned
through the contents of the
.IR pamh_p
pointer.
.TP
.B pam_end
Terminate the
.B Linux-PAM
library. The service application associated with the
.IR pamh
handle, is terminated. The argument,
.IR pam_status ", "
passes the value most recently returned to the application from the
library; it indicates the manner in which the library should be
shutdown. Besides carrying a return value, this argument may be
logically OR'd with
.IR PAM_DATA_SILENT
to indicate that the module should not treat the call too
seriously. It is generally used to indicate that the current closing
of the library is in a
.IR fork "(2)ed"
process, and that the parent will take care of cleaning up things that
exist outside of the current process space (files etc.).
.SH "RETURN VALUE"
.TP
.B pam_start
.TP
.B pam_end
On success,
.BR PAM_SUCCESS
is returned
.SH ERRORS
May be translated to text with
.BR pam_strerror "(3). "
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.sp
Note, the
.BR PAM_DATA_SILENT
flag is pending acceptance with the DCE (as of 1996/12/4).
.SH BUGS
.sp 2
None known.
.SH "SEE ALSO"
.BR fork "(2), "
.BR pam_authenticate "(3), "
.BR pam_acct_mgmt "(3), "
.BR pam_open_session "(3), "
and
.BR pam_chauthtok "(3)."
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,49 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" ripped off from Rick Faith's getgroups man page
.\" $Id: pam_strerror.3,v 1.2 1997/02/15 18:53:04 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
.TH PAM_STRERROR 3 "1997 Feb 15" "Linux-PAM 0.56" "Programmers' Manual"
.SH NAME
pam_strerror \- return a textual description of a Linux-PAM error
.SH SYNOPSIS
.B #include <security/pam_appl.h>
.br
or,
.br
.B #include <security/pam_modules.h>
.sp
.BI "const char *pam_strerror(" int " pam_error);
.sp 2
.SH DESCRIPTION
.B pam_strerror
This function returns a pointer to a line of text describing the
.BR Linux-PAM
error passed as its sole argument.
.SH "RETURN VALUE"
On success this function returns a description of the indicated
error. Should the function not recognize the error, ``Unknown
Linux-PAM error'' is returned.
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.SH BUGS
.sp 2
This function should be internationalized.
.SH "SEE ALSO"
.BR pam "(8). "
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,52 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" $Id: template-man,v 1.1 1997/01/04 18:25:13 morgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_???? 2 "1997 Jan 4" "Linux-PAM 0.55" "Application Programmers' Manual"
.SH NAME
function names \- brief summary of function
.SH SYNOPSIS
.B #include <security/pam_????.h>
.sp
.BI "int pam_???(pam_handle_t " pamh ", int " flags);
.sp 2
.SH DESCRIPTION
.TP
.B pam_???
Here goes the
.I explanation
it may be quite
.IR long .
.TP
.SH "RETURN VALUE"
.B pam_???
On success...
.BR PAM_SUCCESS
is returned
.TP
.SH ERRORS
May be translated to text with
.BR pam_strerror "(2). "
.SH "CONFORMING TO"
.B pam_???
DCE-RFC 86.0, October 1995.
.SH BUGS
.sp 2
none known.
.SH "SEE ALSO"
.BR pam_??? "(2), "
and
.BR pam_??? "(2). "
Also, see the three
.BR Linux-PAM
Guides, for
.BR "System administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "

View File

@ -0,0 +1,13 @@
$Id: README,v 1.2 1996/11/17 17:20:28 morgan Exp $
This directory contains a number of sgml sub-files. One for each
documented module. They contain a description of each module and give
some indication of its reliability.
Additionally, there is a 'module.sgml-template' file which should be
used as a blank form for new module descriptions.
Please feel free to submit amendments/comments etc. regarding these
files to:
Andrew G. Morgan <morgan@parc.power.net>

View File

@ -0,0 +1,170 @@
<!--
$Id: module.sgml-template,v 1.1 1996/11/30 20:59:32 morgan Exp $
This template file was written by Andrew G. Morgan
<morgan@parc.power.net>
[
Text that should be deleted/replaced, is enclosed within
'[' .. ']'
marks. For example, this text should be deleted!
]
-->
<sect1> [*Familiar full name of module*, eg. The "allow all" module.]
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
[
insert the name of the module
Blank is not permitted.
]
<tag><bf>Author[s]:</bf></tag>
[
Insert author names here
Blank is not permitted. If in doubt, put "unknown" if the
author wishes to remain anonymous, put "anonymous".
]
<tag><bf>Maintainer:</bf></tag>
[
Insert names and date-begun of most recent maintainer.
]
<tag><bf>Management groups provided:</bf></tag>
[
list the subset of four management groups supported by the
module. Choose from: account; authentication; password;
session.
Blank entries are not permitted. Explicitly list all of the
management groups. In the future more may be added to libpam!
]
<tag><bf>Cryptographically sensitive:</bf></tag>
[
Indicate whether this module contains code that can perform
reversible (strong) encryption. This field is primarily to
ensure that people redistributing it are not unwittingly
breaking laws...
Modules may also require the presence of some local library
that performs the necessary encryption via some standard API.
In this case "uses API" can be included in this field. The
library in question should be added to the system requirements
below.
Blank = no cryptography is used by module.
]
<tag><bf>Security rating:</bf></tag>
[
Initially, this field should be left blank. If someone takes
it upon themselves to test the strength of the module, it can
later be filled.
Blank = unknown.
]
<tag><bf>Clean code base:</bf></tag>
[
This will probably be filled by the libpam maintainer.
It can be considered to be a public humiliation list. :*)
I am of the opinion that "gcc -with_all_those_flags" is
trying to tell us something about whether the program
works as intended. Since there is currently no Security
evaluation procedure for modules IMHO this is not a
completely unreasonable indication (a lower bound anyway)
of the reliability of a module.
This field would indicate the number and flavor of
warnings that gcc barfs up when trying to compile the
module as part of the tree. Is this too tyrannical?
Blank = Linux-PAM maintainer has not tested it :)
]
<tag><bf>System dependencies:</bf></tag>
[
here we list config files, dynamic libraries needed, system
resources, kernel options.. etc.
Blank = nothing more than libc required.
]
<tag><bf>Network aware:</bf></tag>
[
Does the module base its behavior on probing a network
connection? Does it expect to be protected by the
application?
Blank = Ignorance of network.
]
</descrip>
<sect2>Overview of module
[
some text describing the intended actions of the module
general comments mainly (specifics in sections
below).
]
[
[ now we have a <sect2> level subsection for each of the
management groups. Include as many as there are groups
listed above in the synopsis ]
<sect2>[ Account | Authentication | Password | Session ] component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
[
List the supported arguments (leave their description for the
description below.
Blank = no arguments are read and nothing is logged to syslog
about any arguments that are passed. Note, this
behavior is contrary to the RFC!
]
<tag><bf>Description:</bf></tag>
[
This component of the module performs the task of ...
]
<tag><bf>Examples/suggested usage:</bf></tag>
[
Here we list some doos and don'ts for this module.
]
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,86 @@
<!--
$Id: pam_chroot.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
This file was written by Bruce Campbell <brucec@humbug.org.au>
-->
<sect1>Chroot
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_chroot/
<tag><bf>Author:</bf></tag>
Bruce Campbell &lt;brucec@humbug.org.au&gt;
<tag><bf>Maintainer:</bf></tag>
Author; proposed on 20/11/96 - email for status
<tag><bf>Management groups provided:</bf></tag>
account; session; authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
Unwritten.
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
Expects localhost.
</descrip>
<sect2>Overview of module
<p>
This module is intended to provide a transparent wrapper around the
average user, one that puts them in a fake file-system (eg, their
'<tt>/</tt>' is really <tt>/some/where/else</tt>).
<p>
Useful if you have several classes of users, and are slightly paranoid
about security. Can be used to limit who else users can see on the
system, and to limit the selection of programs they can run.
<sect2>Account component:
<p>
<em/Need more info here./
<sect2>Authentication component:
<p>
<em/Need more info here./
<sect2>Session component:
<p>
<em/Need more info here./
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
Arguments and logging levels for the PAM version are being worked on.
<tag><bf>Description:</bf></tag>
<tag><bf>Examples/suggested usage:</bf></tag>
Do provide a reasonable list of programs - just tossing 'cat', 'ls', 'rm',
'cp' and 'ed' in there is a bit...
<p>
Don't take it to extremes (eg, you can set up a separate environment for
each user, but its a big waste of your disk space.)
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,254 @@
<!--
$Id: pam_cracklib.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp morgan $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
long password amendments are from Philip W. Dalrymple III <pwd@mdtsoft.com>
-->
<sect1>Cracklib pluggable password strength-checker
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_cracklib
<tag><bf>Author:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
password
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Requires the system library <tt/libcrack/ and a system dictionary:
<tt>/usr/lib/cracklib_dict</tt>.
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module can be plugged into the <tt/password/ stack of a given
application to provide some plug-in strength-checking for passwords.
(XXX - note this does not necessarily work with the pam_unix module,
although it is known to work with the pam_pwdb replacement for the
unix module -- see example and pam_pwdb write up for more
information).
<p>
This module works in the following manner: it first calls the
<em>Cracklib</em> routine to check the strength of the password; if
crack likes the password, the module does an additional set of
strength checks. These checks are:
<itemize>
<item> <bf/Palindrome/ -
Is the new password a palindrome of the old one?
<item> <bf/Case Change Only/ -
Is the new password the the old one with only a change of case?
<item> <bf/Similar/ -
Is the new password too much like the old one? This is controlled
by one argument, <tt/difok/ which is a number of characters that if
different between the old and new are enough to accept the new
password, this defaults to 10 or 1/2 the size of the new password
whichever is smaller.
<item <bf/Simple/ -
Is the new password too small? This is controlled by 5 arguments
<tt/minlen/, <tt/dcredit/, <tt/ucredit/, <tt/lcredit/, and
<tt/ocredit/. See the section on the arguments for the details of how
these work and there defaults.
<item <bf/Rotated/ -
Is the new password a rotated version of the old password?
</itemize>
<p>
This module with no arguments will work well for standard unix
password encryption. With md5 encryption, passwords can be longer
than 8 characters and the default settings for this module can make it
hard for the user to choose a satisfactory new password. Notably, the
requirement that the new password contain no more than 1/2 of the
characters in the old password becomes a non-trivial constraint. For
example, an old password of the form "the quick brown fox jumped over
the lazy dogs" would be difficult to change... In addition, the
default action is to allow passwords as small as 5 characters in
length. For a md5 systems it can be a good idea to increase the
required minimum size of a password. One can then allow more credit
for different kinds of characters but accept that the new password may
share most of these characters with the old password.
<sect2>Password component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/type=XXX/; <tt/retry=N/; <tt/difok=N/; <tt/minlen=N/;
<tt/dcredit=N/; <tt/ucredit=N/; <tt/lcredit=N/; <tt/ocredit=N/;
<tag><bf>Description:</bf></tag>
The action of this module is to prompt the user for a password and
check its strength against a system dictionary and a set of rules for
identifying poor choices.
<p>
The default action is to prompt for a single password, check its
strength and then, if it is considered strong, prompt for the password
a second time (to verify that it was typed correctly on the first
occasion). All being well, the password is passed on to subsequent
modules to be installed as the new authentication token.
<p>
The default action may be modified in a number of ways using the
arguments recognized by the module:
<itemize>
<item> <tt/debug/ -
this option makes the module write information to syslog(3) indicating
the behavior of the module (this option does <bf/not/ write password
information to the log file).
<item> <tt/type=XXX/ -
the default action is for the module to use the following prompts when
requesting passwords: ``New UNIX password: '' and ``Retype UNIX
password: ''. Using this option you can replace the word UNIX with
<tt/XXX/.
<item> <tt/retry=N/ -
the default number of times this module will request a new password
(for strength-checking) from the user is 1. Using this argument this
can be increased to <tt/N/.
<item> <tt/difok=N/ -
This argument will change the default of 10 for the number of
characters in the new password that must not be present in the old
password. In addition, if 1/2 of the characters in the new password
are different then the new password will be accepted anyway.
<item> <tt/minlen=N/ -
The minimum acceptable size for the new password plus one. In
addition to the number of characters in the new password, credit (of
+1 in length) is given for each different kind of character (<em>other,
upper, lower</em> and <em/digit/). The default for this parameter is
9 which is good for a old style UNIX password all of the same type of
character but may be too low to exploit the added security of a md5
system. Note that there is a pair of length limits in
<em>Cracklib</em> itself, a "way too short" limit of 4 which is hard
coded in and a defined limit (6) that will be checked without
reference to <tt>minlen</tt>. If you want to allow passwords as short
as 5 characters you should either not use this module or recompile
the crack library and then recompile this module.
<item> <tt/dcredit=N/ -
This is the maximum credit for having digits in the new password. If
you have less than or <tt/N/ digits, each digit will count +1 towards
meeting the current <tt/minlen/ value. The default for <tt/dcredit/
is 1 which is the recommended value for <tt/minlen/ less than 10.
<item> <tt/ucredit=N/ -
This is the maximum credit for having upper case letters in the new
password. If you have less than or <tt/N/ upper case letters each
letter will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/ucredit/ is 1 which is the recommended value for
<tt/minlen/ less than 10.
<item> <tt/lcredit=N/ -
This is the maximum credit for having lower case letters in the new
password. If you have less than or <tt/N/ lower case letters, each
letter will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/lcredit/ is 1 which is the recommended value for
<tt/minlen/ less than 10.
<item> <tt/ocredit=N/ -
This is the maximum credit for having other characters in the new
password. If you have less than or <tt/N/ other characters, each
character will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/ocredit/ is 1 which is the recommended value for
<tt/minlen/ less than 10.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
(At the time of writing, this module can only be stacked before the
<tt/pam_pwdb/ module. Cracklib strength checking may be compiled by
default into the <tt/pam_unix/ module.)
<p>
For an example of the use of this module, we show how it may be
stacked with the password component of <tt/pam_pwdb/:
<tscreen>
<verb>
#
# These lines stack two password type modules. In this example the
# user is given 3 opportunities to enter a strong password. The
# "use_authtok" argument ensures that the pam_pwdb module does not
# prompt for a password, but instead uses the one provided by
# pam_cracklib.
#
passwd password required pam_cracklib.so retry=3
passwd password required pam_pwdb.so use_authtok
</verb>
</tscreen>
<p>
Another example (in the <tt>/etc/pam.d/passwd</tt> format) is for the
case that you want to use md5 password encryption:
<tscreen>
<verb>
#%PAM-1.0
#
# These lines allow a md5 systems to support passwords of at least 14
# bytes with extra credit of 2 for digits and 2 for others the new
# password must have at least three bytes that are not present in the
# old password
#
password required pam_cracklib.so \
difok=3 minlen=15 dcredit= 2 ocredit=2
password required pam_pwdb.so use_authtok nullok md5
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,179 @@
<!--
$Id: pam_deny.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp morgan $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The locking-out module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_deny
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
current <bf/Linux-PAM/ maintainer
<tag><bf>Management groups provided:</bf></tag>
account; authentication; password; session
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
clean.
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module can be used to deny access. It always indicates a failure
to the application through the PAM framework. As is commented in the
overview section <ref id="overview-section" name="above">, this module
might be suitable for using for default (the <tt/OTHER/) entries.
<sect2>Account component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This component does nothing other than return a failure. The
failure type is <tt/PAM_ACCT_EXPIRED/.
<tag><bf>Examples/suggested usage:</bf></tag>
Stacking this module with type <tt/account/ will prevent the user from
gaining access to the system via applications that refer to
<bf/Linux-PAM/'s account management function <tt/pam_acct_mgmt()/.
<p>
The following example would make it impossible to login:
<tscreen>
<verb>
#
# add this line to your other login entries to disable all accounts
#
login account required pam_deny.so
</verb>
</tscreen>
</descrip>
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This component does nothing other than return a failure. The failure
type is <tt/PAM_AUTH_ERR/ in the case that <tt/pam_authenticate()/ is
called (when the application tries to authenticate the user), and is
<tt/PAM_CRED_UNAVAIL/ when the application calls <tt/pam_setcred()/
(to establish and set the credentials of the user -- it is unlikely
that this function will ever be called in practice).
<tag><bf>Examples/suggested usage:</bf></tag>
To deny access to default applications with this component of the
<tt/pam_deny/ module, you might include the following line in your
<bf/Linux-PAM/ configuration file:
<tscreen>
<verb>
#
# add this line to your existing OTHER entries to prevent
# authentication succeeding with default applications.
#
OTHER auth required pam_deny.so
</verb>
</tscreen>
</descrip>
<sect2>Password component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This component of the module denies the user the opportunity to change
their password. It always responds with <tt/PAM_AUTHTOK_ERR/ when
invoked.
<tag><bf>Examples/suggested usage:</bf></tag>
This module should be used to prevent an application from updating the
applicant user's password. For example, to prevent <tt/login/ from
automatically prompting for a new password when the old one has
expired you should include the following line in your configuration
file:
<tscreen>
<verb>
#
# add this line to your other login entries to prevent the login
# application from being able to change the user's password.
#
login password required pam_deny.so
</verb>
</tscreen>
</descrip>
<sect2>Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This aspect of the module prevents an application from starting a
session on the host computer.
<tag><bf>Examples/suggested usage:</bf></tag>
Together with another session module, that displays a message of the
day perhaps (XXX - such a module needs to be written),
this module can be used to block a user from starting a shell. Given
the presence of a <tt/pam_motd/ module, we might use the following
entries in the configuration file to inform the user it is system
time:
<tscreen>
<verb>
#
# An example to see how to configure login to refuse the user a
# session (politely)
#
login session required pam_motd.so \
file=/etc/system_time
login session required pam_deny.so
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,125 @@
<!--
$Id: pam_env.sgml,v 1.1 1997/04/05 06:50:42 morgan Exp $
This file was written by Dave Kinchlea <kinch@kinch.ark.com>
Ed. AGM
-->
<sect1>Set/unset environment variables
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_env/
<tag><bf>Author:</bf></tag>
Dave Kinchlea &lt;kinch@kinch.ark.com&gt;
<tag><bf>Maintainer:</bf></tag>
Author
<tag><bf>Management groups provided:</bf></tag>
Authentication (setcred)
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
<tt>/etc/security/pam_env.conf</tt>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module allows the (un)setting of environment variables. Supported
is the use of previously set environment variables as well as
<em>PAM_ITEM</em>s such as <tt>PAM_RHOST</tt>.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/conffile=/<em/configuration-file-name/
<tag><bf>Description:</bf></tag>
This module allows you to (un)set arbitrary environment variables
using fixed strings, the value of previously set environment variables
and/or <em/PAM_ITEM/s.
<p>
All is controlled via a configuration file (by default,
<tt>/etc/security/pam_env.conf</tt> but can be overriden with
<tt>connfile</tt> argument). Each line starts with the variable name,
there are then two possible options for each variable <bf>DEFAULT</bf>
and <bf>OVERRIDE</bf>. <bf>DEFAULT</bf> allows and administrator to
set the value of the variable to some default value, if none is
supplied then the empty string is assumed. The <bf>OVERRIDE</bf>
option tells pam_env that it should enter in its value (overriding the
default value) if there is one to use. <bf>OVERRIDE</bf> is not used,
<tt>""</tt> is assumed and no override will be done.
<p>
<tscreen>
<verb>
VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]
</verb>
</tscreen>
<p>
(Possibly non-existent) environment variables may be used in values
using the <tt>&dollar;&lcub;string&rcub;</tt> syntax and (possibly
non-existent) <em/PAM_ITEM/s may be used in values using the
<tt>&commat;&lcub;string&rcub;</tt> syntax. Both the <tt>&dollar;</tt>
and <tt>&commat;</tt> characters can be backslash-escaped to be used
as literal values (as in <tt>&bsol;&dollar;</tt>. Double quotes may
be used in values (but not environment variable names) when white
space is needed <bf>the full value must be delimited by the quotes and
embedded or escaped quotes are not supported</bf>.
<p>
The behavior of this module can be modified with one of the following
flags:
<p>
<itemize>
<item><tt/debug/
- write more information to <tt/syslog(3)/.
<item><tt/conffile=/<em/filename/
- by default the file <tt>/etc/security/pam_env.conf</tt> is used as
the configuration file. This option overrides the default. You must
supply a complete path + file name.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
See sample <tt>pam_env.conf</tt> for more information and examples.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,150 @@
<!--
$Id: pam_filter.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The filter module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_filter
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
account; authentication; password; session
<tag><bf>Cryptographically sensitive:</bf></tag>
Not yet.
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
This module compiles cleanly on Linux based systems.
<tag><bf>System dependencies:</bf></tag>
To function it requires <em/filters/ to be installed on the system.
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module was written to offer a plug-in alternative to programs
like ttysnoop (XXX - need a reference). Since writing a filter that
performs this function has not occurred, it is currently only a toy.
The single filter provided with the module simply transposes upper and
lower case letters in the input and output streams. (This can be very
annoying and is not kind to termcap based editors).
<sect2>Account+Authentication+Password+Session components
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/new_term/; <tt/non_term/; <tt/runX/
<tag><bf>Description:</bf></tag>
Each component of the module has the potential to invoke the desired
filter. The filter is always <tt/execv(2)/d with the privilege of the
calling application and <bf/not/ that of the user. For this reason it
cannot usually be killed by the user without closing their session.
<p>
The behavior of the module can be significantly altered by the
arguments passed to it in the <bf/Linux-PAM/ configuration file:
<itemize>
<item><tt/debug/ -
this option increases the amount of information logged to
<tt/syslog(3)/ as the module is executed.
<item><tt/new_term/ -
the default action of the filter is to set the <tt/PAM_TTY/ item to
indicate the terminal that the user is using to connect to the
application. This argument indicates that the filter should set
<tt/PAM_TTY/ to the filtered pseudo-terminal.
<item><tt/non_term/ -
don't try to set the <tt/PAM_TTY/ item.
<item><tt/runX/ -
in order that the module can invoke a filter it should know when to
invoke it. This argument is required to tell the filter when to do
this. The arguments that follow this one are respectively the full
pathname of the filter to be run and any command line arguments that
the filter might expect.
<p>
Permitted values for <tt/X/ are <tt/1/ and <tt/2/. These indicate the
precise time the that filter is to be run. To explain this concept it
will be useful to have read the Linux-PAM Module developer's
guide. Basically, for each management group there are up to two ways
of calling the module's functions.
In the case of the <em/authentication/ and <em/session/ components
there are actually two separate functions. For the case of
authentication, these functions are <tt/_authenticate/ and
<tt/_setcred/ -- here <tt/run1/ means run the filter from the
<tt/_authenticate/ function and <tt/run2/ means run the filter from
<tt/_setcred/. In the case of the session modules, <tt/run1/ implies
that the filter is invoked at the <tt/_open_session/ stage, and
<tt/run2/ for <tt/_close_session/.
<p>
For the case of the account component. Either <tt/run1/ or <tt/run2/
may be used.
<p>
For the case of the password component, <tt/run1/ is used to indicate
that the filter is run on the first occasion <tt/_chauthtok/ is run
(the <tt/PAM_PRELIM_CHECK/ phase) and <tt/run2/ is used to indicate
that the filter is run on the second occasion (the
<tt/PAM_UPDATE_AUTHTOK/ phase).
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
At the time of writing there is little real use to be made of this
module. For fun you might try adding the following line to your
login's configuration entries
<tscreen>
<verb>
#
# An example to see how to configure login to transpose upper and
# lower case letters once the user has logged in(!)
#
login session required pam_filter.so \
run1 /usr/sbin/pam_filter/upperLOWER
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,93 @@
<!--
$Id: pam_ftp.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>Anonymous access module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_ftp.so/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
prompts for email address of user; easily spoofed (XXX - needs work)
</descrip>
<sect2>Overview of module
<p>
The purpose of this module is to provide a pluggable anonymous ftp
mode of access.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/;
<tt/users=XXX,YYY,.../;
<tt/ignore/
<tag><bf>Description:</bf></tag>
This module intercepts the user's name and password. If the name is
``<tt/ftp/'' or ``<tt/anonymous/'', the user's password is broken up
at the `<tt/@/' delimiter into a <tt/PAM_RUSER/ and a <tt/PAM_RHOST/
part; these pam-items being set accordingly. The username is set to
``<tt/ftp/''. In this case the module succeeds. Alternatively, the
module sets the <tt/PAM_AUTHTOK/ item with the entered password and
fails.
<p>
The behavior of the module can be modified with the following flags:
<itemize>
<item><tt/debug/ -
log more information to with <tt/syslog(3)/.
<item><tt/users=XXX,YYY,.../ -
instead of ``<tt/ftp/'' or ``<tt/anonymous/'', provide anonymous login
to the comma separated list of users; ``<tt/XXX,YYY,.../''. Should the
applicant enter one of these usernames the returned username is set to
the first in the list; ``<tt/XXX/''.
<item><tt/ignore/ -
pay no attention to the email address of the user (if supplied).
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
An example of the use of this module is provided in the configuration
file section <ref id="configuration" name="above">. With care, this
module could be used to provide new/temporary account anonymous
login.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,108 @@
<!--
$Id: pam_group.sgml,v 1.2 1997/01/04 20:50:10 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The group access module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_group/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
Sensitive to <em/setgid/ status of file-systems accessible to users.
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Requires an <tt>/etc/security/group.conf</tt> file. Can be compiled
with or without <tt/libpwdb/.
<tag><bf>Network aware:</bf></tag>
Only through correctly set <tt/PAM_TTY/ item.
</descrip>
<sect2>Overview of module
<p>
This module provides group-settings based on the user's name and the
terminal they are requesting a given service from. It takes note of
the time of day.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This module does not authenticate the user, but instead it grants
group memberships (in the credential setting phase of the
authentication module) to the user. Such memberships are based on the
service they are applying for. The group memberships are listed in
text form in the <tt>/etc/security/group.conf</tt> file.
<tag><bf>Examples/suggested usage:</bf></tag>
For this module to function correctly there must be a correctly
formatted <tt>/etc/security/groups.conf</tt> file present. The format
of this file is as follows. Group memberships are given based on the
service application satisfying any combination of lines in the
configuration file. Each line (barring comments which are preceded by
`<tt/#/' marks) has the following
syntax:
<tscreen>
<verb>
services ; ttys ; users ; times ; groups
</verb>
</tscreen>
Here the first four fields share the syntax of the <tt>pam_time</tt>
configuration file; <tt>/etc/security/pam_time.conf</tt>, and the last
field, the <tt/groups/ field, is a comma (or space) separated list of
the text-names of a selection of groups. If the users application for
service satisfies the first four fields, the user is granted membership
of the listed groups.
<p>
As stated in above this module's usefulness relies on the file-systems
accessible to the user. The point being that once granted the
membership of a group, the user may attempt to create a <em/setgid/
binary with a restricted group ownership. Later, when the user is not
given membership to this group, they can recover group membership with
the precompiled binary. The reason that the file-systems that the user
has access to are so significant, is the fact that when a system is
mounted <em/nosuid/ the user is unable to create or execute such a
binary file. For this module to provide any level of security, all
file-systems that the user has write access to should be mounted
<em/nosuid/.
<p>
The <tt>pam_group</tt> module fuctions in parallel with the
<tt>/etc/group</tt> file. If the user is granted any groups based on
the behavior of this module, they are granted <em>in addition</em> to
those entries <tt>/etc/group</tt> (or equivalent).
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,126 @@
<!--
$Id: pam_krb4.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
This file was written by Derrick J. Brashear <shadow@DEMENTIA.ORG>
-->
<sect1>The Kerberos 4 module.
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_krb4/
<tag><bf>Author:</bf></tag>
Derrick J. Brashear &lt;shadow@dementia.org&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
authentication; password; session
<tag><bf>Cryptographically sensitive:</bf></tag>
uses API
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
libraries - <tt/libkrb/, <tt/libdes/, <tt/libcom_err/, <tt/libkadm/;
and a set of Kerberos include files.
<tag><bf>Network aware:</bf></tag>
Gets Kerberos ticket granting ticket via a Kerberos key distribution
center reached via the network.
</descrip>
<sect2>Overview of module
<p>
This module provides an interface for doing Kerberos verification of a
user's password, getting the user a Kerberos ticket granting ticket
for use with the Kerberos ticket granting service, destroying the
user's tickets at logout time, and changing a Kerberos password.
<sect2> Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This component of the module currently sets the user's <tt/KRBTKFILE/
environment variable (although there is currently no way to export
this), as well as deleting the user's ticket file upon logout (until
<tt/PAM_CRED_DELETE/ is supported by <em/login/).
<tag><bf>Examples/suggested usage:</bf></tag>
This part of the module won't be terribly useful until we can change
the environment from within a <tt/Linux-PAM/ module.
</descrip>
<sect2> Password component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/use_first_pass/; <tt/try_first_pass/
<tag><bf>Description:</bf></tag>
This component of the module changes a user's Kerberos password
by first getting and using the user's old password to get
a session key for the password changing service, then sending
a new password to that service.
<tag><bf>Examples/suggested usage:</bf></tag>
This should only be used with a real Kerberos v4 <tt/kadmind/. It
cannot be used with an AFS kaserver unless special provisions are
made. Contact the module author for more information.
</descrip>
<sect2> Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/use_first_pass/; <tt/try_first_pass/
<tag><bf>Description:</bf></tag>
This component of the module verifies a user's Kerberos password
by requesting a ticket granting ticket from the Kerberos server
and optionally using it to attempt to retrieve the local computer's
host key and verifying using the key file on the local machine if
one exists.
It also writes out a ticket file for the user to use later, and
deletes the ticket file upon logout (not until <tt/PAM_CRED_DELETE/
is called from <em/login/).
<tag><bf>Examples/suggested usage:</bf></tag>
This module can be used with a real Kerberos server using MIT
v4 Kerberos keys. The module or the system Kerberos libraries
may be modified to support AFS style Kerberos keys. Currently
this is not supported to avoid cryptography constraints.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,119 @@
<!--
$Id: pam_mail.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The last login module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_lastlog/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author
<tag><bf>Management groups provided:</bf></tag>
auth
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
uses information contained in the <tt>/var/log/wtmp</tt> file.
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This session module maintains the <tt>/var/log/wtmp</tt> file. Adding
an open entry when called via the <tt>pam_open_seesion()</tt> function
and completing it when <tt>pam_close_session()</tt> is called. This
module can also display a line of information about the last login of
the user. If an application already performs these tasks, it is not
necessary to use this module.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/nodate/; <tt/noterm/; <tt/nohost/; <tt/silent/;
<tt/never/
<tag><bf>Description:</bf></tag>
<p>
This module can be used to provide a ``Last login on ...''
message. when the user logs into the system from what ever application
uses the PAM libraries. In addition, the module maintains the
<tt>/var/log/wtmp</tt> file.
<p>
The behavior of this module can be modified with one of the following
flags:
<p>
<itemize>
<item><tt/debug/
- write more information to <tt/syslog(3)/.
<item><tt/nodate/
- neglect to give the date of the last login when displaying
information about the last login on the system.
<item><tt/noterm/
- neglect to diplay the terminal name on which the last login was
attempt.
<item><tt/nohost/
- neglect to indicate from which host the last login was attempted.
<item><tt/silent/
- neglect to inform the user about any previous login: just update
the <tt>/var/log/wtmp</tt> file.
<item><tt/never/
- if the <tt>/var/log/wtmp</tt> file does not contain any old entries
for the user, indicate that the user has never previously logged in
with a ``welcome..." message.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
This module can be used to indicate that the user has new mail when
they <em/login/ to the system. Here is a sample entry for your
<tt>/etc/pam.conf</tt> file:
<tscreen>
<verb>
#
# do we have any mail?
#
login session optional pam_lastlog.so
</verb>
</tscreen>
<p>
Note, some applications may perform this function themselves. In such
cases, this module is not necessary.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,196 @@
<!--
$Id: pam_limits.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
from information compiled by Cristian Gafton (author of module)
-->
<sect1>The resource limits module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_limits/
<tag><bf>Authors:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt; <newline>
Thanks are also due to Elliot Lee &lt;sopwith@redhat.com&gt;
for his comments on improving this module.
<tag><bf>Maintainer:</bf></tag>
Cristian Gafton - 1996/11/20
<tag><bf>Management groups provided:</bf></tag>
session
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
requires an <tt>/etc/security/limits.conf</tt> file and kernel support
for resource limits. Also uses the library, <tt/libpwdb/.
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module, through the <bf/Linux-PAM/ <em/open/-session hook, sets
limits on the system resources that can be obtained in a
user-session. Its actions are dictated more explicitly through the
configuration file discussed below.
<sect2>Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt>conf=/path/to/file.conf</tt>
<tag><bf>Description:</bf></tag>
Through the contents of the configuration file,
<tt>/etc/security/limits.conf</tt>, resource limits are placed on
users' sessions. Users of <tt/uid=0/ are not affected by this
restriction.
<p>
The behavior of this module can be modified with the following
arguments:
<itemize>
<item><tt/debug/ -
verbose logging to <tt/syslog(3)/.
<item><tt>conf=/path/to/file.conf</tt> -
indicate an alternative <em/limits/ configuration file to the default.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
In order to use this module the system administrator must first create
a <em/root-only-readable/ file (default is
<tt>/etc/security/limits.conf</tt>). This file describes the resource
limits the superuser wishes to impose on users and groups. No limits
are imposed on <tt/uid=0/ accounts.
<p>
Each line of the configuration file describes a limit for a user in
the form:
<tscreen>
<verb>
<domain> <type> <item> <value>
</verb>
</tscreen>
<p>
The fields listed above should be filled as follows...<newline>
<tt>&lt;domain&gt;</tt> can be:
<itemize>
<item> a username
<item> a groupname, with <tt>@group</tt> syntax
<item> the wild-card <tt/*/, for default entry
</itemize>
<p>
<tt>&lt;type&gt;</tt> can have the two values:
<itemize>
<item> <tt/hard/ for enforcing <em/hard/ resource limits. These limits
are set by the superuser and enforced by the Linux Kernel. The user
cannot raise his requirement of system resources above such values.
<item> <tt/soft/ for enforcing <em/soft/ resource limits. These limits
are ones that the user can move up or down within the permitted range
by any pre-exisiting <em/hard/ limits. The values specified with this
token can be thought of as <em/default/ values, for normal system
usage.
</itemize>
<p>
<tt>&lt;item&gt;</tt> can be one of the following:
<itemize>
<item><tt/core/ - limits the core file size (KB)
<item><tt/data/ - max data size (KB)
<item><tt/fsize/ - maximum filesize (KB)
<item><tt/memlock/ - max locked-in-memory address space (KB)
<item><tt/nofile/ - max number of open files
<item><tt/rss/ - max resident set size (KB)
<item><tt/stack/ - max stack size (KB)
<item><tt/cpu/ - max CPU time (MIN)
<item><tt/nproc/ - max number of processes
<item><tt/as/ - address space limit
<item><tt/maxlogins/ - max number of logins for this user.
</itemize>
<p>
To completely disable limits for a user (or a group), a single dash
(-) will do (Example: ``<tt/bin -/'', ``<tt/@admin -/''). Please
remember that individual limits have priority over group limits, so if
you impose no limits for <tt/admin/ group, but one of the members in this
group have a limits line, the user will have its limits set according
to this line.
<p>
Also, please note that all limit settings are set <em/per login/.
They are not global, nor are they permanent; existing only for the
duration of the session.
<p>
In the <em/limits/ configuration file, the ``<tt/#/'' character
introduces a comment - after which the rest of the line is ignored.
<p>
The <tt/pam_limits/ module does its best to report configuration
problems found in its configuration file via <tt/syslog(3)/.
<p>
The following is an example configuration file:
<tscreen>
<verb>
# EXAMPLE /etc/security/limits.conf file:
# =======================================
# <domain> <type> <item> <value>
* soft core 0
* hard rss 10000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4
</verb>
</tscreen>
Note, the use of <tt/soft/ and <tt/hard/ limits for the same resource
(see <tt/@faculty/) -- this establishes the <em/default/ and permitted
<em/extreme/ level of resources that the user can can obtain in a
given service-session.
<p>
For the services that need resources limits (login for example) put a
the following line in <tt>/etc/pam.conf</tt> as the last line for that
service (usually after the pam_unix session line:
<tscreen>
<verb>
#
# Resource limits imposed on login sessions via pam_limits
#
login session required pam_limits.so
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,138 @@
<!--
$Id: pam_listfile.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
<sect1>The list-file module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_listfile/
<tag><bf>Author:</bf></tag>
Elliot Lee <tt>&lt;sopwith@cuc.edu&gt;</tt>
<tag><bf>Maintainer:</bf></tag>
Red Hat Software:<newline>
Michael K. Johnson &lt;johnsonm@redhat.com&gt; 1996/11/18<newline>
(if unavailable, contact Elliot Lee &lt;sopwith@cuc.edu&gt;).
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
clean
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
The list-file module provides a way to deny or allow services based on
an arbitrary file.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt>onerr=succeed|fail</tt>;
<tt>sense=allow|deny</tt>;
<tt>file=</tt><it>filename</it>;
<tt>item=user|tty|rhost|ruser|group|shell</tt>
<tt>apply=user|@group</tt>
<tag><bf>Description:</bf></tag>
The module gets the item of the type specified -- <tt>user</tt> specifies
the username, <tt>PAM_USER</tt>; tty specifies the name of the terminal
over which the request has been made, <tt>PAM_TTY</tt>; rhost specifies
the name of the remote host (if any) from which the request was made,
<tt>PAM_RHOST</tt>; and ruser specifies the name of the remote user
(if available) who made the request, <tt>PAM_RUSER</tt> -- and looks for
an instance of that item in the file <it>filename</it>. <it>filename</it>
contains one line per item listed. If the item is found, then if
<tt>sense=allow</tt>, <tt>PAM_SUCCESS</tt> is returned, causing the
authorization request to succeed; else if <tt>sense=deny</tt>,
<tt>PAM_AUTH_ERR</tt> is returned, causing the authorization
request to fail.
<p>
If an error is encountered (for instance, if <it>filename</it>
does not exist, or a poorly-constructed argument is encountered),
then if <tt>onerr=succeed</tt>, <tt>PAM_SUCCESS</tt> is returned,
otherwise if <tt>onerr=fail</tt>, <tt>PAM_AUTH_ERR</tt> or
<tt>PAM_SERVICE_ERR</tt> (as appropriate) will be returned.
<p>
An additional argument, <tt>apply=</tt>, can be used to restrict the
application of the above to a specific user
(<tt>apply=</tt><em>username</em>) or a given group
(<tt>apply=@</tt><em>groupname</em>). This added restriction is only
meaningful when used with the <tt/tty/, <tt/rhost/ and <tt/shell/
<em/items/.
<p>
Besides this last one, all arguments should be specified; do not count
on any default behavior, as it is subject to change.
<p>
No credentials are awarded by this module.
<tag><bf>Examples/suggested usage:</bf></tag>
Classic ``ftpusers'' authentication can be implemented with this entry
in <tt>/etc/pam.conf</tt>:
<tscreen>
<verb>
#
# deny ftp-access to users listed in the /etc/ftpusers file
#
ftp auth required pam_listfile.so \
onerr=succeed item=user sense=deny file=/etc/ftpusers
</verb>
</tscreen>
Note, users listed in <tt>/etc/ftpusers</tt> file are
(counterintuitively) <bf/not/ allowed access to the ftp service.
<p>
To allow login access only for certain users, you can use an
pam.conf entry like this:
<tscreen>
<verb>
#
# permit login to users listed in /etc/loginusers
#
login auth required pam_listfile.so \
onerr=fail item=user sense=allow file=/etc/loginusers
</verb>
</tscreen>
<p>
For this example to work, all users who are allowed to use the login
service should be listed in the file <tt>/etc/loginusers</tt>. Unless
you are explicitly trying to lock out root, make sure that when you do
this, you leave a way for root to log in, either by listing root in
<tt>/etc/loginusers</tt>, or by listing a user who is able to <em/su/
to the root account.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,124 @@
<!--
$Id: pam_mail.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The mail module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_mail/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author
<tag><bf>Management groups provided:</bf></tag>
auth
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Default mail directory <tt>/var/spool/mail/</tt>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module looks at the user's mail directory and indicates
whether the user has any mail in it.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/dir=/<em/direcory-name/; <tt/nopen/; <tt/close/;
<tt/noenv/; <tt/empty/
<tag><bf>Description:</bf></tag>
This module provides the ``you have new mail'' service to the user. It
can be plugged into any application that has credential hooks. It gives a
single message indicating the <em/newness/ of any mail it finds in the
user's mail folder. This module also sets the <bf/Linux-PAM/
environment variable, <tt/MAIL/, to the user's mail directory.
<p>
Although the module supplies functions for the authentication
management group of functions, it cannot be used to authenticate a
user; its authentication function instructs <tt/libpam/ to simply
ignore it when authenticating the user.
<p>
The behavior of this module can be modified with one of the following
flags:
<p>
<itemize>
<item><tt/debug/
- write more information to <tt/syslog(3)/.
<item><tt/dir=/<em/pathname/
- look for the users' mail in an alternative directory given by
<em/pathname/. The default location for mail is
<tt>/var/spool/mail</tt>. Note, if the supplied <em/pathname/ is
prefixed by a `<tt/&tilde;/', the directory is interpreted as
indicating a file in the user's home directory.
<item><tt/nopen/
- instruct the module to <em/not/ print any mail information when the
user's credentials are acquired. This flag is useful to get the <tt/MAIL/
environment variable set, but to not display any information about it.
<item><tt/close/
- instruct the module to indicate if the user has any mail at the as
the user's credentials are revoked.
<item><tt/noenv/
- do not set the <tt/MAIL/ environment variable.
<item><tt/empty/
- indicate that the user's mail directory is empty if this is found to
be the case.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
This module can be used to indicate that the user has new mail when
they <em/login/ to the system. Here is a sample entry for your
<tt>/etc/pam.conf</tt> file:
<tscreen>
<verb>
#
# do we have any mail?
#
login auth optional pam_mail.so
</verb>
</tscreen>
<p>
Note, some applications may perform this function themselves. In such
cases, this module is not necessary.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,75 @@
<!--
$Id: pam_nologin.sgml,v 1.2 1997/01/04 21:56:55 morgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
<sect1>The no-login module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_nologin/
<tag><bf>Author:</bf></tag>
Written by Michael K. Johnson &lt;johnsonm@redhat.com&gt;<newline>
(based on code taken from a module written by Andrew G. Morgan
&lt;morgan@parc.power.net&gt;).
<tag><bf>Maintainer:</bf></tag>
Michael K. Johnson &lt;johnsonm@redhat.com&gt;
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
1 warning about dropping const
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
Provides standard Unix <em/nologin/ authentication.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
Provides standard Unix <em/nologin/ authentication. If the file
<tt>/etc/nologin</tt> exists, only root is allowed to log in; other
users are turned away with an error message. All users (root or
otherwise) are shown the contents of <tt>/etc/nologin</tt>.
<p>
If the file <tt>/etc/nologin</tt> does not exist, this module succeeds
silently.
<tag><bf>Examples/suggested usage:</bf></tag>
In order to make this module effective, all login methods should
be secured by it. It should be used as a <tt>required</tt>
method listed before any <tt>sufficient</tt> methods in order to
get standard Unix nologin semantics.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,83 @@
<!--
$Id: pam_permit.sgml,v 1.2 1997/02/15 18:20:12 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The promiscuous module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_permit
<tag><bf>Author:</bf></tag>
Andrew G. Morgan, &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Linux-PAM maintainer.
<tag><bf>Management groups provided:</bf></tag>
account; authentication; password; session
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
VERY LOW. Use with extreme caution.
<tag><bf>Clean code base:</bf></tag>
Clean.
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module is very dangerous. It should be used with extreme
caution. Its action is always to permit access. It does nothing else.
<sect2>Account+Authentication+Password+Session components
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
No matter what management group, the action of this module is to
simply return <tt/PAM_SUCCESS/ -- operation successful.
<p>
In the case of authentication, the user's name will be acquired. Many
applications become confused if this name is unknown.
<tag><bf>Examples/suggested usage:</bf></tag>
It is seldom a good idea to use this module. However, it does have
some legitimate uses. For example, if the system-administrator wishes
to turn off the account management on a workstation, and at the same
time continue to allow logins, then she might use the following
configuration file entry for login:
<tscreen>
<verb>
#
# add this line to your other login entries to disable account
# management, but continue to permit users to log in...
#
login account required pam_permit.so
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,245 @@
<!--
$Id: pam_pwdb.sgml,v 1.3 1997/04/05 06:50:42 morgan Exp morgan $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The Password-Database module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_pwdb
<tag><bf>Author:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt; <newline>
and Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Authors.
<tag><bf>Management groups provided:</bf></tag>
account; authentication; password; session
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Requires properly configured <tt/libpwdb/
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module is a pluggable replacement for the <tt/pam_unix_../
modules. It uses the generic interface of the <em/Password Database/
library
<tt><htmlurl
url="http://parc.power.net/morgan/libpwdb/index.html"
name="http://parc.power.net/morgan/libpwdb/index.html"></tt>.
<sect2>Account component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/
<tag><bf>Description:</bf></tag>
The <tt/debug/ argument makes the accounting functions of this module
<tt/syslog(3)/ more information on its actions. (Remaining arguments
supported by the other functions of this module are silently ignored,
but others are logged as errors through <tt/syslog(3)/).
Based on the following <tt/pwdb_element/s:
<tt/expire/;
<tt/last_change/;
<tt/max_change/;
<tt/defer_change/;
<tt/warn_change/,
this module performs the task of establishing the status of the user's
account and password. In the case of the latter, it may offer advice
to the user on changing their password or, through the
<tt/PAM_AUTHTOKEN_REQD/ return, delay giving service to the user until
they have established a new password. The entries listed above are
documented in the <em/Password Database Library Guide/ (see pointer
above). Should the user's record not contain one or more of these
entries, the corresponding <em/shadow/ check is not performed.
<tag><bf>Examples/suggested usage:</bf></tag>
In its accounting mode, this module can be inserted as follows:
<tscreen>
<verb>
#
# Ensure users account and password are still active
#
login account required pam_pwdb.so
</verb>
</tscreen>
</descrip>
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/;
<tt/use_first_pass/;
<tt/try_first_pass/;
<tt/nullok/;
<tt/nodelay/
<tag><bf>Description:</bf></tag>
The <tt/debug/ argument makes the authentication functions of this
module <tt/syslog(3)/ more information on its actions.
<p>
The default action of this module is to not permit the user access to
a service if their <em/official/ password is blank. The <tt/nullok/
argument overrides this default.
<p>
When given the argument <tt/try_first_pass/, before prompting the user
for their password, the module first tries the previous stacked
<tt/auth/-module's password in case that satisfies this module as
well. The argument <tt/use_first_pass/ forces the module to use such a
recalled password and will never prompt the user - if no password is
available or the password is not appropriate, the user will be denied
access.
<p>
The argument, <tt>nodelay</tt>, can be used to discourage the
authentication component from requesting a delay should the
authentication as a whole fail. The default action is for the module
to request a delay-on-failure of the order of one second.
<p>
Remaining arguments, supported by the other functions of this module,
are silently ignored. Other arguments are logged as errors through
<tt/syslog(3)/.
<p>
A helper binary, <tt>pwdb_chkpwd</tt>, is provided to check the user's
password when it is stored in a read protected database. This binary
is very simple and will only check the password of the user invoking
it. It is called transparently on behalf of the user by the
authenticating component of this module. In this way it is possible
for applications like <em>xlock</em> to work without being setuid-root.
<tag><bf>Examples/suggested usage:</bf></tag>
The correct functionality of this module is dictated by having an
appropriate <tt>/etc/pwdb.conf</tt> file, the user
databases specified there dictate the source of the authenticated
user's record.
</descrip>
<sect2>Password component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/; <tt/nullok/; <tt/not_set_pass/; <tt/use_authtok/;
<tt/try_first_pass/; <tt/use_first_pass/; <tt/md5/; <tt/bigcrypt/;
<tt/shadow/; <tt/radius/; <tt/unix/
<tag><bf>Description:</bf></tag>
This part of the <tt/pam_pwdb/ module performs the task of updating
the user's password. Thanks to the flexibility of <tt/libpwdb/ this
module is able to move the user's password from one database to
another, perhaps securing the user's database entry in a dynamic
manner (<em/this is very ALPHA code at the moment!/) - this is the
purpose of the <tt/shadow/, <tt/radius/ and <tt/unix/ arguments.
<p>
In the case of conventional unix databases (which store the password
encrypted) the <tt/md5/ argument is used to do the encryption with the
MD5 function as opposed to the <em/conventional/ <tt/crypt(3)/ call.
As an alternative to this, the <tt/bigcrypt/ argument can be used to
encrypt more than the first 8 characters of a password with DEC's
(Digital Equipment Cooperation) `C2' extension to the standard UNIX
<tt/crypt()/ algorithm.
<p>
The <tt/nullok/ module is used to permit the changing of a password
<em/from/ an empty one. Without this argument, empty passwords are
treated as account-locking ones.
<p>
The argument <tt/use_first_pass/ is used to lock the choice of old and
new passwords to that dictated by the previously stacked <tt/password/
module. The <tt/try_first_pass/ argument is used to avoid the user
having to re-enter an old password when <tt/pam_pwdb/ follows a module
that possibly shared the user's old password - if this old password is
not correct the user will be prompted for the correct one. The
argument <tt/use_authtok/ is used to <em/force/ this module to set the
new password to the one provided by the previously stacked
<tt/password/ module (this is used in an example of the stacking of
the <em/Cracklib/ module documented above).
<p>
The <tt/not_set_pass/ argument is used to inform the module that it is
not to pay attention to/make available the old or new passwords from/to
other (stacked) password modules.
<p>
The <tt/debug/ argument makes the password functions of this module
<tt/syslog(3)/ more information on its actions. Other arguments may be
logged as erroneous to <tt/syslog(3)/.
<tag><bf>Examples/suggested usage:</bf></tag>
An example of the stacking of this module with respect to the
pluggable password checking module, <tt/pam_cracklib/, is given in
that modules section above.
</descrip>
<sect2>Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
No arguments are recognized by this module component. Its action is
simply to log the username and the service-type to
<tt/syslog(3)/. Messages are logged at the beginning and end of the
user's session.
<tag><bf>Examples/suggested usage:</bf></tag>
The use of the session modules is straightforward:
<tscreen>
<verb>
#
# pwdb - unix like session opening and closing
#
login session required pam_pwdb.so
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,117 @@
<!--
$Id: pam_radius.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Cristian Gafton <gafton@redhat.com>
-->
<sect1>The RADIUS session module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_radius/
<tag><bf>Author:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
session
<tag><bf>Cryptographically sensitive:</bf></tag>
This module does not deal with passwords
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
gcc reports 1 warning when compiling <tt>/usr/include/rpc/clnt.h</tt>.
Hey, is not my fault !
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
yes; this is a network module (independent of application).
</descrip>
<sect2>Overview of module
<p>
This module is intended to provide the session service for users
autheticated with a RADIUS server. At the present stage, the only
option supported is the use of the RADIUS server as an accounting
server.
<sect2>Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/ - verbose logging to <tt/syslog(3)/.
<tag><bf>Description:</bf></tag>
This module is intended to provide the session service for users
autheticated with a RADIUS server. At the present stage, the only
option supported is the use of the RADIUS server as an <em/accounting/
server.
<p>
(There are few things which needs to be cleared out first in
the PAM project until one will be able to use this module and expect
it to magically start pppd in response to a RADIUS server command to
use PPP for this user, or to initiate a telnet connection to another
host, or to hang and call back the user using parameters provided in
the RADIUS server response. Most of these things are better suited for
the radius login application. I hope to make available Real Soon (tm)
patches for the login apps to make it work this way.)
<p>
When opening a session, this module sends an ``Accounting-Start''
message to the RADIUS server, which will log/update/whatever a
database for this user. On close, an ``Accounting-Stop'' message is
sent to the RADIUS server.
<p>
This module has no other prerequisites for making it work. One can
install a RADIUS server just for fun and use it as a centralized
accounting server and forget about wtmp/last/sac etc. .
<tag><bf>Examples/suggested usage:</bf></tag>
For the services that need this module (<em/login/ for example) put
the following line in <tt>/etc/pam.conf</tt> as the last line for that
service (usually after the pam_unix session line):
<tscreen>
<verb>
login session required pam_radius.so
</verb>
</tscreen>
Replace <tt/login/ for each service you are using this module.
<p>
This module make extensive use of the API provided in libpwdb
0.54preB or later. By default, it will read the radius server
configuration (hostname and secret) from <tt>/etc/raddb/server</tt>.
This is a default compiled into libpwdb, and curently there is no way to
modify this default without recompiling libpwdb. I am working on
extending the radius support from libpwdb to provide a possibility
to make this runtime-configurable.
Also please note that libpwdb will require also the RADIUS
dictionary to be present (<tt>/etc/raddb/dictionary</tt>).
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,157 @@
<!--
$Id: pam_rhosts.sgml,v 1.4 1997/04/05 06:50:42 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The rhosts module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_rhosts_auth/
<tag><bf>Author:</bf></tag>
Al Longyear &lt;longyear@netcom.com&gt;
<tag><bf>Maintainer:</bf></tag>
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
Clean.
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
Standard <tt/inet_addr()/, <tt/gethostbyname()/ function calls.
</descrip>
<sect2>Overview of module
<p>
This module performs the standard network authentication for services,
as used by traditional implementations of <em/rlogin/ and <em/rsh/
etc.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/no_hosts_equiv/; <tt/no_rhosts/; <tt/debug/; <tt/no_warn/;
<tt/privategroup/; <tt/promiscuous/; <tt/suppress/
<tag><bf>Description:</bf></tag>
The authentication mechanism of this module is based on the contents
of two files; <tt>/etc/hosts.equiv</tt> (or <tt/_PATH_HEQUIV/ in
<tt>#include &lt;netdb.h&gt;</tt>) and <tt>~/.rhosts</tt>. Firstly,
hosts listed in the former file are treated as equivalent to the
localhost. Secondly, entries in the user's own copy of the latter file
is used to map "<tt/remote-host remote-user/" pairs to that user's
account on the current host. Access is granted to the user if their
host is present in <tt>/etc/hosts.equiv</tt> and their remote account
is identical to their local one, or if their remote account has an
entry in their personal configuration file.
<p>
Some restrictions are applied to the attributes of the user's personal
configuration file: it must be a regular file (as defined by
<tt/S_ISREG(x)/ of POSIX.1); it must be owned by the <em/superuser/ or
the user; it must not be writable by any user besides its owner.
<p>
The module authenticates a remote user (internally specified by the
item <tt/PAM_RUSER/) connecting from the remote host (internally
specified by the item <tt/PAM_RHOST/). Accordingly, for applications
to be compatible this authentication module they must set these items
prior to calling <tt/pam_authenticate()/. The module is not capable
of independently probing the network connection for such information.
<p>
In the case of <tt/root/-access, the <tt>/etc/host.equiv</tt> file is
<em/ignored/. Instead, the superuser must have a correctly configured
personal configuration file.
<p>
The behavior of the module is modified by flags:
<itemize>
<item>
<tt/debug/ -
log more information to <tt/syslog(3)/. (XXX - actually, this module
does not do any logging currently, please volunteer to fix this!)
<item>
<tt/no_warn/ -
do not give verbal warnings to the user about failures etc. (XXX -
this module currently does not issue any warnings, please volunteer to
fix this!)
<item>
<tt/no_hosts_equiv/ -
ignore the contents of the <tt>/etc/hosts.equiv</tt> file.
<item>
<tt/no_rhosts/ -
ignore the contents of all user's personal configuration file
<tt>~/.rhosts</tt>.
<item>
<tt/privategroup/ -
normally, the <tt>~/.rhosts</tt> file must not be writable by anyone
other than its owner. This option overlooks group write access in the
case that the group owner of this file has the same name as the
user being authenticated. To lessen the security problems associated
with this option, the module also checks that the user is the only
member of their private group.
<item>
<tt/promiscuous/ -
A host entry of `+' will lead to all hosts being granted
access. Without this option, '+' entries will be ignored. Note, that
the <tt/debug/ option will syslog a warning in this latter case.
<item>
<tt/suppress/ -
This will prevent the module from <tt/syslog(3)/ing a warning message
when this authentication fails. This option is mostly for keeping
logs free of meaningless errors, in particular when the module is used
with the <tt/sufficient/ control flag.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
To allow users to login from trusted remote machines, you should try
adding the following line to your <tt>/etc/pam.conf</tt> file
<em/before/ the line that would otherwise prompt the user for a
password:
<tscreen>
<verb>
#
# No passwords required for users from hosts listed above.
#
login auth sufficient pam_rhosts_auth.so no_rhosts
</verb>
</tscreen>
Note, in this example, the system administrator has turned off all
<em/personal/ <em/rhosts/ configuration files. Also note, that this module
can be used to <em/only/ allow remote login from hosts specified in
the <tt>/etc/host.equiv</tt> file, by replacing <tt/sufficient/ in the
above example with <tt/required/.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,85 @@
<!--
$Id: pam_rootok.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>The root access module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
pam_rootok
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
<bf>Linux-PAM</bf> maintainer
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
Clean.
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
This module is for use in situations where the superuser wishes
to gain access to a service without having to enter a password.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/
<tag><bf>Description:</bf></tag>
This module authenticates the user if their <tt/uid/ is <tt/0/.
Applications that are created <em/setuid/-root generally retain the
<tt/uid/ of the user but run with the authority of an enhanced
<em/effective-/<tt/uid/. It is the real <tt/uid/ that is checked.
<tag><bf>Examples/suggested usage:</bf></tag>
In the case of the <tt/su/ application the historical usage is to
permit the superuser to adopt the identity of a lesser user without
the use of a password. To obtain this behavior under <tt/Linux-PAM/
the following pair of lines are needed for the corresponding entry in
the configuration file:
<tscreen>
<verb>
#
# su authentication. Root is granted access by default.
#
su auth sufficient pam_rootok.so
su auth required pam_unix_auth.so
</verb>
</tscreen>
<p>
Note. For programs that are run by the superuser (or started when the
system boots) this module should not be used to authenticate users.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,72 @@
<!--
$Id: pam_securetty.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
<sect1>The securetty module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_securetty/
<tag><bf>Author[s]:</bf></tag>
Elliot Lee &lt;sopwith@cuc.edu&gt;
<tag><bf>Maintainer:</bf></tag>
Red Hat Software:<newline>
<em/currently/ Michael K. Johnson &lt;johnsonm@redhat.com&gt;<newline>
(if unavailable, contact Elliot Lee &lt;sopwith@cuc.edu&gt;).
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
<tt>/etc/securetty</tt> file
<tag><bf>Network aware:</bf></tag>
Requires the application to fill in the <tt>PAM_TTY</tt> item
correctly in order to act meaningfully.
</descrip>
<sect2>Overview of module
<p>
Provides standard Unix securetty checking.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
Provides standard Unix securetty checking, which causes authentication
for root to fail unless <tt>PAM_TTY</tt> is set to a string listed in
the <tt>/etc/securetty</tt> file. For all other users, it succeeds.
<tag><bf>Examples/suggested usage:</bf></tag>
For canonical usage, should be listed as a <tt>required</tt>
authentication method before any <tt>sufficient</tt> authentication
methods.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,166 @@
<!--
$Id: pam_time.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>Time control
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_time/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan <tt>&lt;morgan@parc.power.net&gt;</tt>
<tag><bf>Maintainer:</bf></tag>
Author
<tag><bf>Management groups provided:</bf></tag>
account
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Requires a configuration file <tt>/etc/security/time.conf</tt>
<tag><bf>Network aware:</bf></tag>
Through the <tt/PAM_TTY/ item only
</descrip>
<sect2>Overview of module
<p>
Running a well regulated system occasionally involves restricting
access to certain services in a selective manner. This module offers
some time control for access to services offered by a system. Its
actions are determined with a configuration file. This module can be
configured to deny access to (individual) users based on their name,
the time of day, the day of week, the service they are applying for
and their terminal from which they are making their request.
<sect2>Account component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
This module bases its actions on the rules listed in its configuration
file: <tt>/etc/security/pam.conf</tt>. Each rule has the following
form,
<tscreen>
<em/services/<tt/;/<em/ttys/<tt/;/<em/users/<tt/;/<em/times/
</tscreen>
In words, each rule occupies a line, terminated with a newline or the
beginning of a comment; a `<tt/#/'. It contains four fields separated
with semicolons, `<tt/;/'. The fields are as follows:
<p>
<itemize>
<item><em/services/ -
a logic list of service names that are affected by this rule.
<item><em/ttys/ -
a logic list of terminal names indicating those terminals covered by
the rule.
<item><em/user/ -
a logic list of usernames to which this rule applies
<p>
By a logic list we mean a sequence of tokens (associated with the
appropriate <tt/PAM_/ item), containing no more than one wildcard
character; `<tt/*/', and optionally prefixed with a negation operator;
`<tt/!/'. Such a sequence is concatenated with one of two logical
operators: <tt/&amp;/ (logical AND) and <tt/|/ (logical OR). Two
examples are: <tt>!morgan&amp;!root</tt>, indicating that this rule
does not apply to the user <tt>morgan</tt> nor to <tt>root</tt>; and
<tt>tty*&amp;!ttyp*</tt>, which indicates that the rule applies only
to console terminals but not pseudoterminals.
<item><em/times/ - a logic list of times at which this rule
applies. The format of each element is a day/time-range. The days are
specified by a sequence of two character entries. For example,
<tt/MoTuSa/, indicates Monday Tuesday and Saturday. Note that
repeated days are <em/unset/; <tt/MoTuMo/ indicates Tuesday, and
<tt/MoWk/ means all weekdays bar Monday. The two character
combinations accepted are,
<tscreen>
<verb>
Mo Tu We Th Fr Sa Su Wk Wd Al
</verb>
</tscreen>
The last two of these being <em/weekend/ days and <em/all 7 days/ of
the week respectively.
<p>
The time range part is a pair of 24-hour times, <em/HHMM/, separated
by a hyphen -- indicating the start and finish time for the rule. If
the finsish time is smaller than the start time, it is assumed to
apply on the following day. For an example, <tt/Mo1800-0300/ indicates
that the permitted times are Monday night from 6pm to 3am the
following morning.
</itemize>
<p>
Note, that the given time restriction is only applied when the first
three fields are satisfied by a user's application for service.
<p>
For convenience and readability a rule can be extended beyond a single
line with a `<tt>&bsol;</tt><em/newline/'.
<tag><bf>Examples/suggested usage:</bf></tag>
The use of this module is initiated with an entry in the
<bf/Linux-PAM/ configuration file of the following type:
<tscreen>
<verb>
#
# apply pam_time accounting to login requests
#
login account required pam_time.so
</verb>
</tscreen>
where, here we are applying the module to the <em/login/ application.
<p>
Some examples of rules that can be placed in the
<tt>/etc/security/time.conf</tt> configuration file are the following:
<descrip>
<tag><tt>login ; tty* &amp ; !ttyp* ; !root ; !Al0000-2400</tt></tag>
all users except for <tt/root/ are denied access to console-login at
all times.
<tag><tt>games ; * ; !waster ; Wd0000-2400 | Wk1800-0800</tt></tag>
games (configured to use Linux-PAM) are only to be accessed out of
working hours. This rule does not apply to the user <tt/waster/.
</descrip>
<p>
Note, currently there is no daemon enforcing the end of a session.
This needs to be remedied.
<p>
Poorly formatted rules are logged as errors using <tt/syslog(3)/.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,67 @@
<!--
$Id: pam_warn.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
<sect1>Warning logger module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_warn/
<tag><bf>Author:</bf></tag>
Andrew G. Morgan &lt;morgan@parc.power.net&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
authentication; password
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
<tag><bf>Network aware:</bf></tag>
logs information about the remote user and host (if pam-items are known)
</descrip>
<sect2>Overview of module
<p>
This module is principally for logging information about a
proposed authentication or application to update a password.
<sect2>Authentication+Password component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tag><bf>Description:</bf></tag>
Log the service, terminal, user, remote user and remote host to
<tt/syslog(3)/. The items are not probed for, but instead obtained
from the standard pam-items.
<tag><bf>Examples/suggested usage:</bf></tag>
an example is provided in the configuration file section <ref
id="configuration" name="above">.
</descrip>
<!--
End of sgml insert for this module.
-->

View File

@ -0,0 +1,124 @@
<!--
$Id: pam_wheel.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp morgan $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
from notes provided by Cristian Gafton.
-->
<sect1>The wheel module
<sect2>Synopsis
<p>
<descrip>
<tag><bf>Module Name:</bf></tag>
<tt/pam_wheel/
<tag><bf>Author:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
<tag><bf>Management groups provided:</bf></tag>
authentication
<tag><bf>Cryptographically sensitive:</bf></tag>
<tag><bf>Security rating:</bf></tag>
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
Requires libpwdb.
<tag><bf>Network aware:</bf></tag>
</descrip>
<sect2>Overview of module
<p>
Only permit root access to members of the wheel (<tt/gid=0/) group.
<sect2>Authentication component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
<tt/debug/;
<tt/use_uid/;
<tt/trust/;
<tt/deny/;
<tt/group=XXXX/
<tag><bf>Description:</bf></tag>
This module is used to enforce the so-called wheel group. By default,
it permits root access to the system if the applicant user is a member
of the <tt/wheel/ group (better described as the group with group-id
<tt/0/).
<p>
The action of the module may be modified from this default by one or
more of the following flags in the <tt>/etc/pam.conf</tt> file.
<itemize>
<item>
<tt/debug/ -
Supply more debugging information to <tt/syslog(3)/.
<item>
<tt/use_id/ -
This option modifies the behavior of the module by using the current
<tt/uid/ of the process and not the <tt/getlogin(3)/ name of the user.
This option is useful for being able to jump from one account to
another, for example with 'su'.
<item>
<tt/trust/ -
This option instructs the module to return <tt/PAM_SUCCESS/ should it
find the user applying for root privilege is a member of the wheel
group. The default action is to return <tt/PAM_IGNORE/ in this
situation. By using the <tt/trust/ option it is possible to arrange
for <tt/wheel/-group members to become root without typing a
password. <bf/USE WITH CARE/.
<item>
<tt/deny/ -
This is used to reverse the logic of the module's behavior.
If the user is trying to get <tt/uid=0/ access and is a member of the wheel
group, deny access (for the wheel group, this is perhaps nonsense!):
it is intended for use in conjunction with the <tt/group=/ argument...
<item>
<tt/group=XXXX/ -
Instead of checking the <tt/gid=0/ group, use the user's <tt/XXXX/
group membership for the authentication. Here, <tt/XXXX/ is the name
of the group and <bf/not/ its numeric identifier.
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
To restrict access to superuser status to the members of the
<tt/wheel/ group, use the following entries in your configuration
file:
<tscreen>
<verb>
#
# root gains access by default (rootok), only wheel members can
# become root (wheel) but Unix authenticate non-root applicants.
#
su auth sufficient pam_rootok.so
su auth required pam_wheel.so
su auth required pam_unix_auth.so
</verb>
</tscreen>
</descrip>
<!--
End of sgml insert for this module.
-->

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,985 @@
<!doctype linuxdoc system>
<!--
$Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $
Copyright (c) Andrew G. Morgan 1996,1997. All rights reserved.
Redistribution and use in source (sgml) and binary (derived) forms,
with or without modification, are permitted provided that the
following conditions are met:
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.
ALTERNATIVELY, this product may be distributed under the terms of the
GNU General Public License, 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.)
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
DAMAGE.
-->
<article>
<title>The Linux-PAM System Administrators' Guide
<author>Andrew G. Morgan, <tt>morgan@linux.kernel.org</tt>
<date>DRAFT v0.59 1998/1/7
<abstract>
This manual documents what a system-administrator needs to know about
the <bf>Linux-PAM</bf> library. It covers the correct syntax of the
PAM configuration file and discusses strategies for maintaining a
secure system.
</abstract>
<!-- Table of contents -->
<toc>
<!-- Begin the document -->
<sect>Introduction
<p><bf/Linux-PAM/ (Pluggable Authentication Modules for Linux) is a
suite of shared libraries that enable the local system administrator
to choose how applications authenticate users.
<p>In other words, without (rewriting and) recompiling a PAM-aware
application, it is possible to switch between the authentication
mechanism(s) it uses. Indeed, one may entirely upgrade the local
authentication system without touching the applications themselves.
<p>Historically an application that has required a given user to be
authenticated, has had to be compiled to use a specific authentication
mechanism. For example, in the case of traditional UN*X systems, the
identity of the user is verified by the user entering a correct
password. This password, after being prefixed by a two character
``salt'', is encrypted (with crypt(3)). The user is then authenticated
if this encrypted password is identical to the second field of the
user's entry in the system password database (the <tt>/etc/passwd</tt>
file). On such systems, most if not all forms of privileges are
granted based on this single authentication scheme. Privilege comes in
the form of a personal user-identifier (<tt/uid/) and membership of
various groups. Services and applications are available based on the
personal and group identity of the user. Traditionally, group
membership has been assigned based on entries in the
<tt>/etc/group</tt> file.
<p>
Unfortunately, increases in the speed of computers and the
widespread introduction of network based computing, have made once
secure authentication mechanisms, such as this, vulnerable to
attack. In the light of such realities, new methods of authentication
are continuously being developed.
<p>
It is the purpose of the <bf/Linux-PAM/ project to separate the
development of privilege granting software from the development of
secure and appropriate authentication schemes. This is accomplished
by providing a library of functions that an application may use to
request that a user be authenticated. This PAM library is configured
locally with a system file, <tt>/etc/pam.conf</tt> (or a series of
configuration files located in <tt>/etc/pam.d/</tt>) to authenticate a
user request via the locally available authentication modules. The
modules themselves will usually be located in the directory
<tt>/usr/lib/security</tt> and take the form of dynamically loadable
object files (see <tt/dlopen(3)/).
<sect>Some comments on the text<label id="text-conventions">
<p>
Before proceeding to read the rest of this document, it should be
noted that the text assumes that certain files are placed in certain
directories. Where they have been specified, the conventions we adopt
here for locating these files are those of the relevant RFC (RFC-86.0,
see <ref id="see-also-sec" name="bibliography">). If you are using a
distribution of Linux (or some other operating system) that supports
PAM but chooses to distribute these files in a diferent way (Red Hat
is one such distribution), you should be careful when copying examples
directly from the text.
<p>
As an example of the above, where it is explicit, the text assumes
that PAM loadable object files (the <em/modules/) are to be located in
the following directory: <tt>/usr/lib/security/</tt>. However, Red Hat
Linux, in agreement with the Linux File System Standard (the FSSTND),
places these files in <tt>/lib/security</tt>. Please be careful to
perform the necessary transcription when using the examples from the
text.
<sect>Overview<label id="overview-section">
<p>
For the uninitiated, we begin by considering an example. We take an
application that grants some service to users; <em/login/ is one such
program. <em/Login/ does two things, it first establishes that the
requesting user is whom they claim to be and second provides them with
the requested service: in the case of <em/login/ the service is a
command shell (<em>bash, tcsh, zsh, etc.</em>) running with the
identity of the user.
<p>
Traditinally, the former step is achieved by the <em/login/
application prompting the user for a password and then verifying that
it agrees with that located on the system; hence verifying that the
so far as the system is concerned the user is who they claim to be.
This is the task that is delegated to <bf/Linux-PAM/.
<p>
From the perspective of the application programmer (in this case the
person that wrote the <em/login/ application), <bf/Linux-PAM/ takes
care of this authentication task -- verifying the identity of the user.
<p>
The flexibility of <bf/Linux-PAM/ is that <em/you/, the system
administrator, have the freedom to stipulate which authentication
scheme is to be used. You have the freedom to set the scheme for
any/all PAM-aware applications on your Linux system. That is, you can
authenticate from anything as naive as <em/simple trust/
(<tt/pam_permit/) to something as paranoid as a combination of a
retinal scan, a voice print and a one-time password!
<p>
To illustrate the flexibility you face, consider the following
situation: a system administrator (parent) wishes to improve the
mathematical ability of her users (children). She can configure their
favorite ``Shoot 'em up game'' (PAM-aware of course) to authenticate
them with a request for the product of a couple of random numbers less
than 12. It is clear that if the game is any good they will soon learn
their <em/multiplication tables/. As they mature, the authentication
can be upgraded to include (long) division!
<p>
<bf/Linux-PAM/ deals with four separate types of (management)
task. These are: <em/authentication management/; <em/account
management/; <em/session management/; and <em/password management/.
The association of the preferred management scheme with the behavior
of an application is made with entries in the relevant <bf/Linux-PAM/
configuration file. The management functions are performed by
<em/modules/ specified in the configuration file. The syntax for this
file is discussed in the section <ref id="configuration"
name="below">.
<p>
Here is a figure that describes the overall organization of
<bf/Linux-PAM/.
<tscreen>
<verb>
+----------------+
| application: X |
+----------------+ / +----------+ +================+
| authentication-[---->--\--] Linux- |--<--| PAM config file|
| + [----<--/--] PAM | |================|
|[conversation()][--+ \ | | | X auth .. a.so |
+----------------+ | / +-n--n-----+ | X auth .. b.so |
| | | __| | | _____/
| service user | A | | |____,-----'
| | | V A
+----------------+ +------|-----|---------+ -----+------+
+---u-----u----+ | | |
| auth.... |--[ a ]--[ b ]--[ c ]
+--------------+
| acct.... |--[ b ]--[ d ]
+--------------+
| password |--[ b ]--[ c ]
+--------------+
| session |--[ e ]--[ c ]
+--------------+
</verb>
</tscreen>
By way of explanation, the left of the figure represents the
application; application X. Such an application interfaces with the
<bf/Linux-PAM/ library and knows none of the specifics of its
configured authentication method. The <bf/Linux-PAM/ library (in the
center) consults the contents of the PAM configuration file and loads
the modules that are appropriate for application-X. These modules fall
into one of four management groups (lower-center) and are stacked in
the order they appear in the configuaration file. These modules, when
called by <bf/Linux-PAM/, perform the various authentication tasks for
the application. Textual information, required from/or offered to the
user, can be exchanged through the use of the application-supplied
<em/conversation/ function.
<sect>The Linux-PAM configuration file
<label id="configuration">
<p>
<bf/Linux-PAM/ is designed to provide the system administrator with a
great deal of flexibility in configuring the privilege granting
applications of their system. The local configuration of those aspects
of system security controlled by <tt/Linux-PAM/ is contained in one of
two places: either the single system file, <tt>/etc/pam.conf</tt>; or
the <tt>/etc/pam.d/</tt> directory. In this section we discuss the
correct syntax of and generic options respected by entries to these
files.
<sect1>Configuration file syntax
<p>
The reader should note that the <bf/Linux-PAM/ specific tokens in this
file are case <em/insensitive/. The module paths, however, are case
sensitive since they indicate a file's <em/name/ and reflect the case
dependence of typical Linux file-systems. The case-sensitivity of the
arguments to any given module is defined for each module in turn.
<p>
In addition to the lines described below, there are two <em/special/
characters provided for the convenience of the system administrator:
comments are preceded by a `<tt/&num;/' and extend to the
next end-of-line; also, module specification lines may be extended
with a `<tt/&bsol;/' escaped newline.
<p>
A general configuration line of the <tt>/etc/pam.conf</tt> file has
the following form:
<tscreen>
<verb>
service-name module-type control-flag module-path arguments
</verb>
</tscreen>
Below, we explain the meaning of each of these tokens. The second (and
more recently adopted) way of configuring <bf/Linux-PAM/ is via the
contents of the <tt>/etc/pam.d/</tt> directory. Once we have explained
the meaning of the above tokens, we will describe this method.
<p>
<descrip>
<tag><tt/service-name/</tag>
The name of the service associated with this entry. Frequently the
service name is the conventional name of the given application. For
example, `<tt/ftpd/', `<tt/rlogind/' and `<tt/su/', <em/etc./ .
<p>
There is a special <tt/service-name/, reserved for defining a default
authentication mechanism. It has the name `<tt/OTHER/' and may be
specified in either lower or upper case characters. Note, when there
is a module specified for a named service, the `<tt/OTHER/' entries
are ignored.
<tag><tt/module-type/</tag>
One of (currently) four types of module. The four types are as
follows:
<itemize>
<item> <tt/auth/; this module type provides two aspects of
authenticating the user. Firstly, it establishes that the user is who
they claim to be, by instructing the application to prompt the user
for a password or other means of identification. Secondly, the module
can grant <tt/group/ membership (independently of the
<tt>/etc/groups</tt> file discussed above) or other privileges through
its <em/credential/ granting properties.
<item> <tt/account/; this module performs non-authentication based
account management. It is typically used to restrict/permit access to
a service based on the time of day, currently available system
resources (maximum number of users) or perhaps the location of the
applicant user---`<tt/root/' login only on the console.
<item> <tt/session/; primarily, this module is associated with doing
things that need to be done for the user before/after they can be
given service. Such things include the logging of information
concerning the opening/closing of some data exchange with a user,
mounting directories, etc. .
<item> <tt/password/; this last module type is required for updating the
authentication token associated with the user. Typically, there is one
module for each `challenge/response' based authentication (<tt/auth/)
module-type.
</itemize>
<tag><tt/control-flag/</tag>
The control-flag is used to indicate how the PAM library will react to
the success or failure of the module it is associated with. Since
modules can be <em/stacked/ (modules of the same type execute in
series, one after another), the control-flags determine the relative
importance of each module. The application is not made aware of the
individual success or failure of modules listed in the
`<tt>/etc/pam.conf</tt>' file. Instead, it receives a summary
<em/success/ or <em/fail/ response from the <bf/Linux-PAM/ library.
The order of execution of these modules is that of the entries in the
<tt>/etc/pam.conf</tt> file; earlier entries are executed before later
ones. As of Linux-PAM v0.60, this <em/control-flag/ can be defined
with one of two syntaxes.
<p>
The simpler (and historical) syntax for the control-flag is a single
keyword defined to indicate the severity of concern associated with
the success or failure of a specific module. There are four such
keywords: <tt/required/, <tt/requisite/, <tt/sufficient/ and
<tt/optional/.
<p>
The Linux-PAM library interprets these keywords in the following
manner:
<itemize>
<item> <tt/required/; this indicates that the success of the module is
required for the <tt/module-type/ facility to succeed. Failure of this
module will not be apparent to the user until all of the remaining
modules (of the same <tt/module-type/) have been executed.
<item> <tt/requisite/; like <tt/required/, however, in the case that
such a module returns a failure, control is directly returned to the
application. The return value is that associated with the <em/first/
<tt/required/ or <tt/requisite/ module to fail. Note, this flag can be
used to protect against the possibility of a user getting the
opportunity to enter a password over an unsafe medium. It is
conceivable that such behavior might inform an attacker of valid
accounts on a system. This possibility should be weighed against the
not insignificant concerns of exposing a sensitive password in a
hostile environment.
<item> <tt/sufficient/; the success of this module is deemed
`<em/sufficient/' to satisfy the <bf/Linux-PAM/ library that this
module-type has succeeded in its purpose. In the event that no
previous <tt/required/ module has failed, no more `<em/stacked/'
modules of this type are invoked. (Note, in this case subsequent
<tt/required/ modules are <bf/not/ invoked.). A failure of this module
is not deemed as fatal to satisfying the application that this
<tt/module-type/ has succeeded.
<item> <tt/optional/; as its name suggests, this <tt/control-flag/
marks the module as not being critical to the success or failure of
the user's application for service. However, in the absence of any
successes of previous or subsequent stacked modules this module will
determine the nature of the response to the application.
</itemize>
<p>
The more elaborate (newer) syntax is much more specific and gives the
administrator a great deal of control over how the user is
authenticated. This form of the control flag is delimeted with square
brackets and consists of a series of <tt/value=action/ tokens:
<tscreen>
<verb>
[value1=action1 value2=action2 ...]
</verb>
</tscreen>
<p>
Here, <tt/valueI/ is one of the following <em/return values/:
<tt/success/; <tt/open_err/; <tt/symbol_err/; <tt/service_err/;
<tt/system_err/; <tt/buf_err/; <tt/perm_denied/; <tt/auth_err/;
<tt/cred_insufficient/; <tt/authinfo_unavail/; <tt/user_unknown/;
<tt/maxtries/; <tt/new_authtok_reqd/; <tt/acct_expired/;
<tt/session_err/; <tt/cred_unavail/; <tt/cred_expired/; <tt/cred_err/;
<tt/no_module_data/; <tt/conv_err/; <tt/authtok_err/;
<tt/authtok_recover_err/; <tt/authtok_lock_busy/;
<tt/authtok_disable_aging/; <tt/try_again/; <tt/ignore/; <tt/abort/;
<tt/authtok_expired/; <tt/module_unknown/; <tt/bad_item/; and
<tt/default/. The last of these (<tt/default/) can be used to set the
action for those return values that are not set explicitly.
<p>
The <tt/actionI/ can be a positive integer or one of the following
tokens: <tt/ignore/; <tt/ok/; <tt/done/; <tt/bad/; <tt/die/; and
<tt/reset/. A positive integer, <tt/J/, when specified as the action
can be used to indicate that the next <em/J/ modules of the current
type will be skipped. In this way, the administrator can develop a
moderately sophisticated stack of modules with a number of different
paths of execution. Which path is taken can be determined by the
reactions of individual modules.
<p>
<bf>Note, at time of writing, this newer syntax is so new that I don't
want to write too much about it. Please play with this. Report all
the bugs and make suggestions for new actions (etc.).</bf>
<tag> <tt/module-path/</tag>
The path-name of the dynamically loadable object file; <em/the
pluggable module/ itself. If the first character of the module path is
`<tt>/</tt>', it is assumed to be a complete path. If this is not the
case, the given module path is appended to the default module path:
<tt>/usr/lib/security</tt> (but see the notes <ref
id="text-conventions" name="above">).
<tag> <tt/args/</tag>
The <tt/args/ are a list of tokens that are passed to the module when
it is invoked. Much like arguments to a typical Linux shell command.
Generally, valid arguments are optional and are specific to any given
module. Invalid arguments are ignored by a module, however, when
encountering an invalid argument, the module is required to write an
error to <tt/syslog(3)/. For a list of <em/generic/ options see the
next section.
</descrip>
<p>
Any line in (one of) the confiuration file(s), that is not formatted
correctly, will generally tend (erring on the side of caution) to make
the authentication process fail. A corresponding error is written to
the system log files with a call to <tt/syslog(3)/.
<sect1>Directory based configuration
<p>
More flexible than the single configuration file, as of version 0.56,
it is possible to configure <tt>libpam</tt> via the contents of the
<tt>/etc/pam.d/</tt> directory. In this case the directory is filled
with files each of which has a filename equal to a service-name (in
lower-case): it is the personal configuration file for the named
service.
<p>
<bf/Linux-PAM/ can be compiled in one of two modes. The preferred
mode uses either <tt>/etc/pam.d/</tt> or <tt>/etc/pam.conf</tt>
configuration but not both. That is to say, if there is a
<tt>/etc/pam.d/</tt> directory then libpam only uses the files
contained in this directory. However, in the absence of the
<tt>/etc/pam.d/</tt> directory the <tt>/etc/pam.conf</tt> file is
used. The other mode (and the one currently supported by Red Hat 4.2)
is to use both <tt>/etc/pam.d/</tt> and <tt>/etc/pam.conf</tt> in
sequence. In this mode, entries in <tt>/etc/pam.d/</tt> override
those of <tt>/etc/pam.conf</tt>.
The syntax of each file in <tt>/etc/pam.d/</tt> is similar to that of
the <tt>/etc/pam.conf</tt> file and is made up of lines of the
following form:
<tscreen>
<verb>
module-type control-flag module-path arguments
</verb>
</tscreen>
The only difference being that the <tt>service-name</tt> is not
present. The service-name is of course the name of the given
configuration file. For example, <tt>/etc/pam.d/login</tt> contains
the configuration for the <em>login</em> service.
<p>
This method of configuration has a number of advantages over the
single file approach. We list them here to assist the reader in
deciding which scheme to adopt:
<p>
<itemize>
<item>A lower chance of misconfiguring an application. There is one
less field to mis-type when editing the configuration files by hand.
<item>Easier to maintain. One application may be reconfigured without
risk of interfering with other applications on the system.
<item>It is possible to symbolically link different services
configuration files to a single file. This makes it easier to keep the
system policy for access consistent across different applications.
(It should be noted, to conserve space, it is equally possible to
<em>hard</em> link a number of configuration files. However, care
should be taken when administering this arrangement as editing a hard
linked file is likely to break the link.)
<item>A potential for quicker configuration file parsing. Only the
relevant entries are parsed when a service gets bound to its modules.
<item>It is possible to limit read access to individual <bf/Linux-PAM/
configuration files using the file protections of the filesystem.
<item>Package management becomes simpler. Every time a new
application is installed, it can be accompanied by an
<tt>/etc/pam.d/</tt><em>xxxxxx</em> file.
</itemize>
<sect1>Generic optional arguments
<p>
The following are optional arguments which are likely to be understood
by any module. Arguments (including these) are in general
<em/optional/.
<p>
<descrip>
<tag><tt/debug/</tag>
Use the <tt/syslog(3)/ call to log debugging information to the system
log files.
<tag> <tt/no_warn/</tag>
Instruct module to not give warning messages to the application.
<tag> <tt/use_first_pass/</tag>
The module should not prompt the user for a password. Instead, it
should obtain the previously typed password (from the preceding
<tt/auth/ module), and use that. If that doesn't work, then the user
will not be authenticated. (This option is intended for <tt/auth/
and <tt/password/ modules only).
<tag> <tt/try_first_pass/</tag>
The module should attempt authentication with the previously typed
password (from the preceding <tt/auth/ module). If that doesn't work,
then the user is prompted for a password. (This option is intended for
<tt/auth/ modules only).
<tag> <tt/use_mapped_pass/</tag>
This argument is not currently supported by any of the modules in the
<bf/Linux-PAM/ distribution because of possible consequences
associated with U.S. encryption exporting restrictions. Within the
U.S., module developers are, of course, free to implement it (as are
developers in other countries). For compatibility reasons we describe
its use as suggested in the <bf/DCE-RFC 86.0/, see section <ref
id="see-also-sec" name="bibliography"> for a pointer to this document.
<p>
The <tt/use_mapped_pass/ argument instructs the module to take the
clear text authentication token entered by a previous module (that
requests such a token) and use it to generate an encryption/decryption
key with which to safely store/retrieve the authentication token
required for this module. In this way the user can enter a single
authentication token and be quietly authenticated by a number of
stacked modules. Obviously a convenient feature that necessarily
requires some reliably strong encryption to make it secure.
This argument is intended for the <tt/auth/ and <tt/password/ module
types only.
</descrip>
<sect1>Example configuration file entries
<p>
In this section, we give some examples of entries that can be present
in the <bf/Linux-PAM/ configuration file. As a first attempt at
configuring your system you could do worse than to implement these.
<sect2>Default policy
<p>
If a system is to be considered secure, it had better have a
reasonably secure `<tt/OTHER/' entry. The following is a paranoid
setting (which is not a bad place to start!):
<tscreen>
<verb>
#
# default; deny access
#
OTHER auth required /usr/lib/security/pam_deny.so
OTHER account required /usr/lib/security/pam_deny.so
OTHER password required /usr/lib/security/pam_deny.so
OTHER session required /usr/lib/security/pam_deny.so
</verb>
</tscreen>
Whilst fundamentally a secure default, this is not very sympathetic to
a misconfigured system. For example, such a system is vulnerable to
locking everyone out should the rest of the file become badly written.
<p>
The module <tt/pam_deny/ (documented in a later section) is not very
sophisticated. For example, it logs no information when it is invoked
so unless the users of a system contact the administrator when failing
to execute a service application, the administrator may go for a long
while in ignorance of the fact that his system is misconfigured.
<p>
The addition of the following line before those in the above example
would provide a suitable warning to the administrator.
<tscreen>
<verb>
#
# default; wake up! This application is not configured
#
OTHER auth required /usr/lib/security/pam_warn.so
OTHER password required /usr/lib/security/pam_warn.so
</verb>
</tscreen>
Having two ``<tt/OTHER auth/'' lines is an example of stacking.
<p>
On a system that uses the <tt>/etc/pam.d/</tt> configuration, the
corresponding default setup would be achieved with the following file:
<tscreen>
<verb>
#
# default configuration: /etc/pam.d/other
#
auth required /usr/lib/security/pam_warn.so
auth required /usr/lib/security/pam_deny.so
account required /usr/lib/security/pam_deny.so
password required /usr/lib/security/pam_warn.so
password required /usr/lib/security/pam_deny.so
session required /usr/lib/security/pam_deny.so
</verb>
</tscreen>
This is the only explicit example we give for an <tt>/etc/pam.d/</tt>
file. In general, it should be clear how to transpose the remaining
examples to this configuration scheme.
<p>
On a less sensitive computer, one on which the system administrator
wishes to remain ignorant of much of the power of <tt/Linux-PAM/, the
following selection of lines (in <tt>/etc/pam.conf</tt>) is likely to
mimic the historically familiar Linux setup.
<tscreen>
<verb>
#
# default; standard UNIX access
#
OTHER auth required /usr/lib/security/pam_unix_auth.so
OTHER account required /usr/lib/security/pam_unix_acct.so
OTHER password required /usr/lib/security/pam_unix_passwd.so
OTHER session required /usr/lib/security/pam_unix_session.so
</verb>
</tscreen>
In general this will provide a starting place for most applications.
Unfortunately, most is not all. One application that might require
additional lines is <em/ftpd/ if you wish to enable
<em/anonymous-ftp/.
<p>
To enable anonymous-ftp, the following lines might be used to replace
the default (<tt/OTHER/) ones. (<bf/*WARNING*/ as of 1996/12/28 this
does not work correctly with any ftpd. Consequently, this description
may be subject to change or the application will be fixed.)
<tscreen>
<verb>
#
# ftpd; add ftp-specifics. These lines enable anonymous ftp over
# standard UNIX access (the listfile entry blocks access to
# users listed in /etc/ftpusers)
#
ftpd auth sufficient /usr/lib/security/pam_ftp.so
ftpd auth required /usr/lib/security/pam_unix_auth.so use_first_pass
ftpd auth required /usr/lib/security/pam_listfile.so \
onerr=succeed item=user sense=deny file=/etc/ftpusers
</verb>
</tscreen>
Note, the second line is necessary since the default entries are
ignored by a service application (here <em/ftpd/) if there are
<em/any/ entries in <tt>/etc/pam.conf</tt> for that specified service.
Again, this is an example of authentication module stacking. Note the
use of the <tt/sufficient/ control-flag. It says that ``if this module
authenticates the user, ignore the subsequent <tt/auth/
modules''. Also note the use of the ``<tt/use_first_pass/''
module-argument, this instructs the UNIX authentication module that it
is not to prompt for a password but rely one already having been
obtained by the ftp module.
<p>
The standard UNIX modules, used above, are strongly tied to using the
default `<tt/libc/' user database functions (see for example, <tt/man
getpwent/). It is the opinion of the author that these functions are
not sufficently flexible to make full use of the power of
<bf/Linux-PAM/. For this reason, and as a small plug, I mention in
passing that there is a pluggable replacement for the <tt/pam_unix_../
modules; <tt/pam_pwdb/. See the section below for a more complete
description.
<sect>Security issues of Linux-PAM
<p>
This section will discuss good practices for using Linux-PAM in a
secure manner. <em>It is currently sadly lacking...suggestions are
welcome!</em>
<sect1>If something goes wrong
<p>
<bf/Linux-PAM/ has the potential to seriously change the security of
your system. You can choose to have no security or absolute security
(no access permitted). In general, <bf/Linux-PAM/ errs towards the
latter. Any number of configuration errors can dissable access to
your system partially, or completely.
<p>
The most dramatic problem that is likely to be encountered when
configuring <bf/Linux-PAM/ is that of <em>deleting</em> the
configuration file(s): <tt>/etc/pam.d/*</tt> and/or
<tt>/etc/pam.conf</tt>. This will lock you out of your own system!
<p>
To recover, your best bet is to reboot the system in single user mode
and set about correcting things from there. The following has been
<em>adapted</em> from a life-saving email on the subject from David
Wood:
<verb>
> What the hell do I do now?
OK, don't panic. The first thing you have to realize is that
this happens to 50% of users who ever do anything with PAM.
It happened here, not once, not twice, but three times, all
different, and in the end, the solution was the same every
time.
First, I hope you installed LILO with a delay. If you can,
reboot, hit shift or tab or something and type:
LILO boot: linux single
(Replace 'linux' with 'name-of-your-normal-linux-image').
This will let you in without logging in. Ever wondered how
easy it is to break into a linux machine from the console?
Now you know.
If you can't do that, then get yourself a bootkernel floppy
and a root disk a-la slackware's rescue.gz. (Red Hat's
installation disks can be used in this mode too.)
In either case, the point is to get back your root prompt.
Second, I'm going to assume that you haven't completely
nuked your pam installation - just your configuration files.
Here's how you make your configs nice again:
cd /etc
mv pam.conf pam.conf.orig
mv pam.d pam.d.orig
mkdir pam.d
cd pam.d
and then use vi to create a file called "other" in this
directory. It should contain the following four lines:
auth required pam_unix_auth.so
account required pam_unix_acct.so
password required pam_unix_passwd.so
session required pam_unix_session.so
Now you have the simplest possible PAM configuration that
will work the way you're used to. Everything should
magically start to work again. Try it out by hitting ALT-F2
and logging in on another virtual console. If it doesn't
work, you have bigger problems, or you've mistyped
something. One of the wonders of this system (seriously,
perhaps) is that if you mistype anything in the conf files,
you usually get no error reporting of any kind on the
console - just some entries in the log file. So look there!
(Try 'tail /var/log/messages'.)
From here you can go back and get a real configuration
going, hopefully after you've tested it first on a machine
you don't care about screwing up. :/
Some pointers (to make everything "right" with Red Hat...):
Install the newest pam, pamconfig, and pwdb from the
redhat current directory, and do it all on the same
command line with rpm...
rpm -Uvh [maybe --force too] pam-* pamconfig-* pwdb-*
Then make sure you install (or reinstall) the newest
version of libc, util-linux, wuftp, and NetKit. For
kicks you might try installing the newest versions of
the affected x apps, like xlock, but I haven't gotten
those to work at all yet.
</verb>
<sect1>Avoid having a weak `other' configuration
<p>
It is not a good thing to have a weak default (<tt/OTHER/) entry.
This service is the default configuration for all PAM aware
applications and if it is weak, your system is likely to be vulnerable
to attack.
<sect>A reference guide for available modules
<p>
Here, we collect together some descriptions of the various modules
available for <bf/Linux-PAM/. In general these modules should be
freely available. Where this is not the case, it will be indicated.
<p>
Also please note the comments contained in the section <ref
id="text-conventions" name="on text conventions above"> when copying
the examples listed below.
<!-- insert-file MODULES-SGML -->
<sect>Files
<p><descrip>
<tag><tt>/usr/lib/libpam.so.*</tt></tag>
the shared library providing applications with access to
<bf/Linux-PAM/.
<tag><tt>/etc/pam.conf</tt></tag>
the <bf/Linux-PAM/ configuration file.
<tag><tt>/usr/lib/security/pam_*.so</tt></tag>
the primary location for <bf/Linux-PAM/ dynamically loadable object
files; the modules.
</descrip>
<sect>See also<label id="see-also-sec">
<p><itemize>
<item>The <bf/Linux-PAM/ Application Writers' Guide.
<item>The <bf/Linux-PAM/ Module Writers' Guide.
<item>The V. Samar and R. Schemers (SunSoft), ``UNIFIED LOGIN WITH
PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation Request
For Comments 86.0, October 1995. See this url:
<tt><htmlurl
url="http://www.pilgrim.umass.edu/pub/osf_dce/RFC/rfc86.0.txt"
name="http://www.pilgrim.umass.edu/pub/osf&lowbar;dce/RFC/rfc86.0.txt"></tt>
</itemize>
<sect>Notes
<p>
I intend to put development comments here... like ``at the moment
this isn't actually supported''. At release time what ever is in
this section will be placed in the Bugs section below! :)
<p>
Are we going to be able to support the <tt/use_mapped_pass/ module
argument? Anyone know a cheap (free) good lawyer?!
<p>
<itemize>
<item>
This issue may go away, as Sun have investigated adding a new
management group for mappings. In this way, libpam would have mapping
modules that could securely store passwords using strong cryptography
and in such a way that they need not be distributed with Linux-PAM.
</itemize>
<sect>Author/acknowledgments
<p>
This document was written by Andrew G. Morgan (morgan@parc.power.net)
with many contributions from
<!-- insert credits here -->
<!--
an sgml list of people to credit for their contributions to Linux-PAM
$Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $
-->
Craig S. Bell,
Derrick J. Brashear,
Ben Buxton,
Oliver Crow,
Marc Ewing,
Cristian Gafton,
Eric Hester,
Eric Jacksch,
Michael K. Johnson,
David Kinchlea,
Elliot Lee,
Al Longyear,
Marek Michalkiewicz,
Aleph One,
Sean Reifschneider,
Eric Troan,
Theodore Ts'o,
Jeff Uphoff,
Ronald Wahl,
John Wilmes,
Joseph S. D. Yao
and
Alex O. Yuriev.
<p>
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
<bf/Linux-PAM/, Sun graciously made the documentation for their
implementation of PAM available. This act greatly accelerated the
development of <bf/Linux-PAM/.
<sect>Bugs/omissions
<p>
More PAM modules are being developed all the time. It is unlikely that
this document will ever be truely up to date!
<p>
Currently there is no documentation for PAM-aware applications.
<p>
This manual is unfinished. Only a partial list of people is credited
for all the good work they have done.
<sect>Copyright information for this document
<p>
Copyright (c) Andrew G. Morgan 1996. All rights reserved.
<newline>
Email: <tt>&lt;morgan@parc.power.net&gt;</tt>
<p>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
<p>
<itemize>
<item>
1. Redistributions of source code must retain the above copyright
notice, and the entire permission notice in its entirety,
including the disclaimer of warranties.
<item>
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.
<item>
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
</itemize>
<p>
<bf/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 <bf/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.)
<p>
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
DAMAGE.
<p>
<tt>$Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $</tt>
</article>

View File

@ -0,0 +1,3 @@
$Id: README,v 1.1 1996/11/10 19:28:16 morgan Exp $
this is the directory for the postscipt documentation

View File

@ -0,0 +1,270 @@
PAM working group ## A.G. Morgan
Internet Draft: ## March 24, 1998
Document: draft-morgan-pam-00.txt ##
Expires: September 24, 1998 ##
Obsoletes: ##
## Pluggable Authentication Modules ##
#$ Status of this memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet- Drafts as reference
material or to cite them other than as "work in progress."
To view the entire list of current Internet-Drafts, please check the
"1id-abstracts.txt" listing contained in the Internet-Drafts Shadow
Directories on ftp.is.co.za (Africa), ftp.nordu.net (Northern Europe),
ftp.nis.garr.it (Southern Europe), munnari.oz.au (Pacific Rim),
ftp.ietf.org (US East Coast), or ftp.isi.edu (US West Coast).
#$ Abstract
This document is concerned with the definition of a general
infrastructure for module based authentication. The infrastructure is
named Pluggable Authentication Modules (PAM for short).
#$ Introduction
Computers are tools. They provide services to people and other
computers (collectively we shall call these "users" entities). In
order to provide convenient, reliable and individual service to
different entities, it is common for entities to be labelled. Having
defined a label as refering to a some specific entity, the label is
used for the purpose of protecting and allocating data resources.
All modern operating systems have a notion of labelled entities and
all modern operating systems face a common problem: how to
authenticate the association of a predefined label with applicant
entities.
There are as many authentication methods as one might care to count.
None of them are perfect and none of them are invulnerable. In
general, any given authentication method becomes weaker over time. It
is common then for new authentication methods to be developed in
response to newly discovered weaknesses in the old authentication
methods.
The problem with reinventing authentication methods is the fact that
old applications do not support them. This contributes to an inertia
that discourages the overhaul of weakly protected systems. Another
problem is that individuals (people) are frequently powerless to layer
the protective authentication around their systems. They are forced
to rely on single (lowest common denominator) authentication schemes
even in situations where this is far from appropriate.
PAM, as discussed in this document, is a generalization of the
approach first introduced in [#$R#{OSF_RFC_PAM}]. In short, it is a
general framework of interfaces that abstract the process of
authentication. With PAM, a service provider can custom protect
individual services to the level that they deam is appropriate.
PAM has nothing explicit to say about transport layer encryption.
Within the context of this document encryption and/or compression of
data exchanges are application specific (strictly between client and
server).
#$ Definitions
Here we pose the authentication problem as one of configuring defined
interfaces between two entities.
#$$#{players} Players in the authentication process
PAM reserves the following words to specify unique entities in the
authentication process:
applicant
the entity (user) initiating an application for service
[PAM associates PAM_RUSER with this requesting user].
arbitrator
the entity (user) under who's identity the service application
is negotiated and with who's authority service is granted.
user
the entity (user) who's identity is being authenticated
[PAM associates PAM_USER with this identity].
server
the application that provides service, or acts as an
authenticated gateway to the requested service. This
application is completely responsible for the transport
layer. PAM makes no assumptions about how data is
exchanged between the server and the client.
client
application providing the direct/primary interface to
applicant. This application is completely responsible
for transporting client-side data to the server.
PAM makes no assumptions about how data is exchanged between
the client and the server.
module
authentication binary that provides server-side support for
some authentication method.
agent
authentication binary that provides client-side support for
some authentication method.
#$$ Special cases
In the previous section (#{players}) we identified the most general
selection of authentication participants. In the case of network
authentication, it is easy to ascribe identities to the defined
players. However, there are special (less general) cases and we
recognize them here.
The primary authentication step, when a user is directly introduced
into a computer system (log's on to a workstation) is a special case.
In this situation, the "client" and the "server" are generally one
application. Before authenticating such a user, the "applicant" is
formally unknown.
#$ Defined interfaces
Here, we discuss the formal interfaces between the players in the
authentication process.
#$$#{applicant_client} Applicant <-> client
Once the client is invoked, requests to the applicant entity are
initiated by the client application. General clients are able to make
the following requests to an applicant:
echo text
echo error
prompt for echo'd text input
prompt for concealed text input
the nature of the interface provided by the client for the benefit of
the applicant entity is client specific and not defined by PAM.
#$$ Client <-> agent
In general, authentication schemes require more modes of exchange than
the four defined in the previous section (#{applicant_client}). This
provides a role for client-loadable agents. The client and agent
exchange binary-messages that can have one of the following forms:
client -> agent
prompt for binary data packet using a binary packet
agent -> client
set environment variable
get environment variable
echo text
echo error
prompt for echo'd text input
prompt for concealed text input
The single defined procedure for exchange is that the client first
prompts the agent with a binary packet and expects to receive a binary
(response) packet in return. Before returning the binary response,
the agent may request an arbitrary number of exchanges with the client.
#$$ Client <-> server
Once the client has established a connection with the server (the
nature of the transport protocol is not specified by PAM), the server
is reponsible for driving the authentication process.
General servers can request the following from the client:
(directed to the applicant)
echo text
echo error
prompt for echo'd text response
prompt for concealed text response
(directed to the appropriate agent)
binary prompt for a binary response
Client side agents are required to process binary prompts. Their
binary responses are passed directly back to the server.
#$$ Server <-> module
Modules drive the authentication process. The server provides a
conversation function with which it encapsulates module-generated
requests and exchanges them with the client.
General conversation functions can support the following five
"conversation" requests:
echo text
echo error
prompt for echo'd text response
prompt for concealed text response
prompt for binary packet with binary packet
The server is responsible for redirecting these requests to the
client.
#$ C API for defined interfaces
#$$ Applicant <-> client
No API is defined for this interface. The interface is considered to
be specific to the client application. Example applications include
terminal login, (X)windows login, machine file transfer applications.
#$$ Client <-> agent
This interface is concerned with the exchange of "binary prompts". A
binary prompt has the following form: { 4 8-bit bytes in network order
encoding an unsigened 32 bit integer (length), 4 8-bit bytes in
network order encoding an unsigened 32 bit integer (control),
"length-4" 8-bit bytes bytes comprising upto 2^32-4 bytes of binary
data }.
## [ u32 | u32 | (length-4 bytes) ] ##
## length control data ##
The composition of the "data" is not specified. Valid control values
are:
##control value | used by | description ##
##------------------------------------------------------------------##
## | | ##
##PAMC_CONTROL_OK | agent | agent is happy ##
##PAMC_CONTROL_FAIL | agent | agent failed ##
##PAMC_CONTROL_BUSY | agent | agent is busy ##
##PAMC_CONTROL_PUTENV | agent | set envvar of client ##
##PAMC_CONTROL_GETENV | agent | want envvar of client ##
##PAMC_CONTROL_GETECHO | agent | echo'd prompt to applicant##
##PAMC_CONTROL_GETNOECHO | agent | secret prompt to applicant##
##PAMC_CONTROL_PUTTEXT | agent | echo text to applicant ##
##PAMC_CONTROL_SELECT | client | client selects named agent##
##PAMC_CONTROL_EXCHANGE | client+agent | data exchange packet ##
##PAMC_CONTROL_DONE | agent | agent has completed ##
##PAMC_CONTROL_EMPTY | agent | agent has no reply ##
#$ Security considerations
This document is devoted to standardizing authentication
infrastructure: everything in this document has implications for
security.
#$ Contact
The email list for discussing issues related to this document is
<pam-list@redhat.com>.
#$ References
[#{OSF_RFC_PAM}] OSF RFC 86.0, "Unified Login with Pluggable Authentication
Modules (PAM)", October 1995
#$ Author's Address
Andrew Morgan
Email: morgan@ftp.kernel.org

View File

@ -0,0 +1,16 @@
LIBS=-lfl
padout: parse.tab.o
$(CC) -o padout parse.tab.o $(LIBS)
parse.tab.o: parse.tab.c lex.yy.c
$(CC) -c parse.tab.c
parse.tab.c: parse.y
bison parse.y
lex.yy.c: parse.lex
flex parse.lex
clean:
rm -f parse.tab.o parse.tab.c lex.yy.c padout *~ core

View File

@ -0,0 +1,11 @@
%%
\#[\$]+[a-zA-Z]*(\=[0-9]+)? return NEW_COUNTER;
\#\{[a-zA-Z][a-zA-Z0-9\_]*\} return LABEL;
\# return NO_INDENT;
\#\# return RIGHT;
\\\# return HASH;
[^\n] return CHAR;
[\n] return NEWLINE;
%%

View File

@ -0,0 +1,293 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 1000
#define INDENT_STRING " "
#define PAPER_WIDTH 74
int indent=0;
int line=1;
char *last_label=NULL;
extern void yyerror(const char *x);
extern char *get_label(const char *label);
extern void set_label(const char *label, const char *target);
char *new_counter(const char *key);
#include "lex.yy.c"
%}
%union {
int def;
char *string;
}
%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT
%type <string> stuff text
%start doc
%%
doc:
| doc NEWLINE {
printf("\n");
++line;
}
| doc stuff NEWLINE {
if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) {
yyerror("line too long");
}
printf("%s%s\n", indent ? INDENT_STRING:"", $2);
free($2);
indent = 1;
++line;
}
| doc stuff RIGHT stuff NEWLINE {
char fixed[PAPER_WIDTH+1];
int len;
len = PAPER_WIDTH-(strlen($2)+strlen($4));
if (len >= 0) {
memset(fixed, ' ', len);
fixed[len] = '\0';
} else {
yyerror("line too wide");
fixed[0] = '\0';
}
printf("%s%s%s\n", $2, fixed, $4);
free($2);
free($4);
indent = 1;
++line;
}
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
char fixed[PAPER_WIDTH+1];
int len, l;
len = PAPER_WIDTH-(strlen($2)+strlen($4));
if (len < 0) {
len = 0;
yyerror("line too wide");
}
l = len/2;
memset(fixed, ' ', l);
fixed[l] = '\0';
printf("%s%s%s", $2, fixed, $4);
free($2);
free($4);
l = (len+1)/2;
memset(fixed, ' ', l);
fixed[l] = '\0';
printf("%s%s\n", fixed, $6);
free($6);
indent = 1;
++line;
}
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
char fixed[PAPER_WIDTH+1];
int len, l;
len = PAPER_WIDTH-(strlen($2)+strlen($4));
if (len < 0) {
len = 0;
yyerror("line too wide");
}
l = len/2;
memset(fixed, ' ', l);
fixed[l] = '\0';
printf("%s%s%s", $2, fixed, $4);
free($2);
free($4);
l = (len+1)/2;
memset(fixed, ' ', l);
fixed[l] = '\0';
printf("%s%s\n", fixed, $6);
free($6);
indent = 1;
++line;
}
;
stuff: {
$$ = strdup("");
}
| stuff text {
$$ = malloc(strlen($1)+strlen($2)+1);
sprintf($$,"%s%s", $1, $2);
free($1);
free($2);
}
;
text: CHAR {
$$ = strdup(yytext);
}
| text CHAR {
$$ = malloc(strlen($1)+2);
sprintf($$,"%s%s", $1, yytext);
free($1);
}
| NO_INDENT {
$$ = strdup("");
indent = 0;
}
| HASH {
$$ = strdup("#");
}
| LABEL {
if (($$ = get_label(yytext)) == NULL) {
set_label(yytext, last_label);
$$ = strdup("");
}
}
| NEW_COUNTER {
$$ = new_counter(yytext);
}
;
%%
typedef struct node_s {
struct node_s *left, *right;
const char *key;
char *value;
} *node_t;
node_t label_root = NULL;
node_t counter_root = NULL;
const char *find_key(node_t root, const char *key)
{
while (root) {
int cmp = strcmp(key, root->key);
if (cmp > 0) {
root = root->right;
} else if (cmp) {
root = root->left;
} else {
return root->value;
}
}
return NULL;
}
node_t set_key(node_t root, const char *key, const char *value)
{
if (root) {
int cmp = strcmp(key, root->key);
if (cmp > 0) {
root->right = set_key(root->right, key, value);
} else if (cmp) {
root->left = set_key(root->left, key, value);
} else {
free(root->value);
root->value = strdup(value);
}
} else {
root = malloc(sizeof(struct node_s));
root->right = root->left = NULL;
root->key = strdup(key);
root->value = strdup(value);
}
return root;
}
void yyerror(const char *x)
{
fprintf(stderr, "line %d: %s\n", line, x);
}
char *get_label(const char *label)
{
const char *found = find_key(label_root, label);
if (found) {
return strdup(found);
}
return NULL;
}
void set_label(const char *label, const char *target)
{
if (target == NULL) {
yyerror("no hanging value for label");
target = "<??>";
}
label_root = set_key(label_root, label, target);
}
char *new_counter(const char *key)
{
int i=0, j, ndollars = 0;
const char *old;
char *new;
if (key[i++] != '#') {
yyerror("bad index");
return strdup("<???>");
}
while (key[i] == '$') {
++ndollars;
++i;
}
key += i;
old = find_key(counter_root, key);
new = malloc(20*ndollars);
if (old) {
for (j=0; ndollars > 1 && old[j]; ) {
if (old[j++] == '.' && --ndollars <= 0) {
break;
}
}
if (j) {
strncpy(new, old, j);
}
if (old[j]) {
i = atoi(old+j);
} else {
new[j++] = '.';
i = 0;
}
} else {
j=0;
while (--ndollars > 0) {
new[j++] = '0';
new[j++] = '.';
}
i = 0;
}
new[j] = '\0';
sprintf(new+j, "%d", ++i);
counter_root = set_key(counter_root, key, new);
if (last_label) {
free(last_label);
}
last_label = strdup(new);
return new;
}
main()
{
yyparse();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
$Id: README,v 1.1 1996/11/10 19:18:06 morgan Exp $
This is a directory for text versions of the pam documentation

View File

@ -0,0 +1,42 @@
#
# $Id: Makefile,v 1.10 1996/11/10 19:50:59 morgan Exp $
#
dummy:
@echo "*** This is not a top level Makefile!"
PROGS = blank xsh check_user
SRCS = blank.c xsh.c check_user.c
# have removed the following pair since they no longer conform to
# any recognized conventions: vpass test
# ditto: vpass.c test.c
PROGSUID =
all: $(PROGS)
check_user: check_user.o
$(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
blank: blank.o
$(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
xsh: xsh.o
$(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
install: all
if [ -n "$(PROGS)" ]; then cp $(PROGS) ../bin ; fi
if [ -n "$(PROGSUID)" ]; then \
$(INSTALL) -m 4555 -o root -g bin $(PROGSUID) ../bin ; fi
clean:
rm -f *.a *.so *.o *~ $(PROGS) $(PROGSUID)
remove:
cd ../bin ; rm -f $(PROGS) $(PROGSUID)
extraclean: clean
rm -f *.a *.out *.o *.so
for x in $(PROGS) $(PROGSUID) ; do rm -f ../bin/$$x ; done

View File

@ -0,0 +1,173 @@
/*
* $Id: blank.c,v 1.7 1996/12/01 03:16:53 morgan Exp morgan $
*
* $Log: blank.c,v $
* Revision 1.7 1996/12/01 03:16:53 morgan
* added setcred closing function
*
* Revision 1.6 1996/11/10 19:51:40 morgan
* minor change to avoid gcc warning
*
* Revision 1.5 1996/07/07 23:53:05 morgan
* added optional fail delay (non-standard Linux-PAM)
*
* Revision 1.4 1996/05/02 04:44:18 morgan
* moved conversation to a libmisc library routine.
*
*
*/
/* Andrew Morgan (morgan@parc.power.net) -- a self contained `blank'
* application
*
* I am not very proud of this code. It makes use of a possibly ill-
* defined pamh pointer to call pam_strerror() with. The reason that
* I was sloppy with this is historical (pam_strerror, prior to 0.59,
* did not require a pamh argument) and if this program is used as a
* model for anything, I should wish that you will take this error into
* account.
*/
#include <stdio.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
/* ------ some local (static) functions ------- */
static void bail_out(pam_handle_t *pamh, int really, int code, const char *fn)
{
fprintf(stderr,"==> called %s()\n got: `%s'\n", fn,
pam_strerror(pamh, code));
if (really && code)
exit (1);
}
/* ------ some static data objects ------- */
static struct pam_conv conv = {
misc_conv,
NULL
};
/* ------- the application itself -------- */
void main(int argc, char **argv)
{
pam_handle_t *pamh=NULL;
char *username=NULL;
int retcode;
/* did the user call with a username as an argument ? */
if (argc > 2) {
fprintf(stderr,"usage: %s [username]\n",argv[0]);
} else if (argc == 2) {
username = argv[1];
}
/* initialize the Linux-PAM library */
retcode = pam_start("blank", username, &conv, &pamh);
bail_out(pamh,1,retcode,"pam_start");
/* test the environment stuff */
{
#define MAXENV 15
const char *greek[MAXENV] = {
"a=alpha", "b=beta", "c=gamma", "d=delta", "e=epsilon",
"f=phi", "g=psi", "h=eta", "i=iota", "j=mu", "k=nu",
"l=zeta", "h=", "d", "k=xi"
};
char **env;
int i;
for (i=0; i<MAXENV; ++i) {
retcode = pam_putenv(pamh,greek[i]);
bail_out(pamh,0,retcode,"pam_putenv");
}
env = pam_getenvlist(pamh);
if (env)
env = pam_misc_drop_env(env);
else
fprintf(stderr,"???\n");
fprintf(stderr,"a test: c=[%s], j=[%s]\n"
, pam_getenv(pamh, "c"), pam_getenv(pamh, "j"));
}
/* to avoid using goto we abuse a loop here */
for (;;) {
/* authenticate the user --- `0' here, could have been PAM_SILENT
* | PAM_DISALLOW_NULL_AUTHTOK */
retcode = pam_authenticate(pamh, 0);
bail_out(pamh,0,retcode,"pam_authenticate");
/* has the user proved themself valid? */
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: invalid request\n",argv[0]);
break;
}
/* the user is valid, but should they have access at this
time? */
retcode = pam_acct_mgmt(pamh, 0); /* `0' could be as above */
bail_out(pamh,0,retcode,"pam_acct_mgmt");
if (retcode == PAM_NEW_AUTHTOK_REQD) {
fprintf(stderr,"Application must request new password...\n");
retcode = pam_chauthtok(pamh,PAM_CHANGE_EXPIRED_AUTHTOK);
bail_out(pamh,0,retcode,"pam_chauthtok");
}
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: invalid request\n",argv[0]);
break;
}
/* `0' could be as above */
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
bail_out(pamh,0,retcode,"pam_setcred1");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem setting user credentials\n"
,argv[0]);
break;
}
/* open a session for the user --- `0' could be PAM_SILENT */
retcode = pam_open_session(pamh,0);
bail_out(pamh,0,retcode,"pam_open_session");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem opening a session\n",argv[0]);
break;
}
fprintf(stderr,"The user has been authenticated and `logged in'\n");
/* close a session for the user --- `0' could be PAM_SILENT
* it is possible that this pam_close_call is in another program..
*/
retcode = pam_close_session(pamh,0);
bail_out(pamh,0,retcode,"pam_close_session");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem closing a session\n",argv[0]);
break;
}
retcode = pam_setcred(pamh, PAM_DELETE_CRED);
bail_out(pamh,0,retcode,"pam_setcred2");
break; /* don't go on for ever! */
}
/* close the Linux-PAM library */
retcode = pam_end(pamh, PAM_SUCCESS);
pamh = NULL;
bail_out(pamh,1,retcode,"pam_end");
exit(0);
}

View File

@ -0,0 +1,65 @@
/*
$Id: check_user.c,v 1.1 1996/11/10 21:19:30 morgan Exp morgan $
This program was contributed by Shane Watts <shane@icarus.bofh.asn.au>
slight modifications by AGM.
You need to add the following (or equivalent) to the /etc/pam.conf file.
# check authorization
check auth required pam_unix_auth.so
check account required pam_unix_acct.so
$Log: check_user.c,v $
Revision 1.1 1996/11/10 21:19:30 morgan
Initial revision
*/
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>
static struct pam_conv conv = {
misc_conv,
NULL
};
int main(int argc, char *argv[])
{
pam_handle_t *pamh=NULL;
int retval;
const char *user="nobody";
if(argc == 2) {
user = argv[1];
}
if(argc > 2) {
fprintf(stderr, "Usage: check_user [username]\n");
exit(1);
}
retval = pam_start("check", user, &conv, &pamh);
if (retval == PAM_SUCCESS)
retval = pam_authenticate(pamh, 0); /* is user really user? */
if (retval == PAM_SUCCESS)
retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
/* This is where we have been authorized or not. */
if (retval == PAM_SUCCESS) {
fprintf(stdout, "Authenticated\n");
} else {
fprintf(stdout, "Not Authenticated\n");
}
if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
pamh = NULL;
fprintf(stderr, "check_user: failed to release authenticator\n");
exit(1);
}
return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
}

View File

@ -0,0 +1,99 @@
/*
* $Log: test.c,v $
* Revision 1.3 1996/03/10 00:14:20 morgan
* made lines less than 80 chars long.
*
* Revision 1.2 1996/03/09 09:16:26 morgan
* changed the header file that it includes.
*
* Revision 1.1 1996/03/09 09:13:34 morgan
* Initial revision
*/
/* Marc Ewing (marc@redhat.com) - original test code
* Alexander O. Yuriev (alex@bach.cis.temple.edu)
* Andrew Morgan (morgan@physics.ucla.edu)
*/
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <security/pam_appl.h>
/* this program is not written to the PAM spec: it tests the
* pam_[sg]et_data() functions. Which is usually reserved for modules */
#include <security/pam_modules.h>
#include <security/pam_misc.h>
#define USERNAMESIZE 1024
static int test_conv( int num_msg,
const struct pam_message **msgm,
struct pam_response **response,
void *appdata_ptr )
{
return 0;
}
static struct pam_conv conv = {
test_conv,
NULL
};
static int cleanup_func(pam_handle_t *pamh, void *data, int error_status)
{
printf("Cleaning up!\n");
return PAM_SUCCESS;
}
void main( void )
{
pam_handle_t *pamh;
char *name = ( char *) malloc( USERNAMESIZE + 1 );
char *p = NULL;
char *s = NULL;
if (! name )
{
perror( "Ouch, don't have enough memory");
exit( -1 );
}
fprintf( stdout, "Enter a name of a user to authenticate : ");
name = fgets( name , USERNAMESIZE, stdin );
if ( !name )
{
perror ( "Hey, how can authenticate "
"someone whos name I don't know?" );
exit ( -1 );
}
*( name + strlen ( name ) - 1 ) = 0;
pam_start( "login", name, &conv, &pamh );
p = x_strdup( getpass ("Password: ") );
if ( !p )
{
perror ( "You love NULL pointers, "
"don't you? I don't ");
exit ( -1 );
}
pam_set_item ( pamh, PAM_AUTHTOK, p );
pam_get_item ( pamh, PAM_USER, (void**) &s);
pam_set_data(pamh, "DATA", "Hi there! I'm data!", cleanup_func);
pam_get_data(pamh, "DATA", (void **) &s);
printf("%s\n", s);
fprintf( stdout, "*** Attempting to perform "
"PAM authentication...\n");
fprintf( stdout, "%s\n",
pam_strerror( pam_authenticate( pamh, 0 ) ) ) ;
pam_end(pamh, PAM_SUCCESS);
}

View File

@ -0,0 +1,47 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <security/pam_appl.h>
static int test_conv(int num_msg, const struct pam_message **msgm,
struct pam_response **response, void *appdata_ptr)
{
return 0;
}
static struct pam_conv conv = {
test_conv,
NULL
};
int main(void)
{
char *user;
pam_handle_t *pamh;
struct passwd *pw;
uid_t uid;
int res;
uid = geteuid();
pw = getpwuid(uid);
if (pw) {
user = pw->pw_name;
} else {
fprintf(stderr, "Invalid userid: %d\n", uid);
exit(1);
}
pam_start("vpass", user, &conv, &pamh);
pam_set_item(pamh, PAM_TTY, "/dev/tty");
if ((res = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
fprintf(stderr, "Oops: %s\n", pam_strerror(res));
exit(1);
}
pam_end(pamh, res);
exit(0);
}

View File

@ -0,0 +1,139 @@
/*
* $Id: xsh.c,v 1.4 1996/11/10 21:09:45 morgan Exp morgan $
*
* $Log: xsh.c,v $
* Revision 1.4 1996/11/10 21:09:45 morgan
* no gcc warnings
*
* Revision 1.3 1996/07/07 23:53:36 morgan
* added support for non standard pam_fail_delay
*
* Revision 1.2 1996/05/02 04:44:48 morgan
* moved conversaation to a libmisc routine.
*
* Revision 1.1 1996/04/07 08:18:55 morgan
* Initial revision
*
*/
/* Andrew Morgan (morgan@parc.power.net) -- an example application
* that invokes a shell, based on blank.c */
#include <stdio.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
/* ------ some local (static) functions ------- */
static void bail_out(pam_handle_t *pamh,int really, int code, const char *fn)
{
fprintf(stderr,"==> called %s()\n got: `%s'\n", fn,
pam_strerror(pamh,code));
if (really && code)
exit (1);
}
/* ------ some static data objects ------- */
static struct pam_conv conv = {
misc_conv,
NULL
};
/* ------- the application itself -------- */
void main(int argc, char **argv, char **envp)
{
pam_handle_t *pamh=NULL;
char *username=NULL;
int retcode;
/* did the user call with a username as an argument ? */
if (argc > 2) {
fprintf(stderr,"usage: %s [username]\n",argv[0]);
} else if (argc == 2) {
username = argv[1];
}
/* initialize the Linux-PAM library */
retcode = pam_start("xsh", username, &conv, &pamh);
bail_out(pamh,1,retcode,"pam_start");
/* to avoid using goto we abuse a loop here */
for (;;) {
/* authenticate the user --- `0' here, could have been PAM_SILENT
* | PAM_DISALLOW_NULL_AUTHTOK */
retcode = pam_authenticate(pamh, 0);
bail_out(pamh,0,retcode,"pam_authenticate");
/* has the user proved themself valid? */
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: invalid request\n",argv[0]);
break;
}
/* the user is valid, but should they have access at this
time? */
retcode = pam_acct_mgmt(pamh, 0); /* `0' could be as above */
bail_out(pamh,0,retcode,"pam_acct_mgmt");
if (retcode == PAM_NEW_AUTHTOK_REQD) {
fprintf(stderr,"Application must request new password...\n");
retcode = pam_chauthtok(pamh,PAM_CHANGE_EXPIRED_AUTHTOK);
bail_out(pamh,0,retcode,"pam_chauthtok");
}
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: invalid request\n",argv[0]);
break;
}
/* `0' could be as above */
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
bail_out(pamh,0,retcode,"pam_setcred");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem setting user credentials\n"
,argv[0]);
break;
}
/* open a session for the user --- `0' could be PAM_SILENT */
retcode = pam_open_session(pamh,0);
bail_out(pamh,0,retcode,"pam_open_session");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem opening a session\n",argv[0]);
break;
}
fprintf(stderr,"The user has been authenticated and `logged in'\n");
/* this is always a really bad thing for security! */
system("/bin/sh");
/* close a session for the user --- `0' could be PAM_SILENT
* it is possible that this pam_close_call is in another program..
*/
retcode = pam_close_session(pamh,0);
bail_out(pamh,0,retcode,"pam_close_session");
if (retcode != PAM_SUCCESS) {
fprintf(stderr,"%s: problem closing a session\n",argv[0]);
break;
}
break; /* don't go on for ever! */
}
/* close the Linux-PAM library */
retcode = pam_end(pamh, PAM_SUCCESS);
pamh = NULL;
bail_out(pamh,1,retcode,"pam_end");
exit(0);
}

View File

@ -0,0 +1,177 @@
#
# $Id: Makefile,v 1.19 1997/04/05 06:58:43 morgan Exp morgan $
#
# $Log: Makefile,v $
# Revision 1.19 1997/04/05 06:58:43 morgan
# fakeroot
#
# Revision 1.18 1997/02/15 15:56:09 morgan
# inherit major and minor numbers
#
# Revision 1.17 1997/01/04 20:03:09 morgan
# update for .55
#
# Revision 1.16 1996/12/01 03:14:13 morgan
# update for .54
#
# Revision 1.15 1996/11/10 20:07:51 morgan
# updated for .53
#
# Revision 1.14 1996/09/05 06:06:53 morgan
# added local flag for locking, slight reorganization too.
#
# need to tell libpam about the default directory for PAMs
MOREFLAGS=-D"DEFAULT_MODULE_PATH=\"$(SECUREDIR)/\""
# you may uncomment the following to build libpam in modified ways
# lots of debugging information goes to /tmp/pam-debug.log
#MOREFLAGS += -D"DEBUG"
# pay attention to locked /etc/pam.conf or /etc/pam.d/* files
#MOREFLAGS += -D"PAM_LOCKING"
# read both the /etc/pam.d/ and pam.conf files specific to the deisred service
#MOREFLAGS += -D"PAM_READ_BOTH_CONFS"
# make a kludge attempt to be compatible with the old pam_strerror
# calling convention
#MOREFLAGS += -D"UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT"
ifeq ($(DEBUG_REL),yes)
LIBNAME=libpamd
else
LIBNAME=libpam
endif
VERSION=.$(MAJOR_REL)
MODIFICATION=.$(MINOR_REL)
# ---------------------------------------------
dummy:
@echo "*** This is not a top-level Makefile!"
# ---------------------------------------------
CFLAGS += $(DYNAMIC) $(STATIC) $(MOREFLAGS)
# dynamic library names
LIBPAM = $(LIBNAME).$(DYNTYPE)
LIBPAMNAME = $(LIBPAM)$(VERSION)
LIBPAMFULL = $(LIBPAMNAME)$(MODIFICATION)
# static library name
LIBPAMSTATIC = $(LIBNAME).a
ifdef STATIC
MODULES = $(shell cat ../modules/_static_module_objects)
STATICOBJ = pam_static.o
endif
ifdef MEMORY_DEBUG
EXTRAS += pam_malloc.o
endif
LIBOBJECTS = pam_item.o pam_strerror.o pam_end.o pam_start.o pam_data.o \
pam_delay.o pam_dispatch.o pam_handlers.o pam_misc.o \
pam_account.o pam_auth.o pam_session.o pam_password.o \
pam_env.o pam_log.o $(EXTRAS)
ifdef DYNAMIC_LIBPAM
DLIBOBJECTS = $(addprefix dynamic/,$(LIBOBJECTS) $(STATICOBJ))
ifdef STATICOBJ
dynamic/pam_static.o: pam_static.c ../modules/_static_module_objects
$(CC) $(CFLAGS) -c pam_static.c -o $@
endif
endif
ifdef STATIC_LIBPAM
SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS) $(STATICOBJ))
ifdef STATICOBJ
static/pam_static.o: pam_static.c ../modules/_static_module_objects
$(CC) $(CFLAGS) -c pam_static.c -o $@
endif
endif
# ---------------------------------------------
## rules
all: dirs $(LIBPAM) $(LIBPAMSTATIC)
dirs:
ifdef DYNAMIC_LIBPAM
mkdir -p dynamic
endif
ifdef STATIC_LIBPAM
mkdir -p static
endif
dynamic/%.o : %.c
$(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
static/%.o : %.c
$(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
$(LIBPAM): $(DLIBOBJECTS)
ifdef DYNAMIC_LIBPAM
ifeq ($(USESONAME),yes)
$(LD_L) $(SOSWITCH) $(LIBPAMNAME) -o $@ $(DLIBOBJECTS) $(MODULES)
else
$(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
endif
ifeq ($(NEEDSONAME),yes)
rm -f $(LIBPAMFULL)
ln -s $(LIBPAM) $(LIBPAMFULL)
rm -f $(LIBPAMNAME)
ln -s $(LIBPAM) $(LIBPAMNAME)
endif
endif
$(LIBPAMSTATIC): $(SLIBOBJECTS)
ifdef STATIC_LIBPAM
$(AR) $@ $(SLIBOBJECTS) $(MODULES)
$(RANLIB) $@
endif
install: all
$(MKDIR) $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/pam_appl.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/pam_modules.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/_pam_macros.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/_pam_types.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/_pam_compat.h $(FAKEROOT)$(INCLUDED)
ifdef MEMORY_DEBUG
$(INSTALL) -m 644 include/security/pam_malloc.h $(FAKEROOT)$(INCLUDED)
endif
ifdef DYNAMIC_LIBPAM
$(INSTALL) -m $(SHLIBMODE) $(LIBPAM) $(FAKEROOT)$(LIBDIR)/$(LIBPAMFULL)
$(LDCONFIG)
ifneq ($(DYNTYPE),"sl")
( cd $(FAKEROOT)$(LIBDIR) ; rm -f $(LIBPAM) ; ln -s $(LIBPAMNAME) $(LIBPAM) )
endif
endif
ifdef STATIC_LIBPAM
$(INSTALL) -m 644 $(LIBPAMSTATIC) $(FAKEROOT)$(LIBDIR)
endif
remove:
rm -f $(FAKEROOT)$(INCLUDED)/_pam_types.h
rm -f $(FAKEROOT)$(INCLUDED)/_pam_macros.h
rm -f $(FAKEROOT)$(INCLUDED)/pam_appl.h
rm -f $(FAKEROOT)$(INCLUDED)/pam_modules.h
rm -f $(FAKEROOT)$(INCLUDED)/pam_malloc.h
rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAM).*
rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAM)
$(LDCONFIG)
rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAMSTATIC)
clean:
rm -f a.out core *~ static/*.o dynamic/*.o
extraclean: clean
rm -f *.a *.out *.o *.so ./include/security/*~
if [ -d dynamic ]; then rmdir dynamic ; fi
if [ -d static ]; then rmdir static ; fi

View File

@ -0,0 +1,109 @@
#ifndef _PAM_COMPAT_H
#define _PAM_COMPAT_H
/*
* This file was contributed by Derrick J Brashear <shadow@dementia.org>
*
* A number of operating systems have started to implement PAM.
* unfortunately, they have a different set of numeric values for
* certain constants. This file is included for compatibility's sake.
*/
/* Solaris uses different constants. We redefine to those here */
#if defined(solaris) || (defined(__SVR4) && defined(sun))
/* generic for pam_* functions */
# undef PAM_SILENT
# define PAM_SILENT 0x80000000
/* flags for pam_chauthtok() */
# undef PAM_PRELIM_CHECK
# define PAM_PRELIM_CHECK 0x1
# undef PAM_UPDATE_AUTHTOK
# define PAM_UPDATE_AUTHTOK 0x2
/* flags for pam_setcred() */
# undef PAM_ESTABLISH_CRED
# define PAM_ESTABLISH_CRED 0x1
# undef PAM_DELETE_CRED
# define PAM_DELETE_CRED 0x2
# undef PAM_REINITIALIZE_CRED
# define PAM_REINITIALIZE_CRED 0x4
# define PAM_REFRESH_CRED 0x8
# undef PAM_REFRESH_CRED
/* another binary incompatibility comes from the return codes! */
# undef PAM_CONV_ERR
# define PAM_CONV_ERR 6
# undef PAM_PERM_DENIED
# define PAM_PERM_DENIED 7
# undef PAM_MAXTRIES
# define PAM_MAXTRIES 8
# undef PAM_AUTH_ERR
# define PAM_AUTH_ERR 9
# undef PAM_NEW_AUTHTOK_REQD
# define PAM_NEW_AUTHTOK_REQD 10
# undef PAM_CRED_INSUFFICIENT
# define PAM_CRED_INSUFFICIENT 11
# undef PAM_AUTHINFO_UNAVAIL
# define PAM_AUTHINFO_UNAVAIL 12
# undef PAM_USER_UNKNOWN
# define PAM_USER_UNKNOWN 13
# undef PAM_CRED_UNAVAIL
# define PAM_CRED_UNAVAIL 14
# undef PAM_CRED_EXPIRED
# define PAM_CRED_EXPIRED 15
# undef PAM_CRED_ERR
# define PAM_CRED_ERR 16
# undef PAM_ACCT_EXPIRED
# define PAM_ACCT_EXPIRED 17
# undef PAM_AUTHTOK_EXPIRED
# define PAM_AUTHTOK_EXPIRED 18
# undef PAM_SESSION_ERR
# define PAM_SESSION_ERR 19
# undef PAM_AUTHTOK_ERR
# define PAM_AUTHTOK_ERR 20
# undef PAM_AUTHTOK_RECOVERY_ERR
# define PAM_AUTHTOK_RECOVERY_ERR 21
# undef PAM_AUTHTOK_LOCK_BUSY
# define PAM_AUTHTOK_LOCK_BUSY 22
# undef PAM_AUTHTOK_DISABLE_AGING
# define PAM_AUTHTOK_DISABLE_AGING 23
# undef PAM_NO_MODULE_DATA
# define PAM_NO_MODULE_DATA 24
# undef PAM_IGNORE
# define PAM_IGNORE 25
# undef PAM_ABORT
# define PAM_ABORT 26
# undef PAM_TRY_AGAIN
# define PAM_TRY_AGAIN 27
#endif /* defined(solaris) || (defined(__SVR4) && defined(sun)) */
#endif /* _PAM_COMPAT_H */

View File

@ -0,0 +1,165 @@
#ifndef PAM_MACROS_H
#define PAM_MACROS_H
/*
* All kind of macros used by PAM, but usable in some other
* programs too.
* Organized by Cristian Gafton <gafton@redhat.com>
*/
/* a 'safe' version of strdup */
extern char *strdup(const char *s);
#define x_strdup(s) ( (s) ? strdup(s):NULL )
/* Good policy to strike out passwords with some characters not just
free the memory */
#define _pam_overwrite(x) \
do { \
register char *__xx__; \
if ((__xx__=(x))) \
while (*__xx__) \
*__xx__++ = '\0'; \
} while (0)
/*
* Don't just free it, forget it too.
*/
#define _pam_drop(X) \
do { \
if (X) { \
free(X); \
X=NULL; \
} \
} while (0)
#define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
do { \
int reply_i; \
\
for (reply_i=0; reply_i<replies; ++reply_i) { \
if (reply[reply_i].resp) { \
_pam_overwrite(reply[reply_i].resp); \
free(reply[reply_i].resp); \
} \
} \
if (reply) \
free(reply); \
} while (0)
/* some debugging code */
#ifdef DEBUG
/*
* This provides the necessary function to do debugging in PAM.
* Cristian Gafton <gafton@redhat.com>
*/
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
/*
* This is for debugging purposes ONLY. DO NOT use on live systems !!!
* You have been warned :-) - CG
*
* to get automated debugging to the log file, it must be created manually.
* _PAM_LOGFILE must exist, mode 666
*/
#ifndef _PAM_LOGFILE
#define _PAM_LOGFILE "/tmp/pam-debug.log"
#endif
static void _pam_output_debug_info(const char *file, const char *fn
, const int line)
{
FILE *logfile;
int must_close = 1;
if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
logfile = stderr;
must_close = 0;
}
fprintf(logfile,"[%s:%s(%d)] ",file, fn, line);
if (must_close) {
fflush(logfile);
fclose(logfile);
}
}
static void _pam_output_debug(const char *format, ...)
{
va_list args;
FILE *logfile;
int must_close = 1;
va_start(args, format);
if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
logfile = stderr;
must_close = 0;
}
vfprintf(logfile, format, args);
fprintf(logfile, "\n");
if (must_close) {
fflush(logfile);
fclose(logfile);
}
va_end(args);
}
#define D(x) do { \
_pam_output_debug_info(__FILE__, __FUNCTION__, __LINE__); \
_pam_output_debug x ; \
} while (0)
#define _pam_show_mem(X,XS) do { \
int i; \
register unsigned char *x; \
x = (unsigned char *)X; \
fprintf(stderr, " <start at %p>\n", X); \
for (i = 0; i < XS ; ++x, ++i) { \
fprintf(stderr, " %02X. <%p:%02X>\n", i, x, *x); \
} \
fprintf(stderr, " <end for %p after %d bytes>\n", X, XS); \
} while (0)
#define _pam_show_reply(/* struct pam_response * */reply, /* int */replies) \
do { \
int reply_i; \
setbuf(stderr, NULL); \
fprintf(stderr, "array at %p of size %d\n",reply,replies); \
fflush(stderr); \
if (reply) { \
for (reply_i = 0; reply_i < replies; reply_i++) { \
fprintf(stderr, " elem# %d at %p: resp = %p, retcode = %d\n", \
reply_i, reply+reply_i, reply[reply_i].resp, \
reply[reply_i].resp, _retcode); \
fflush(stderr); \
if (reply[reply_i].resp) { \
fprintf(stderr, " resp[%d] = '%s'\n", \
strlen(reply[reply_i].resp), reply[reply_i].resp); \
fflush(stderr); \
} \
} \
} \
fprintf(stderr, "done here\n"); \
fflush(stderr); \
} while (0)
#else
#define D(x) do { } while (0)
#define _pam_show_mem(X,XS) do { } while (0)
#define _pam_show_reply(reply, replies) do { } while (0)
#endif /* DEBUG */
#endif /* PAM_MACROS_H */

View File

@ -0,0 +1,356 @@
/*
* <security/_pam_types.h>
*
* $Id: _pam_types.h,v 1.10 1997/04/05 06:52:50 morgan Exp morgan $
*
* This file defines all of the types common to the Linux-PAM library
* applications and modules.
*
* Note, the copyright+license information is at end of file.
*
* Created: 1996/3/5 by AGM
*
* $Log$
*/
#ifndef _SECURITY__PAM_TYPES_H
#define _SECURITY__PAM_TYPES_H
/*
* include local definition for POSIX - NULL
*/
#include <locale.h>
/* This is a blind structure; users aren't allowed to see inside a
* pam_handle_t, so we don't define struct pam_handle here. This is
* defined in a file private to the PAM library. (i.e., it's private
* to PAM service modules, too!) */
typedef struct pam_handle pam_handle_t;
/* ----------------- The Linux-PAM return values ------------------ */
#define PAM_SUCCESS 0 /* Successful function return */
#define PAM_OPEN_ERR 1 /* dlopen() failure when dynamically */
/* loading a service module */
#define PAM_SYMBOL_ERR 2 /* Symbol not found */
#define PAM_SERVICE_ERR 3 /* Error in service module */
#define PAM_SYSTEM_ERR 4 /* System error */
#define PAM_BUF_ERR 5 /* Memory buffer error */
#define PAM_PERM_DENIED 6 /* Permission denied */
#define PAM_AUTH_ERR 7 /* Authentication failure */
#define PAM_CRED_INSUFFICIENT 8 /* Can not access authentication data */
/* due to insufficient credentials */
#define PAM_AUTHINFO_UNAVAIL 9 /* Underlying authentication service */
/* can not retrieve authenticaiton */
/* information */
#define PAM_USER_UNKNOWN 10 /* User not known to the underlying */
/* authenticaiton module */
#define PAM_MAXTRIES 11 /* An authentication service has */
/* maintained a retry count which has */
/* been reached. No further retries */
/* should be attempted */
#define PAM_NEW_AUTHTOK_REQD 12 /* New authentication token required. */
/* This is normally returned if the */
/* machine security policies require */
/* that the password should be changed */
/* beccause the password is NULL or it */
/* has aged */
#define PAM_ACCT_EXPIRED 13 /* User account has expired */
#define PAM_SESSION_ERR 14 /* Can not make/remove an entry for */
/* the specified session */
#define PAM_CRED_UNAVAIL 15 /* Underlying authentication service */
/* can not retrieve user credentials */
/* unavailable */
#define PAM_CRED_EXPIRED 16 /* User credentials expired */
#define PAM_CRED_ERR 17 /* Failure setting user credentials */
#define PAM_NO_MODULE_DATA 18 /* No module specific data is present */
#define PAM_CONV_ERR 19 /* Conversation error */
#define PAM_AUTHTOK_ERR 20 /* Authentication token manipulation error */
#define PAM_AUTHTOK_RECOVER_ERR 21 /* Authentication information */
/* cannot be recovered */
#define PAM_AUTHTOK_LOCK_BUSY 22 /* Authentication token lock busy */
#define PAM_AUTHTOK_DISABLE_AGING 23 /* Authentication token aging disabled */
#define PAM_TRY_AGAIN 24 /* Preliminary check by password service */
#define PAM_IGNORE 25 /* Ingore underlying account module */
/* regardless of whether the control */
/* flag is required, optional, or sufficient */
#define PAM_ABORT 26 /* Critical error (?module fail now request) */
#define PAM_AUTHTOK_EXPIRED 27 /* user's authentication token has expired */
#define PAM_MODULE_UNKNOWN 28 /* module is not known */
#define PAM_BAD_ITEM 29 /* Bad item passed to pam_*_item() */
#define PAM_CONV_AGAIN 30 /* conversation function is event driven
and data is not available yet */
#define PAM_INCOMPLETE 31 /* please call this function again to
complete authentication stack. Before
calling again, verify that conversation
is completed */
/* Add new #define's here */
#define _PAM_RETURN_VALUES 32 /* this is the number of return values */
/* ---------------------- The Linux-PAM flags -------------------- */
/* Authentication service should not generate any messages */
#define PAM_SILENT 0x8000U
/* Note: these flags are used by pam_authenticate{,_secondary}() */
/* The authentication service should return PAM_AUTH_ERROR if the
* user has a null authentication token */
#define PAM_DISALLOW_NULL_AUTHTOK 0x0001U
/* Note: these flags are used for pam_setcred() */
/* Set user credentials for an authentication service */
#define PAM_ESTABLISH_CRED 0x0002U
/* Delete user credentials associated with an authentication service */
#define PAM_DELETE_CRED 0x0004U
/* Reinitialize user credentials */
#define PAM_REINITIALIZE_CRED 0x0008U
/* Extend lifetime of user credentials */
#define PAM_REFRESH_CRED 0x0010U
/* Note: these flags are used by pam_chauthtok */
/* The password service should only update those passwords that have
* aged. If this flag is not passed, the password service should
* update all passwords. */
#define PAM_CHANGE_EXPIRED_AUTHTOK 0x0020U
/* ------------------ The Linux-PAM item types ------------------- */
/* these defines are used by pam_set_item() and pam_get_item() */
#define PAM_SERVICE 1 /* The service name */
#define PAM_USER 2 /* The user name */
#define PAM_TTY 3 /* The tty name */
#define PAM_RHOST 4 /* The remote host name */
#define PAM_CONV 5 /* The pam_conv structure */
/* missing entries found in <security/pam_modules.h> for modules only! */
#define PAM_RUSER 8 /* The remote user name */
#define PAM_USER_PROMPT 9 /* the prompt for getting a username */
#define PAM_FAIL_DELAY 10 /* app supplied function to override failure
delays */
#define PAM_LOG_STATE 11 /* ident, facility etc. logging info */
/* ---------- Common Linux-PAM application/module PI ----------- */
extern int pam_set_item(pam_handle_t *pamh, int item_type, const void *item);
extern int pam_get_item(const pam_handle_t *pamh, int item_type,
const void **item);
extern const char *pam_strerror(pam_handle_t *pamh, int errnum);
extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
extern const char *pam_getenv(pam_handle_t *pamh, const char *name);
extern char **pam_getenvlist(pam_handle_t *pamh);
/* ---------- Common Linux-PAM application/module PI ----------- */
/*
* here are some proposed error status definitions for the
* 'error_status' argument used by the cleanup function associated
* with data items they should be logically OR'd with the error_status
* of the latest return from libpam -- new with .52 and positive
* impression from Sun although not official as of 1996/9/4
* [generally the other flags are to be found in pam_modules.h]
*/
#define PAM_DATA_SILENT 0x40000000 /* used to suppress messages... */
/*
* here we define an externally (by apps or modules) callable function
* that primes the libpam library to delay when a stacked set of
* modules results in a failure. In the case of PAM_SUCCESS this delay
* is ignored.
*
* Note, the pam_[gs]et_item(... PAM_FAIL_DELAY ...) can be used to set
* a function pointer which can override the default fail-delay behavior.
* This item was added to accommodate event driven programs that need to
* manage delays more carefully. The function prototype for this data
* item is
* void (*fail_delay)(int status, unsigned int delay);
*/
#define HAVE_PAM_FAIL_DELAY
extern int pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay);
/*
* the standard libc interface for syslog suffers from some problems.
* The first is that it is not thread safe. It is also three functions
* where PAM only really needs a "log this" function. It also does
* not provide modules and applications with information about whether
* the log is currently open or not etc... All of these things mean
* that we need to centralize PAM's logging facility. These two functions
* provide this centralization. They are, however, just a gateway to
* libc's openlog/syslog/closelog functions. Please note, your apps/modules
* will likely start to segfault if you do not use this function for
* system logging.
*/
struct pam_log_state {
char *ident;
int option;
int facility;
};
#ifndef LOG_ERR
# include <syslog.h> /* this is a sad HACK. But we need LOG_CRIT etc.. */
#endif
#define PAM_LOG_STATE_IDENT "PAM"
#define PAM_LOG_STATE_OPTION LOG_PID
#define PAM_LOG_STATE_FACILITY LOG_AUTHPRIV
#ifndef va_start
# include <stdarg.h>
#endif
#define HAVE_PAM_SYSTEM_LOG
extern void pam_vsystem_log(const pam_handle_t *pamh,
const struct pam_log_state *log_state,
int priority, const char *format, va_list args);
extern void pam_system_log(const pam_handle_t *pamh,
const struct pam_log_state *log_state,
int priority, const char *format, ... );
#ifdef MEMORY_DEBUG
/*
* this defines some macros that keep track of what memory has been
* allocated and indicates leakage etc... It should not be included in
* production application/modules.
*/
#include <security/pam_malloc.h>
#endif
/* ------------ The Linux-PAM conversation structures ------------ */
/* Message styles */
#define PAM_PROMPT_ECHO_OFF 1
#define PAM_PROMPT_ECHO_ON 2
#define PAM_ERROR_MSG 3
#define PAM_TEXT_INFO 4
/* Linux-PAM specific types */
#define PAM_RADIO_TYPE 5 /* yes/no/maybe conditionals */
/* This is for server client non-human interaction.. these are NOT
part of the X/Open PAM specification (yet although Vipin has hinted
that they may well be 1997/7/8) but are currently included for
exploritory reasons. Basically, they are for the module to obtain a
binary chunk of data from the client (via the server). Such data
is intercepted by the server and unpacked in preparation for the
module */
#define PAM_BINARY_MSG 6
#define PAM_BINARY_PROMPT 7
/* maximum size of messages/responses etc.. (these are mostly
arbitrary so Linux-PAM should handle longer values). */
#define PAM_MAX_NUM_MSG 32
#define PAM_MAX_MSG_SIZE 512
#define PAM_MAX_RESP_SIZE 512
/* Used to pass prompting text, error messages, or other informatory
* text to the user. This structure is allocated and freed by the PAM
* library (or loaded module). */
struct pam_message {
int msg_style;
const char *msg;
};
/* if the pam_message.msg_style = PAM_BINARY_PROMPT
the 'pam_message.msg' is a pointer to a 'const *' for the following
pseudo-structure. When used with a PAM_BINARY_PROMPT, the returned
pam_response.resp pointer points to an object with the following
structure:
struct {
u32 length; # network byte order
unsigned char data[length];
};
The 'libpam_client' library is designed around this flavor of
message and should be used to handle this flavor of msg_style.
*/
/* Used to return the user's response to the PAM library. This
structure is allocated by the application program, and free()'d by
the Linux-PAM library (or calling module). */
struct pam_response {
char *resp;
int resp_retcode; /* currently un-used, zero expected */
};
/* The actual conversation structure itself */
struct pam_conv {
int (*conv)(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
void *appdata_ptr;
};
#ifndef LINUX_PAM
/*
* the following few lines represent a hack. They are there to make
* the Linux-PAM headers more compatible with the Sun ones, which have a
* less strictly separated notion of module specific and application
* specific definitions.
*/
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#endif
/* ... adapted from the pam_appl.h file created by Theodore Ts'o and
*
* Copyright Theodore Ts'o, 1996. All rights reserved.
* Copyright (c) Andrew G. Morgan <morgan@linux.kernel.org>, 1996-8
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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.
*
* ALTERNATIVELY, this product may be distributed under the terms of
* the GNU Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is
* necessary due to a potential bad interaction between the GPL and
* the restrictions contained in a BSD-style copyright.)
*
* 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 DAMAGE. */
#endif /* _SECURITY__PAM_TYPES_H */

View File

@ -0,0 +1,99 @@
/*
* <security/pam_appl.h>
*
* This header file collects definitions for the PAM API --- that is,
* public interface between the PAM library and an application program
* that wishes to use it.
*
* Note, the copyright information is at end of file.
*
* Created: 15-Jan-96 by TYT
* Last modified: 1996/3/5 by AGM
*
* $Log: pam_appl.h,v $
* Revision 1.5 1996/11/10 19:56:11 morgan
* minor prototype change
*
* Revision 1.4 1996/03/16 22:38:17 morgan
* made all of the pam_start input arguments constant
*
* Revision 1.3 1996/03/16 20:22:59 morgan
* changed name comment at top of file.
*
* Revision 1.2 1996/03/09 20:39:06 morgan
* added RCS information
*
*
* $Id: pam_appl.h,v 1.5 1996/11/10 19:56:11 morgan Exp $
*
*/
#ifndef _SECURITY_PAM_APPL_H
#define _SECURITY_PAM_APPL_H
#include <security/_pam_types.h> /* Linux-PAM common defined types */
/* -------------- The Linux-PAM Framework layer API ------------- */
extern int pam_start(const char *service_name, const char *user,
const struct pam_conv *pam_conversation,
pam_handle_t **pamh);
extern int pam_end(pam_handle_t *pamh, int pam_status);
/* Authentication API's */
extern int pam_authenticate(pam_handle_t *pamh, int flags);
extern int pam_setcred(pam_handle_t *pamh, int flags);
/* Account Management API's */
extern int pam_acct_mgmt(pam_handle_t *pamh, int flags);
/* Session Management API's */
extern int pam_open_session(pam_handle_t *pamh, int flags);
extern int pam_close_session(pam_handle_t *pamh, int flags);
/* Password Management API's */
extern int pam_chauthtok(pam_handle_t *pamh, int flags);
/* take care of any compatibility issues */
#include <security/_pam_compat.h>
/*
* Copyright Theodore Ts'o, 1996. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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.
*
* ALTERNATIVELY, this product may be distributed under the terms of
* the GNU Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is
* necessary due to a potential bad interaction between the GPL and
* the restrictions contained in a BSD-style copyright.)
*
* 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 DAMAGE.
*/
#endif /* _SECURITY_PAM_APPL_H */

View File

@ -0,0 +1,73 @@
/* $Id: pam_malloc.h,v 1.1 1996/11/10 21:23:14 morgan Exp $
*
* $Log: pam_malloc.h,v $
* Revision 1.1 1996/11/10 21:23:14 morgan
* Initial revision
*
*/
/*
* This file (via the use of macros) defines a wrapper for the malloc
* family of calls. It logs where the memory was requested and also
* where it was free()'d and keeps a list of currently requested memory.
*
* It is hoped that it will provide some help in locating memory leaks.
*/
#ifndef PAM_MALLOC_H
#define PAM_MALLOC_H
/* these are the macro definitions for the stdlib.h memory functions */
#define malloc(s) pam_malloc(s,__FILE__,__FUNCTION__,__LINE__)
#define calloc(n,s) pam_calloc(n,s,__FILE__,__FUNCTION__,__LINE__)
#define free(x) pam_free(x,__FILE__,__FUNCTION__,__LINE__)
/* #define memalign(a,s) pam_memalign(a,s,__FILE__,__FUNCTION__,__LINE__) */
#define realloc(x,s) pam_realloc(x,s,__FILE__,__FUNCTION__,__LINE__)
/* #define valloc(s) pam_valloc(s,__FILE__,__FUNCTION__,__LINE__) */
/* #define alloca(s) pam_alloca(s,__FILE__,__FUNCTION__,__LINE__) */
#define exit(i) pam_exit(i,__FILE__,__FUNCTION__,__LINE__)
/* these are the prototypes for the wrapper functions */
#include <sys/types.h>
extern void *pam_malloc(size_t s,const char *,const char *,const int);
extern void *pam_calloc(size_t n,size_t s,const char *,const char *,const int);
extern void pam_free(void *x,const char *,const char *,const int);
extern void *pam_memalign(size_t a,size_t s
,const char *,const char *,const int);
extern void *pam_realloc(void *x,size_t s,const char *,const char *,const int);
extern void *pam_valloc(size_t s,const char *,const char *,const int);
extern void *pam_alloca(size_t s,const char *,const char *,const int);
extern void pam_exit(int i,const char *,const char *,const int);
/* these are the flags used to turn on and off diagnostics */
#define PAM_MALLOC_LEAKED 01
#define PAM_MALLOC_REQUEST 02
#define PAM_MALLOC_FREE 04
#define PAM_MALLOC_EXCH (PAM_MALLOC_FREED|PAM_MALLOC_EXCH)
#define PAM_MALLOC_RESIZE 010
#define PAM_MALLOC_FAIL 020
#define PAM_MALLOC_NULL 040
#define PAM_MALLOC_VERIFY 0100
#define PAM_MALLOC_FUNC 0200
#define PAM_MALLOC_PAUSE 0400
#define PAM_MALLOC_STOP 01000
#define PAM_MALLOC_ALL 0777
#define PAM_MALLOC_DEFAULT \
(PAM_MALLOC_LEAKED|PAM_MALLOC_PAUSE|PAM_MALLOC_FAIL)
#include <stdio.h>
extern FILE *pam_malloc_outfile; /* defaults to stdout */
/* how much output do you want? */
extern int pam_malloc_flags;
extern int pam_malloc_delay_length; /* how long to pause on errors */
#endif /* PAM_MALLOC_H */

View File

@ -0,0 +1,189 @@
/*
* <security/pam_modules.h>
*
* $Id: pam_modules.h,v 1.8 1997/01/04 20:14:42 morgan Exp morgan $
*
* This header file documents the PAM SPI --- that is, interface
* between the PAM library and a PAM service library which is called
* by the PAM library.
*
* Note, the copyright information is at end of file.
*
* $Log: pam_modules.h,v $
* Revision 1.8 1997/01/04 20:14:42 morgan
* moved PAM_DATA_SILENT to _pam_types.h so applications can use it too
*
* Revision 1.7 1996/11/10 19:57:08 morgan
* pam_get_user prototype.
*
* Revision 1.6 1996/09/05 06:18:45 morgan
* added some data error_status masks, changed prototype for cleanup()
*
* Revision 1.5 1996/06/02 07:58:37 morgan
* altered the way in which modules obtain static prototypes for
* functions
*
*/
#ifndef _SECURITY_PAM_MODULES_H
#define _SECURITY_PAM_MODULES_H
#include <security/_pam_types.h> /* Linux-PAM common defined types */
/* these defines are used by pam_set_item() and pam_get_item() and are
* in addition to those found in <security/_pam_types.h> */
#define PAM_AUTHTOK 6 /* The authentication token (password) */
#define PAM_OLDAUTHTOK 7 /* The old authentication token */
/* -------------- The Linux-PAM Module PI ------------- */
extern int pam_set_data(pam_handle_t *pamh, const char *module_data_name,
void *data,
void (*cleanup)(pam_handle_t *pamh, void *data,
int error_status));
extern int pam_get_data(const pam_handle_t *pamh,
const char *module_data_name, const void **data);
extern int pam_get_user(pam_handle_t *pamh, const char **user
, const char *prompt);
#ifdef PAM_STATIC
#define PAM_EXTERN static
struct pam_module {
const char *name; /* Name of the module */
/* These are function pointers to the module's key functions. */
int (*pam_sm_authenticate)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
int (*pam_sm_setcred)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
int (*pam_sm_acct_mgmt)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
int (*pam_sm_open_session)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
int (*pam_sm_close_session)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
int (*pam_sm_chauthtok)(pam_handle_t *pamh, int flags,
int argc, const char **argv);
};
#else /* !PAM_STATIC */
#define PAM_EXTERN extern
#endif /* PAM_STATIC */
/* Lots of files include pam_modules.h that don't need these
* declared. However, when they are declared static, they
* need to be defined later. So we have to protect C files
* that include these without wanting these functions defined.. */
#if (defined(PAM_STATIC) && defined(PAM_SM_AUTH)) || !defined(PAM_STATIC)
/* Authentication API's */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char **argv);
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char **argv);
#endif /*(defined(PAM_STATIC) && defined(PAM_SM_AUTH))
|| !defined(PAM_STATIC)*/
#if (defined(PAM_STATIC) && defined(PAM_SM_ACCOUNT)) || !defined(PAM_STATIC)
/* Account Management API's */
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char **argv);
#endif /*(defined(PAM_STATIC) && defined(PAM_SM_ACCOUNT))
|| !defined(PAM_STATIC)*/
#if (defined(PAM_STATIC) && defined(PAM_SM_SESSION)) || !defined(PAM_STATIC)
/* Session Management API's */
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char **argv);
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char **argv);
#endif /*(defined(PAM_STATIC) && defined(PAM_SM_SESSION))
|| !defined(PAM_STATIC)*/
#if (defined(PAM_STATIC) && defined(PAM_SM_PASSWORD)) || !defined(PAM_STATIC)
/* Password Management API's */
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char **argv);
#endif /*(defined(PAM_STATIC) && defined(PAM_SM_PASSWORD))
|| !defined(PAM_STATIC)*/
/* The following two flags are for use across the Linux-PAM/module
* interface only. The Application is not permitted to use these
* tokens.
*
* The password service should only perform preliminary checks. No
* passwords should be updated. */
#define PAM_PRELIM_CHECK 0x4000
/* The password service should update passwords Note: PAM_PRELIM_CHECK
* and PAM_UPDATE_AUTHTOK can not both be set simultaneously! */
#define PAM_UPDATE_AUTHTOK 0x2000
/*
* here are some proposed error status definitions for the
* 'error_status' argument used by the cleanup function associated
* with data items they should be logically OR'd with the error_status
* of the latest return from libpam -- new with .52 and positive
* impression from Sun although not official as of 1996/9/4 there are
* others in _pam_types.h -- they are for common module/app use.
*/
#define PAM_DATA_REPLACE 0x20000000 /* used when replacing a data item */
/* take care of any compatibility issues */
#include <security/_pam_compat.h>
/* Copyright (C) Theodore Ts'o, 1996.
* Copyright (C) Andrew Morgan, 1996-8.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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.
*
* ALTERNATIVELY, this product may be distributed under the terms of
* the GNU General Public License, 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.)
*
* 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 DAMAGE. */
#endif /* _SECURITY_PAM_MODULES_H */

View File

@ -0,0 +1,13 @@
/* pam_account.c - PAM Account Management */
#include <stdio.h>
#include "pam_private.h"
int pam_acct_mgmt(pam_handle_t *pamh, int flags)
{
D(("called"));
IF_NO_PAMH("pam_acct_mgmt",pamh,PAM_SYSTEM_ERR);
return _pam_dispatch(pamh, flags, PAM_ACCOUNT);
}

View File

@ -0,0 +1,61 @@
/*
* pam_auth.c -- PAM authentication
*
* $Id: pam_auth.c,v 1.7 1997/04/05 06:53:52 morgan Exp morgan $
*
* $Log: pam_auth.c,v $
* Revision 1.7 1997/04/05 06:53:52 morgan
* fail-delay changes
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "pam_private.h"
int pam_authenticate(pam_handle_t *pamh, int flags)
{
int retval;
D(("pam_authenticate called"));
if (pamh->former.choice == PAM_NOT_STACKED) {
_pam_sanitize(pamh);
_pam_start_timer(pamh); /* we try to make the time for a failure
independent of the time it takes to
fail */
}
IF_NO_PAMH("pam_authenticate",pamh,PAM_SYSTEM_ERR);
retval = _pam_dispatch(pamh, flags, PAM_AUTHENTICATE);
if (retval != PAM_INCOMPLETE) {
_pam_sanitize(pamh);
_pam_await_timer(pamh, retval); /* if unsuccessful then wait now */
D(("pam_authenticate exit"));
} else {
D(("will resume when ready"));
}
return retval;
}
int pam_setcred(pam_handle_t *pamh, int flags)
{
int retval;
IF_NO_PAMH("pam_setcred", pamh, PAM_SYSTEM_ERR);
D(("pam_setcred called"));
if (! flags) {
flags = PAM_ESTABLISH_CRED;
}
retval = _pam_dispatch(pamh, flags, PAM_SETCRED);
D(("pam_setcred exit"));
return retval;
}

View File

@ -0,0 +1,123 @@
/* pam_data.c */
/*
* $Id: pam_data.c,v 1.5 1996/12/01 03:14:13 morgan Exp $
*
* $Log: pam_data.c,v $
* Revision 1.5 1996/12/01 03:14:13 morgan
* use _pam_macros.h
*
* Revision 1.4 1996/11/10 19:59:56 morgan
* internalized strdup for malloc debugging
*
* Revision 1.3 1996/09/05 06:10:31 morgan
* changed type of cleanup(), added PAM_DATA_REPLACE to replacement
* cleanup() call.
*
* Revision 1.2 1996/03/16 21:33:05 morgan
* removed const from cleanup argument, also deleted comment about SUN stuff
*
*
*/
#include <stdlib.h>
#include <string.h>
#include "pam_private.h"
struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name);
int pam_set_data(
pam_handle_t *pamh,
const char *module_data_name,
void *data,
void (*cleanup)(pam_handle_t *pamh, void *data, int error_status))
{
struct pam_data *data_entry;
IF_NO_PAMH("pam_set_data",pamh,PAM_SYSTEM_ERR);
/* first check if there is some data already. If so clean it up */
if ((data_entry = _pam_locate_data(pamh, module_data_name))) {
if (data_entry->cleanup) {
data_entry->cleanup(pamh, data_entry->data
, PAM_DATA_REPLACE | PAM_SUCCESS );
}
} else if ((data_entry = malloc(sizeof(*data_entry)))) {
char *tname;
if ((tname = _pam_strdup(module_data_name)) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"pam_set_data: no memory for data name");
_pam_drop(data_entry);
return PAM_BUF_ERR;
}
data_entry->next = pamh->data;
pamh->data = data_entry;
data_entry->name = tname;
} else {
pam_system_log(pamh, NULL, LOG_CRIT,
"pam_set_data: cannot allocate data entry");
return PAM_BUF_ERR;
}
data_entry->data = data; /* note this could be NULL */
data_entry->cleanup = cleanup;
return PAM_SUCCESS;
}
int pam_get_data(
const pam_handle_t *pamh,
const char *module_data_name,
const void **datap)
{
struct pam_data *data;
IF_NO_PAMH("pam_get_data",pamh,PAM_SYSTEM_ERR);
data = _pam_locate_data(pamh, module_data_name);
if (data) {
*datap = data->data;
return PAM_SUCCESS;
}
return PAM_NO_MODULE_DATA;
}
struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name)
{
struct pam_data *data;
IF_NO_PAMH("_pam_locate_data",pamh,NULL);
data = pamh->data;
while (data) {
if (!strcmp(data->name, name)) {
return data;
}
data = data->next;
}
return NULL;
}
void _pam_free_data(pam_handle_t *pamh, int status)
{
struct pam_data *last;
struct pam_data *data;
IF_NO_PAMH("_pam_free_data",pamh,/* no return value for void fn */);
data = pamh->data;
while (data) {
last = data;
data = data->next;
if (last->cleanup) {
last->cleanup(pamh, last->data, status);
}
_pam_drop(last->name);
_pam_drop(last);
}
}

View File

@ -0,0 +1,152 @@
/*
* pam_delay.c
*
* Copyright (c) Andrew G. Morgan <morgan@linux.kernel.org> 1996-8
* All rights reserved.
*
* $Id: pam_delay.c,v 1.5 1997/04/05 06:54:19 morgan Exp $
*
* $Log: pam_delay.c,v $
*/
/*
* This is a simple implementation of a delay on failure mechanism; an
* attempt to overcome authentication-time attacks in a simple manner.
*/
#include <unistd.h>
#include "pam_private.h"
/* **********************************************************************
* initialize the time as unset, this is set on the return from the
* authenticating pair of of the libpam pam_XXX calls.
*/
void _pam_reset_timer(pam_handle_t *pamh)
{
D(("setting pamh->fail_delay.set to FALSE"));
pamh->fail_delay.set = PAM_FALSE;
}
/* **********************************************************************
* this function sets the start time for possible delayed failing.
*
* Eventually, it may set the timer so libpam knows how long the program
* has already been executing. Currently, this value is used to seed
* a pseudo-random number generator...
*/
void _pam_start_timer(pam_handle_t *pamh)
{
pamh->fail_delay.begin = time(NULL);
D(("starting timer..."));
}
/* *******************************************************************
* Compute a pseudo random time. The value is base*(1 +/- 1/5) where
* the distribution is pseudo gausian (the sum of three evenly
* distributed random numbers -- central limit theorem and all ;^) The
* linear random numbers are based on a formulae given in Knuth's
* Seminumerical recipies that was reproduced in `Numerical Recipies
* in C'. It is *not* a cryptographically strong generator, but it is
* probably "good enough" for our purposes here.
*
* /dev/random might be a better place to look for some numbers...
*/
static unsigned int _pam_rand(unsigned int seed)
{
#define N1 1664525
#define N2 1013904223
return N1*seed + N2;
}
static unsigned int _pam_compute_delay(unsigned int seed, unsigned int base)
{
int i;
double sum;
unsigned int ans;
for (sum=i=0; i<3; ++i) {
seed = _pam_rand(seed);
sum += (double) ((seed / 10) % 1000000);
}
sum = (sum/3.)/1e6 - .5; /* rescale */
ans = (unsigned int) ( base*(1.+sum) );
D(("random number: base=%u -> ans=%u\n", base, ans));
return ans;
}
/* **********************************************************************
* the following function sleeps for a random time. The actual time
* slept is computed above.. It is based on the requested time but will
* differ by up to +/- 25%.
*/
void _pam_await_timer(pam_handle_t *pamh, int status)
{
unsigned int delay;
D(("waiting?..."));
delay = _pam_compute_delay(pamh->fail_delay.begin,
pamh->fail_delay.delay);
if (pamh->fail_delay.delay_fn_ptr) {
union {
const void *value;
void (*fn)(int, unsigned);
} hack_fn_u;
/* always call the applications delay function, even if
the delay is zero - indicate status */
hack_fn_u.value = pamh->fail_delay.delay_fn_ptr;
hack_fn_u.fn(status, delay);
} else if (status != PAM_SUCCESS && pamh->fail_delay.set) {
D(("will wait %u usec", delay));
if (delay > 0) {
struct timeval tval;
tval.tv_sec = delay / 1000000;
tval.tv_usec = delay % 1000000;
select(0, NULL, NULL, NULL, &tval);
}
}
_pam_reset_timer(pamh);
D(("waiting done"));
}
/* **********************************************************************
* this function is known to both the module and the application, it
* keeps a running score of the largest-requested delay so far, as
* specified by either modules or an application.
*/
int pam_fail_delay(pam_handle_t *pamh, unsigned int usec)
{
int largest;
IF_NO_PAMH("pam_fail_delay", pamh, PAM_SYSTEM_ERR);
D(("setting delay to %u",usec));
if (pamh->fail_delay.set) {
largest = pamh->fail_delay.delay;
} else {
pamh->fail_delay.set = PAM_TRUE;
largest = 0;
}
D(("largest = %u",largest));
if (largest < usec) {
D(("resetting largest delay"));
pamh->fail_delay.delay = usec;
}
return PAM_SUCCESS;
}

View File

@ -0,0 +1,286 @@
/* pam_dispatch.c - handles module function dispatch */
/*
* $Id: pam_dispatch.c,v 1.8 1997/01/04 20:04:09 morgan Exp morgan $
*
* last modified by AGM
*/
#include <stdlib.h>
#include <stdio.h>
#include "pam_private.h"
/*
* this is the return code we return when a function pointer is NULL
* or, the handler structure indicates a broken module config line
*/
#define PAM_MUST_FAIL_CODE PAM_PERM_DENIED
/* impression codes - this gives some sense to the logical choices */
#define _PAM_UNDEF 0
#define _PAM_POSITIVE +1
#define _PAM_NEGATIVE -1
/*
* walk a stack of modules. Interpret the administrator's instructions
* when combining the return code of each module.
*/
static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
_pam_boolean resumed)
{
int depth, impression, status, skip_depth;
IF_NO_PAMH("_pam_dispatch_aux", pamh, PAM_SYSTEM_ERR);
if (h == NULL) {
const char *service=NULL;
(void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service);
pam_system_log(pamh, NULL, LOG_ERR,
"no modules loaded for `%s' service",
service ? service:"<unknown>" );
service = NULL;
return PAM_MUST_FAIL_CODE;
}
/* if we are recalling this module stack because a former call did
not complete, we restore the state of play from pamh. */
if (resumed) {
skip_depth = pamh->former.depth;
status = pamh->former.status;
impression = pamh->former.impression;
/* forget all that */
pamh->former.impression = _PAM_UNDEF;
pamh->former.status = PAM_MUST_FAIL_CODE;
pamh->former.depth = 0;
} else {
skip_depth = 0;
impression = _PAM_UNDEF;
status = PAM_MUST_FAIL_CODE;
}
/* Loop through module logic stack */
for (depth=0 ; h != NULL ; h = h->next, ++depth) {
int retval, action;
/* skip leading modules if they have already returned */
if (depth < skip_depth) {
continue;
}
/* attempt to call the module */
if (h->func == NULL) {
D(("module function is not defined, indicating failure"));
retval = PAM_MODULE_UNKNOWN;
} else {
D(("passing control to module..."));
retval = h->func(pamh, flags, h->argc, h->argv);
D(("module returned: %s", pam_strerror(pamh, retval)));
if (h->must_fail) {
D(("module poorly listed in pam.conf; forcing failure"));
retval = PAM_MUST_FAIL_CODE;
}
}
/*
* PAM_INCOMPLETE return is special. It indicates that the
* module wants to wait for the application before continuing.
* In order to return this, the module will have saved its
* state so it can resume from an equivalent position when it
* is called next time. (This was added as of 0.65)
*/
if (retval == PAM_INCOMPLETE) {
pamh->former.impression = impression;
pamh->former.status = status;
pamh->former.depth = depth;
D(("module %d returned PAM_INCOMPLETE", depth));
return retval;
}
/* verify that the return value is a valid one */
if (retval < PAM_SUCCESS || retval >= _PAM_RETURN_VALUES) {
retval = PAM_MUST_FAIL_CODE;
action = _PAM_ACTION_BAD;
} else {
action = h->actions[retval];
}
/* decide what to do */
switch (action) {
case _PAM_ACTION_RESET:
impression = _PAM_UNDEF;
status = PAM_MUST_FAIL_CODE;
break;
case _PAM_ACTION_OK:
case _PAM_ACTION_DONE:
if ( impression == _PAM_UNDEF
|| (impression == _PAM_POSITIVE && status == PAM_SUCCESS) ) {
impression = _PAM_POSITIVE;
status = retval;
}
if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) {
goto decision_made;
}
break;
case _PAM_ACTION_BAD:
case _PAM_ACTION_DIE:
#ifdef PAM_FAIL_NOW_ON
if ( retval == PAM_ABORT ) {
impression = _PAM_NEGATIVE;
status = PAM_PERM_DENIED;
goto decision_made;
}
#endif /* PAM_FAIL_NOW_ON */
if ( impression != _PAM_NEGATIVE ) {
impression = _PAM_NEGATIVE;
status = retval;
}
if ( action == _PAM_ACTION_DIE ) {
goto decision_made;
}
break;
case _PAM_ACTION_IGNORE:
break;
/* if we get here, we expect action is a positive number --
this is what the ...JUMP macro checks. */
default:
if ( _PAM_ACTION_IS_JUMP(action) ) {
/* this means that we need to skip #action stacked modules */
do {
h = h->next;
} while ( --action > 0 && h != NULL );
/* note if we try to skip too many modules action is
still non-zero and we snag the next if. */
}
/* this case is a syntax error: we can't succeed */
if (action) {
D(("action syntax error"));
impression = _PAM_NEGATIVE;
status = PAM_MUST_FAIL_CODE;
}
}
}
decision_made: /* by getting here we have made a decision */
/* Sanity check */
if ( status == PAM_SUCCESS && impression != _PAM_POSITIVE ) {
D(("caught on sanity check -- this is probably a config error!"));
status = PAM_MUST_FAIL_CODE;
}
/* We have made a decision about the modules executed */
return status;
}
/*
* This function translates the module dispatch request into a pointer
* to the stack of modules that will actually be run. the
* _pam_dispatch_aux() function (above) is responsible for walking the
* module stack.
*/
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
struct handler *h = NULL;
int retval;
_pam_boolean resumed;
IF_NO_PAMH("_pam_dispatch",pamh,PAM_SYSTEM_ERR);
/* Load all modules, resolve all symbols */
if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
pam_system_log(pamh, NULL, LOG_ERR, "unable to dispatch function");
return retval;
}
switch (choice) {
case PAM_AUTHENTICATE:
h = pamh->handlers.conf.authenticate;
break;
case PAM_SETCRED:
h = pamh->handlers.conf.setcred;
break;
case PAM_ACCOUNT:
h = pamh->handlers.conf.acct_mgmt;
break;
case PAM_OPEN_SESSION:
h = pamh->handlers.conf.open_session;
break;
case PAM_CLOSE_SESSION:
h = pamh->handlers.conf.close_session;
break;
case PAM_CHAUTHTOK:
h = pamh->handlers.conf.chauthtok;
break;
default:
pam_system_log(pamh, NULL, LOG_ERR, "undefined fn choice; %d", choice);
return PAM_ABORT;
}
if (h == NULL) { /* there was no handlers.conf... entry; will use
* handlers.other... */
switch (choice) {
case PAM_AUTHENTICATE:
h = pamh->handlers.other.authenticate;
break;
case PAM_SETCRED:
h = pamh->handlers.other.setcred;
break;
case PAM_ACCOUNT:
h = pamh->handlers.other.acct_mgmt;
break;
case PAM_OPEN_SESSION:
h = pamh->handlers.other.open_session;
break;
case PAM_CLOSE_SESSION:
h = pamh->handlers.other.close_session;
break;
case PAM_CHAUTHTOK:
h = pamh->handlers.other.chauthtok;
break;
}
}
/* Did a module return an "incomplete state" last time? */
if (pamh->former.choice != PAM_NOT_STACKED) {
if (pamh->former.choice != choice) {
pam_system_log(pamh, NULL, LOG_ERR,
"application failed to re-exec stack [%d:%d]",
pamh->former.choice, choice);
return PAM_ABORT;
}
resumed = PAM_TRUE;
} else {
resumed = PAM_FALSE;
}
/* call the list of module functions */
retval = _pam_dispatch_aux(pamh, flags, h, resumed);
resumed = PAM_FALSE;
/* Should we recall where to resume next time? */
if (retval == PAM_INCOMPLETE) {
D(("module [%d] returned PAM_INCOMPLETE"));
pamh->former.choice = choice;
} else {
pamh->former.choice = PAM_NOT_STACKED;
}
return retval;
}
/*
* $Log: pam_dispatch.c,v $
*/

View File

@ -0,0 +1,77 @@
/* pam_end.c */
/*
* $Id: pam_end.c,v 1.5 1996/12/01 03:14:13 morgan Exp $
*
* $Log: pam_end.c,v $
*/
#include <stdlib.h>
#include "pam_private.h"
int pam_end(pam_handle_t *pamh, int pam_status)
{
int ret;
IF_NO_PAMH("pam_end", pamh, PAM_SYSTEM_ERR);
D(("entering pam_end()"));
/* first liberate the modules (it is not inconcevible that the
modules may need to use the service_name etc. to clean up) */
_pam_free_data(pamh, pam_status);
/* now drop all modules */
if ((ret = _pam_free_handlers(pamh)) != PAM_SUCCESS) {
return ret; /* error occurred */
}
/* from this point we cannot call the modules any more. Free the remaining
memory used by the Linux-PAM interface */
_pam_drop_env(pamh); /* purge the environment */
_pam_overwrite(pamh->authtok); /* blank out old token */
_pam_drop(pamh->authtok);
_pam_overwrite(pamh->oldauthtok); /* blank out old token */
_pam_drop(pamh->oldauthtok);
_pam_overwrite(pamh->former.prompt);
_pam_drop(pamh->former.prompt); /* drop saved prompt */
_pam_overwrite(pamh->service_name);
_pam_drop(pamh->service_name);
_pam_overwrite(pamh->user);
_pam_drop(pamh->user);
_pam_overwrite(pamh->prompt);
_pam_drop(pamh->prompt); /* prompt for pam_get_user() */
_pam_overwrite(pamh->tty);
_pam_drop(pamh->tty);
_pam_overwrite(pamh->rhost);
_pam_drop(pamh->rhost);
_pam_overwrite(pamh->ruser);
_pam_drop(pamh->ruser);
_pam_drop(pamh->pam_conversation);
pamh->fail_delay.delay_fn_ptr = NULL;
_pam_overwrite(pamh->pam_default_log.ident);
_pam_drop(pamh->pam_default_log.ident);
/* and finally liberate the memory for the pam_handle structure */
_pam_drop(pamh);
D(("exiting pam_end() successfully"));
return PAM_SUCCESS;
}

View File

@ -0,0 +1,403 @@
/*
* pam_env.c
*
* Copyright (c) Andrew G. Morgan <morgan@parc.power.net> 1996,1997
* All rights reserved.
*
* This file was written from a "hint" provided by the people at SUN.
* and the X/Open XSSO draft of March 1997.
*
* $Id: pam_env.c,v 1.2 1997/02/15 15:56:48 morgan Exp morgan $
*
* $Log: pam_env.c,v $
* Revision 1.2 1997/02/15 15:56:48 morgan
* liberate pamh->env structure too!
*
* Revision 1.1 1996/12/01 03:14:13 morgan
* Initial revision
*/
#include <string.h>
#include <stdlib.h>
#ifdef sunos
#define memmove(x,y,z) bcopy(y,x,z)
#endif
#include "pam_private.h"
/* helper functions */
#ifdef DEBUG
static void _pam_dump_env(pam_handle_t *pamh)
{
int i;
D(("Listing environment of pamh=%p", pamh));
D(("pamh->env = %p", pamh->env));
D(("environment entries used = %d [of %d allocated]"
, pamh->env->requested, pamh->env->entries));
for (i=0; i<pamh->env->requested; ++i) {
_pam_output_debug(">%-3d [%9p]:[%s]"
, i, pamh->env->list[i], pamh->env->list[i]);
}
_pam_output_debug("*NOTE* the last item should be (nil)");
}
#else
#define _pam_dump_env(x)
#endif
/*
* Create the environment
*/
int _pam_make_env(pam_handle_t *pamh)
{
D(("called."));
IF_NO_PAMH("_pam_make_env", pamh, PAM_ABORT);
/*
* get structure memory
*/
pamh->env = (struct pam_environ *) malloc(sizeof(struct pam_environ));
if (pamh->env == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT, "_pam_make_env: out of memory");
return PAM_BUF_ERR;
}
/*
* get list memory
*/
pamh->env->list = (char **)calloc( PAM_ENV_CHUNK, sizeof(char *) );
if (pamh->env->list == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"_pam_make_env: no memory for list");
_pam_drop(pamh->env);
return PAM_BUF_ERR;
}
/*
* fill entries in pamh->env
*/
pamh->env->entries = PAM_ENV_CHUNK;
pamh->env->requested = 1;
pamh->env->list[0] = NULL;
_pam_dump_env(pamh); /* only active when debugging */
return PAM_SUCCESS;
}
/*
* purge the environment
*/
void _pam_drop_env(pam_handle_t *pamh)
{
D(("called."));
IF_NO_PAMH("_pam_make_env", pamh, /* nothing to return */);
if (pamh->env != NULL) {
int i;
/* we will only purge the pamh->env->requested number of elements */
for (i=pamh->env->requested-1; i-- > 0; ) {
D(("dropping #%3d>%s<", i, pamh->env->list[i]));
_pam_overwrite(pamh->env->list[i]); /* clean */
_pam_drop(pamh->env->list[i]); /* forget */
}
pamh->env->requested = 0;
pamh->env->entries = 0;
_pam_drop(pamh->env->list); /* forget */
_pam_drop(pamh->env); /* forget */
} else {
D(("no environment present in pamh?"));
}
}
/*
* Return the item number of the given variable = first 'length' chars
* of 'name_value'. Since this is a static function, it is safe to
* assume its supplied arguments are well defined.
*/
static int _pam_search_env(const struct pam_environ *env
, const char *name_value, int length)
{
int i;
for (i=env->requested-1; i-- > 0; ) {
if (strncmp(name_value,env->list[i],length) == 0
&& env->list[i][length] == '=') {
return i; /* Got it! */
}
}
return -1; /* no luck */
}
/*
* externally visible functions
*/
/*
* pam_putenv(): Add/replace/delete a PAM-environment variable.
*
* Add/replace:
* name_value = "NAME=VALUE" or "NAME=" (for empty value="\0")
*
* delete:
* name_value = "NAME"
*/
int pam_putenv(pam_handle_t *pamh, const char *name_value)
{
int l2eq, item, retval;
D(("called."));
IF_NO_PAMH("pam_putenv", pamh, PAM_ABORT);
if (name_value == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_putenv: no variable indicated");
return PAM_PERM_DENIED;
}
/*
* establish if we are setting or deleting; scan for '='
*/
for (l2eq=0; name_value[l2eq] && name_value[l2eq] != '='; ++l2eq);
if (l2eq <= 0) {
pam_system_log(pamh, NULL, LOG_ERR, "pam_putenv: bad variable");
return PAM_BAD_ITEM;
}
/*
* Look first for environment.
*/
if (pamh->env == NULL || pamh->env->list == NULL) {
pam_system_log(pamh, NULL, LOG_ERR, "pam_putenv: no env%s found"
, pamh->env == NULL ? "":"-list");
return PAM_ABORT;
}
/* find the item to replace */
item = _pam_search_env(pamh->env, name_value, l2eq);
if (name_value[l2eq]) { /* (re)setting */
if (item == -1) { /* new variable */
D(("adding item: %s", name_value));
/* enough space? */
if (pamh->env->entries <= pamh->env->requested) {
register int i;
register char **tmp;
/* get some new space */
tmp = calloc( pamh->env->entries + PAM_ENV_CHUNK
, sizeof(char *) );
if (tmp == NULL) {
/* nothing has changed - old env intact */
pam_system_log(pamh, NULL, LOG_CRIT,
"pam_putenv: cannot grow environment");
return PAM_BUF_ERR;
}
/* copy old env-item pointers/forget old */
for (i=0; i<pamh->env->requested; ++i) {
tmp[i] = pamh->env->list[i];
pamh->env->list[i] = NULL;
}
/* drop old list and replace with new */
_pam_drop(pamh->env->list);
pamh->env->list = tmp;
pamh->env->entries += PAM_ENV_CHUNK;
D(("resized env list"));
_pam_dump_env(pamh); /* only when debugging */
}
item = pamh->env->requested-1; /* old last item (NULL) */
/* add a new NULL entry at end; increase counter */
pamh->env->list[pamh->env->requested++] = NULL;
} else { /* replace old */
D(("replacing item: %s\n with: %s"
, pamh->env->list[item], name_value));
_pam_overwrite(pamh->env->list[item]);
_pam_drop(pamh->env->list[item]);
}
/*
* now we have a place to put the new env-item, insert at 'item'
*/
pamh->env->list[item] = _pam_strdup(name_value);
if (pamh->env->list[item] != NULL) {
_pam_dump_env(pamh); /* only when debugging */
return PAM_SUCCESS;
}
/* something went wrong; we should delete the item - fall through */
retval = PAM_BUF_ERR; /* an error occurred */
} else {
retval = PAM_SUCCESS; /* we requested delete */
}
/* getting to here implies we are deleting an item */
if (item < 0) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_putenv: delete non-existent entry; %s",
name_value);
return PAM_BAD_ITEM;
}
/*
* remove item: purge memory; reset counter; resize [; display-env]
*/
D(("deleting: env#%3d:[%s]", item, pamh->env->list[item]));
_pam_overwrite(pamh->env->list[item]);
_pam_drop(pamh->env->list[item]);
--(pamh->env->requested);
D(("mmove: item[%d]+%d -> item[%d]"
, item+1, ( pamh->env->requested - item ), item));
(void) memmove(&pamh->env->list[item], &pamh->env->list[item+1]
, ( pamh->env->requested - item )*sizeof(char *) );
_pam_dump_env(pamh); /* only when debugging */
/*
* deleted.
*/
return retval;
}
/*
* Return the value of the requested environment variable
*/
const char *pam_getenv(pam_handle_t *pamh, const char *name)
{
int item;
D(("called."));
IF_NO_PAMH("pam_getenv", pamh, NULL);
if (name == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_getenv: no variable indicated");
return NULL;
}
if (pamh->env == NULL || pamh->env->list == NULL) {
pam_system_log(pamh, NULL, LOG_ERR, "pam_getenv: no env%s found",
pamh->env == NULL ? "":"-list" );
return NULL;
}
/* find the requested item */
item = _pam_search_env(pamh->env, name, strlen(name));
if (item != -1) {
D(("env-item: %s, found!", name));
return (pamh->env->list[item] + 1 + strlen(name));
} else {
D(("env-item: %s, not found", name));
return NULL;
}
}
static char **_copy_env(pam_handle_t *pamh)
{
char **dump;
int i = pamh->env->requested; /* reckon size of environment */
char *const *env = pamh->env->list;
D(("now get some memory for dump"));
/* allocate some memory for this (plus the null tail-pointer) */
dump = (char **) calloc(i, sizeof(char *));
D(("dump = %p", dump));
if (dump == NULL) {
return NULL;
}
/* now run through entries and copy the variables over */
dump[--i] = NULL;
while (i-- > 0) {
D(("env[%d]=`%s'", i,env[i]));
dump[i] = _pam_strdup(env[i]);
D(("->dump[%d]=`%s'", i,dump[i]));
if (dump[i] == NULL) {
/* out of memory */
while (dump[++i]) {
_pam_overwrite(dump[i]);
_pam_drop(dump[i]);
}
return NULL;
}
}
env = NULL; /* forget now */
/* return transcribed environment */
return dump;
}
char **pam_getenvlist(pam_handle_t *pamh)
{
int i;
D(("called."));
IF_NO_PAMH("pam_getenvlist", pamh, NULL);
if (pamh->env == NULL || pamh->env->list == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_getenvlist: no env%s found",
pamh->env == NULL ? "":"-list" );
return NULL;
}
/* some quick checks */
if (pamh->env->requested > pamh->env->entries) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_getenvlist: environment corruption");
_pam_dump_env(pamh); /* only active when debugging */
return NULL;
}
for (i=pamh->env->requested-1; i-- > 0; ) {
if (pamh->env->list[i] == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_getenvlist: environment broken");
_pam_dump_env(pamh); /* only active when debugging */
return NULL; /* somehow we've broken the environment!? */
}
}
/* Seems fine; copy environment */
_pam_dump_env(pamh); /* only active when debugging */
return _copy_env(pamh);
}

View File

@ -0,0 +1,901 @@
/* pam_handlers.c -- pam config file parsing and module loading */
/*
* created by Marc Ewing.
* Currently maintained by Andrew G. Morgan <morgan@linux.kernel.org>
*
* $Id: pam_handlers.c,v 1.17 1997/04/05 06:55:24 morgan Exp morgan $
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef PAM_SHL
# include <dl.h>
#else
# include <dlfcn.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include "pam_private.h"
/* FreeBSD doesn't define this */
#ifndef RTLD_NOW
# define RTLD_NOW 1
#endif
/* If not required, define as nothing - FreeBSD needs it to be "_"... */
#ifndef SHLIB_SYM_PREFIX
# define SHLIB_SYM_PREFIX ""
#endif
#define BUF_SIZE 1024
#define MODULE_CHUNK 4
static int _pam_assemble_line(FILE *f, char *buf, int buf_len);
static void _pam_free_handlers_aux(struct handler **hp);
static int _pam_add_handler(pam_handle_t *pamh
, int must_fail, int other, int type
, int *actions, const char *mod_path
, int argc, char **argv, int argvlen);
/* Values for module type */
#define PAM_T_AUTH 1
#define PAM_T_SESS 2
#define PAM_T_ACCT 4
#define PAM_T_PASS 8
static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f
, const char *known_service /* specific file */
#ifdef PAM_READ_BOTH_CONFS
, int not_other
#endif /* PAM_READ_BOTH_CONFS */
)
{
char buf[BUF_SIZE];
int x; /* read a line from the FILE *f ? */
/*
* read a line from the configuration (FILE *) f
*/
while ((x = _pam_assemble_line(f, buf, BUF_SIZE)) > 0) {
char *tok, *nexttok=NULL;
const char *this_service;
const char *mod_path;
int module_type, actions[_PAM_RETURN_VALUES];
int other; /* set if module is for PAM_DEFAULT_SERVICE */
int res; /* module added successfully? */
int must_fail=0; /* a badly formatted line must fail when used */
int argc;
char **argv;
int argvlen;
D(("_pam_init_handler: LINE: %s", buf));
if (known_service != NULL) {
nexttok = buf;
/* No service field: all lines are for the known service. */
this_service = known_service;
} else {
this_service = tok = _pam_StrTok(buf, " \n\t", &nexttok);
}
#ifdef PAM_READ_BOTH_CONFS
if (not_other)
other = 0;
else
#endif /* PAM_READ_BOTH_CONFS */
other = !_pam_strCMP(this_service, PAM_DEFAULT_SERVICE);
/* accept "service name" or PAM_DEFAULT_SERVICE modules */
if (!_pam_strCMP(this_service, pamh->service_name) || other) {
/* This is a service we are looking for */
D(("_pam_init_handlers: Found PAM config entry for: %s"
, this_service));
tok = _pam_StrTok(NULL, " \n\t", &nexttok);
if (!_pam_strCMP("auth", tok)) {
module_type = PAM_T_AUTH;
} else if (!_pam_strCMP("session", tok)) {
module_type = PAM_T_SESS;
} else if (!_pam_strCMP("account", tok)) {
module_type = PAM_T_ACCT;
} else if (!_pam_strCMP("password", tok)) {
module_type = PAM_T_PASS;
} else {
/* Illegal module type */
D(("_pam_init_handlers: bad module type: %s", tok));
pam_system_log(pamh, NULL, LOG_ERR,
"(%s) illegal module type: %s"
, this_service, tok);
module_type = PAM_T_AUTH; /* most sensitive */
must_fail = 1; /* install as normal but fail when dispatched */
}
D(("Using %s config entry: %s", must_fail?"BAD ":"", tok));
/* reset the actions to .._UNDEF's -- this is so that
we can work out which entries are not yet set (for default). */
{
int i;
for (i=0; i<_PAM_RETURN_VALUES;
actions[i++] = _PAM_ACTION_UNDEF);
}
tok = _pam_StrTok(NULL, " \n\t", &nexttok);
if (!_pam_strCMP("required", tok)) {
D(("*PAM_F_REQUIRED*"));
actions[PAM_SUCCESS] = _PAM_ACTION_OK;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_OK;
actions[PAM_IGNORE] = _PAM_ACTION_IGNORE;
_pam_set_default_control(actions, _PAM_ACTION_BAD);
} else if (!_pam_strCMP("requisite", tok)) {
D(("*PAM_F_REQUISITE*"));
actions[PAM_SUCCESS] = _PAM_ACTION_OK;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_OK;
actions[PAM_IGNORE] = _PAM_ACTION_IGNORE;
_pam_set_default_control(actions, _PAM_ACTION_DIE);
} else if (!_pam_strCMP("optional", tok)) {
D(("*PAM_F_OPTIONAL*"));
actions[PAM_SUCCESS] = _PAM_ACTION_OK;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_OK;
_pam_set_default_control(actions, _PAM_ACTION_IGNORE);
} else if (!_pam_strCMP("sufficient", tok)) {
D(("*PAM_F_SUFFICIENT*"));
actions[PAM_SUCCESS] = _PAM_ACTION_DONE;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_DONE;
_pam_set_default_control(actions, _PAM_ACTION_IGNORE);
} else {
D(("will need to parse %s", tok));
_pam_parse_control(actions, tok);
/* by default the default is to treat as failure */
_pam_set_default_control(actions, _PAM_ACTION_BAD);
}
tok = _pam_StrTok(NULL, " \n\t", &nexttok);
if (tok != NULL) {
mod_path = tok;
D(("mod_path = %s",mod_path));
} else {
/* no module name given */
D(("_pam_init_handlers: no module name supplied"));
pam_system_log(pamh, NULL, LOG_ERR,
"(%s) no module name supplied", this_service);
mod_path = NULL;
must_fail = 1;
}
/* nexttok points to remaining arguments... */
if (nexttok != NULL) {
D(("list: %s",nexttok));
argvlen = _pam_mkargv(nexttok, &argv, &argc);
D(("argvlen = %d",argvlen));
} else { /* there are no arguments so fix by hand */
D(("_pam_init_handlers: empty argument list"));
argvlen = argc = 0;
argv = NULL;
}
#ifdef DEBUG
{
int y;
D(("CONF%s: %s%s %d %s %d"
, must_fail?"<*will fail*>":""
, this_service, other ? "(backup)":""
, module_type
, mod_path, argc));
for (y = 0; y < argc; y++) {
D(("CONF: %s", argv[y]));
}
for (y = 0; y<_PAM_RETURN_VALUES; ++y) {
D(("RETURN %s(%d) -> %d %s",
_pam_token_returns[y], y, actions[y],
actions[y]>0 ? "jump":
_pam_token_actions[-actions[y]]));
}
fprintf(stderr, "pause to look at debugging: ");
getchar();
}
#endif
res = _pam_add_handler(pamh, must_fail, other
, module_type, actions, mod_path
, argc, argv, argvlen);
if (res != PAM_SUCCESS) {
pam_system_log(pamh, NULL, LOG_ERR,
"error loading %s", mod_path);
D(("failed to load module - aborting"));
return PAM_ABORT;
}
}
}
return ( (x < 0) ? PAM_ABORT:PAM_SUCCESS );
}
/* Parse config file, allocate handler structures, dlopen() */
int _pam_init_handlers(pam_handle_t *pamh)
{
FILE *f;
int retval;
D(("_pam_init_handlers called"));
IF_NO_PAMH("_pam_init_handlers",pamh,PAM_SYSTEM_ERR);
/* Return immediately if everything is already loaded */
if (pamh->handlers.handlers_loaded) {
return PAM_SUCCESS;
}
D(("_pam_init_handlers: initializing"));
/* First clean the service structure */
_pam_free_handlers(pamh);
if (! pamh->handlers.module) {
if ((pamh->handlers.module =
malloc(MODULE_CHUNK * sizeof(struct loaded_module))) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"_pam_init_handlers: no memory loading module");
return PAM_BUF_ERR;
}
pamh->handlers.modules_allocated = MODULE_CHUNK;
pamh->handlers.modules_used = 0;
}
if (pamh->service_name == NULL) {
return PAM_BAD_ITEM; /* XXX - better error? */
}
#ifdef PAM_LOCKING
/* Is the PAM subsystem locked? */
{
int fd_tmp;
if ((fd_tmp = open( PAM_LOCK_FILE, O_RDONLY )) != -1) {
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: PAM lockfile ("
PAM_LOCK_FILE ") exists - aborting");
(void) close(fd_tmp);
/*
* to avoid swamping the system with requests
*/
_pam_start_timer(pamh);
pam_fail_delay(pamh, 5000000);
_pam_await_timer(pamh, PAM_ABORT);
return PAM_ABORT;
}
}
#endif /* PAM_LOCKING */
/*
* Now parse the config file(s) and add handlers
*/
{
struct stat test_d;
/* Is there a PAM_CONFIG_D directory? */
if ( stat(PAM_CONFIG_D, &test_d) == 0 && S_ISDIR(test_d.st_mode) ) {
char *filename;
int read_something=0;
D(("searching " PAM_CONFIG_D " for config files"));
filename = malloc(sizeof(PAM_CONFIG_DF)
+strlen(pamh->service_name));
if (filename == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: no memory; service %s",
pamh->service_name);
return PAM_BUF_ERR;
}
sprintf(filename, PAM_CONFIG_DF, pamh->service_name);
D(("opening %s", filename));
f = fopen(filename, "r");
if (f != NULL) {
/* would test magic here? */
retval = _pam_parse_conf_file(pamh, f, pamh->service_name
#ifdef PAM_READ_BOTH_CONFS
, 0
#endif /* PAM_READ_BOTH_CONFS */
);
fclose(f);
if (retval != PAM_SUCCESS) {
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: error reading %s",
filename);
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: [%s]",
pam_strerror(pamh, retval));
} else {
read_something = 1;
}
} else {
D(("unable to open %s", filename));
#ifdef PAM_READ_BOTH_CONFS
D(("checking %s", PAM_CONFIG));
if ((f = fopen(PAM_CONFIG,"r")) != NULL) {
retval = _pam_parse_conf_file(pamh, f, NULL, 1);
fclose(f);
} else
#endif /* PAM_READ_BOTH_CONFS */
retval = PAM_SUCCESS;
/*
* XXX - should we log an error? Some people want to always
* use "other"
*/
}
_pam_drop(filename);
if (retval == PAM_SUCCESS) {
/* now parse the PAM_DEFAULT_SERVICE_FILE */
D(("opening %s", PAM_DEFAULT_SERVICE_FILE));
f = fopen(PAM_DEFAULT_SERVICE_FILE, "r");
if (f != NULL) {
/* would test magic here? */
retval = _pam_parse_conf_file(pamh, f
, PAM_DEFAULT_SERVICE
#ifdef PAM_READ_BOTH_CONFS
, 0
#endif /* PAM_READ_BOTH_CONFS */
);
fclose(f);
if (retval != PAM_SUCCESS) {
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: error reading %s",
PAM_DEFAULT_SERVICE_FILE);
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: [%s]",
pam_strerror(pamh, retval));
} else {
read_something = 1;
}
} else {
D(("unable to open %s", PAM_DEFAULT_SERVICE_FILE));
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: no default config %s",
PAM_DEFAULT_SERVICE_FILE);
}
if (!read_something) { /* nothing read successfully */
retval = PAM_ABORT;
}
}
} else {
if ((f = fopen(PAM_CONFIG, "r")) == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"_pam_init_handlers: could not open "
PAM_CONFIG );
return PAM_ABORT;
}
retval = _pam_parse_conf_file(pamh, f, NULL
#ifdef PAM_READ_BOTH_CONFS
, 0
#endif /* PAM_READ_BOTH_CONFS */
);
D(("closing configuration file"));
fclose(f);
}
}
if (retval != PAM_SUCCESS) {
/* Read error */
pam_system_log(pamh, NULL, LOG_ERR,
"error reading PAM configuration file");
return PAM_ABORT;
}
pamh->handlers.handlers_loaded = 1;
D(("_pam_init_handlers exiting"));
return PAM_SUCCESS;
}
/*
* This is where we read a line of the PAM config file. The line may be
* preceeded by lines of comments and also extended with "\\\n"
*/
int _pam_assemble_line(FILE *f, char *buffer, int buf_len)
{
char *p = buffer;
char *s, *os;
int used = 0;
/* loop broken with a 'break' when a non-'\\n' ended line is read */
D(("called."));
for (;;) {
if (used >= buf_len) {
/* Overflow */
D(("_pam_assemble_line: overflow"));
return -1;
}
if (fgets(p, buf_len - used, f) == NULL) {
if (used) {
/* Incomplete read */
return -1;
} else {
/* EOF */
return 0;
}
}
/* skip leading spaces --- line may be blank */
s = p + strspn(p, " \n\t");
if (*s && (*s != '#')) {
os = s;
/*
* we are only interested in characters before the first '#'
* character
*/
while (*s && *s != '#')
++s;
if (*s == '#') {
*s = '\0';
used += strlen(os);
break; /* the line has been read */
}
s = os;
/*
* Check for backslash by scanning back from the end of
* the entered line, the '\n' has been included since
* normally a line is terminated with this
* character. fgets() should only return one though!
*/
s += strlen(s);
while (s > os && ((*--s == ' ') || (*s == '\t')
|| (*s == '\n')));
/* check if it ends with a backslash */
if (*s == '\\') {
*s++ = ' '; /* replace backslash with ' ' */
*s = '\0'; /* truncate the line here */
used += strlen(os);
p = s; /* there is more ... */
} else {
/* End of the line! */
used += strlen(os);
break; /* this is the complete line */
}
} else {
/* Nothing in this line */
/* Don't move p */
}
}
return used;
}
typedef int (*servicefn)(pam_handle_t *, int, int, char **);
int _pam_add_handler(pam_handle_t *pamh
, int must_fail, int other, int type
, int *actions, const char *mod_path
, int argc, char **argv, int argvlen)
{
struct loaded_module *mod;
int x = 0;
struct handler **handler_p;
struct handler **handler_p2;
struct handlers *the_handlers;
const char *sym, *sym2;
#ifdef PAM_SHL
const char *_sym, *_sym2;
#endif
char *mod_full_path=NULL;
servicefn func, func2;
int success;
D(("called."));
IF_NO_PAMH("_pam_add_handler",pamh,PAM_SYSTEM_ERR);
/* if NULL set to something that can be searched for */
if (mod_path == NULL) {
mod_path = "<*unknown module path*>";
} else if (mod_path[0] != '/') {
mod_full_path = malloc(sizeof(DEFAULT_MODULE_PATH)+strlen(mod_path));
sprintf(mod_full_path, DEFAULT_MODULE_PATH "%s", mod_path);
mod_path = mod_full_path;
}
D(("_pam_add_handler: adding type %d, module `%s'",type,mod_path));
mod = pamh->handlers.module;
/* First, ensure the module is loaded */
while (x < pamh->handlers.modules_used) {
if (!strcmp(mod[x].name, mod_path)) { /* case sensitive ! */
break;
}
x++;
}
if (x == pamh->handlers.modules_used) {
/* Not found */
if (pamh->handlers.modules_allocated == pamh->handlers.modules_used) {
/* will need more memory */
void *tmp = realloc(pamh->handlers.module,
(pamh->handlers.modules_allocated+MODULE_CHUNK)
*sizeof(struct loaded_module));
if (tmp == NULL) {
D(("cannot enlarge module pointer memory"));
pam_system_log(pamh, NULL, LOG_ERR,
"realloc returned NULL in _pam_add_handler");
_pam_drop(mod_full_path);
return PAM_ABORT;
}
pamh->handlers.module = tmp;
pamh->handlers.modules_allocated += MODULE_CHUNK;
}
mod = &(pamh->handlers.module[x]);
/* Be pessimistic... */
success = PAM_ABORT;
#ifdef PAM_DYNAMIC
D(("_pam_add_handler: dlopen(%s) -> %lx", mod_path, &mod->dl_handle));
mod->dl_handle =
# ifdef PAM_SHL
shl_load(mod_path, BIND_IMMEDIATE, 0L);
# else /* PAM_SHL */
dlopen(mod_path, RTLD_NOW);
# endif /* PAM_SHL */
D(("_pam_add_handler: dlopen'ed"));
if (mod->dl_handle == NULL) {
D(("_pam_add_handler: dlopen(%s) failed", mod_path));
pam_system_log(pamh, NULL, LOG_ERR, "unable to dlopen(%s)",
mod_path);
# ifndef PAM_SHL
pam_system_log(pamh, NULL, LOG_ERR, "[dlerror: %s]", dlerror());
# endif /* PAM_SHL */
/* Don't abort yet; static code may be able to find function.
* But defaults to abort if nothing found below... */
} else {
D(("module added successfully"));
success = PAM_SUCCESS;
mod->type = PAM_MT_DYNAMIC_MOD;
pamh->handlers.modules_used++;
}
#endif
#ifdef PAM_STATIC
/* Only load static function if function was not found dynamically.
* This code should work even if no dynamic loading is available. */
if (success != PAM_SUCCESS) {
D(("_pam_add_handler: open static handler %s", mod_path));
mod->dl_handle = _pam_open_static_handler(mod_path);
if (mod->dl_handle == NULL) {
D(("_pam_add_handler: unable to find static handler %s",
mod_path));
pam_system_log(pamh, NULL, LOG_ERR,
"unable to open static handler %s", mod_path);
/* Didn't find module in dynamic or static..will mark bad */
} else {
D(("static module added successfully"));
success = PAM_SUCCESS;
mod->type = PAM_MT_STATIC_MOD;
pamh->handlers.modules_used++;
}
}
#endif
if (success != PAM_SUCCESS) { /* add a malformed module */
mod->dl_handle = NULL;
mod->type = PAM_MT_FAULTY_MOD;
pamh->handlers.modules_used++;
pam_system_log(pamh, NULL, LOG_ERR,
"adding faulty module: %s", mod_path);
success = PAM_SUCCESS; /* We have successfully added a module */
}
/* indicate its name - later we will search for it by this */
if ((mod->name = _pam_strdup(mod_path)) == NULL) {
D(("_pam_handler: couldn't get memory for mod_path"));
pam_system_log(pamh, NULL, LOG_ERR,
"no memory for module path", mod_path);
success = PAM_ABORT;
}
} else { /* x != pamh->handlers.modules_used */
mod += x; /* the located module */
success = PAM_SUCCESS;
}
_pam_drop(mod_full_path);
mod_path = NULL; /* no longer needed or trusted */
/* Now return error if necessary after trying all possible ways... */
if (success != PAM_SUCCESS)
return(success);
/*
* At this point 'mod' points to the stored/loaded module. If its
* dl_handle is unknown, then we must be able to indicate dispatch
* failure with 'must_fail'
*/
/* Now define the handler(s) based on mod->dlhandle and type */
/* decide which list of handlers to use */
the_handlers = (other) ? &pamh->handlers.other : &pamh->handlers.conf;
handler_p = handler_p2 = NULL;
func = func2 = NULL;
#ifdef PAM_SHL
_sym2 =
#endif /* PAM_SHL */
sym2 = NULL;
/* point handler_p's at the root addresses of the function stacks */
switch (type) {
case PAM_T_AUTH:
handler_p = &the_handlers->authenticate;
sym = SHLIB_SYM_PREFIX "pam_sm_authenticate";
handler_p2 = &the_handlers->setcred;
sym2 = SHLIB_SYM_PREFIX "pam_sm_setcred";
#ifdef PAM_SHL
_sym = "_pam_sm_authenticate";
_sym2 = "_pam_sm_setcred";
#endif
break;
case PAM_T_SESS:
handler_p = &the_handlers->open_session;
sym = SHLIB_SYM_PREFIX "pam_sm_open_session";
handler_p2 = &the_handlers->close_session;
sym2 = SHLIB_SYM_PREFIX "pam_sm_close_session";
#ifdef PAM_SHL
_sym = "_pam_sm_open_session";
_sym2 = "_pam_sm_close_session";
#endif
break;
case PAM_T_ACCT:
handler_p = &the_handlers->acct_mgmt;
sym = SHLIB_SYM_PREFIX "pam_sm_acct_mgmt";
#ifdef PAM_SHL
_sym = "_pam_sm_acct_mgmt";
#endif
break;
case PAM_T_PASS:
handler_p = &the_handlers->chauthtok;
sym = SHLIB_SYM_PREFIX "pam_sm_chauthtok";
#ifdef PAM_SHL
_sym = "_pam_sm_chauthtok";
#endif
break;
default:
/* Illegal module type */
D(("_pam_add_handler: illegal module type %d", type));
return PAM_ABORT;
}
/* are the modules reliable? */
if (
#ifdef PAM_DYNAMIC
mod->type != PAM_MT_DYNAMIC_MOD
&&
#endif /* PAM_DYNAMIC */
#ifdef PAM_STATIC
mod->type != PAM_MT_STATIC_MOD
&&
#endif /* PAM_STATIC */
mod->type != PAM_MT_FAULTY_MOD
) {
D(("_pam_add_handlers: illegal module library type; %d", mod->type));
pam_system_log(pamh, NULL, LOG_ERR,
"internal error: module library type not known: %s;%d",
sym, mod->type);
return PAM_ABORT;
}
/* now identify this module's functions - for non-faulty modules */
#ifdef PAM_DYNAMIC
if ((mod->type == PAM_MT_DYNAMIC_MOD) &&
# ifdef PAM_SHL
(shl_findsym(&mod->dl_handle, sym, (short) TYPE_PROCEDURE, &func) &&
shl_findsym(&mod->dl_handle, _sym, (short) TYPE_PROCEDURE, &func))
# else /* PAM_SHL */
(func = (servicefn) dlsym(mod->dl_handle, sym)) == NULL
# endif /* PAM_SHL */
) {
pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
sym);
}
#endif
#ifdef PAM_STATIC
if ((mod->type == PAM_MT_STATIC_MOD) &&
(func = (servicefn)_pam_get_static_sym(mod->dl_handle, sym)) == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"unable to resolve static symbol: %s", sym);
}
#endif
if (sym2) {
#ifdef PAM_DYNAMIC
if ((mod->type == PAM_MT_DYNAMIC_MOD) &&
# ifdef PAM_SHL
(shl_findsym(&mod->dl_handle,sym2,(short)TYPE_PROCEDURE, &func2)&&
shl_findsym(&mod->dl_handle,_sym2,(short)TYPE_PROCEDURE, &func2))
# else /* PAM_SHL */
(func2 = (servicefn) dlsym(mod->dl_handle, sym2)) == NULL
# endif /* PAM_SHL */
) {
pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
sym2);
}
#endif
#ifdef PAM_STATIC
if ((mod->type == PAM_MT_STATIC_MOD) &&
(func2 = (servicefn)_pam_get_static_sym(mod->dl_handle, sym2))
== NULL) {
pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
sym2);
}
#endif
}
/* here func (and perhaps func2) point to the appropriate functions */
/* add new handler to end of existing list */
while (*handler_p != NULL) {
handler_p = &((*handler_p)->next);
}
if ((*handler_p = malloc(sizeof(struct handler))) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"cannot malloc struct handler #1");
return (PAM_ABORT);
}
(*handler_p)->must_fail = must_fail; /* failure forced? */
(*handler_p)->func = func;
memcpy((*handler_p)->actions,actions,sizeof((*handler_p)->actions));
(*handler_p)->argc = argc;
(*handler_p)->argv = argv; /* not a copy */
(*handler_p)->next = NULL;
/* some of the modules have a second calling function */
if (handler_p2) {
/* add new handler to end of existing list */
while (*handler_p2) {
handler_p2 = &((*handler_p2)->next);
}
if ((*handler_p2 = malloc(sizeof(struct handler))) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"cannot malloc struct handler #2");
return (PAM_ABORT);
}
(*handler_p2)->must_fail = must_fail; /* failure forced? */
(*handler_p2)->func = func2;
memcpy((*handler_p2)->actions,actions,sizeof((*handler_p2)->actions));
(*handler_p2)->argc = argc;
if (argv) {
if (((*handler_p2)->argv = malloc(argvlen)) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"cannot malloc argv for handler #2");
return (PAM_ABORT);
}
memcpy((*handler_p2)->argv, argv, argvlen);
} else {
(*handler_p2)->argv = NULL; /* no arguments */
}
(*handler_p2)->next = NULL;
}
D(("_pam_add_handler: returning successfully"));
return PAM_SUCCESS;
}
/* Free various allocated structures and dlclose() the libs */
int _pam_free_handlers(pam_handle_t *pamh)
{
struct loaded_module *mod;
D(("called."));
IF_NO_PAMH("_pam_free_handlers",pamh,PAM_SYSTEM_ERR);
mod = pamh->handlers.module;
/* Close all loaded modules */
while (pamh->handlers.modules_used) {
D(("_pam_free_handlers: dlclose(%s)", mod->name));
free(mod->name);
#ifdef PAM_DYNAMIC
# ifdef PAM_SHL
if (mod->type == PAM_MT_DYNAMIC_MOD) shl_unload(mod->dl_handle);
# else
if (mod->type == PAM_MT_DYNAMIC_MOD) dlclose(mod->dl_handle);
# endif
#endif
mod++;
pamh->handlers.modules_used--;
}
/* Free all the handlers */
_pam_free_handlers_aux(&(pamh->handlers.conf.authenticate));
_pam_free_handlers_aux(&(pamh->handlers.conf.setcred));
_pam_free_handlers_aux(&(pamh->handlers.conf.acct_mgmt));
_pam_free_handlers_aux(&(pamh->handlers.conf.open_session));
_pam_free_handlers_aux(&(pamh->handlers.conf.close_session));
_pam_free_handlers_aux(&(pamh->handlers.conf.chauthtok));
_pam_free_handlers_aux(&(pamh->handlers.other.authenticate));
_pam_free_handlers_aux(&(pamh->handlers.other.setcred));
_pam_free_handlers_aux(&(pamh->handlers.other.acct_mgmt));
_pam_free_handlers_aux(&(pamh->handlers.other.open_session));
_pam_free_handlers_aux(&(pamh->handlers.other.close_session));
_pam_free_handlers_aux(&(pamh->handlers.other.chauthtok));
/* no more loaded modules */
_pam_drop(pamh->handlers.module);
/* Indicate that handlers are not initialized for this pamh */
pamh->handlers.handlers_loaded = 0;
return PAM_SUCCESS;
}
void _pam_start_handlers(pam_handle_t *pamh)
{
D(("called."));
/* NB. There is no check for a NULL pamh here, since no return
* value to communicate the fact! */
/* Indicate that handlers are not initialized for this pamh */
pamh->handlers.handlers_loaded = 0;
pamh->handlers.modules_allocated = 0;
pamh->handlers.modules_used = 0;
pamh->handlers.module = NULL;
/* initialize the .conf and .other entries */
pamh->handlers.conf.authenticate = NULL;
pamh->handlers.conf.setcred = NULL;
pamh->handlers.conf.acct_mgmt = NULL;
pamh->handlers.conf.open_session = NULL;
pamh->handlers.conf.close_session = NULL;
pamh->handlers.conf.chauthtok = NULL;
pamh->handlers.other.authenticate = NULL;
pamh->handlers.other.setcred = NULL;
pamh->handlers.other.acct_mgmt = NULL;
pamh->handlers.other.open_session = NULL;
pamh->handlers.other.close_session = NULL;
pamh->handlers.other.chauthtok = NULL;
}
void _pam_free_handlers_aux(struct handler **hp)
{
struct handler *h = *hp;
struct handler *last;
D(("called."));
while (h) {
last = h;
_pam_drop(h->argv); /* This is all alocated in a single chunk */
h = h->next;
memset(last, 0, sizeof(*last));
free(last);
}
*hp = NULL;
}

View File

@ -0,0 +1,313 @@
/* pam_item.c */
/*
* $Id: pam_item.c,v 1.8 1997/02/15 15:58:49 morgan Exp morgan $
*
* $Log: pam_item.c,v $
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "pam_private.h"
#define RESET(X, Y) \
{ \
char *_TMP_ = (X); \
if (_TMP_ != (Y)) { \
(X) = (Y) ? _pam_strdup(Y) : NULL; \
if (_TMP_) \
free(_TMP_); \
} \
}
/* functions */
int pam_set_item (
pam_handle_t *pamh,
int item_type,
const void *item)
{
int retval;
D(("called"));
IF_NO_PAMH("pam_set_item", pamh, PAM_SYSTEM_ERR);
retval = PAM_SUCCESS;
switch (item_type) {
case PAM_SERVICE:
/* Setting handlers_loaded to 0 will cause the handlers
* to be reloaded on the next call to a service module.
*/
pamh->handlers.handlers_loaded = 0;
RESET(pamh->service_name, item);
{
char *tmp;
for (tmp=pamh->service_name; *tmp; ++tmp)
*tmp = tolower(*tmp); /* require lower case */
}
break;
case PAM_USER:
RESET(pamh->user, item);
break;
case PAM_USER_PROMPT:
RESET(pamh->prompt, item);
break;
case PAM_TTY:
D(("setting tty to %s", item));
RESET(pamh->tty, item);
break;
case PAM_RUSER:
RESET(pamh->ruser, item);
break;
case PAM_RHOST:
RESET(pamh->rhost, item);
break;
case PAM_AUTHTOK:
/*
* The man page says this is only supposed to be available to
* the module providers. In order to use this item the app
* has to #include <security/pam_modules.h>. This is something
* it is *not* supposed to do with "Linux-"PAM! - AGM.
*/
{
char *_TMP_ = pamh->authtok;
if (_TMP_ == item) /* not changed so leave alone */
break;
pamh->authtok = (item) ? _pam_strdup(item) : NULL;
if (_TMP_) {
_pam_overwrite(_TMP_);
free(_TMP_);
}
break;
}
case PAM_OLDAUTHTOK:
/* See note above. */
{
char *_TMP_ = pamh->oldauthtok;
if (_TMP_ == item) /* not changed so leave alone */
break;
pamh->oldauthtok = (item) ? _pam_strdup(item) : NULL;
if (_TMP_) {
_pam_overwrite(_TMP_);
free(_TMP_);
}
break;
}
case PAM_CONV: /* want to change the conversation function */
if (item == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_set_item: attempt to set conv() to NULL");
retval = PAM_PERM_DENIED;
} else {
struct pam_conv *tconv;
if ((tconv=
(struct pam_conv *) malloc(sizeof(struct pam_conv))
) == NULL) {
pam_system_log(pamh, NULL, LOG_CRIT,
"pam_set_item: malloc failed for pam_conv");
retval = PAM_BUF_ERR;
} else {
memcpy(tconv, item, sizeof(struct pam_conv));
_pam_drop(pamh->pam_conversation);
pamh->pam_conversation = tconv;
}
}
break;
case PAM_FAIL_DELAY:
pamh->fail_delay.delay_fn_ptr = item;
break;
case PAM_LOG_STATE:
{
char *old_ident = pamh->pam_default_log.ident;
if (item == NULL) {
/* reset the default state */
pamh->pam_default_log.ident = x_strdup(PAM_LOG_STATE_IDENT);
pamh->pam_default_log.option = PAM_LOG_STATE_OPTION;
pamh->pam_default_log.facility = PAM_LOG_STATE_FACILITY;
} else {
const struct pam_log_state *state = item;
pamh->pam_default_log.ident = x_strdup(state->ident);
pamh->pam_default_log.option = state->option;
pamh->pam_default_log.facility = state->facility;
}
_pam_overwrite(old_ident);
_pam_drop(old_ident);
break;
}
default:
retval = PAM_BAD_ITEM;
}
return (retval);
}
int pam_get_item (
const pam_handle_t *pamh,
int item_type,
const void **item)
{
D(("called."));
IF_NO_PAMH("pam_get_item",pamh,PAM_SYSTEM_ERR);
if (item == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_get_item: nowhere to place requested item");
return PAM_PERM_DENIED;
}
switch (item_type) {
case PAM_SERVICE:
*item = pamh->service_name;
break;
case PAM_USER:
*item = pamh->user;
break;
case PAM_USER_PROMPT:
*item = pamh->prompt;
break;
case PAM_TTY:
D(("returning tty=%s", pamh->tty));
*item = pamh->tty;
break;
case PAM_RUSER:
*item = pamh->ruser;
break;
case PAM_RHOST:
*item = pamh->rhost;
break;
case PAM_AUTHTOK:
*item = pamh->authtok;
break;
case PAM_OLDAUTHTOK:
*item = pamh->oldauthtok;
break;
case PAM_CONV:
*item = pamh->pam_conversation;
break;
case PAM_FAIL_DELAY:
*item = pamh->fail_delay.delay_fn_ptr;
break;
case PAM_LOG_STATE:
*item = &(pamh->pam_default_log);
break;
default:
/* XXX - I made this up */
return PAM_BAD_ITEM;
}
return PAM_SUCCESS;
}
/* added by AGM 1996/3/2 */
int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
{
const char *use_prompt;
int retval;
struct pam_message msg,*pmsg;
struct pam_response *resp;
D(("called."));
IF_NO_PAMH("pam_get_user", pamh, PAM_SYSTEM_ERR);
if (pamh->pam_conversation == NULL) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_get_user: no conv element in pamh");
return PAM_SERVICE_ERR;
}
if (user == NULL) { /* ensure the the module has suplied a destination */
pam_system_log(pamh, NULL, LOG_ERR,
"pam_get_user: nowhere to record username");
return PAM_PERM_DENIED;
} else
*user = NULL;
if (pamh->user) { /* have one so return it */
*user = pamh->user;
return PAM_SUCCESS;
}
/* will need a prompt */
use_prompt = prompt;
if (use_prompt == NULL) {
use_prompt = pamh->prompt;
if (use_prompt == NULL) {
use_prompt = PAM_DEFAULT_PROMPT;
}
}
/* If we are resuming an old conversation, we verify that the prompt
is the same. Anything else is an error. */
if (pamh->former.want_user) {
/* must have a prompt to resume with */
if (! pamh->former.prompt) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_get_user: failed to resume with prompt"
);
return PAM_ABORT;
}
/* must be the same prompt as last time */
if (strcmp(pamh->former.prompt, use_prompt)) {
pam_system_log(pamh, NULL, LOG_ERR,
"pam_get_user: resumed with different prompt");
return PAM_ABORT;
}
/* ok, we can resume where we left off last time */
pamh->former.want_user = PAM_FALSE;
_pam_overwrite(pamh->former.prompt);
_pam_drop(pamh->former.prompt);
}
/* converse with application -- prompt user for a username */
pmsg = &msg;
msg.msg_style = PAM_PROMPT_ECHO_ON;
msg.msg = use_prompt;
resp = NULL;
retval = pamh->pam_conversation->
conv(1, (const struct pam_message **) &pmsg, &resp,
pamh->pam_conversation->appdata_ptr);
if (retval == PAM_CONV_AGAIN) {
/* conversation function is waiting for an event - save state */
D(("conversation function is not ready yet"));
pamh->former.want_user = PAM_TRUE;
pamh->former.prompt = _pam_strdup(use_prompt);
} else if (resp == NULL) {
/*
* conversation should have given a response
*/
D(("pam_get_user: no response provided"));
retval = PAM_CONV_ERR;
} else if (retval == PAM_SUCCESS) { /* copy the username */
/*
* now we set the PAM_USER item -- this was missing from pre.53
* releases. However, reading the Sun manual, it is part of
* the standard API.
*/
RESET(pamh->user, resp->resp);
*user = pamh->user;
}
if (resp) {
/*
* note 'resp' is allocated by the application and is
* correctly free()'d here
*/
_pam_drop_reply(resp, 1);
}
return retval; /* pass on any error from conversation */
}

View File

@ -0,0 +1,425 @@
/*
* pam_log.c -- PAM system logging
*
* $Id$
*
* $Log$
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "pam_private.h"
#ifdef __hpux
# include <stdio.h>
# include <syslog.h>
# ifdef __STDC__
# ifndef __P
# define __P(p) p
# endif /* __P */
# include <stdarg.h>
# define VA_LOCAL_DECL va_list ap;
# define VA_START(f) va_start(ap, f)
# define VA_END va_end(ap)
# else /* __STDC__ */
# ifndef __P
# define __P(p) ()
# endif /* __P */
# include <varargs.h>
# define VA_LOCAL_DECL va_list ap;
# define VA_START(f) va_start(ap)
# define VA_END va_end(ap)
# endif /* __STDC__ */
/**************************************************************
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
**************************************************************/
static void dopr();
static char *end;
# ifndef _SCO_DS
/* VARARGS3 */
int
# ifdef __STDC__
snprintf(char *str, size_t count, const char *fmt, ...)
# else /* __STDC__ */
snprintf(str, count, fmt, va_alist)
char *str;
size_t count;
const char *fmt;
va_dcl
# endif /* __STDC__ */
{
int len;
VA_LOCAL_DECL
VA_START(fmt);
len = vsnprintf(str, count, fmt, ap);
VA_END;
return len;
}
# endif /* _SCO_DS */
int
# ifdef __STDC__
vsnprintf(char *str, size_t count, const char *fmt, va_list args)
# else /* __STDC__ */
vsnprintf(str, count, fmt, args)
char *str;
int count;
char *fmt;
va_list args;
# endif /* __STDC__ */
{
str[0] = 0;
end = str + count - 1;
dopr( str, fmt, args );
if (count > 0)
end[0] = 0;
return strlen(str);
}
/*
* dopr(): poor man's version of doprintf
*/
static void fmtstr __P((char *value, int ljust, int len, int zpad,
int maxwidth));
static void fmtnum __P((long value, int base, int dosign, int ljust, int len,
int zpad));
static void dostr __P(( char * , int ));
static char *output;
static void dopr_outch __P(( int c ));
static void
# ifdef __STDC__
dopr(char * buffer, const char * format, va_list args )
# else /* __STDC__ */
dopr( buffer, format, args )
char *buffer;
char *format;
va_list args;
# endif /* __STDC__ */
{
int ch;
long value;
int longflag = 0;
int pointflag = 0;
int maxwidth = 0;
char *strvalue;
int ljust;
int len;
int zpad;
output = buffer;
while( (ch = *format++) ){
switch( ch ){
case '%':
ljust = len = zpad = maxwidth = 0;
longflag = pointflag = 0;
nextch:
ch = *format++;
switch( ch ){
case 0:
dostr( "**end of format**" , 0);
return;
case '-': ljust = 1; goto nextch;
case '0': /* set zero padding if len not set */
if(len==0 && !pointflag) zpad = '0';
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
if (pointflag)
maxwidth = maxwidth*10 + ch - '0';
else
len = len*10 + ch - '0';
goto nextch;
case '*':
if (pointflag)
maxwidth = va_arg( args, int );
else
len = va_arg( args, int );
goto nextch;
case '.': pointflag = 1; goto nextch;
case 'l': longflag = 1; goto nextch;
case 'u': case 'U':
/*fmtnum(value,base,dosign,ljust,len,zpad) */
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 10,0, ljust, len, zpad ); break;
case 'o': case 'O':
/*fmtnum(value,base,dosign,ljust,len,zpad) */
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 8,0, ljust, len, zpad ); break;
case 'd': case 'D':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 10,1, ljust, len, zpad ); break;
case 'x':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 16,0, ljust, len, zpad ); break;
case 'X':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value,-16,0, ljust, len, zpad ); break;
case 's':
strvalue = va_arg( args, char *);
if (maxwidth > 0 || !pointflag) {
if (pointflag && len > maxwidth)
len = maxwidth; /* Adjust padding */
fmtstr( strvalue,ljust,len,zpad, maxwidth);
}
break;
case 'c':
ch = va_arg( args, int );
dopr_outch( ch ); break;
case '%': dopr_outch( ch ); continue;
default:
dostr( "???????" , 0);
}
break;
default:
dopr_outch( ch );
break;
}
}
*output = 0;
}
static void
fmtstr( value, ljust, len, zpad, maxwidth )
char *value;
int ljust, len, zpad, maxwidth;
{
int padlen, strlen; /* amount to pad */
if( value == 0 ){
value = "<NULL>";
}
for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
if (strlen > maxwidth && maxwidth)
strlen = maxwidth;
padlen = len - strlen;
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
while( padlen > 0 ) {
dopr_outch( ' ' );
--padlen;
}
dostr( value, maxwidth );
while( padlen < 0 ) {
dopr_outch( ' ' );
++padlen;
}
}
static void
fmtnum( value, base, dosign, ljust, len, zpad )
long value;
int base, dosign, ljust, len, zpad;
{
int signvalue = 0;
unsigned long uvalue;
char convert[20];
int place = 0;
int padlen = 0; /* amount to pad */
int caps = 0;
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
value, base, dosign, ljust, len, zpad )); */
uvalue = value;
if( dosign ){
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
}
}
if( base < 0 ){
caps = 1;
base = -base;
}
do{
convert[place++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")
[uvalue % (unsigned)base ];
uvalue = (uvalue / (unsigned)base );
}while(uvalue);
convert[place] = 0;
padlen = len - place;
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
convert,place,signvalue,padlen)); */
if( zpad && padlen > 0 ){
if( signvalue ){
dopr_outch( signvalue );
--padlen;
signvalue = 0;
}
while( padlen > 0 ){
dopr_outch( zpad );
--padlen;
}
}
while( padlen > 0 ) {
dopr_outch( ' ' );
--padlen;
}
if( signvalue ) dopr_outch( signvalue );
while( place > 0 ) dopr_outch( convert[--place] );
while( padlen < 0 ){
dopr_outch( ' ' );
++padlen;
}
}
static void
dostr( str , cut)
char *str;
int cut;
{
if (cut) {
while(*str && cut-- > 0) dopr_outch(*str++);
} else {
while(*str) dopr_outch(*str++);
}
}
static void
dopr_outch( c )
int c;
{
if( end == 0 || output < end )
*output++ = c;
}
int
# ifdef __STDC__
vsyslog(int priority, const char *fmt, ...)
# else /* __STDC__ */
vsyslog(priority, fmt, va_alist)
int priority;
const char *fmt;
va_dcl
# endif /* __STDC__ */
{
VA_LOCAL_DECL
char logbuf[BUFSIZ];
VA_START(fmt);
vsnprintf(logbuf, BUFSIZ, fmt, ap);
syslog(priority, "%s", logbuf);
VA_END;
}
#endif /* __hpux */
void pam_vsystem_log(const pam_handle_t *pamh,
const struct pam_log_state *log_state,
int priority, const char *format, va_list args)
{
const char *ident;
int option, facility;
D(("pam_vsystem_log called"));
/* make sure we have a log state to use */
if (NULL == log_state) {
if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
ident = pamh->pam_default_log.ident;
option = pamh->pam_default_log.option;
facility = pamh->pam_default_log.facility;
} else {
ident = PAM_LOG_STATE_IDENT;
option = PAM_LOG_STATE_OPTION;
facility = PAM_LOG_STATE_FACILITY;
}
openlog(ident, option, facility);
} else {
openlog(log_state->ident, log_state->option, log_state->facility);
}
vsyslog(priority, format, args);
closelog();
D(("done."));
}
void pam_system_log(const pam_handle_t *pamh,
const struct pam_log_state *log_state,
int priority, const char *format, ... )
{
const char *ident;
int option, facility;
va_list args;
D(("pam_system_log called"));
/* make sure we have a log state to use */
if (NULL == log_state) {
if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
ident = pamh->pam_default_log.ident;
option = pamh->pam_default_log.option;
facility = pamh->pam_default_log.facility;
} else {
ident = PAM_LOG_STATE_IDENT;
option = PAM_LOG_STATE_OPTION;
facility = PAM_LOG_STATE_FACILITY;
}
openlog(ident, option, facility);
} else {
openlog(log_state->ident, log_state->option, log_state->facility);
}
va_start(args, format);
vsyslog(priority, format, args);
va_end(args);
closelog();
D(("done."));
}
/*
* Recommended #defines to make porting legacy apps easier [Ed. at this
* point, the syslog() #define is breoken -- suggestions?]
*
* #ifdef PAM_LOG_STATE
* # define openlog(ident, option, facility) { \
* struct pam_log_state tmp_state; \
* tmp_state.ident = ident; \
* tmp_state.option = option; \
* tmp_state.facility = facility; \
* (void) pam_set_item(pamh, PAM_LOG_STATE, &tmp_state); \
* }
* # define syslog pam_system_log
* # define closelog()
* #endif
*/

View File

@ -0,0 +1,394 @@
/*
* $Id: pam_malloc.c,v 1.2 1996/12/01 03:14:13 morgan Exp $
*
* $Log: pam_malloc.c,v $
* Revision 1.2 1996/12/01 03:14:13 morgan
* use _pam_macros.h
*
* Revision 1.1 1996/11/10 21:26:11 morgan
* Initial revision
*
*/
/*
* This pair of files helps to locate memory leaks. It is a wrapper for
* the malloc family of calls. (Actutally, it currently only deals
* with calloc, malloc, realloc, free and exit)
*
* To use these functions the header "pam_malloc.h" must be included
* in all parts of the code (that use the malloc functions) and this
* file must be linked with the result. The pam_malloc_flags can be
* set from another function and determine the level of logging.
*
* The output is via the macros defined in _pam_macros.h
*
* It is a debugging tool and should be turned off in released code.
*
* This suite was written by Andrew Morgan <morgan@parc.power.net> for
* Linux-PAM.
*/
#ifndef DEBUG
#define DEBUG
#endif
#include "pam_private.h"
#include <security/pam_malloc.h>
#include <security/_pam_macros.h>
/* this must be done to stop infinite recursion! */
#undef malloc
#undef calloc
#undef free
#undef realloc
#undef exit
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*
* default debugging level
*/
int pam_malloc_flags = PAM_MALLOC_DEFAULT;
int pam_malloc_delay_length = 4;
#define on(x) ((pam_malloc_flags&(x))==(x))
/*
* the implementation
*/
static const char *last_fn=NULL;
static const char *last_file=NULL;
static const char *last_call=NULL;
static int last_line = 1;
#define err(x) { _pam_output_xdebug_info(); _pam_output_debug x ; }
static void set_last_(const char *x, const char *f
, const char *fn, const int l)
{
last_fn = x ? x : "error-in-pam_malloc..";
last_file = f ? f : "*bad-file*";
last_call = fn ? fn: "*bad-fn*";
last_line = l;
}
static void _pam_output_xdebug_info(void)
{
FILE *logfile;
int must_close = 1;
if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
logfile = stderr;
must_close = 0;
}
fprintf(logfile, "[%s:%s(%d)->%s()] ",
last_file, last_call, last_line, last_fn);
if (must_close) {
fflush(logfile);
fclose(logfile);
}
}
static void hinder(void)
{
if (on(PAM_MALLOC_PAUSE)) {
if (on(0)) err(("pause requested"));
sleep(pam_malloc_delay_length);
}
if (on(PAM_MALLOC_STOP)) {
if (on(0)) err(("stop requested"));
exit(1);
}
}
/*
* here are the memory pointer registering functions.. these actually
* use malloc(!) but that's ok! ;^)
*/
struct reference {
void *ptr; /* pointer */
int nelements; /* number of elements */
int size; /* - each of this size */
char *file; /* where it was requested - filename */
char *function; /* - function */
int line; /* - line number */
/*
* linking info
*/
struct reference *next;
};
static void _dump(const char *say, const struct reference *ref)
{
_pam_output_debug(" <%s: %p (#%d of %d) req. by %s(); %s line %d>\n"
, say
, ref->ptr,ref->nelements,ref->size
, ref->function,ref->file,ref->line);
}
static struct reference *root=NULL;
static char *_strdup(const char *x)
{
char *s;
s = (char *)malloc(strlen(x)+1);
if (s == NULL) {
if (on(0)) err(("_strdup failed"));
exit(1);
}
strcpy(s,x);
return s;
}
static void add_new_ref(void *new, int n, int size)
{
struct reference *ref=NULL;
ref = (struct reference *) malloc( sizeof(struct reference) );
if (new == NULL || ref == NULL) {
if (on(0)) err(("internal error {add_new_ref}"));
exit(1);
}
ref->ptr = new;
ref->nelements = n;
ref->size = size;
ref->file = _strdup(last_file);
ref->function = _strdup(last_call);
ref->line = last_line;
ref->next = root;
if (on(PAM_MALLOC_REQUEST)) {
_dump("new_ptr", ref);
}
root = ref;
}
static void del_old_ref(void *old)
{
struct reference *this,*last;
if (old == NULL) {
if (on(0)) err(("internal error {del_old_ref}"));
exit(1);
}
/* locate old pointer */
last = NULL;
this = root;
while (this) {
if (this->ptr == old)
break;
last = this;
this = this->next;
}
/* Did we find a reference ? */
if (this) {
if (on(PAM_MALLOC_FREE)) {
_dump("free old_ptr", this);
}
if (last == NULL) {
root = this->next;
} else {
last->next = this->next;
}
free(this->file);
free(this->function);
free(this);
} else {
if (on(0)) err(("ERROR!: bad memory"));
hinder();
}
}
static void verify_old_ref(void *old)
{
struct reference *this;
if (old == NULL) {
if (on(0)) err(("internal error {verify_old_ref}"));
exit(1);
}
/* locate old pointer */
this = root;
while (this) {
if (this->ptr == old)
break;
this = this->next;
}
/* Did we find a reference ? */
if (this) {
if (on(PAM_MALLOC_VERIFY)) {
_dump("verify_ptr", this);
}
} else {
if (on(0)) err(("ERROR!: bad request"));
hinder();
}
}
static void dump_memory_list(const char *dump)
{
struct reference *this;
this = root;
if (this) {
if (on(0)) err(("un-free()'d memory"));
while (this) {
_dump(dump, this);
this = this->next;
}
} else {
if (on(0)) err(("no memory allocated"));
}
}
/* now for the wrappers */
#define _fn(x) set_last_(x,file,fn,line)
void *pam_malloc(size_t size, const char *file, const char *fn, const int line)
{
void *new;
_fn("malloc");
if (on(PAM_MALLOC_FUNC)) err(("request for %d", size));
new = malloc(size);
if (new == NULL) {
if (on(PAM_MALLOC_FAIL)) err(("returned NULL"));
} else {
if (on(PAM_MALLOC_REQUEST)) err(("request new"));
add_new_ref(new, 1, size);
}
return new;
}
void *pam_calloc(size_t nelm, size_t size
, const char *file, const char *fn, const int line)
{
void *new;
_fn("calloc");
if (on(PAM_MALLOC_FUNC)) err(("request for %d of %d", nelm, size));
new = calloc(nelm,size);
if (new == NULL) {
if (on(PAM_MALLOC_FAIL)) err(("returned NULL"));
} else {
if (on(PAM_MALLOC_REQUEST)) err(("request new"));
add_new_ref(new, nelm, size);
}
return new;
}
void pam_free(void *ptr
, const char *file, const char *fn, const int line)
{
_fn("free");
if (on(PAM_MALLOC_FUNC)) err(("request to free %p", ptr));
if (ptr == NULL) {
if (on(PAM_MALLOC_NULL)) err(("passed NULL pointer"));
} else {
if (on(PAM_MALLOC_FREE)) err(("deleted old"));
del_old_ref(ptr);
free(ptr);
}
}
void *pam_memalign(size_t ali, size_t size
, const char *file, const char *fn, const int line)
{
_fn("memalign");
if (on(0)) err(("not implemented currently (Sorry)"));
exit(1);
}
void *pam_realloc(void *ptr, size_t size
, const char *file, const char *fn, const int line)
{
void *new;
_fn("realloc");
if (on(PAM_MALLOC_FUNC)) err(("resize %p to %d", ptr, size));
if (ptr == NULL) {
if (on(PAM_MALLOC_NULL)) err(("passed NULL pointer"));
} else {
verify_old_ref(ptr);
}
new = realloc(ptr, size);
if (new == NULL) {
if (on(PAM_MALLOC_FAIL)) err(("returned NULL"));
} else {
if (ptr) {
if (on(PAM_MALLOC_FREE)) err(("deleted old"));
del_old_ref(ptr);
} else {
if (on(PAM_MALLOC_NULL)) err(("old is NULL"));
}
if (on(PAM_MALLOC_REQUEST)) err(("request new"));
add_new_ref(new, 1, size);
}
return new;
}
void *pam_valloc(size_t size
, const char *file, const char *fn, const int line)
{
_fn("valloc");
if (on(0)) err(("not implemented currently (Sorry)"));
exit(1);
}
#include <alloca.h>
void *pam_alloca(size_t size
, const char *file, const char *fn, const int line)
{
_fn("alloca");
if (on(0)) err(("not implemented currently (Sorry)"));
exit(1);
}
void pam_exit(int i
, const char *file, const char *fn, const int line)
{
_fn("exit");
if (on(0)) err(("passed (%d)", i));
if (on(PAM_MALLOC_LEAKED)) {
dump_memory_list("leaked");
}
exit(i);
}
/* end of file */

Some files were not shown because too many files have changed in this diff Show More