aboutsummaryrefslogtreecommitdiff
path: root/contrib/libpam/modules
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpam/modules')
-rw-r--r--contrib/libpam/modules/Makefile90
-rw-r--r--contrib/libpam/modules/README2
-rw-r--r--contrib/libpam/modules/Simple.Rules92
-rw-r--r--contrib/libpam/modules/dont_makefile4
-rwxr-xr-xcontrib/libpam/modules/download-all30
-rwxr-xr-xcontrib/libpam/modules/install_conf49
-rw-r--r--contrib/libpam/modules/pam_access/Makefile110
-rw-r--r--contrib/libpam/modules/pam_access/README6
-rw-r--r--contrib/libpam/modules/pam_access/pam_access.c153
-rw-r--r--contrib/libpam/modules/pam_cracklib/Makefile104
-rw-r--r--contrib/libpam/modules/pam_cracklib/README18
-rw-r--r--contrib/libpam/modules/pam_cracklib/pam_cracklib.c433
-rw-r--r--contrib/libpam/modules/pam_deny/Makefile118
-rw-r--r--contrib/libpam/modules/pam_deny/README2
-rw-r--r--contrib/libpam/modules/pam_deny/pam_deny.c15
-rw-r--r--contrib/libpam/modules/pam_env/Makefile107
-rw-r--r--contrib/libpam/modules/pam_env/README6
-rw-r--r--contrib/libpam/modules/pam_env/pam_env.c186
-rw-r--r--contrib/libpam/modules/pam_env/pam_env.conf-example6
-rw-r--r--contrib/libpam/modules/pam_filter/Makefile64
-rw-r--r--contrib/libpam/modules/pam_filter/README2
-rw-r--r--contrib/libpam/modules/pam_filter/include/pam_filter.h4
-rw-r--r--contrib/libpam/modules/pam_filter/pam_filter.c18
-rw-r--r--contrib/libpam/modules/pam_filter/upperLOWER/Makefile33
-rw-r--r--contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c17
-rw-r--r--contrib/libpam/modules/pam_ftp/Makefile91
-rw-r--r--contrib/libpam/modules/pam_ftp/README26
-rw-r--r--contrib/libpam/modules/pam_ftp/pam_ftp.c52
-rw-r--r--contrib/libpam/modules/pam_group/Makefile113
-rw-r--r--contrib/libpam/modules/pam_group/group.conf2
-rw-r--r--contrib/libpam/modules/pam_group/pam_group.c41
-rw-r--r--contrib/libpam/modules/pam_issue/Makefile15
-rw-r--r--contrib/libpam/modules/pam_issue/pam_issue.c266
-rw-r--r--contrib/libpam/modules/pam_lastlog/Makefile101
-rw-r--r--contrib/libpam/modules/pam_lastlog/pam_lastlog.c17
-rw-r--r--contrib/libpam/modules/pam_limits/Makefile101
-rw-r--r--contrib/libpam/modules/pam_limits/README35
-rw-r--r--contrib/libpam/modules/pam_limits/limits.skel1
-rw-r--r--contrib/libpam/modules/pam_limits/pam_limits.c246
-rw-r--r--contrib/libpam/modules/pam_listfile/Makefile81
-rw-r--r--contrib/libpam/modules/pam_listfile/pam_listfile.c103
-rw-r--r--contrib/libpam/modules/pam_mail/Makefile102
-rw-r--r--contrib/libpam/modules/pam_mail/README17
-rw-r--r--contrib/libpam/modules/pam_mail/pam_mail.c246
-rw-r--r--contrib/libpam/modules/pam_mkhomedir/Makefile15
-rw-r--r--contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c370
-rw-r--r--contrib/libpam/modules/pam_motd/Makefile15
-rw-r--r--contrib/libpam/modules/pam_motd/pam_motd.c119
-rw-r--r--contrib/libpam/modules/pam_nologin/Makefile83
-rw-r--r--contrib/libpam/modules/pam_nologin/README2
-rw-r--r--contrib/libpam/modules/pam_nologin/pam_nologin.c16
-rw-r--r--contrib/libpam/modules/pam_permit/Makefile119
-rw-r--r--contrib/libpam/modules/pam_permit/README2
-rw-r--r--contrib/libpam/modules/pam_permit/pam_permit.c12
-rw-r--r--contrib/libpam/modules/pam_pwdb/BUGS7
-rw-r--r--contrib/libpam/modules/pam_pwdb/CHANGELOG2
-rw-r--r--contrib/libpam/modules/pam_pwdb/Makefile91
-rw-r--r--contrib/libpam/modules/pam_pwdb/README4
-rw-r--r--contrib/libpam/modules/pam_pwdb/TODO2
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5.c26
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5.h20
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5_crypt.c72
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_pwdb.c55
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c24
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c46
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_md.-c20
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c60
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c14
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c18
-rw-r--r--contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c39
-rw-r--r--contrib/libpam/modules/pam_pwdb/support.-c132
-rw-r--r--contrib/libpam/modules/pam_radius/Makefile12
-rw-r--r--contrib/libpam/modules/pam_radius/pam_radius.h9
-rw-r--r--contrib/libpam/modules/pam_rhosts/Makefile103
-rw-r--r--contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c56
-rw-r--r--contrib/libpam/modules/pam_rootok/Makefile106
-rw-r--r--contrib/libpam/modules/pam_rootok/README2
-rw-r--r--contrib/libpam/modules/pam_rootok/pam_rootok.c17
-rw-r--r--contrib/libpam/modules/pam_securetty/Makefile80
-rw-r--r--contrib/libpam/modules/pam_securetty/pam_securetty.c63
-rw-r--r--contrib/libpam/modules/pam_shells/Makefile81
-rw-r--r--contrib/libpam/modules/pam_shells/pam_shells.c18
-rw-r--r--contrib/libpam/modules/pam_stress/Makefile104
-rw-r--r--contrib/libpam/modules/pam_stress/README2
-rw-r--r--contrib/libpam/modules/pam_stress/pam_stress.c30
-rw-r--r--contrib/libpam/modules/pam_tally/Makefile54
-rw-r--r--contrib/libpam/modules/pam_tally/README52
-rw-r--r--contrib/libpam/modules/pam_tally/faillog.h55
-rw-r--r--contrib/libpam/modules/pam_tally/pam_tally.c150
-rw-r--r--contrib/libpam/modules/pam_tally/pam_tally_app.c7
-rw-r--r--contrib/libpam/modules/pam_time/Makefile120
-rw-r--r--contrib/libpam/modules/pam_time/README9
-rw-r--r--contrib/libpam/modules/pam_time/pam_time.c29
-rw-r--r--contrib/libpam/modules/pam_unix/CHANGELOG57
-rw-r--r--contrib/libpam/modules/pam_unix/Makefile168
-rw-r--r--contrib/libpam/modules/pam_unix/README58
-rw-r--r--contrib/libpam/modules/pam_unix/bigcrypt.c119
-rw-r--r--contrib/libpam/modules/pam_unix/lckpwdf.-c117
-rw-r--r--contrib/libpam/modules/pam_unix/md5.c256
-rw-r--r--contrib/libpam/modules/pam_unix/md5.h31
-rw-r--r--contrib/libpam/modules/pam_unix/md5_crypt.c149
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_acct.c195
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_auth.c347
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_passwd.c1615
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_sess.c214
-rw-r--r--contrib/libpam/modules/pam_unix/support.c958
-rw-r--r--contrib/libpam/modules/pam_unix/support.h144
-rw-r--r--contrib/libpam/modules/pam_unix/unix_chkpwd.c314
-rw-r--r--contrib/libpam/modules/pam_unix/yppasswd.h51
-rw-r--r--contrib/libpam/modules/pam_unix/yppasswd_xdr.c38
-rw-r--r--contrib/libpam/modules/pam_userdb/Makefile35
-rw-r--r--contrib/libpam/modules/pam_userdb/README30
-rw-r--r--contrib/libpam/modules/pam_userdb/conv.c125
-rw-r--r--contrib/libpam/modules/pam_userdb/create.pl23
-rw-r--r--contrib/libpam/modules/pam_userdb/pam_userdb.c304
-rw-r--r--contrib/libpam/modules/pam_userdb/pam_userdb.h61
-rw-r--r--contrib/libpam/modules/pam_warn/Makefile91
-rw-r--r--contrib/libpam/modules/pam_warn/README7
-rw-r--r--contrib/libpam/modules/pam_warn/pam_warn.c56
-rw-r--r--contrib/libpam/modules/pam_wheel/Makefile89
-rw-r--r--contrib/libpam/modules/pam_wheel/pam_wheel.c32
121 files changed, 6959 insertions, 4594 deletions
diff --git a/contrib/libpam/modules/Makefile b/contrib/libpam/modules/Makefile
index 0066fb473e0c..aece2068904c 100644
--- a/contrib/libpam/modules/Makefile
+++ b/contrib/libpam/modules/Makefile
@@ -1,89 +1,17 @@
-# $Id: Makefile,v 1.21 1997/04/05 06:44:43 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# Makefile
#
# This makefile controls the build process of shared and static PAM modules.
#
-# $Log: Makefile,v $
-# Revision 1.21 1997/04/05 06:44:43 morgan
-# pam_env and pam_tally added
-#
-# Revision 1.20 1997/02/15 18:57:11 morgan
-# fixed bash syntax
-#
-# Revision 1.19 1997/01/04 20:21:32 morgan
-# moved responsibility of conditional compilation to modules (more flexible)
-#
-# Revision 1.18 1996/12/01 03:34:40 morgan
-# update for .54
-#
-# Revision 1.17 1996/11/10 20:20:15 morgan
-# cross platform support and new modules
-#
-# Revision 1.16 1996/09/05 06:20:45 morgan
-# added two modules: listfile and shells
-#
-# Revision 1.15 1996/08/09 05:38:28 morgan
-# added new/proposed modules.
-# fixed makefile installation dependencies
-#
-# Revision 1.14 1996/07/08 00:00:33 morgan
-# added wheel and group modules
#
-MODDIRS=\
- pam_access \
- pam_afs \
- pam_afsauth \
- pam_afspass \
- pam_afstok \
- pam_cracklib \
- pam_deny \
- pam_desgold \
- pam_env \
- pam_filter \
- pam_ftp \
- pam_group \
- pam_kerberos \
- pam_krb4 \
- pam_lastlog \
- pam_listfile \
- pam_limits \
- pam_mail \
- pam_nologin \
- pam_opie \
- pam_passwd+ \
- pam_permit \
- pam_pwdb \
- pam_radius \
- pam_restrict \
- pam_rhosts \
- pam_rootok \
- pam_securetty \
- pam_shells \
- pam_sid \
- pam_skey \
- pam_skey2 \
- pam_stress \
- pam_syslog \
- pam_tally \
- pam_time \
- pam_unix \
- pam_warn \
- pam_wheel
+include ../Make.Rules
-
-# ////////////////////////////////////////////////////
-# // You should not modify anything below this line //
-# ////////////////////////////////////////////////////
-
-dummy:
- @echo "*** This is not a top-level Makefile! ***"
-
-# -----------------------------------------------------------
+MODDIRS=$(shell /bin/ls -d pam_*)
all:
- @echo modules for $(OS) are:
+ @echo modules sources available are:
@ls -d $(MODDIRS) 2>/dev/null ; echo :--------
@echo
ifdef STATIC
@@ -98,6 +26,9 @@ endif
} fi ; \
done
+download:
+ @./download-all
+
install:
for i in $(MODDIRS) ; do \
if [ -d $$i ]; then { \
@@ -123,10 +54,3 @@ clean: lclean
} fi ; \
done
-extraclean: lclean
- for i in $(MODDIRS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i extraclean ; \
- fi ; \
- done
-
diff --git a/contrib/libpam/modules/README b/contrib/libpam/modules/README
index 864159478c65..73d3cf0c2e49 100644
--- a/contrib/libpam/modules/README
+++ b/contrib/libpam/modules/README
@@ -1,7 +1,7 @@
This directory contains the modules.
If you want to reserve a module name please email <pam-list@redhat.com>
-and announce its name. Andrew Morgan, <morgan@parc.power.net>, will
+and announce its name. Andrew Morgan, <morgan@linux.kernel.org>, will
add it to the Makefile in the next release of Linux-PAM.
As of Linux-PAM-0.40 modules can optionally conform to the static
diff --git a/contrib/libpam/modules/Simple.Rules b/contrib/libpam/modules/Simple.Rules
new file mode 100644
index 000000000000..954641c668a3
--- /dev/null
+++ b/contrib/libpam/modules/Simple.Rules
@@ -0,0 +1,92 @@
+# $Id: Simple.Rules,v 1.3 2001/02/22 04:55:41 agmorgan Exp $
+#
+# For simple modules with no significant dependencies, set $(TITLE)
+# and include this file.
+#
+# There are a few ways to customize this set of rules. Namely, define
+#
+# $(MODULE_SIMPLE_EXTRACLEAN)
+# $(MODULE_SIMPLE_CLEAN)
+# $(MODULE_SIMPLE_REMOVE)
+# $(MODULE_SIMPLE_INSTALL)
+# $(MODULE_SIMPLE_EXTRALIBS) - other things to link with the module
+# $(MODULE_SIMPLE_EXTRAFILES) - other files to build (no .c suffix)
+#
+
+LIBFILES = $(TITLE) $(MODULE_SIMPLE_EXTRAFILES)
+LIBSRC = $(addsuffix .c,$(LIBFILES))
+LIBOBJ = $(addsuffix .o,$(LIBFILES))
+LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
+LIBOBJS = $(addprefix static/,$(LIBOBJ))
+
+ifdef DYNAMIC
+LIBSHARED = $(TITLE).so
+endif
+
+ifdef STATIC
+LIBSTATIC = lib$(TITLE).o
+endif
+
+####################### don't edit below #######################
+
+all: dirs $(LIBSHARED) $(LIBSTATIC) register
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
+
+static/%.o : %.c
+ $(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
+
+dirs:
+ifdef DYNAMIC
+ $(MKDIR) ./dynamic
+endif
+ifdef STATIC
+ $(MKDIR) ./static
+endif
+
+register:
+ifdef STATIC
+ ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+endif
+
+ifdef DYNAMIC
+$(LIBOBJD): $(LIBSRC)
+endif
+
+ifdef DYNAMIC
+$(LIBSHARED): $(LIBOBJD)
+ $(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C)
+
+endif
+
+ifdef STATIC
+$(LIBOBJS): $(LIBSRC)
+endif
+
+ifdef STATIC
+$(LIBSTATIC): $(LIBOBJS)
+ $(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS)
+endif
+
+install: all
+ $(MKDIR) $(FAKEROOT)$(SECUREDIR)
+ifdef DYNAMIC
+ $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
+endif
+ $(MODULE_SIMPLE_INSTALL)
+
+remove:
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ $(MODULE_SIMPLE_REMOVE)
+
+clean:
+ rm -f $(LIBOBJD) $(LIBOBJS) core *~
+ $(MODULE_SIMPLE_CLEAN)
+ rm -f *.a *.o *.so *.bak
+ rm -rf dynamic static
+ $(MODULE_SIMPLE_EXTRACLEAN)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
diff --git a/contrib/libpam/modules/dont_makefile b/contrib/libpam/modules/dont_makefile
index f256ce1b3a61..48307f02ecd4 100644
--- a/contrib/libpam/modules/dont_makefile
+++ b/contrib/libpam/modules/dont_makefile
@@ -1,4 +1,6 @@
#########################################################################
+# $Id: dont_makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
+#########################################################################
# This is a makefile that does nothing. It is designed to be included
# by module Makefile-s when they are not compatable with the local
# system
@@ -7,7 +9,7 @@
all:
@echo "This module will not be compiled on this system"
-extraclean: clean
+remove: clean
install: clean
diff --git a/contrib/libpam/modules/download-all b/contrib/libpam/modules/download-all
new file mode 100755
index 000000000000..9b6cf6558136
--- /dev/null
+++ b/contrib/libpam/modules/download-all
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# $Id: download-all,v 1.1.1.1 2000/06/20 22:11:29 agmorgan Exp $
+#
+cat <<EOT
+For a number of reasons it is not practical for Linux-PAM to be
+distributed with every module out there. However, this shell script
+is intended as a convenient way for users to download modules from the
+'net in some semiautomated fashion.
+
+Please feel free to send (pam-list@redhat.com) snippets of code that
+will help others to download and unpack your favorite module into the
+Linux-PAM source tree. Especially welcome are snippets of the
+following form:
+
+ncftp ftp://my.ftpsite.org/pub/fluff/pam_fluff.tar.gz
+rm -fr pam_fluff
+tar zvfx pam_fluff.tar.gz
+
+Cheers
+
+Andrew
+morgan@linux.kernel.org
+EOT
+
+# --- insert your snippets below ---
+
+# --- insert your snippets above ---
+
+exit 0
diff --git a/contrib/libpam/modules/install_conf b/contrib/libpam/modules/install_conf
new file mode 100755
index 000000000000..80f6be292d19
--- /dev/null
+++ b/contrib/libpam/modules/install_conf
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+FAKEROOT=$1
+CONFD=$1$2
+CONFILE=$1$3
+MODULE=$4
+CONF=$5
+
+IGNORE_AGE=./.ignore_age
+QUIET_INSTALL=../../.quiet_install
+
+echo
+
+if [ -f "$QUIET_INSTALL" ]; then
+ if [ ! -f "$CONFILE" ]; then
+ yes="y"
+ else
+ yes="skip"
+ fi
+elif [ -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 $MODULE configuration file already exists ($CONFILE)"
+ echo "Do you wish to copy the $CONF file in this distribution"
+ echo "to $CONFILE ? (y/n) [skip] "
+ read yes
+ else
+ yes="y"
+ fi
+else
+ yes="skip"
+fi
+
+if [ "$yes" = "y" ]; then
+ mkdir -p $CONFD
+ echo " copying $CONF to $CONFILE"
+ cp $CONF $CONFILE
+else
+ echo " Skipping $CONF installation"
+ if [ "$yes" = "n" ]; then
+ touch "$IGNORE_AGE"
+ fi
+fi
+
+echo
+
+exit 0
diff --git a/contrib/libpam/modules/pam_access/Makefile b/contrib/libpam/modules/pam_access/Makefile
index a3d684bb7179..88c02fee7b54 100644
--- a/contrib/libpam/modules/pam_access/Makefile
+++ b/contrib/libpam/modules/pam_access/Makefile
@@ -1,111 +1,21 @@
-# $Id: Makefile,v 1.1 1997/06/23 00:39:42 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.1 1997/06/23 00:39:42 morgan
-# Initial revision
-#
-#
-
-TITLE=pam_access
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/access.conf
-export CONFILE
-
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
+TITLE=pam_access
+LOCAL_CONFILE=./access.conf
+INSTALLED_CONFILE=$(SCONFIGD)/access.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_access/README b/contrib/libpam/modules/pam_access/README
index df10c269ec04..ddd4725f0e04 100644
--- a/contrib/libpam/modules/pam_access/README
+++ b/contrib/libpam/modules/pam_access/README
@@ -1,4 +1,8 @@
-# Description of its configuration file (/etc/security/access.conf):
+# Description of its configuration file
+#
+# (The default config file is "/etc/security/access.conf". This
+# default can be overridden with a module config argument
+# 'accessfile=<full-path>'):
#
# Login access control table.
#
diff --git a/contrib/libpam/modules/pam_access/pam_access.c b/contrib/libpam/modules/pam_access/pam_access.c
index 121333928a26..87ad708d81ed 100644
--- a/contrib/libpam/modules/pam_access/pam_access.c
+++ b/contrib/libpam/modules/pam_access/pam_access.c
@@ -5,12 +5,27 @@
* (I took login_access from logdaemon-5.6 and converted it to PAM
* using parts of pam_time code.)
*
+ ************************************************************************
+ * Copyright message from logdaemon-5.6 (original file name DISCLAIMER)
+ ************************************************************************
+ * Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+ * may be covered by other copyrights (as noted in the file itself.)
+ *
+ * This material was originally written and compiled by Wietse Venema at
+ * Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+ * 1992, 1993, 1994 and 1995.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this entire copyright notice is duplicated in all such
+ * copies.
+ *
+ * This software is provided "as is" and without any expressed or implied
+ * warranties, including, without limitation, the implied warranties of
+ * merchantibility and fitness for any particular purpose.
+ *************************************************************************
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -46,21 +61,6 @@ extern int gethostname(char *name, size_t len);
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-/* --- static functions for checking whether the user should be let in --- */
-
-static void _log_err(const char *format, ... )
-{
- va_list args;
-
- va_start(args, format);
- openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(LOG_ERR, format, args);
- va_end(args);
- closelog();
-}
-
-#define PAM_ACCESS_CONFIG CONFILE
-
int strcasecmp(const char *s1, const char *s2);
/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
@@ -79,10 +79,16 @@ int strcasecmp(const char *s1, const char *s2);
#define MAXHOSTNAMELEN 256
#endif
+#ifdef DEFAULT_CONF_FILE
+# define PAM_ACCESS_CONFIG DEFAULT_CONF_FILE
+#else
+# define PAM_ACCESS_CONFIG "/etc/security/access.conf"
+#endif
+
/* Delimiters for fields and for lists of users, ttys or hosts. */
-static char fs[] = ":"; /* field separator */
-static char sep[] = ", \t"; /* list-element separator */
+static const char fs[] = ":"; /* field separator */
+static const char sep[] = ", \t"; /* list-element separator */
/* Constants to be used in assignments only, not in comparisons... */
@@ -96,8 +102,50 @@ static char sep[] = ", \t"; /* list-element separator */
struct login_info {
struct passwd *user;
char *from;
+ const char *config_file;
+ const char *service;
};
+/* --- static functions for checking whether the user should be let in --- */
+
+static void _log_err(const char *format, ... )
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(LOG_ERR, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* Parse module config arguments */
+
+static int parse_args(struct login_info *loginfo, int argc, const char **argv)
+{
+ int i;
+
+ for (i=0; i<argc; ++i) {
+ if (!strncmp("accessfile=", argv[i], 11)) {
+ FILE *fp = fopen(11 + argv[i], "r");
+
+ if (fp) {
+ loginfo->config_file = 11 + argv[i];
+ fclose(fp);
+ } else {
+ _log_err("for service [%s] failed to open accessfile=[%s]"
+ , loginfo->service, 11 + argv[i]);
+ return 0;
+ }
+
+ } else {
+ _log_err("unrecognized option [%s]", argv[i]);
+ }
+ }
+
+ return 1; /* OK */
+}
+
typedef int match_func (char *, struct login_info *);
static int list_match (char *, struct login_info *,
@@ -108,23 +156,16 @@ static int string_match (char *, char *);
/* login_access - match username/group and host/tty with access control file */
-static int login_access(struct passwd *user, char *from)
+static int login_access(struct login_info *item)
{
- struct login_info item;
FILE *fp;
char line[BUFSIZ];
- char *perm; /* becomes permission field */
- char *users; /* becomes list of login names */
- char *froms; /* becomes list of terminals or hosts */
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
int match = NO;
int end;
- int lineno = 0; /* for diagnostics */
-
- /*
- * Bundle up the arguments to avoid unnecessary clumsiness lateron.
- */
- item.user = user;
- item.from = from;
+ int lineno = 0; /* for diagnostics */
/*
* Process the table one line at a time and stop at the first match.
@@ -134,12 +175,12 @@ static int login_access(struct passwd *user, char *from)
* non-existing table means no access control.
*/
- if ((fp = fopen(PAM_ACCESS_CONFIG, "r"))!=NULL) {
+ if ((fp = fopen(item->config_file, "r"))!=NULL) {
while (!match && fgets(line, sizeof(line), fp)) {
lineno++;
if (line[end = strlen(line) - 1] != '\n') {
_log_err("%s: line %d: missing newline or line too long",
- PAM_ACCESS_CONFIG, lineno);
+ item->config_file, lineno);
continue;
}
if (line[0] == '#')
@@ -153,19 +194,21 @@ static int login_access(struct passwd *user, char *from)
|| !(users = strtok((char *) 0, fs))
|| !(froms = strtok((char *) 0, fs))
|| strtok((char *) 0, fs)) {
- _log_err("%s: line %d: bad field count", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad field count",
+ item->config_file, lineno);
continue;
}
if (perm[0] != '+' && perm[0] != '-') {
- _log_err("%s: line %d: bad first field", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad first field",
+ item->config_file, lineno);
continue;
}
- match = (list_match(froms, &item, from_match)
- && list_match(users, &item, user_match));
+ match = (list_match(froms, item, from_match)
+ && list_match(users, item, user_match));
}
(void) fclose(fp);
} else if (errno != ENOENT) {
- _log_err("cannot open %s: %m", PAM_ACCESS_CONFIG);
+ _log_err("cannot open %s: %m", item->config_file);
}
return (match == 0 || (line[0] == '+'));
}
@@ -356,10 +399,17 @@ int strcasecmp(const char *s1, const char *s2)
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
- const char *user=NULL;
+ struct login_info loginfo;
+ const char *user=NULL, *service=NULL;
char *from=NULL;
struct passwd *user_pw;
+ if ((pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
+ != PAM_SUCCESS) || (service == NULL) || (*service == ' ')) {
+ _log_err("cannot find the service name");
+ return PAM_ABORT;
+ }
+
/* set username */
if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
@@ -398,8 +448,27 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
}
}
+
if ((user_pw=getpwnam(user))==NULL) return (PAM_USER_UNKNOWN);
- if (login_access(user_pw,from)) return (PAM_SUCCESS); else {
+
+ /*
+ * Bundle up the arguments to avoid unnecessary clumsiness later on.
+ */
+ loginfo.user = user_pw;
+ loginfo.from = from;
+ loginfo.service = service;
+ loginfo.config_file = PAM_ACCESS_CONFIG;
+
+ /* parse the argument list */
+
+ if (!parse_args(&loginfo, argc, argv)) {
+ _log_err("failed to parse the module arguments");
+ return PAM_ABORT;
+ }
+
+ if (login_access(&loginfo)) {
+ return (PAM_SUCCESS);
+ } else {
_log_err("access denied for user `%s' from `%s'",user,from);
return (PAM_PERM_DENIED);
}
diff --git a/contrib/libpam/modules/pam_cracklib/Makefile b/contrib/libpam/modules/pam_cracklib/Makefile
index 668f2f846296..371ac0a86c3e 100644
--- a/contrib/libpam/modules/pam_cracklib/Makefile
+++ b/contrib/libpam/modules/pam_cracklib/Makefile
@@ -1,110 +1,32 @@
#
+# $Id: Makefile,v 1.3 2001/02/10 22:15:23 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10
+# Created by Andrew Morgan <morgan@kernel.org> 2000/10/08
#
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-#
-# here you should make default variable defines...
-#
-MKDIR=mkdir -p
-LD_D=gcc -shared -Xlinker -x
-INSTALL=install
-SECUREDIR=/usr/lib/security
-#
-HAVE_CRACKLIB=yes
-endif
-
-ifeq ($(HAVE_CRACKLIB),yes)
+include ../../Make.Rules
TITLE=pam_cracklib
-CRACKLIB=-lcrack
-CRACKLIB_DICTPATH=/usr/lib/cracklib_dict
-#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+ifeq ($(HAVE_LIBCRACK),yes)
+BUILD_THIS_MODULE=yes
+MODULE_SIMPLE_EXTRALIBS=-lcrack
-ifdef CRACKLIB_DICTPATH
+# These two should really be provided by ../../pam_aconf.h
CFLAGS+=-DCRACKLIB_DICTPATH=\"$(CRACKLIB_DICTPATH)\"
-endif
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+ifeq ($(HAVE_LIBCRYPT),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lcrypt
endif
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC) Makefile
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(CRACKLIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
endif
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+ifeq ($(BUILD_THIS_MODULE),yes)
+ include ../Simple.Rules
else
-
-include ../dont_makefile
-
+ include ../dont_makefile
endif
diff --git a/contrib/libpam/modules/pam_cracklib/README b/contrib/libpam/modules/pam_cracklib/README
index e4b02731b523..69662f7385b3 100644
--- a/contrib/libpam/modules/pam_cracklib/README
+++ b/contrib/libpam/modules/pam_cracklib/README
@@ -13,9 +13,25 @@ RECOGNIZED ARGUMENTS:
retry=N Prompt user at most N times before returning with
error. Default N=1.
+ difok=N How many characters can be the same in the new
+ password relative to the old
+ difignore=N How many characters long should the password be
+ before we ignore difok.
+
+ minlen=N The minimum simplicity count for a good password.
+
+ dcredit=N
+ ucredit=N
+ lcredit=N
+ ocredit=N Weight, digits, upper, lower, other characters with
+ count N. Use these values to compute the
+ 'unsimplicity' of the password.
+
+ use_authtok Get the proposed password from PAM_AUTHTOK
+
MODULE SERVICES PROVIDED:
passwd chauthtok
AUTHOR:
- Cristian Gafton <gafton@sorosis.ro>
+ Cristian Gafton <gafton@redhat.com>
diff --git a/contrib/libpam/modules/pam_cracklib/pam_cracklib.c b/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
index 3400dfb25209..07725db7ee7b 100644
--- a/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
+++ b/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
@@ -29,8 +29,12 @@
* S.A.G. in the section on the cracklib module.
*/
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
-#define __USE_BSD
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
@@ -43,7 +47,7 @@
extern char *FascistCheck(char *pw, const char *dictpath);
#ifndef CRACKLIB_DICTPATH
-#define CRACKLIB_DICTPATH "/usr/lib/cracklib_dict"
+#define CRACKLIB_DICTPATH "/usr/share/dict/cracklib_dict"
#endif
#define PROMPT1 "New %s password: "
@@ -82,20 +86,31 @@ static void _pam_log(int err, const char *format, ...)
/* argument parsing */
#define PAM_DEBUG_ARG 0x0001
-/* module data - AGM: please remove these static variables... PAM was
- * designed to be reentrant based soley on a unique pamh... this
- * breaks that. */
-
-static int retry_times = 0;
-static int diff_ok = 10;
-static int min_length = 9;
-static int dig_credit = 1;
-static int up_credit = 1;
-static int low_credit = 1;
-static int oth_credit = 1;
-static char prompt_type[BUFSIZ];
+struct cracklib_options {
+ int retry_times;
+ int diff_ok;
+ int diff_ignore;
+ int min_length;
+ int dig_credit;
+ int up_credit;
+ int low_credit;
+ int oth_credit;
+ int use_authtok;
+ char prompt_type[BUFSIZ];
+};
-static int _pam_parse(int argc, const char **argv)
+#define CO_RETRY_TIMES 1
+#define CO_DIFF_OK 10
+#define CO_DIFF_IGNORE 23
+#define CO_MIN_LENGTH 9
+# define CO_MIN_LENGTH_BASE 5
+#define CO_DIG_CREDIT 1
+#define CO_UP_CREDIT 1
+#define CO_LOW_CREDIT 1
+#define CO_OTH_CREDIT 1
+#define CO_USE_AUTHTOK 0
+
+static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv)
{
int ctrl=0;
@@ -108,35 +123,41 @@ static int _pam_parse(int argc, const char **argv)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
else if (!strncmp(*argv,"type=",5))
- strcpy(prompt_type, *argv+5);
+ strcpy(opt->prompt_type, *argv+5);
else if (!strncmp(*argv,"retry=",6)) {
- retry_times = strtol(*argv+6,&ep,10);
- if (!ep || (retry_times < 1))
- retry_times = 1;
+ opt->retry_times = strtol(*argv+6,&ep,10);
+ if (!ep || (opt->retry_times < 1))
+ opt->retry_times = CO_RETRY_TIMES;
} else if (!strncmp(*argv,"difok=",6)) {
- diff_ok = strtol(*argv+6,&ep,10);
- if (!ep || (diff_ok < 0))
- diff_ok = 10;
+ opt->diff_ok = strtol(*argv+6,&ep,10);
+ if (!ep || (opt->diff_ok < 0))
+ opt->diff_ok = CO_DIFF_OK;
+ } else if (!strncmp(*argv,"difignore=",10)) {
+ opt->diff_ignore = strtol(*argv+10,&ep,10);
+ if (!ep || (opt->diff_ignore < 0))
+ opt->diff_ignore = CO_DIFF_IGNORE;
} else if (!strncmp(*argv,"minlen=",7)) {
- min_length = strtol(*argv+7,&ep,10);
- if (!ep || (min_length < 5))
- min_length = 5;
+ opt->min_length = strtol(*argv+7,&ep,10);
+ if (!ep || (opt->min_length < CO_MIN_LENGTH_BASE))
+ opt->min_length = CO_MIN_LENGTH_BASE;
} else if (!strncmp(*argv,"dcredit=",8)) {
- dig_credit = strtol(*argv+8,&ep,10);
- if (!ep || (dig_credit < 0))
- dig_credit = 0;
+ opt->dig_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->dig_credit < 0))
+ opt->dig_credit = 0;
} else if (!strncmp(*argv,"ucredit=",8)) {
- up_credit = strtol(*argv+8,&ep,10);
- if (!ep || (up_credit < 0))
- up_credit = 0;
+ opt->up_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->up_credit < 0))
+ opt->up_credit = 0;
} else if (!strncmp(*argv,"lcredit=",8)) {
- low_credit = strtol(*argv+8,&ep,10);
- if (!ep || (low_credit < 0))
- low_credit = 0;
+ opt->low_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->low_credit < 0))
+ opt->low_credit = 0;
} else if (!strncmp(*argv,"ocredit=",8)) {
- oth_credit = strtol(*argv+8,&ep,10);
- if (!ep || (oth_credit < 0))
- oth_credit = 0;
+ opt->oth_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->oth_credit < 0))
+ opt->oth_credit = 0;
+ } else if (!strncmp(*argv,"use_authtok",11)) {
+ opt->use_authtok = 1;
} else {
_pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
}
@@ -216,32 +237,36 @@ static int palindrome(const char *old, const char *new)
}
/*
- * more than half of the characters are different ones.
- * or at least diff_ok are different
- * NOTE that the defaults are NOT the same as befor this
- * change. as long as there are at least 10 different bytes
- * in a new password it will now pass even if the password
- * is longer than 20 bytes (MD5)
+ * This is a reasonably severe check for a different selection of characters
+ * in the old and new passwords.
*/
-static int similiar(const char *old, const char *new)
+static int similar(struct cracklib_options *opt,
+ const char *old, const char *new)
{
- int i, j;
+ int i, j;
- for (i = j = 0;new[i] && old[i];i++)
- if (strchr (new, old[i]))
- j++;
+ for (i = j = 0; old[i]; i++) {
+ if (strchr (new, old[i])) {
+ j++;
+ }
+ }
- if (j >= diff_ok || i >= j * 2)
- return 0;
+ if (((i-j) >= opt->diff_ok)
+ || (strlen(new) >= (j * 2))
+ || (strlen(new) >= opt->diff_ignore)) {
+ /* passwords are not very similar */
+ return 0;
+ }
- return 1;
+ /* passwords are too similar */
+ return 1;
}
/*
* a nice mix of characters.
*/
-static int simple(const char *old, const char *new)
+static int simple(struct cracklib_options *opt, const char *old, const char *new)
{
int digits = 0;
int uppers = 0;
@@ -269,19 +294,19 @@ static int simple(const char *old, const char *new)
* defaults cause the effect to be the same as before the change
*/
- if (digits > dig_credit)
- digits = dig_credit;
+ if (digits > opt->dig_credit)
+ digits = opt->dig_credit;
- if (uppers > up_credit)
- uppers = up_credit;
+ if (uppers > opt->up_credit)
+ uppers = opt->up_credit;
- if (lowers > low_credit)
- lowers = low_credit;
+ if (lowers > opt->low_credit)
+ lowers = opt->low_credit;
- if (others > oth_credit)
- others = oth_credit;
+ if (others > opt->oth_credit)
+ others = opt->oth_credit;
- size = min_length;
+ size = opt->min_length;
size -= digits;
size -= uppers;
size -= lowers;
@@ -302,7 +327,7 @@ static char * str_lower(char *string)
return string;
}
-static const char * password_check(const char *old, const char *new)
+static const char * password_check(struct cracklib_options *opt, const char *old, const char *new)
{
const char *msg = NULL;
char *oldmono, *newmono, *wrapped;
@@ -324,10 +349,10 @@ static const char * password_check(const char *old, const char *new)
if (!msg && strcmp(oldmono, newmono) == 0)
msg = "case changes only";
- if (!msg && similiar(oldmono, newmono))
- msg = "is too similiar to the old one";
+ if (!msg && similar(opt, oldmono, newmono))
+ msg = "is too similar to the old one";
- if (!msg && simple(old, new))
+ if (!msg && simple(opt, old, new))
msg = "is too simple";
if (!msg && strstr(wrapped, newmono))
@@ -344,12 +369,51 @@ static const char * password_check(const char *old, const char *new)
}
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+
+static const char * check_old_password(const char *forwho, const char *newpass)
+{
+ static char buf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas;
+ const char *msg = NULL;
+ FILE *opwfile;
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL)
+ return NULL;
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf)-1] = '\0';
+ s_luser = strtok(buf, ":,");
+ s_uid = strtok(NULL, ":,");
+ s_npas = strtok(NULL, ":,");
+ s_pas = strtok(NULL, ":,");
+ while (s_pas != NULL) {
+ if (!strcmp(crypt(newpass, s_pas), s_pas)) {
+ msg = "has been already used";
+ break;
+ }
+ s_pas = strtok(NULL, ":,");
+ }
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ return msg;
+}
+
+
static int _pam_unix_approve_pass(pam_handle_t *pamh,
unsigned int ctrl,
+ struct cracklib_options *opt,
const char *pass_old,
const char *pass_new)
{
const char *msg = NULL;
+ const char *user;
+ int retval;
if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) {
if (ctrl && PAM_DEBUG_ARG)
@@ -364,7 +428,18 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh,
* if one wanted to hardwire authentication token strength
* checking this would be the place
*/
- msg = password_check(pass_old,pass_new);
+ msg = password_check(opt, pass_old,pass_new);
+ if (!msg) {
+ retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ if (retval != PAM_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_ERR,"Can not get username");
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+ msg = check_old_password(user, pass_new);
+ }
+
if (msg) {
char remark[BUFSIZ];
@@ -387,14 +462,24 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
unsigned int ctrl;
+ struct cracklib_options options;
+
+ options.retry_times = CO_RETRY_TIMES;
+ options.diff_ok = CO_DIFF_OK;
+ options.diff_ignore = CO_DIFF_IGNORE;
+ options.min_length = CO_MIN_LENGTH;
+ options.dig_credit = CO_DIG_CREDIT;
+ options.up_credit = CO_UP_CREDIT;
+ options.low_credit = CO_LOW_CREDIT;
+ options.oth_credit = CO_OTH_CREDIT;
+ options.use_authtok = CO_USE_AUTHTOK;
+ memset(options.prompt_type, 0, BUFSIZ);
- retry_times = 1;
- memset(prompt_type,0,sizeof(prompt_type));
- ctrl = _pam_parse(argc, argv);
+ ctrl = _pam_parse(&options, argc, argv);
D(("called."));
- if (!prompt_type[0])
- strcpy(prompt_type,"UNIX");
+ if (!options.prompt_type[0])
+ strcpy(options.prompt_type,"UNIX");
if (flags & PAM_PRELIM_CHECK) {
/* Check for passwd dictionary */
@@ -421,7 +506,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
} else if (flags & PAM_UPDATE_AUTHTOK) {
int retval;
char *token1, *token2, *oldtoken;
- const char *item;
struct pam_message msg[1],*pmsg[1];
struct pam_response *resp;
const char *cracklib_dictpath = CRACKLIB_DICTPATH;
@@ -443,7 +527,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
*/
token1 = token2 = NULL;
- if (!retry_times) {
+ if (!options.retry_times) {
D(("returning %s because maxtries reached",
pam_strerror(pamh, retval)));
return retval;
@@ -457,33 +541,51 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
* set PAM_AUTHTOK and return
*/
- /* Prepare to ask the user for the first time */
- memset(prompt,0,sizeof(prompt));
- sprintf(prompt,PROMPT1,prompt_type);
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
- resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token1 = x_strdup(resp[0].resp);
- if (token1 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 1");
- retval = PAM_AUTHTOK_RECOVER_ERR;
+ if (options.use_authtok == 1) {
+ const char *item = NULL;
+
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &item);
+ if (retval != PAM_SUCCESS) {
+ /* very strange. */
+ _pam_log(LOG_ALERT
+ ,"pam_get_item returned error to pam_cracklib"
+ );
+ } else if (item != NULL) { /* we have a password! */
+ token1 = x_strdup(item);
+ item = NULL;
+ } else {
+ retval = PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ }
+
+ } else {
+ /* Prepare to ask the user for the first time */
+ memset(prompt,0,sizeof(prompt));
+ sprintf(prompt,PROMPT1,options.prompt_type);
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = prompt;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+ if (resp != NULL) {
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token1 = x_strdup(resp[0].resp);
+ if (token1 == NULL) {
+ _pam_log(LOG_NOTICE,
+ "could not recover authentication token 1");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ }
}
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ */
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS) ?
+ PAM_AUTHTOK_RECOVER_ERR:retval ;
}
- /*
- * tidy up the conversation (resp_retcode) is ignored
- */
- _pam_drop_reply(resp, 1);
- } else {
- retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
- }
+ }
if (retval != PAM_SUCCESS) {
if (ctrl && PAM_DEBUG_ARG)
@@ -512,13 +614,14 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* check it for strength too... */
D(("for strength"));
if (oldtoken) {
- retval = _pam_unix_approve_pass(pamh,ctrl,
+ retval = _pam_unix_approve_pass(pamh,ctrl,&options,
oldtoken,token1);
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
retval = PAM_AUTHTOK_ERR;
else
retval = PAM_SUCCESS;
+ }
}
}
}
@@ -534,77 +637,81 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
/* Now we have a good passwd. Ask for it once again */
-
- bzero(prompt,sizeof(prompt));
- sprintf(prompt,PROMPT2,prompt_type);
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
- resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token2 = x_strdup(resp[0].resp);
- if (token2 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 2");
- retval = PAM_AUTHTOK_RECOVER_ERR;
+
+ if (options.use_authtok == 0) {
+ bzero(prompt,sizeof(prompt));
+ sprintf(prompt,PROMPT2,options.prompt_type);
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = prompt;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+ if (resp != NULL) {
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token2 = x_strdup(resp[0].resp);
+ if (token2 == NULL) {
+ _pam_log(LOG_NOTICE,
+ "could not recover authentication token 2");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ }
}
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ */
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS) ?
+ PAM_AUTHTOK_RECOVER_ERR:retval ;
}
- /*
- * tidy up the conversation (resp_retcode) is ignored
- */
- _pam_drop_reply(resp, 1);
- } else {
- retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
- }
- if (retval != PAM_SUCCESS) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG
- ,"unable to obtain the password a second time");
- continue;
- }
+ if (retval != PAM_SUCCESS) {
+ if (ctrl && PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG
+ ,"unable to obtain the password a second time");
+ continue;
+ }
- /* Hopefully now token1 and token2 the same password ... */
- if (strcmp(token1,token2) != 0) {
- /* tell the user */
- make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS);
- token1 = _pam_delete(token1);
- token2 = _pam_delete(token2);
- pam_set_item(pamh, PAM_AUTHTOK, NULL);
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE,"Password mistyped");
- retval = PAM_AUTHTOK_RECOVER_ERR;
- continue;
- }
+ /* Hopefully now token1 and token2 the same password ... */
+ if (strcmp(token1,token2) != 0) {
+ /* tell the user */
+ make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS);
+ token1 = _pam_delete(token1);
+ token2 = _pam_delete(token2);
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_NOTICE,"Password mistyped");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ continue;
+ }
- /* Yes, the password was typed correct twice
- * we store this password as an item
- */
+ /* Yes, the password was typed correct twice
+ * we store this password as an item
+ */
- retval = pam_set_item(pamh, PAM_AUTHTOK, token1);
- /* clean it up */
- token1 = _pam_delete(token1);
- token2 = _pam_delete(token2);
- if (
- (retval != PAM_SUCCESS) ||
- (
- (
- retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item)
- ) != PAM_SUCCESS
- )
- ) {
- _pam_log(LOG_CRIT, "error manipulating password");
- continue;
+ {
+ const char *item = NULL;
+
+ retval = pam_set_item(pamh, PAM_AUTHTOK, token1);
+
+ /* clean up */
+ token1 = _pam_delete(token1);
+ token2 = _pam_delete(token2);
+
+ if ( (retval != PAM_SUCCESS) ||
+ ((retval = pam_get_item(pamh, PAM_AUTHTOK,
+ (const void **)&item)
+ ) != PAM_SUCCESS) ) {
+ _pam_log(LOG_CRIT, "error manipulating password");
+ continue;
+ }
+ item = NULL; /* break link to password */
+ return PAM_SUCCESS;
+ }
}
- item = NULL; /* break link to password */
- return PAM_SUCCESS;
- } while (retry_times--);
+ } while (options.retry_times--);
} else {
if (ctrl & PAM_DEBUG_ARG)
diff --git a/contrib/libpam/modules/pam_deny/Makefile b/contrib/libpam/modules/pam_deny/Makefile
index 02506cb38122..2fdd6e1111a5 100644
--- a/contrib/libpam/modules/pam_deny/Makefile
+++ b/contrib/libpam/modules/pam_deny/Makefile
@@ -1,125 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:43:41 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:43:41 morgan
-# full-source-tree and fakeroot
-#
-# Revision 1.6 1997/02/15 19:04:27 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:11:48 morgan
-# crossplatform support
-#
-# Revision 1.4 1996/09/05 06:50:12 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:48:38 morgan
-# make dynamic and static dirs
-#
-# Revision 1.2 1996/05/26 04:00:16 morgan
-# changes for automated static/dynamic modules
-#
-# Revision 1.1 1996/03/16 17:47:36 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-#
+include ../../Make.Rules
TITLE=pam_deny
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_deny/README b/contrib/libpam/modules/pam_deny/README
index 4f7f6de664fe..2eb96d4e35d1 100644
--- a/contrib/libpam/modules/pam_deny/README
+++ b/contrib/libpam/modules/pam_deny/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/03/16 18:11:12 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:33 agmorgan Exp $
#
this module always fails, it ignores all options.
diff --git a/contrib/libpam/modules/pam_deny/pam_deny.c b/contrib/libpam/modules/pam_deny/pam_deny.c
index 76ba24d3fd90..8be1a8a87f55 100644
--- a/contrib/libpam/modules/pam_deny/pam_deny.c
+++ b/contrib/libpam/modules/pam_deny/pam_deny.c
@@ -1,23 +1,10 @@
/* pam_permit module */
/*
- * $Id: pam_deny.c,v 1.4 1997/02/15 19:05:15 morgan Exp $
+ * $Id: pam_deny.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
*
- * $Log: pam_deny.c,v $
- * Revision 1.4 1997/02/15 19:05:15 morgan
- * fixed email
- *
- * Revision 1.3 1996/06/02 08:06:19 morgan
- * changes for new static protocol
- *
- * Revision 1.2 1996/05/26 04:01:12 morgan
- * added static support
- *
- * Revision 1.1 1996/03/16 17:47:36 morgan
- * Initial revision
- *
*/
/*
diff --git a/contrib/libpam/modules/pam_env/Makefile b/contrib/libpam/modules/pam_env/Makefile
index df363bc9536b..189f1ee3fe6a 100644
--- a/contrib/libpam/modules/pam_env/Makefile
+++ b/contrib/libpam/modules/pam_env/Makefile
@@ -1,107 +1,22 @@
#
-# $Id: Makefile,v 1.1 1997/04/05 06:42:35 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.1 1997/04/05 06:42:35 morgan
-# Initial revision
-#
-# Revision 1.1 1997/01/04 20:32:52 morgan
-# Initial revision
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-# Adaptations by Dave Kinclea and Cristian Gafton
-#
-
-TITLE=pam_env
-
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/pam_env.conf
-export CONFILE
-
-#ifeq ($(HAVE_PWDBLIB),yes)
-#CFLAGS += -DWANT_PWDB
-#EXTRALIB = -lpwdb
-#endif
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+include ../../Make.Rules
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(EXTRALIB)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
+TITLE=pam_env
+LOCAL_CONFILE=./pam_env.conf-example
+INSTALLED_CONFILE=$(SCONFIGD)/pam_env.conf
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
+CFLAGS += $(DEFS)
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_env/README b/contrib/libpam/modules/pam_env/README
index d6e959cdbee5..5053618a7835 100644
--- a/contrib/libpam/modules/pam_env/README
+++ b/contrib/libpam/modules/pam_env/README
@@ -1,6 +1,6 @@
-# $Date: 1997/04/05 06:42:35 $
-# $Author: morgan $
-# $Id: README,v 1.1 1997/04/05 06:42:35 morgan Exp $
+# $Date: 2000/06/20 22:11:33 $
+# $Author: agmorgan $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:33 agmorgan Exp $
#
# This is the configuration file for pam_env, a PAM module to load in
# a configurable list of environment variables for a
diff --git a/contrib/libpam/modules/pam_env/pam_env.c b/contrib/libpam/modules/pam_env/pam_env.c
index bd0879c52283..5f5aa815e6be 100644
--- a/contrib/libpam/modules/pam_env/pam_env.c
+++ b/contrib/libpam/modules/pam_env/pam_env.c
@@ -1,59 +1,21 @@
/* pam_mail module */
/*
- * $Id: pam_env.c,v 1.1 1997/04/05 06:42:35 morgan Exp morgan $
+ * $Id: pam_env.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* Written by Dave Kinchlea <kinch@kinch.ark.com> 1997/01/31
* Inspired by Andrew Morgan <morgan@parc.power.net, who also supplied the
* template for this file (via pam_mail)
- *
- * $Log: pam_env.c,v $
- * Revision 1.1 1997/04/05 06:42:35 morgan
- * Initial revision
- *
- * Revision 0.6 1997/02/04 17:58:27 kinch
- * Debugging code cleaned up, lots added (whereever _log_err called) some removed
- *
- * Revision 0.5 1997/02/04 17:20:30 kinch
- * Changed default config file
- * Removed bogus message in pam_sm_authenticate()
- * Added back support in pam_sm_session(), this could conceivably be used
- * both as an auth_setcred and a session module
- *
- * Revision 0.4 1997/02/04 07:34:15 kinch
- * Fixed dealing with escaped '$' and '@' characters
- * This is now an pam_sm_setcred module to work closer to the RFC model
- * though this whole thing seems to have little to do with Authentication
- *
- * Revision 0.3 1997/02/04 04:53:15 kinch
- * Removed bogus space in PAM_ENV_SILENT
- * Removed line that added a space when allowing for escaped newlines, that
- * is not what we want at all, if we want a space, we can add one.
- * Changed a PAM_ABORT to PAM_BUF_ERR for a malloc failure
- * Changed bogus PAM_RUSER to PAM_RHOST
- *
- * Revision 0.2 1997/02/03 23:31:26 kinch
- * Lots of D(()) debugging code added, probably too much actually.
- * This now seems to work for all cases I can think of
- * Lots of little code changes but nothing major and no function
- * interface changes, largest change has to do with adding the
- * logic to get &quote hack to make it through all the code. Probably
- * ought to have done this with a global flag for each of defval and
- * override - it would have been cleaner.
- *
- * Revision 0.1 1997/02/03 01:39:06 kinch
- * Initial code, it compiles cleanly but has not been tested at all.
- *
*/
#ifndef DEFAULT_CONF_FILE
#define DEFAULT_CONF_FILE "/etc/security/pam_env.conf"
#endif
-#ifdef linux
-#define _GNU_SOURCE
-#include <features.h>
-#endif
+#define DEFAULT_ETC_ENVFILE "/etc/environment"
+#define DEFAULT_READ_ENVFILE 1
+
+#include <security/_pam_aconf.h>
#include <ctype.h>
#include <errno.h>
@@ -67,10 +29,6 @@
#include <sys/types.h>
#include <unistd.h>
-#ifdef WANT_PWDB
-#include <pwdb/pwdb_public.h>
-#endif
-
/*
* here, we make a definition for the externally accessible function
* in this file (this definition is required for static a module
@@ -132,11 +90,13 @@ static void _log_err(int err, const char *format, ...)
/* argument parsing */
-#define PAM_DEBUG_ARG 01
-#define PAM_NEW_CONF_FILE 02
-#define PAM_ENV_SILENT 04
+#define PAM_DEBUG_ARG 0x01
+#define PAM_NEW_CONF_FILE 0x02
+#define PAM_ENV_SILENT 0x04
+#define PAM_NEW_ENV_FILE 0x10
-static int _pam_parse(int flags, int argc, const char **argv, char **conffile)
+static int _pam_parse(int flags, int argc, const char **argv, char **conffile,
+ char **envfile, int *readenv)
{
int ctrl=0;
@@ -157,9 +117,19 @@ static int _pam_parse(int flags, int argc, const char **argv, char **conffile)
_log_err(LOG_CRIT,
"Configuration file specification missing argument - ignored");
}
- } else {
+ } else if (!strncmp(*argv,"envfile=",8)) {
+ *envfile = x_strdup(8+*argv);
+ if (*envfile != NULL) {
+ D(("new Env File: %s", *envfile));
+ ctrl |= PAM_NEW_ENV_FILE;
+ } else {
+ _log_err(LOG_CRIT,
+ "Env file specification missing argument - ignored");
+ }
+ } else if (!strncmp(*argv,"readenv=",8))
+ *readenv = atoi(8+*argv);
+ else
_log_err(LOG_ERR,"pam_parse: unknown option; %s",*argv);
- }
}
return ctrl;
@@ -192,7 +162,7 @@ static int _parse_config_file(pam_handle_t *pamh, int ctrl, char **conffile)
if ((conf = fopen(file,"r")) == NULL) {
_log_err(LOG_ERR, "Unable to open config file: %s",
strerror(errno));
- return PAM_ABORT;
+ return PAM_IGNORE;
}
/* _pam_assemble_line will provide a complete line from the config file, with all
@@ -230,6 +200,88 @@ static int _parse_config_file(pam_handle_t *pamh, int ctrl, char **conffile)
return (retval<0?PAM_ABORT:PAM_SUCCESS);
}
+static int _parse_env_file(pam_handle_t *pamh, int ctrl, char **env_file)
+{
+ int retval=PAM_SUCCESS, i, t;
+ const char *file;
+ char buffer[BUF_SIZE], *key, *mark;
+ FILE *conf;
+
+ if (ctrl & PAM_NEW_ENV_FILE)
+ file = *env_file;
+ else
+ file = DEFAULT_ETC_ENVFILE;
+
+ D(("Env file name is: %s", file));
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ D(("Unable to open env file: %s", strerror(errno)));
+ return PAM_ABORT;
+ }
+
+ while (_assemble_line(conf, buffer, BUF_SIZE) > 0) {
+ D(("Read line: %s", buffer));
+ key = buffer;
+
+ /* skip leading white space */
+ key += strspn(key, " \n\t");
+
+ /* skip blanks lines and comments */
+ if (!key || key[0] == '#')
+ continue;
+
+ /* skip over "export " if present so we can be compat with
+ bash type declerations */
+ if (strncmp(key, "export ", (size_t) 7) == 0)
+ key += 7;
+
+ /* now find the end of value */
+ mark = key;
+ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
+ mark++;
+ if (mark[0] != '\0')
+ mark[0] = '\0';
+
+ /*
+ * sanity check, the key must be alpha-numeric
+ */
+
+ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ )
+ if (!isalnum(key[i]) && key[i] != '_') {
+ D(("key is not alpha numeric - '%s', ignoring", key));
+ continue;
+ }
+
+ /* now we try to be smart about quotes around the value,
+ but not too smart, we can't get all fancy with escaped
+ values like bash */
+ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) {
+ for ( t = i+1 ; key[t] != '\0' ; t++)
+ if (key[t] != '\"' && key[t] != '\'')
+ key[i++] = key[t];
+ else if (key[t+1] != '\0')
+ key[i++] = key[t];
+ key[i] = '\0';
+ }
+
+ /* set the env var, if it fails, we break out of the loop */
+ retval = pam_putenv(pamh, key);
+ if (retval != PAM_SUCCESS) {
+ D(("error setting env \"%s\"", key));
+ break;
+ }
+ }
+
+ (void) fclose(conf);
+
+ /* tidy up */
+ _pam_overwrite(*env_file);
+ _pam_drop(*env_file);
+ file = NULL;
+ D(("Exit."));
+ return (retval<0?PAM_IGNORE: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"
@@ -536,7 +588,7 @@ static int _expand_arg(pam_handle_t *pamh, char **value)
_log_err(LOG_ERR, "Unterminated expandable variable: <%s>", orig-2);
return PAM_ABORT;
}
- strcpy(tmpval, orig);
+ strncpy(tmpval, orig, (size_t) BUF_SIZE);
orig=ptr;
/*
* so, we know we need to expand tmpval, it is either
@@ -696,18 +748,21 @@ PAM_EXTERN
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
- int retval, ctrl;
- char *conf_file=NULL;
-
+ int retval, ctrl, readenv=DEFAULT_READ_ENVFILE;
+ char *conf_file=NULL, *env_file=NULL;
+
/*
* this module sets environment variables read in from a file
*/
D(("Called."));
- ctrl = _pam_parse(flags, argc, argv, &conf_file);
-
+ ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv);
+
retval = _parse_config_file(pamh, ctrl, &conf_file);
-
+
+ if(readenv)
+ _parse_env_file(pamh, ctrl, &env_file);
+
/* indicate success or failure */
D(("Exit."));
@@ -726,18 +781,21 @@ PAM_EXTERN
int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
- int retval, ctrl;
- char *conf_file=NULL;
+ int retval, ctrl, readenv=DEFAULT_READ_ENVFILE;
+ char *conf_file=NULL, *env_file=NULL;
/*
* this module sets environment variables read in from a file
*/
D(("Called."));
- ctrl = _pam_parse(flags, argc, argv, &conf_file);
+ ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv);
retval = _parse_config_file(pamh, ctrl, &conf_file);
+ if(readenv)
+ _parse_env_file(pamh, ctrl, &env_file);
+
/* indicate success or failure */
D(("Exit."));
diff --git a/contrib/libpam/modules/pam_env/pam_env.conf-example b/contrib/libpam/modules/pam_env/pam_env.conf-example
index 388e8b6b16d4..89637083be4e 100644
--- a/contrib/libpam/modules/pam_env/pam_env.conf-example
+++ b/contrib/libpam/modules/pam_env/pam_env.conf-example
@@ -1,6 +1,6 @@
-# $Date: 1997/04/05 06:42:35 $
-# $Author: morgan $
-# $Id: pam_env.conf-example,v 1.1 1997/04/05 06:42:35 morgan Exp $
+# $Date: 2000/06/20 22:11:35 $
+# $Author: agmorgan $
+# $Id: pam_env.conf-example,v 1.1.1.1 2000/06/20 22:11:35 agmorgan Exp $
#
# This is the configuration file for pam_env, a PAM module to load in
# a configurable list of environment variables for a
diff --git a/contrib/libpam/modules/pam_filter/Makefile b/contrib/libpam/modules/pam_filter/Makefile
index dbd6452ab285..1126aff9b301 100644
--- a/contrib/libpam/modules/pam_filter/Makefile
+++ b/contrib/libpam/modules/pam_filter/Makefile
@@ -1,24 +1,11 @@
#
-# $Id: Makefile,v 1.10 1997/04/05 06:41:09 morgan Exp $
+# $Id: Makefile,v 1.3 2000/12/21 06:06:34 vorlon Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.10 1997/04/05 06:41:09 morgan
-# fakeroot
-#
-# Revision 1.9 1997/02/15 18:58:48 morgan
-# fixed bash syntax
-#
-# Revision 1.8 1997/01/04 20:24:29 morgan
-# don't compile on solaris, make -> $(MAKE)
-#
-# Revision 1.7 1996/11/10 20:12:09 morgan
-# cross platform support
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
#
ifeq ($(OS),solaris)
@@ -27,12 +14,14 @@ include ../dont_makefile
else
+include ../../Make.Rules
+
TITLE=pam_filter
FILTERS=upperLOWER
FILTERSDIR=$(SUPLEMENTED)/pam_filter
export FILTERSDIR
-#
+CFLAGS += -Iinclude
LIBSRC = $(TITLE).c
LIBOBJ = $(TITLE).o
@@ -55,10 +44,6 @@ endif
####################### don't edit below #######################
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
#
# this is where we compile this module
#
@@ -66,6 +51,7 @@ dummy:
all: dirs $(LIBSHARED) $(LIBSTATIC) register filters
dirs:
+ if [ ! -r include/security ]; then ln -sf . include/security ; fi
ifdef DYNAMIC
$(MKDIR) ./dynamic
endif
@@ -104,6 +90,15 @@ $(LIBSTATIC): $(LIBOBJS)
$(LD) -r -o $@ $(LIBOBJS)
endif
+remove:
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ rm -f $(FAKEROOT)$(INCLUDED)/pam_filter.h
+ @for i in $(FILTERS) ; do \
+ if [ -d $$i ]; then \
+ $(MAKE) -C $$i remove ; \
+ fi ; \
+ done
+
install: all
@for i in $(FILTERS) ; do \
if [ -d $$i ]; then \
@@ -117,34 +112,15 @@ endif
$(MKDIR) $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/pam_filter.h $(FAKEROOT)$(INCLUDED)
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(INCLUDED)/pam_filter.h
- @for i in $(FILTERS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i remove ; \
- fi ; \
- done
-
-lclean:
- rm -f $(LIBSHARED) $(LIBOBJD) $(LIBOBJS) core *~
-
-clean: lclean
+clean:
@for i in $(FILTERS) ; do \
if [ -d $$i ]; then \
$(MAKE) -C $$i clean ; \
fi ; \
done
-
-extraclean: lclean
- @rm -f *.a *.o *.so *.bak
- for i in $(FILTERS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i extraclean ; \
- fi ; \
- done
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+ rm -f $(LIBSHARED) $(LIBOBJD) $(LIBOBJS) core *~
+ rm -f include/security
+ rm -fr dynamic static
+ rm -f *.a *.o *.so *.bak
endif
diff --git a/contrib/libpam/modules/pam_filter/README b/contrib/libpam/modules/pam_filter/README
index 9d46a56e5c9c..12c4aeb5175b 100644
--- a/contrib/libpam/modules/pam_filter/README
+++ b/contrib/libpam/modules/pam_filter/README
@@ -1,5 +1,5 @@
#
-# $Id: README,v 1.5 1996/12/01 02:53:08 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:35 agmorgan Exp $
#
# This describes the behavior of this module with respect to the
# /etc/pam.conf file.
diff --git a/contrib/libpam/modules/pam_filter/include/pam_filter.h b/contrib/libpam/modules/pam_filter/include/pam_filter.h
index 3eb2730e768b..69e3a3e298ab 100644
--- a/contrib/libpam/modules/pam_filter/include/pam_filter.h
+++ b/contrib/libpam/modules/pam_filter/include/pam_filter.h
@@ -1,8 +1,8 @@
/*
- * $Id: pam_filter.h,v 1.2 1997/02/15 19:09:09 morgan Exp $
+ * $Id: pam_filter.h,v 1.1.1.1 2000/06/20 22:11:36 agmorgan Exp $
*
* this file is associated with the Linux-PAM filter module.
- * it was written by Andrew G. Morgan <morgan@parc.power.net>
+ * it was written by Andrew G. Morgan <morgan@linux.kernel.org>
*
*/
diff --git a/contrib/libpam/modules/pam_filter/pam_filter.c b/contrib/libpam/modules/pam_filter/pam_filter.c
index fc3d1f2b53fc..3ab2d8670646 100644
--- a/contrib/libpam/modules/pam_filter/pam_filter.c
+++ b/contrib/libpam/modules/pam_filter/pam_filter.c
@@ -1,24 +1,12 @@
/*
- * $Id: pam_filter.c,v 1.9 1997/02/15 19:07:49 morgan Exp morgan $
- *
- * $Log: pam_filter.c,v $
- * Revision 1.9 1997/02/15 19:07:49 morgan
- * fixed email
- *
- * Revision 1.8 1996/11/10 20:59:23 morgan
- * gcc warning removed
- *
- * Revision 1.7 1996/07/08 00:01:17 morgan
- * set the PAM_TTY item now
- *
- * Revision 1.6 1996/06/02 08:08:19 morgan
- * completely re-written
- *
+ * $Id: pam_filter.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* written by Andrew Morgan <morgan@transmeta.com> with much help from
* Richard Stevens' UNIX Network Programming book.
*/
+#include <security/_pam_aconf.h>
+
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
diff --git a/contrib/libpam/modules/pam_filter/upperLOWER/Makefile b/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
index 09b693bf6803..92da2479e0a8 100644
--- a/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
+++ b/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
@@ -1,44 +1,28 @@
#
-# $Id: Makefile,v 1.5 1997/04/05 06:41:35 morgan Exp $
-#
-# $Log: Makefile,v $
-# Revision 1.5 1997/04/05 06:41:35 morgan
-# fakeroot
-#
-# Revision 1.4 1997/01/04 20:25:04 morgan
-# removed need for make
-#
-# Revision 1.3 1996/11/10 20:13:08 morgan
-# email address
-#
-# Revision 1.2 1996/11/10 20:12:24 morgan
-# cross platform support
-#
-# Revision 1.1 1996/06/02 08:17:02 morgan
-# Initial revision
-#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This directory contains a pam_filter filter executable
#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@transmeta.com> 1996/3/11
#
+include ../../../Make.Rules
+
TITLE=upperLOWER
#
+CFLAGS += -I../include
+
OBJS = $(TITLE).o
####################### don't edit below #######################
-dummy:
- @echo "**** This is not a top-level Makefile "
-
all: $(TITLE)
$(TITLE): $(OBJS)
$(CC) -o $(TITLE) $(OBJS)
- strip $(TITLE)
+ $(STRIP) $(TITLE)
install:
$(MKDIR) $(FAKEROOT)$(FILTERSDIR)
@@ -50,9 +34,6 @@ remove:
clean:
rm -f $(TITLE) $(OBJS) core *~
-extraclean: clean
- rm -f *.bak
-
.c.o:
$(CC) $(CFLAGS) -c $<
diff --git a/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c b/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
index b375c0794edf..6178c2797e2e 100644
--- a/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
+++ b/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
@@ -1,17 +1,14 @@
/*
- * $Id: upperLOWER.c,v 1.1 1996/06/02 08:17:02 morgan Exp $
+ * $Id: upperLOWER.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* This is a sample filter program, for use with pam_filter (a module
* provided with Linux-PAM). This filter simply transposes upper and
* lower case letters, it is intended for demonstration purposes and
* it serves no purpose other than to annoy the user...
- *
- * $Log: upperLOWER.c,v $
- * Revision 1.1 1996/06/02 08:17:02 morgan
- * Initial revision
- *
*/
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
#include <syslog.h>
#include <sys/time.h>
@@ -52,7 +49,9 @@ static void do_transpose(char *buffer,int len)
}
}
-int main(int argc, char **argv, char **envp)
+extern char **environ;
+
+int main(int argc, char **argv)
{
char buffer[BUFSIZ];
fd_set readers;
@@ -64,8 +63,8 @@ int main(int argc, char **argv, char **envp)
int i;
fprintf(stderr,"environment :[\r\n");
- for (i=0; envp[i]; ++i) {
- fprintf(stderr,"-> %s\r\n",envp[i]);
+ for (i=0; environ[i]; ++i) {
+ fprintf(stderr,"-> %s\r\n",environ[i]);
}
fprintf(stderr,"]: end\r\n");
}
diff --git a/contrib/libpam/modules/pam_ftp/Makefile b/contrib/libpam/modules/pam_ftp/Makefile
index b5355c68b55e..456161bfe597 100644
--- a/contrib/libpam/modules/pam_ftp/Makefile
+++ b/contrib/libpam/modules/pam_ftp/Makefile
@@ -1,96 +1,15 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:40:33 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:40:33 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1996/12/01 03:17:57 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/11/14
-#
-
-TITLE=pam_ftp
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-dummy:
+include ../../Make.Rules
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_ftp
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_ftp/README b/contrib/libpam/modules/pam_ftp/README
index 597f9120bd86..6d03330c10ed 100644
--- a/contrib/libpam/modules/pam_ftp/README
+++ b/contrib/libpam/modules/pam_ftp/README
@@ -1,20 +1,18 @@
-# $Id: README,v 1.1 1996/12/01 03:17:57 morgan Exp $
-#
+This is the README for pam_ftp
+------------------------------
-This module is an authentication module that does not authenticate.
-Instead it always returns PAM_IGNORE, indicating that it does not want
-to affect the authentication process.
-
-Its purpose is to log a message to the syslog indicating the
-pam_item's available at the time it was invoked. It is a diagnostic
-tool.
+This module is an authentication module that does simple ftp
+authentication.
Recognized arguments:
- none
-
-module services provided:
+ "debug" print debug messages
+ "users=" comma separated list of users which
+ could login only with email adress
+ "ignore" allow invalid email adresses
- auth _authetication and _setcred (blank)
+Options for:
+auth: for authentication it provides pam_authenticate() and
+ pam_setcred() hooks.
-Andrew Morgan
+Thorsten Kukuk <kukuk@suse.de>, 17. June 1999
diff --git a/contrib/libpam/modules/pam_ftp/pam_ftp.c b/contrib/libpam/modules/pam_ftp/pam_ftp.c
index ca2d41545e94..3fcbcec8cd54 100644
--- a/contrib/libpam/modules/pam_ftp/pam_ftp.c
+++ b/contrib/libpam/modules/pam_ftp/pam_ftp.c
@@ -1,17 +1,9 @@
/* pam_ftp module */
/*
- * $Id: pam_ftp.c,v 1.2 1997/02/15 16:23:59 morgan Exp morgan $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_ftp.c,v $
- * Revision 1.2 1997/02/15 16:23:59 morgan
- * fixed logging to avoid a fixed buffer size
- *
- * Revision 1.1 1996/12/01 03:17:57 morgan
- * Initial revision
+ * $Id: pam_ftp.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*
*/
@@ -22,10 +14,7 @@
/* the following is a password that "can't be correct" */
#define BLOCK_PASSWORD "\177BAD PASSWPRD\177"
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -76,7 +65,7 @@ static int converse(pam_handle_t *pamh, int nargs
D(("returned from application's conversation function\n"));
- if (retval != PAM_SUCCESS) {
+ if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN)) {
_pam_log(LOG_DEBUG, "conversation failure [%s]"
, pam_strerror(pamh, retval));
}
@@ -211,24 +200,33 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
char *prompt=NULL;
int i=0;
- mesg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- if (anon) {
- prompt = malloc(sizeof(PLEASE_ENTER_PASSWORD + strlen(user)));
- sprintf(prompt, PLEASE_ENTER_PASSWORD, user);
- msg[i].msg = prompt;
+ if (!anon) {
+ prompt = malloc(strlen(PLEASE_ENTER_PASSWORD) + strlen(user));
+ if (prompt == NULL) {
+ D(("out of memory!?"));
+ return PAM_BUF_ERR;
+ } else {
+ sprintf(prompt, PLEASE_ENTER_PASSWORD, user);
+ msg[i].msg = prompt;
+ }
} else {
msg[i].msg = GUEST_LOGIN_PROMPT;
}
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ mesg[i] = &msg[i];
+
retval = converse(pamh, ++i, mesg, &resp);
- _pam_overwrite(prompt);
- _pam_drop(prompt);
+ if (prompt) {
+ _pam_overwrite(prompt);
+ _pam_drop(prompt);
+ }
if (retval != PAM_SUCCESS) {
if (resp != NULL)
_pam_drop_reply(resp,i);
- return PAM_AUTHINFO_UNAVAIL;
+ return ((retval == PAM_CONV_AGAIN)
+ ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
}
if (anon) {
@@ -238,11 +236,15 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
token = strtok(resp->resp, "@");
retval = pam_set_item(pamh, PAM_RUSER, token);
- if (token && retval != PAM_SUCCESS) {
+ if ((token) && (retval == PAM_SUCCESS)) {
token = strtok(NULL, "@");
retval = pam_set_item(pamh, PAM_RHOST, token);
}
}
+
+ /* we are happy to grant annonymous access to the user */
+ retval = PAM_SUCCESS;
+
} else {
/*
* we have a password so set AUTHTOK
diff --git a/contrib/libpam/modules/pam_group/Makefile b/contrib/libpam/modules/pam_group/Makefile
index 5db53ccf1133..afa888803315 100644
--- a/contrib/libpam/modules/pam_group/Makefile
+++ b/contrib/libpam/modules/pam_group/Makefile
@@ -1,114 +1,21 @@
-#
-# $Id: Makefile,v 1.6 1997/04/05 06:39:56 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.6 1997/04/05 06:39:56 morgan
-# fakeroot
-#
-# Revision 1.5 1997/01/04 20:28:47 morgan
-# compile with and without libpwdb
-#
-# Revision 1.4 1996/11/10 20:13:18 morgan
-# cross platform support
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/6/11
-#
-
-TITLE=pam_group
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/group.conf
-export CONFILE
-
-#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
-ifndef STATIC
-ifeq ($(HAVE_PWDBLIB),yes)
- DEFS+=-DWANT_PWDB
- ELIBS=-lpwdb
-endif
-endif
+TITLE=pam_group
+LOCAL_CONFILE=./group.conf
+INSTALLED_CONFILE=$(SCONFIGD)/group.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(ELIBS)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(ELIBS)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_group/group.conf b/contrib/libpam/modules/pam_group/group.conf
index bdd76adbe68f..e721b9907eea 100644
--- a/contrib/libpam/modules/pam_group/group.conf
+++ b/contrib/libpam/modules/pam_group/group.conf
@@ -10,7 +10,7 @@
# *** NOT inherently secure. If a user can create an executable that
# *** is setgid a group that they are infrequently given membership
# *** of, they can basically obtain group membership any time they
-# *** like. Example: games are alowed between the hours of 6pm and 6am
+# *** like. Example: games are allowed between the hours of 6pm and 6am
# *** user joe logs in at 7pm writes a small C-program toplay.c that
# *** invokes their favorite shell, compiles it and does
# *** "chgrp games toplay; chmod g+s toplay". They are basically able
diff --git a/contrib/libpam/modules/pam_group/pam_group.c b/contrib/libpam/modules/pam_group/pam_group.c
index 9e2cf885e9cf..2d04119ad88a 100644
--- a/contrib/libpam/modules/pam_group/pam_group.c
+++ b/contrib/libpam/modules/pam_group/pam_group.c
@@ -1,32 +1,17 @@
/* pam_group module */
/*
- * $Id: pam_group.c,v 1.7 1997/02/15 17:31:48 morgan Exp morgan $
+ * $Id: pam_group.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/7/6
- *
- * $Log: pam_group.c,v $
- * Revision 1.7 1997/02/15 17:31:48 morgan
- * time parsing more robust
- *
- * Revision 1.6 1997/01/04 21:57:49 morgan
- * fixed warning about setgroups not being defined
- *
- * Revision 1.5 1997/01/04 20:26:49 morgan
- * can be compiled with and without libpwdb. fixed buffer underwriting
- * pays attention to PAM_CRED flags(!)
- *
- * Revision 1.4 1996/12/01 02:54:37 morgan
- * mostly debugging now uses D(())
- *
- * Revision 1.3 1996/11/10 21:01:22 morgan
- * compatability and pam_get_user changes
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/7/6
*/
const static char rcsid[] =
-"$Id: pam_group.c,v 1.7 1997/02/15 17:31:48 morgan Exp morgan $;\n"
+"$Id: pam_group.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $;\n"
"Version 0.5 for Linux-PAM\n"
-"Copyright (c) Andrew G. Morgan 1996 <morgan@parc.power.net>\n";
+"Copyright (c) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
+
+#define _BSD_SOURCE
#include <sys/file.h>
#include <stdio.h>
@@ -38,17 +23,16 @@ const static char rcsid[] =
#include <syslog.h>
#include <string.h>
-#define __USE_BSD
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#ifdef WANT_PWDB
-#include <pwdb/pwdb_public.h>
+#ifdef DEFAULT_CONF_FILE
+# define PAM_GROUP_CONF DEFAULT_CONF_FILE /* from external define */
+#else
+# define PAM_GROUP_CONF "/etc/security/group.conf"
#endif
-
-#define PAM_GROUP_CONF CONFILE /* from external define */
#define PAM_GROUP_BUFLEN 1000
#define FIELD_SEPARATOR ';' /* this is new as of .02 */
@@ -137,6 +121,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
_log_err("error reading " PAM_GROUP_CONF);
return -1;
} else if (!i) {
+ close(fd);
fd = -1; /* end of file reached */
} else
*to += i;
@@ -180,6 +165,8 @@ static int read_field(int fd, char **buf, int *from, int *to)
if ((*buf)[i+1] == '\n') {
shift_bytes(i + *buf, 2, *to - (i+2));
*to -= 2;
+ } else {
+ ++i; /* we don't escape non-newline characters */
}
break;
case '!':
@@ -260,7 +247,7 @@ static int logic_member(const char *string, int *at)
default:
if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
- || c == '-' || c == '.') {
+ || c == '-' || c == '.' || c == '/') {
token = 1;
} else if (token) {
--to;
diff --git a/contrib/libpam/modules/pam_issue/Makefile b/contrib/libpam/modules/pam_issue/Makefile
new file mode 100644
index 000000000000..1bd2be217db5
--- /dev/null
+++ b/contrib/libpam/modules/pam_issue/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_issue
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_issue/pam_issue.c b/contrib/libpam/modules/pam_issue/pam_issue.c
new file mode 100644
index 000000000000..2cb54bec77d6
--- /dev/null
+++ b/contrib/libpam/modules/pam_issue/pam_issue.c
@@ -0,0 +1,266 @@
+/* pam_issue module - a simple /etc/issue parser to set PAM_USER_PROMPT
+ *
+ * Copyright 1999 by Ben Collins <bcollins@debian.org>
+ *
+ * Needs to be called before any other auth modules so we can setup the
+ * user prompt before it's first used. Allows one argument option, which
+ * is the full path to a file to be used for issue (uses /etc/issue as a
+ * default) such as "issue=/etc/issue.telnet".
+ *
+ * We can also parse escapes within the the issue file (enabled by
+ * default, but can be disabled with the "noesc" option). It's the exact
+ * same parsing as util-linux's agetty program performs.
+ *
+ * Released under the GNU LGPL version 2 or later
+ */
+
+#define _GNU_SOURCE
+#define _BSD_SOURCE
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <utmp.h>
+#include <malloc.h>
+
+#include <security/_pam_macros.h>
+
+#define PAM_SM_AUTH
+
+#include <security/pam_modules.h>
+
+static int _user_prompt_set = 0;
+
+char *do_prompt (FILE *);
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval = PAM_SUCCESS;
+ FILE *fd;
+ int parse_esc = 1;
+ char *prompt_tmp = NULL, *cur_prompt = NULL;
+ struct stat st;
+ char *issue_file = NULL;
+
+ /* If we've already set the prompt, don't set it again */
+ if(_user_prompt_set)
+ return PAM_IGNORE;
+ else
+ /* we set this here so if we fail below, we wont get further
+ than this next time around (only one real failure) */
+ _user_prompt_set = 1;
+
+ for ( ; argc-- > 0 ; ++argv ) {
+ if (!strncmp(*argv,"issue=",6)) {
+ issue_file = (char *) strdup(6+*argv);
+ if (issue_file != NULL) {
+ D(("set issue_file to: %s", issue_file));
+ } else {
+ D(("failed to strdup issue_file - ignored"));
+ return PAM_IGNORE;
+ }
+ } else if (!strcmp(*argv,"noesc")) {
+ parse_esc = 0;
+ D(("turning off escape parsing by request"));
+ } else
+ D(("unknown option passed: %s", *argv));
+ }
+
+ if (issue_file == NULL)
+ issue_file = strdup("/etc/issue");
+
+ if ((fd = fopen(issue_file, "r")) != NULL) {
+ int tot_size = 0;
+
+ if (stat(issue_file, &st) < 0)
+ return PAM_IGNORE;
+
+ retval = pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &cur_prompt);
+ if (retval != PAM_SUCCESS)
+ return PAM_IGNORE;
+
+ /* first read in the issue file */
+
+ if (parse_esc)
+ prompt_tmp = do_prompt(fd);
+ else {
+ int count = 0;
+ prompt_tmp = malloc(st.st_size + 1);
+ if (prompt_tmp == NULL) return PAM_IGNORE;
+ memset (prompt_tmp, '\0', st.st_size + 1);
+ count = fread(prompt_tmp, sizeof(char *), st.st_size, fd);
+ prompt_tmp[st.st_size] = '\0';
+ }
+
+ fclose(fd);
+
+ tot_size = strlen(prompt_tmp) + strlen(cur_prompt) + 1;
+
+ /*
+ * alloc some extra space for the original prompt
+ * and postpend it to the buffer
+ */
+ prompt_tmp = realloc(prompt_tmp, tot_size);
+ strcpy(prompt_tmp+strlen(prompt_tmp), cur_prompt);
+
+ prompt_tmp[tot_size] = '\0';
+
+ retval = pam_set_item(pamh, PAM_USER_PROMPT, (const char *) prompt_tmp);
+
+ free(issue_file);
+ free(prompt_tmp);
+ } else {
+ D(("could not open issue_file: %s", issue_file));
+ return PAM_IGNORE;
+ }
+
+ return retval;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+char *do_prompt(FILE *fd)
+{
+ int c, size = 1024;
+ char *issue = (char *)malloc(size);
+ char buf[1024];
+ struct utsname uts;
+
+ if (issue == NULL || fd == NULL)
+ return NULL;
+
+ issue[0] = '\0'; /* zero this, for strcat to work on first buf */
+ (void) uname(&uts);
+
+ while ((c = getc(fd)) != EOF) {
+ if (c == '\\') {
+ c = getc(fd);
+ switch (c) {
+ case 's':
+ snprintf (buf, 1024, "%s", uts.sysname);
+ break;
+ case 'n':
+ snprintf (buf, 1024, "%s", uts.nodename);
+ break;
+ case 'r':
+ snprintf (buf, 1024, "%s", uts.release);
+ break;
+ case 'v':
+ snprintf (buf, 1024, "%s", uts.version);
+ break;
+ case 'm':
+ snprintf (buf, 1024, "%s", uts.machine);
+ break;
+ case 'o':
+ {
+ char domainname[256];
+
+ getdomainname(domainname, sizeof(domainname));
+ domainname[sizeof(domainname)-1] = '\0';
+ snprintf (buf, 1024, "%s", domainname);
+ }
+ break;
+
+ case 'd':
+ case 't':
+ {
+ const char *weekday[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu",
+ "Fri", "Sat" };
+ const char *month[] = {
+ "Jan", "Feb", "Mar", "Apr", "May",
+ "Jun", "Jul", "Aug", "Sep", "Oct",
+ "Nov", "Dec" };
+ time_t now;
+ struct tm *tm;
+
+ (void) time (&now);
+ tm = localtime(&now);
+
+ if (c == 'd')
+ snprintf (buf, 1024, "%s %s %d %d",
+ weekday[tm->tm_wday], month[tm->tm_mon],
+ tm->tm_mday,
+ tm->tm_year + 1900);
+ else
+ snprintf (buf, 1024, "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
+ break;
+ case 'l':
+ {
+ char *ttyn = ttyname(1);
+ if (!strncmp(ttyn, "/dev/", 5))
+ ttyn += 5;
+ snprintf (buf, 1024, "%s", ttyn);
+ }
+ break;
+ case 'u':
+ case 'U':
+ {
+ int users = 0;
+ struct utmp *ut;
+ setutent();
+ while ((ut = getutent()))
+ if (ut->ut_type == USER_PROCESS)
+ users++;
+ endutent();
+ printf ("%d ", users);
+ if (c == 'U')
+ snprintf (buf, 1024, "%s", (users == 1) ?
+ " user" : " users");
+ break;
+ }
+ default:
+ buf[0] = c; buf[1] = '\0';
+ }
+ if ((strlen(issue) + strlen(buf)) < size + 1) {
+ size += strlen(buf) + 1;
+ issue = (char *) realloc (issue, size);
+ }
+ strcat(issue, buf);
+ } else {
+ buf[0] = c; buf[1] = '\0';
+ if ((strlen(issue) + strlen(buf)) < size + 1) {
+ size += strlen(buf) + 1;
+ issue = (char *) realloc (issue, size);
+ }
+ strcat(issue, buf);
+ }
+ }
+ return issue;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_issue_modstruct = {
+ "pam_issue",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_lastlog/Makefile b/contrib/libpam/modules/pam_lastlog/Makefile
index e51a72d31f50..e8062714af81 100644
--- a/contrib/libpam/modules/pam_lastlog/Makefile
+++ b/contrib/libpam/modules/pam_lastlog/Makefile
@@ -1,106 +1,19 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:17:14 morgan Exp morgan $
+# $Id: Makefile,v 1.3 2001/02/10 22:33:10 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:17:14 morgan
-# fakeroot fixed
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1997/01/04 20:29:28 morgan
-# Initial revision
-#
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-#
-
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-TITLE=pam_lastlog
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-
-####################### don't edit below #######################
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
+include ../../Make.Rules
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+ifeq ($(HAVE_LIBUTIL),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lutil
endif
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_lastlog
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_lastlog/pam_lastlog.c b/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
index 96714f6bc16d..385d96405dd7 100644
--- a/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
+++ b/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
@@ -1,26 +1,17 @@
/* pam_lastlog module */
/*
- * $Id: pam_lastlog.c,v 1.3 1997/04/05 06:18:21 morgan Exp morgan $
+ * $Id: pam_lastlog.c,v 1.3 2001/02/10 22:33:10 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*
* This module does the necessary work to display the last login
* time+date for this user, it then updates this entry for the
* present (login) service.
- *
- * $Log: pam_lastlog.c,v $
- * Revision 1.3 1997/04/05 06:18:21 morgan
- * removed xstrdup - unused
- *
- * Revision 1.2 1997/02/15 17:18:21 morgan
- * removed fixed buffer in logging
- *
- * Revision 1.1 1997/01/04 20:29:28 morgan
- * Initial revision
- *
*/
+#include <security/_pam_aconf.h>
+
#include <fcntl.h>
#include <time.h>
#ifdef HAVE_UTMP_H
diff --git a/contrib/libpam/modules/pam_limits/Makefile b/contrib/libpam/modules/pam_limits/Makefile
index f6a0e07ca48b..695bc02df2f5 100644
--- a/contrib/libpam/modules/pam_limits/Makefile
+++ b/contrib/libpam/modules/pam_limits/Makefile
@@ -1,102 +1,31 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10
-#
-
-ifeq ($(OS),linux)
-ifeq ($(HAVE_PWDBLIB),yes)
-TITLE=pam_limits
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/limits.conf
-export CONFILE
-
-CFLAGS+=-DLIMITS_FILE=\"$(CONFILE)\"
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
+include ../../Make.Rules
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) -lpwdb
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
+TITLE=pam_limits
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
+ifeq ($(OS),linux)
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+LOCAL_CONFILE=./limits.skel
+INSTALLED_CONFILE=$(SCONFIGD)/limits.conf
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
+CFLAGS += $(DEFS)
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
else
+
include ../dont_makefile
-endif
-else
-include ../dont_makefile
+
endif
diff --git a/contrib/libpam/modules/pam_limits/README b/contrib/libpam/modules/pam_limits/README
index 06a6857a8135..2398334b91e7 100644
--- a/contrib/libpam/modules/pam_limits/README
+++ b/contrib/libpam/modules/pam_limits/README
@@ -4,9 +4,10 @@ pam_limits module:
THEORY OF OPERATION:
-First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE
-defined Makefile) that describes the resource limits you wish to impose. No
-limits are imposed on UID 0 accounts.
+First, make a root-only-readable file (/etc/security/limits.conf by
+default or INSTALLED_CONFILE defined Makefile) that describes the
+resource limits you wish to impose. No limits are imposed on UID 0
+accounts.
Each line describes a limit for a user in the form:
@@ -18,9 +19,10 @@ Where:
- a group name, with @group syntax
- the wildcard *, for default entry
-<type> can have the two values:
- - "soft" for enforcinf the soft limits
+<type> can have the three values:
+ - "soft" for enforcing the soft limits
- "hard" for enforcing hard limits
+ - "-" for enforcing both soft and hard limits
<item> can be one of the following:
- core - limits the core file size (KB)
@@ -35,15 +37,18 @@ Where:
- as - address space limit
- maxlogins - max number of logins for this user
- maxsyslogins - max number of logins on the system
-
-To completely disable limits for a user (or a group), a single dash (-)
-will do (Example: 'bin -', '@admin -'). Please remember that individual
-limits have priority over group limits, so if you impose no limits for 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.
+
+Note, if you specify a type of '-' but neglect to supply the item and
+value fields then the module will never enforce any limits on the
+specified user/group etc. .
+
+Please remember that individual limits have priority over group
+limits, so if you impose no limits for admin group, but one of the
+members in this group has a limits line, the user will have its limits
+set according to this line.
Also, please note that all limit settings are set PER LOGIN. They are
-not global, nor are they permanent (the session only)
+not global, nor are they permanent (they apply for the session only).
In the LIMITS_FILE, the # character introduces a comment - the rest of the
line is ignored.
@@ -68,6 +73,12 @@ ARGUMENTS RECOGNIZED:
conf=/path/to/file the limits configuration file if different from the
one set at compile time.
+ change_uid change real uid to the user for who the limits
+ are set up. Use this option if you have problems
+ like login not forking a shell for user who has
+ no processes. Be warned that something else
+ may break when you do this.
+
MODULE SERVICES PROVIDED:
session _open_session and _close_session (blank)
diff --git a/contrib/libpam/modules/pam_limits/limits.skel b/contrib/libpam/modules/pam_limits/limits.skel
index ea57e42513e4..5ddd9b4c38e5 100644
--- a/contrib/libpam/modules/pam_limits/limits.skel
+++ b/contrib/libpam/modules/pam_limits/limits.skel
@@ -26,6 +26,7 @@
# - nproc - max number of processes
# - as - address space limit
# - maxlogins - max number of logins for this user
+# - priority - the priority to run user process with
#
#<domain> <type> <item> <value>
#
diff --git a/contrib/libpam/modules/pam_limits/pam_limits.c b/contrib/libpam/modules/pam_limits/pam_limits.c
index 179c43028b4e..7a5ec472579c 100644
--- a/contrib/libpam/modules/pam_limits/pam_limits.c
+++ b/contrib/libpam/modules/pam_limits/pam_limits.c
@@ -1,6 +1,8 @@
/*
* pam_limits - impose resource limits when opening a user session
*
+ * 1.6 - modified for PLD (added process priority settings)
+ * by Marcin Korzonek <mkorz@shadow.eu.org
* 1.5 - Elliot Lee's "max system logins patch"
* 1.4 - addressed bug in configuration file parser
* 1.3 - modified the configuration file format
@@ -15,9 +17,10 @@
#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
#endif
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
#include <unistd.h>
-#define __USE_POSIX2
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
@@ -26,11 +29,15 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
+
#include <utmp.h>
#ifndef UT_USER /* some systems have ut_name instead of ut_user */
#define UT_USER ut_user
#endif
+#include <grp.h>
+#include <pwd.h>
+
/* Module defines */
#define LINE_LENGTH 1024
@@ -39,23 +46,28 @@
#define LIMITS_DEF_DEFAULT 2 /* limit was set by an default entry */
#define LIMITS_DEF_NONE 3 /* this limit was not set yet */
-/* internal data */
-static char conf_file[BUFSIZ];
-
struct user_limits_struct {
int src_soft;
int src_hard;
struct rlimit limit;
};
-static struct user_limits_struct limits[RLIM_NLIMITS];
-static int login_limit; /* the max logins limit */
-static int login_limit_def; /* which entry set the login limit */
-static int flag_numsyslogins; /* whether to limit logins only for a
- specific user or to count all logins */
+/* internal data */
+struct pam_limit_s {
+ int login_limit; /* the max logins limit */
+ int login_limit_def; /* which entry set the login limit */
+ int flag_numsyslogins; /* whether to limit logins only for a
+ specific user or to count all logins */
+ int priority; /* the priority to run user process with */
+ struct user_limits_struct limits[RLIM_NLIMITS];
+ char conf_file[BUFSIZ];
+};
#define LIMIT_LOGIN RLIM_NLIMITS+1
#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2
+
+#define LIMIT_PRI RLIM_NLIMITS+3
+
#define LIMIT_SOFT 1
#define LIMIT_HARD 2
@@ -63,7 +75,6 @@ static int flag_numsyslogins; /* whether to limit logins only for a
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
-#include <pwdb/pwdb_map.h>
/* logging */
static void _pam_log(int err, const char *format, ...)
@@ -80,8 +91,9 @@ static void _pam_log(int err, const char *format, ...)
/* argument parsing */
#define PAM_DEBUG_ARG 0x0001
+#define PAM_DO_SETREUID 0x0002
-static int _pam_parse(int argc, const char **argv)
+static int _pam_parse(int argc, const char **argv, struct pam_limit_s *pl)
{
int ctrl=0;
@@ -93,7 +105,9 @@ static int _pam_parse(int argc, const char **argv)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
else if (!strncmp(*argv,"conf=",5))
- strcpy(conf_file,*argv+5);
+ strcpy(pl->conf_file,*argv+5);
+ else if (!strncmp(*argv,"change_uid",10))
+ ctrl |= PAM_DO_SETREUID;
else {
_pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
}
@@ -104,15 +118,18 @@ static int _pam_parse(int argc, const char **argv)
/* limits stuff */
-#ifndef LIMITS_FILE
-#define LIMITS_FILE "/etc/security/limits.conf"
+#ifdef DEFAULT_CONF_FILE
+# define LIMITS_FILE DEFAULT_CONF_FILE
+#else
+# define LIMITS_FILE "/etc/security/limits.conf"
#endif
#define LIMIT_ERR 1 /* error setting a limit */
#define LOGIN_ERR 2 /* too many logins err */
/* Counts the number of user logins and check against the limit*/
-static int check_logins(const char *name, int limit, int ctrl)
+static int check_logins(const char *name, int limit, int ctrl,
+ struct pam_limit_s *pl)
{
struct utmp *ut;
unsigned int count;
@@ -137,7 +154,7 @@ static int check_logins(const char *name, int limit, int ctrl)
#endif
if (ut->UT_USER[0] == '\0')
continue;
- if (!flag_numsyslogins
+ if (!pl->flag_numsyslogins
&& strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0)
continue;
if (++count >= limit)
@@ -212,65 +229,61 @@ static int is_on_group(const char *user_name, const char *group_name)
return 0;
}
-static int init_limits(void)
+static int init_limits(struct pam_limit_s *pl)
{
+ int i;
int retval = PAM_SUCCESS;
D(("called."));
- retval |= getrlimit(RLIMIT_CPU, &limits[RLIMIT_CPU].limit);
- limits[RLIMIT_CPU].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_CPU].src_hard = LIMITS_DEF_NONE;
+ for(i = 0; i < RLIM_NLIMITS; i++)
+ retval |= getrlimit(i, &pl->limits[i].limit);
+
+ pl->limits[RLIMIT_CPU].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CPU].src_hard = LIMITS_DEF_NONE;
+
+ pl->limits[RLIMIT_FSIZE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_FSIZE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_FSIZE, &limits[RLIMIT_FSIZE].limit);
- limits[RLIMIT_FSIZE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_FSIZE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_DATA].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_DATA].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_DATA, &limits[RLIMIT_DATA].limit);
- limits[RLIMIT_DATA].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_DATA].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_STACK].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_STACK].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_STACK, &limits[RLIMIT_STACK].limit);
- limits[RLIMIT_STACK].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_STACK].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CORE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CORE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_CORE, &limits[RLIMIT_CORE].limit);
- limits[RLIMIT_CORE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_CORE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_RSS].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_RSS].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_RSS, &limits[RLIMIT_RSS].limit);
- limits[RLIMIT_RSS].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_RSS].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NPROC].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NPROC].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_NPROC, &limits[RLIMIT_NPROC].limit);
- limits[RLIMIT_NPROC].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_NPROC].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NOFILE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NOFILE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_NOFILE, &limits[RLIMIT_NOFILE].limit);
- limits[RLIMIT_NOFILE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_NOFILE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_MEMLOCK].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_MEMLOCK].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_MEMLOCK, &limits[RLIMIT_MEMLOCK].limit);
- limits[RLIMIT_MEMLOCK].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_MEMLOCK].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_AS].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_AS].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_AS, &limits[RLIMIT_AS].limit);
- limits[RLIMIT_AS].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_AS].src_hard = LIMITS_DEF_NONE;
+ pl->priority = 0;
+ pl->login_limit = -2;
+ pl->login_limit_def = LIMITS_DEF_NONE;
- login_limit = -2;
- login_limit_def = LIMITS_DEF_NONE;
return retval;
}
static void process_limit(int source, const char *lim_type,
const char *lim_item, const char *lim_value,
- int ctrl)
+ int ctrl, struct pam_limit_s *pl)
{
int limit_item;
int limit_type = 0;
long limit_value;
- char **endptr = (char **) &lim_value;
+ const char **endptr = &lim_value;
const char *value_orig = lim_value;
if (ctrl & PAM_DEBUG_ARG)
@@ -299,10 +312,12 @@ static void process_limit(int source, const char *lim_type,
limit_item = RLIMIT_AS;
else if (strcmp(lim_item, "maxlogins") == 0) {
limit_item = LIMIT_LOGIN;
- flag_numsyslogins = 0;
+ pl->flag_numsyslogins = 0;
} else if (strcmp(lim_item, "maxsyslogins") == 0) {
limit_item = LIMIT_NUMSYSLOGINS;
- flag_numsyslogins = 1;
+ pl->flag_numsyslogins = 1;
+ } else if (strcmp(lim_item, "priority") == 0) {
+ limit_item = LIMIT_PRI;
} else {
_pam_log(LOG_DEBUG,"unknown limit item '%s'", lim_item);
return;
@@ -349,38 +364,47 @@ static void process_limit(int source, const char *lim_type,
break;
}
- if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS) {
- if (limit_type & LIMIT_SOFT)
- if (limits[limit_item].src_soft < source)
+ if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS
+ && limit_item != LIMIT_PRI
+ ) {
+ if (limit_type & LIMIT_SOFT) {
+ if (pl->limits[limit_item].src_soft < source) {
return;
- else {
- limits[limit_item].limit.rlim_cur = limit_value;
- limits[limit_item].src_soft = source;
+ } else {
+ pl->limits[limit_item].limit.rlim_cur = limit_value;
+ pl->limits[limit_item].src_soft = source;
}
- if (limit_type & LIMIT_HARD)
- if (limits[limit_item].src_hard < source)
+ }
+ if (limit_type & LIMIT_HARD) {
+ if (pl->limits[limit_item].src_hard < source) {
return;
- else {
- limits[limit_item].limit.rlim_max = limit_value;
- limits[limit_item].src_hard = source;
+ } else {
+ pl->limits[limit_item].limit.rlim_max = limit_value;
+ pl->limits[limit_item].src_hard = source;
}
- } else
- if (login_limit_def < source)
- return;
- else {
- login_limit = limit_value;
- login_limit_def = source;
- }
-
- return;
+ }
+ } else
+ if (limit_item == LIMIT_PRI) {
+ /* additional check */
+ pl->priority = ((limit_value>0)?limit_value:0);
+ } else {
+ if (pl->login_limit_def < source) {
+ return;
+ } else {
+ pl->login_limit = limit_value;
+ pl->login_limit_def = source;
+ }
+ }
+ return;
}
-static int parse_config_file(const char *uname, int ctrl)
+static int parse_config_file(const char *uname, int ctrl,
+ struct pam_limit_s *pl)
{
FILE *fil;
char buf[LINE_LENGTH];
-#define CONF_FILE (conf_file[0])?conf_file:LIMITS_FILE
+#define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE
/* check for the LIMITS_FILE */
if (ctrl & PAM_DEBUG_ARG)
_pam_log(LOG_DEBUG,"reading settings from '%s'", CONF_FILE);
@@ -428,6 +452,9 @@ static int parse_config_file(const char *uname, int ctrl)
memset(value, 0, sizeof(value));
i = sscanf(buf,"%s%s%s%s", domain, ltype, item, value);
+ D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]",
+ i, domain, ltype, item, value));
+
for(j=0; j < strlen(domain); j++)
domain[j]=tolower(domain[j]);
for(j=0; j < strlen(ltype); j++)
@@ -439,36 +466,56 @@ static int parse_config_file(const char *uname, int ctrl)
if (i == 4) { /* a complete line */
if (strcmp(uname, domain) == 0) /* this user have a limit */
- process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl);
+ process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl, pl);
else if (domain[0]=='@') {
if (is_on_group(uname, domain+1))
- process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl);
+ process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl,
+ pl);
} else if (strcmp(domain, "*") == 0)
- process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl);
- } else
- _pam_log(LOG_DEBUG,"invalid line '%s'", buf);
+ process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl,
+ pl);
+ } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */
+ if (strcmp(uname, domain) == 0) {
+ _pam_log(LOG_DEBUG, "no limits for '%s'", uname);
+ fclose(fil);
+ return PAM_IGNORE;
+ } else if (domain[0] == '@' && is_on_group(uname, domain+1)) {
+ _pam_log(LOG_DEBUG, "no limits for '%s' in group '%s'",
+ uname, domain+1);
+ fclose(fil);
+ return PAM_IGNORE;
+ }
+ } else {
+ _pam_log(LOG_DEBUG,"invalid line '%s' - skipped", buf);
+ }
}
fclose(fil);
return PAM_SUCCESS;
}
-static int setup_limits(const char * uname, int ctrl)
+static int setup_limits(const char * uname, int ctrl, struct pam_limit_s *pl)
{
int i;
int retval = PAM_SUCCESS;
for (i=0; i<RLIM_NLIMITS; i++) {
- if (limits[i].limit.rlim_cur > limits[i].limit.rlim_max)
- limits[i].limit.rlim_cur = limits[i].limit.rlim_max;
- retval |= setrlimit(i, &limits[i].limit);
+ if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max)
+ pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max;
+ retval |= setrlimit(i, &pl->limits[i].limit);
}
if (retval != PAM_SUCCESS)
retval = LIMIT_ERR;
- if (login_limit > 0) {
- if (check_logins(uname, login_limit, ctrl) == LOGIN_ERR)
+
+ retval=setpriority(PRIO_PROCESS, 0, pl->priority);
+
+ if (retval != PAM_SUCCESS)
+ retval = LIMIT_ERR;
+
+ if (pl->login_limit > 0) {
+ if (check_logins(uname, pl->login_limit, ctrl, pl) == LOGIN_ERR)
retval |= LOGIN_ERR;
- } else if (login_limit == 0)
+ } else if (pl->login_limit == 0)
retval |= LOGIN_ERR;
return retval;
}
@@ -481,12 +528,13 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
char *user_name;
struct passwd *pwd;
int ctrl;
-
+ struct pam_limit_s pl;
+
D(("called."));
- memset(conf_file, 0, sizeof(conf_file));
-
- ctrl = _pam_parse(argc, argv);
+ memset(&pl, 0, sizeof(pl));
+
+ ctrl = _pam_parse(argc, argv, &pl);
retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
if ( user_name == NULL || retval != PAM_SUCCESS ) {
_pam_log(LOG_CRIT, "open_session - error recovering username");
@@ -511,19 +559,25 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
return PAM_SUCCESS;
}
- retval = init_limits();
+ retval = init_limits(&pl);
if (retval != PAM_SUCCESS) {
- _pam_log(LOG_WARNING, "can not initialize");
+ _pam_log(LOG_WARNING, "cannot initialize");
return PAM_IGNORE;
}
- retval = parse_config_file(pwd->pw_name,ctrl);
+ retval = parse_config_file(pwd->pw_name, ctrl, &pl);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file has an applicable '<domain> -' entry"));
+ return PAM_SUCCESS;
+ }
if (retval != PAM_SUCCESS) {
_pam_log(LOG_WARNING, "error parsing the configuration file");
return PAM_IGNORE;
}
-
- retval = setup_limits(pwd->pw_name, ctrl);
+
+ if (ctrl & PAM_DO_SETREUID)
+ setreuid(pwd->pw_uid, -1);
+ retval = setup_limits(pwd->pw_name, ctrl, &pl);
if (retval & LOGIN_ERR) {
printf("\nToo many logins for '%s'\n",pwd->pw_name);
sleep(2);
diff --git a/contrib/libpam/modules/pam_listfile/Makefile b/contrib/libpam/modules/pam_listfile/Makefile
index 02940390b333..c5447c949cf7 100644
--- a/contrib/libpam/modules/pam_listfile/Makefile
+++ b/contrib/libpam/modules/pam_listfile/Makefile
@@ -1,84 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_listfile
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_listfile
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_listfile/pam_listfile.c b/contrib/libpam/modules/pam_listfile/pam_listfile.c
index e54b12aaec0c..2f4f3d0bf98a 100644
--- a/contrib/libpam/modules/pam_listfile/pam_listfile.c
+++ b/contrib/libpam/modules/pam_listfile/pam_listfile.c
@@ -1,39 +1,16 @@
/*
- * $Id: pam_listfile.c,v 1.6 1997/04/05 06:38:35 morgan Exp $
- *
- * $Log: pam_listfile.c,v $
- * Revision 1.6 1997/04/05 06:38:35 morgan
- * reformat mostly
- *
- * Revision 1.5 1997/02/15 17:29:41 morgan
- * removed fixed length buffer in logging
- *
- * Revision 1.4 1997/01/04 20:32:10 morgan
- * ammendments for pam_listfile handling
- *
- * Revision 1.3 1996/11/10 21:02:08 morgan
- * compiles with .53
- *
- * Revision 1.2 1996/09/05 06:22:58 morgan
- * Michael's patches
+ * $Id: pam_listfile.c,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
*
*/
/*
- * by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
- * July 25, 1996.
- * This code shamelessly ripped from the pam_rootok module.
+ * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. July 25, 1996.
+ * log refused access error christopher mccrory <chrismcc@netus.com> 1998/7/11
+ *
+ * This code began life as the pam_rootok module.
*/
-#ifdef linux
-# define _SVID_SOURCE
-# define _BSD_SOURCE
-# define __USE_BSD
-# define __USE_SVID
-# define __USE_MISC
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -64,15 +41,15 @@
/* some syslogging */
+#define LOCAL_LOG_PREFIX "PAM-listfile: "
+
static void _pam_log(int err, const char *format, ...)
{
va_list args;
-
+
va_start(args, format);
- openlog("PAM-listfile", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
+ vsyslog(LOG_AUTH | err, format, args);
va_end(args);
- closelog();
}
/* checks if a user is on a list of members */
@@ -223,36 +200,41 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
strncpy(apply_val,myval,sizeof(apply_val)-1);
}
} else {
- _pam_log(LOG_ERR,"Unknown option: %s",mybuf);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Unknown option: %s",mybuf);
return onerr;
}
}
if(!citem) {
- _pam_log(LOG_ERR,"Unknown item or item not specified");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Unknown item or item not specified");
return onerr;
} else if(!ifname) {
- _pam_log(LOG_ERR,"List filename not specified");
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "List filename not specified");
return onerr;
} else if(sense == 2) {
- _pam_log(LOG_ERR,"Unknown sense or sense not specified");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Unknown sense or sense not specified");
return onerr;
} else if(
(apply_type==APPLY_TYPE_NONE) ||
((apply_type!=APPLY_TYPE_NULL) && (*apply_val=='\0'))
) {
- _pam_log(LOG_ERR,"Invalid usage for apply= parameter");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Invalid usage for apply= parameter");
return onerr;
}
/* Check if it makes sense to use the apply= parameter */
if (apply_type != APPLY_TYPE_NULL) {
if((citem==PAM_USER) || (citem==PAM_RUSER)) {
- _pam_log(LOG_WARNING,"Non-sense use for apply= parameter");
+ _pam_log(LOG_WARNING,
+ LOCAL_LOG_PREFIX "Non-sense use for apply= parameter");
apply_type=APPLY_TYPE_NULL;
}
if(extitem && (extitem==EI_GROUP)) {
- _pam_log(LOG_WARNING,"Non-sense use for apply= parameter");
+ _pam_log(LOG_WARNING,
+ LOCAL_LOG_PREFIX "Non-sense use for apply= parameter");
apply_type=APPLY_TYPE_NULL;
}
}
@@ -269,7 +251,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(strcmp(user_name, apply_val)) {
/* Does not apply to this user */
#ifdef DEBUG
- _pam_log(LOG_DEBUG,"don't apply: apply=%s, user=%s",
+ _pam_log(LOG_DEBUG,
+ LOCAL_LOG_PREFIX "don't apply: apply=%s, user=%s",
apply_val,user_name);
#endif /* DEBUG */
return PAM_IGNORE;
@@ -278,7 +261,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(!is_on_group(user_name,apply_val)) {
/* Not a member of apply= group */
#ifdef DEBUG
- _pam_log(LOG_DEBUG,"don't apply: %s not a member of group %s",
+ _pam_log(LOG_DEBUG,
+ LOCAL_LOG_PREFIX
+ "don't apply: %s not a member of group %s",
user_name,apply_val);
#endif /* DEBUG */
return PAM_IGNORE;
@@ -331,18 +316,21 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
endpwent();
break;
default:
- _pam_log(LOG_ERR,"Internal weirdness, unknown extended item %d",
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX
+ "Internal weirdness, unknown extended item %d",
extitem);
return onerr;
}
}
#ifdef DEBUG
- _pam_log(LOG_INFO,"Got file = %s, item = %d, value = %s, sense = %d",
+ _pam_log(LOG_INFO,
+ LOCAL_LOG_PREFIX
+ "Got file = %s, item = %d, value = %s, sense = %d",
ifname, citem, citemp, sense);
#endif
if(lstat(ifname,&fileinfo)) {
- _pam_log(LOG_ERR,
- "Couldn't open %s",ifname);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Couldn't open %s",ifname);
return onerr;
}
@@ -350,7 +338,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
|| !S_ISREG(fileinfo.st_mode)) {
/* If the file is world writable or is not a
normal file, return error */
- _pam_log(LOG_ERR,
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX
"%s is either world writable or not a normal file",
ifname);
return PAM_AUTH_ERR;
@@ -360,7 +348,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(inf == NULL) { /* Check that we opened it successfully */
if (onerr == PAM_SERVICE_ERR) {
/* Only report if it's an error... */
- _pam_log(LOG_ERR, "Error opening %s", ifname);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Error opening %s", ifname);
}
return onerr;
}
@@ -394,19 +382,24 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
}
fclose(inf);
free(ifname);
- if(retval) {
+ if ((sense && retval) || (!sense && !retval)) {
#ifdef DEBUG
- syslog(LOG_INFO,"Returning %d, retval = %d",
- sense?PAM_AUTH_ERR:PAM_SUCCESS, retval);
+ _pam_log(LOG_INFO, LOCAL_LOG_PREFIX
+ "Returning PAM_SUCCESS, retval = %d", retval);
#endif
- return sense?PAM_SUCCESS:PAM_AUTH_ERR;
+ return PAM_SUCCESS;
}
else {
+ const char *service, *user_name;
#ifdef DEBUG
- syslog(LOG_INFO,"Returning %d, retval = %d",
- sense?PAM_SUCCESS:PAM_AUTH_ERR, retval);
+ _pam_log(LOG_INFO,LOCAL_LOG_PREFIX
+ "Returning PAM_AUTH_ERR, retval = %d", retval);
#endif
- return sense?PAM_AUTH_ERR:PAM_SUCCESS;
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service);
+ (void) pam_get_user(pamh, &user_name, NULL);
+ _pam_log(LOG_ALERT,LOCAL_LOG_PREFIX "Refused user %s for service %s",
+ user_name, service);
+ return PAM_AUTH_ERR;
}
}
diff --git a/contrib/libpam/modules/pam_mail/Makefile b/contrib/libpam/modules/pam_mail/Makefile
index 5a402ea4015b..2d9b8e9a30a3 100644
--- a/contrib/libpam/modules/pam_mail/Makefile
+++ b/contrib/libpam/modules/pam_mail/Makefile
@@ -1,107 +1,15 @@
#
-# $Id: Makefile,v 1.3 1997/04/05 06:37:45 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.3 1997/04/05 06:37:45 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.2 1997/02/15 16:07:22 morgan
-# optional libpwdb compilation
-#
-# Revision 1.1 1997/01/04 20:32:52 morgan
-# Initial revision
-#
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-#
-
-TITLE=pam_mail
-
-ifndef STATIC
-ifeq ($(HAVE_PWDBLIB),yes)
-CFLAGS += -DWANT_PWDB
-EXTRALIB = -lpwdb
-endif
-endif
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
+include ../../Make.Rules
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(EXTRALIB)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_mail
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_mail/README b/contrib/libpam/modules/pam_mail/README
new file mode 100644
index 000000000000..155bd1db66dc
--- /dev/null
+++ b/contrib/libpam/modules/pam_mail/README
@@ -0,0 +1,17 @@
+This is the README for pam_mail
+-------------------------------
+
+This PAM module tells the User that he has new/unread email.
+
+Options for:
+auth: for authentication it provides pam_authenticate() and
+ pam_setcred() hooks.
+
+ "debug" write more information to syslog
+ "dir=maildir" users mailbox is maildir/<login>
+ "hash=count" mail directory hash depth
+ "close" print message also on logout
+ "nopen" print message not on login
+ "noenv" don't set the MAIL environment variable
+ "empty" also print message if user has no mail
+
diff --git a/contrib/libpam/modules/pam_mail/pam_mail.c b/contrib/libpam/modules/pam_mail/pam_mail.c
index 15160f3d5208..df00315ab304 100644
--- a/contrib/libpam/modules/pam_mail/pam_mail.c
+++ b/contrib/libpam/modules/pam_mail/pam_mail.c
@@ -1,29 +1,14 @@
/* pam_mail module */
/*
- * $Id: pam_mail.c,v 1.2 1997/02/15 16:06:14 morgan Exp morgan $
+ * $Id: pam_mail.c,v 1.3 2000/12/04 20:59:13 baggins Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
* $HOME additions by David Kinchlea <kinch@kinch.ark.com> 1997/1/7
- *
- * $Log: pam_mail.c,v $
- * Revision 1.2 1997/02/15 16:06:14 morgan
- * session -> setcred, also added "~"=$HOME
- *
- * Revision 1.1 1997/01/04 20:33:02 morgan
- * Initial revision
+ * mailhash additions by Chris Adams <cadams@ro.com> 1998/7/11
*/
-#define DEFAULT_MAIL_DIRECTORY "/var/spool/mail"
-#define MAIL_FILE_FORMAT "%s/%s"
-#define MAIL_ENV_NAME "MAIL"
-#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
-#define YOUR_MAIL_FORMAT "You have %s mail in %s"
-
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <ctype.h>
#include <pwd.h>
@@ -35,11 +20,20 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <dirent.h>
#ifdef WANT_PWDB
#include <pwdb/pwdb_public.h>
#endif
+#define DEFAULT_MAIL_DIRECTORY PAM_PATH_MAILDIR
+#define MAIL_FILE_FORMAT "%s%s/%s"
+#define MAIL_ENV_NAME "MAIL"
+#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
+#define YOUR_MAIL_VERBOSE_FORMAT "You have %s mail in %s."
+#define YOUR_MAIL_STANDARD_FORMAT "You have %smail."
+#define NO_MAIL_STANDARD_FORMAT "No mail."
+
/*
* here, we make a definition for the externally accessible function
* in this file (this definition is required for static a module
@@ -47,6 +41,7 @@
* modules include file to define the function prototypes.
*/
+#define PAM_SM_SESSION
#define PAM_SM_AUTH
#include <security/pam_modules.h>
@@ -67,16 +62,19 @@ static void _log_err(int err, const char *format, ...)
/* argument parsing */
-#define PAM_DEBUG_ARG 01
-#define PAM_NO_LOGIN 02
-#define PAM_LOGOUT_TOO 04
-#define PAM_NEW_MAIL_DIR 010
-#define PAM_MAIL_SILENT 020
-#define PAM_NO_ENV 040
-#define PAM_HOME_MAIL 0100
-#define PAM_EMPTY_TOO 0200
-
-static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_NO_LOGIN 0x0002
+#define PAM_LOGOUT_TOO 0x0004
+#define PAM_NEW_MAIL_DIR 0x0010
+#define PAM_MAIL_SILENT 0x0020
+#define PAM_NO_ENV 0x0040
+#define PAM_HOME_MAIL 0x0100
+#define PAM_EMPTY_TOO 0x0200
+#define PAM_STANDARD_MAIL 0x0400
+#define PAM_QUIET_MAIL 0x1000
+
+static int _pam_parse(int flags, int argc, const char **argv, char **maildir,
+ int *hashcount)
{
int ctrl=0;
@@ -84,6 +82,8 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
ctrl |= PAM_MAIL_SILENT;
}
+ *hashcount = 0;
+
/* step through arguments */
for (; argc-- > 0; ++argv) {
@@ -91,6 +91,10 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv,"quiet"))
+ ctrl |= PAM_QUIET_MAIL;
+ else if (!strcmp(*argv,"standard"))
+ ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO;
else if (!strncmp(*argv,"dir=",4)) {
*maildir = x_strdup(4+*argv);
if (*maildir != NULL) {
@@ -100,6 +104,12 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
_log_err(LOG_CRIT,
"failed to duplicate mail directory - ignored");
}
+ } else if (!strncmp(*argv,"hash=",5)) {
+ char *ep = NULL;
+ *hashcount = strtol(*argv+5,&ep,10);
+ if (!ep || (*hashcount < 0)) {
+ *hashcount = 0;
+ }
} else if (!strcmp(*argv,"close")) {
ctrl |= PAM_LOGOUT_TOO;
} else if (!strcmp(*argv,"nopen")) {
@@ -113,6 +123,11 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
}
}
+ if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) {
+ *maildir = x_strdup(DEFAULT_MAIL_DIRECTORY);
+ ctrl |= PAM_NEW_MAIL_DIR;
+ }
+
return ctrl;
}
@@ -150,8 +165,8 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
return retval; /* propagate error status */
}
-static int get_folder(pam_handle_t *pamh, int ctrl
- , char **path_mail, char **folder_p)
+static int get_folder(pam_handle_t *pamh, int ctrl,
+ char **path_mail, char **folder_p, int hashcount)
{
int retval;
const char *user, *path;
@@ -184,6 +199,9 @@ static int get_folder(pam_handle_t *pamh, int ctrl
return PAM_ABORT;
}
ctrl |= PAM_HOME_MAIL;
+ if (hashcount != 0) {
+ _log_err(LOG_ALERT, "can't do hash= and home directory mail");
+ }
}
} else {
path = DEFAULT_MAIL_DIRECTORY;
@@ -195,14 +213,29 @@ static int get_folder(pam_handle_t *pamh, int ctrl
folder = malloc(sizeof(MAIL_FILE_FORMAT)
+strlen(pwd->pw_dir)+strlen(path));
} else {
- folder = malloc(sizeof(MAIL_FILE_FORMAT)+strlen(path)+strlen(user));
+ folder = malloc(sizeof(MAIL_FILE_FORMAT)+strlen(path)+strlen(user)
+ +2*hashcount);
}
if (folder != NULL) {
if (ctrl & PAM_HOME_MAIL) {
- sprintf(folder, MAIL_FILE_FORMAT, pwd->pw_dir, path);
+ sprintf(folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path);
} else {
- sprintf(folder, MAIL_FILE_FORMAT, path, user);
+ int i;
+ char *hash = malloc(2*hashcount+1);
+
+ if (hash) {
+ for (i = 0; i < hashcount; i++) {
+ hash[2*i] = '/';
+ hash[2*i+1] = user[i];
+ }
+ hash[2*i] = '\0';
+ sprintf(folder, MAIL_FILE_FORMAT, path, hash, user);
+ _pam_overwrite(hash);
+ _pam_drop(hash);
+ } else {
+ sprintf(folder, "error");
+ }
}
D(("folder =[%s]", folder));
}
@@ -226,17 +259,52 @@ static int get_folder(pam_handle_t *pamh, int ctrl
static const char *get_mail_status(int ctrl, const char *folder)
{
- const char *type;
+ const char *type = NULL;
+ static char dir[256];
struct stat mail_st;
-
- if (stat(folder, &mail_st) == 0 && mail_st.st_size > 0) {
- type = (mail_st.st_atime < mail_st.st_mtime) ? "new":"old" ;
- } else if (ctrl & PAM_EMPTY_TOO) {
- type = "no";
- } else {
- type = NULL;
+ struct dirent **namelist;
+ int i;
+
+ if (stat(folder, &mail_st) == 0) {
+ if (S_ISDIR(mail_st.st_mode)) { /* Assume Maildir format */
+ sprintf(dir, "%.250s/new", folder);
+ i = scandir(dir, &namelist, 0, alphasort);
+ if (i > 2) {
+ type = "new";
+ while (--i)
+ free(namelist[i]);
+ } else {
+ while (--i >= 0)
+ free(namelist[i]);
+ sprintf(dir, "%.250s/cur", folder);
+ i = scandir(dir, &namelist, 0, alphasort);
+ if (i > 2) {
+ type = "old";
+ while (--i)
+ free(namelist[i]);
+ } else if (ctrl & PAM_EMPTY_TOO) {
+ while (--i >= 0)
+ free(namelist[i]);
+ type = "no";
+ } else {
+ type = NULL;
+ }
+ }
+ } else {
+ if (mail_st.st_size > 0) {
+ if (mail_st.st_atime < mail_st.st_mtime) /* new */
+ type = (ctrl & PAM_STANDARD_MAIL) ? "new " : "new";
+ else /* old */
+ type = (ctrl & PAM_STANDARD_MAIL) ? "" : "old";
+ } else if (ctrl & PAM_EMPTY_TOO) {
+ type = "no";
+ } else {
+ type = NULL;
+ }
+ }
}
+ memset(dir, 0, 256);
memset(&mail_st, 0, sizeof(mail_st));
D(("user has %s mail in %s folder", type, folder));
return type;
@@ -247,17 +315,29 @@ static int report_mail(pam_handle_t *pamh, int ctrl
{
int retval;
- if (!(ctrl & PAM_MAIL_SILENT)) {
+ if (!(ctrl & PAM_MAIL_SILENT) || ((ctrl & PAM_QUIET_MAIL) && strcmp(type, "new"))) {
char *remark;
- remark = malloc(sizeof(YOUR_MAIL_FORMAT)+strlen(type)+strlen(folder));
+ if (ctrl & PAM_STANDARD_MAIL)
+ if (!strcmp(type, "no"))
+ remark = malloc(strlen(NO_MAIL_STANDARD_FORMAT)+1);
+ else
+ remark = malloc(strlen(YOUR_MAIL_STANDARD_FORMAT)+strlen(type)+1);
+ else
+ remark = malloc(strlen(YOUR_MAIL_VERBOSE_FORMAT)+strlen(type)+strlen(folder)+1);
if (remark == NULL) {
retval = PAM_BUF_ERR;
} else {
struct pam_message msg[1], *mesg[1];
struct pam_response *resp=NULL;
- sprintf(remark, YOUR_MAIL_FORMAT, type, folder);
+ if (ctrl & PAM_STANDARD_MAIL)
+ if (!strcmp(type, "no"))
+ sprintf(remark, NO_MAIL_STANDARD_FORMAT);
+ else
+ sprintf(remark, YOUR_MAIL_STANDARD_FORMAT, type);
+ else
+ sprintf(remark, YOUR_MAIL_VERBOSE_FORMAT, type, folder);
mesg[0] = &msg[0];
msg[0].msg_style = PAM_TEXT_INFO;
@@ -279,28 +359,51 @@ static int report_mail(pam_handle_t *pamh, int ctrl
return retval;
}
-/* --- authentication management functions (only) --- */
+static int _do_mail(pam_handle_t *, int, int, const char **, int);
-/*
- * Cannot use mail to authenticate yourself
- */
+/* --- authentication functions --- */
PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
- ,const char **argv)
+int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
+ const char **argv)
{
return PAM_IGNORE;
}
-/*
- * MAIL is a "credential"
- */
+/* Checking mail as part of authentication */
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED)))
+ return PAM_IGNORE;
+ return _do_mail(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED));
+}
+
+/* --- session management functions --- */
+
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return _do_mail(pamh,flags,argc,argv,0);;
+}
+/* Checking mail as part of the session management */
PAM_EXTERN
-int pam_sm_setcred(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 retval, ctrl;
+ return _do_mail(pamh,flags,argc,argv,1);
+}
+
+
+/* --- The Beaf (Tm) --- */
+
+static int _do_mail(pam_handle_t *pamh, int flags, int argc,
+ const char **argv, int est)
+{
+ int retval, ctrl, hashcount;
char *path_mail=NULL, *folder;
const char *type;
@@ -309,17 +412,16 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
* the user has any new mail.
*/
- ctrl = _pam_parse(flags, argc, argv, &path_mail);
+ ctrl = _pam_parse(flags, argc, argv, &path_mail, &hashcount);
/* Do we have anything to do? */
- if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED))) {
+ if (flags & PAM_SILENT)
return PAM_SUCCESS;
- }
/* which folder? */
- retval = get_folder(pamh, ctrl, &path_mail, &folder);
+ retval = get_folder(pamh, ctrl, &path_mail, &folder, hashcount);
if (retval != PAM_SUCCESS) {
D(("failed to find folder"));
return retval;
@@ -327,7 +429,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
/* set the MAIL variable? */
- if (!(ctrl & PAM_NO_ENV) && (flags & PAM_ESTABLISH_CRED)) {
+ if (!(ctrl & PAM_NO_ENV) && est) {
char *tmp;
tmp = malloc(strlen(folder)+sizeof(MAIL_ENV_FORMAT));
@@ -357,24 +459,20 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
* OK. we've got the mail folder... what about its status?
*/
- if (((flags & PAM_ESTABLISH_CRED) && !(ctrl & PAM_NO_LOGIN))
- || ((flags & PAM_DELETE_CRED) && (ctrl & PAM_LOGOUT_TOO))) {
+ if ((est && !(ctrl & PAM_NO_LOGIN))
+ || (!est && (ctrl & PAM_LOGOUT_TOO))) {
type = get_mail_status(ctrl, folder);
if (type != NULL) {
retval = report_mail(pamh, ctrl, type, folder);
type = NULL;
}
}
-
- /*
- * Delete environment variable?
- */
-
- if (flags & PAM_DELETE_CRED) {
+
+ /* Delete environment variable? */
+ if (!est)
(void) pam_putenv(pamh, MAIL_ENV_NAME);
- }
- _pam_overwrite(folder); /* clean up */
+ _pam_overwrite(folder); /* clean up */
_pam_drop(folder);
/* indicate success or failure */
@@ -391,8 +489,8 @@ struct pam_module _pam_mail_modstruct = {
pam_sm_authenticate,
pam_sm_setcred,
NULL,
- NULL,
- NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
NULL,
};
diff --git a/contrib/libpam/modules/pam_mkhomedir/Makefile b/contrib/libpam/modules/pam_mkhomedir/Makefile
new file mode 100644
index 000000000000..f017f4a469ec
--- /dev/null
+++ b/contrib/libpam/modules/pam_mkhomedir/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.3 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_mkhomedir
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c b/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c
new file mode 100644
index 000000000000..ec05993dfa1e
--- /dev/null
+++ b/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -0,0 +1,370 @@
+/* PAM Make Home Dir module
+
+ This module will create a users home directory if it does not exist
+ when the session begins. This allows users to be present in central
+ database (such as nis, kerb or ldap) without using a distributed
+ file system or pre-creating a large number of directories.
+
+ Here is a sample /etc/pam.d/login file for Debian GNU/Linux
+ 2.1:
+
+ auth requisite pam_securetty.so
+ auth sufficient pam_ldap.so
+ auth required pam_pwdb.so
+ auth optional pam_group.so
+ auth optional pam_mail.so
+ account requisite pam_time.so
+ account sufficient pam_ldap.so
+ account required pam_pwdb.so
+ session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+ session required pam_pwdb.so
+ session optional pam_lastlog.so
+ password required pam_pwdb.so
+
+ Released under the GNU LGPL version 2 or later
+ Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999
+ Structure taken from pam_lastlogin by Andrew Morgan
+ <morgan@parc.power.net> 1996
+ */
+
+/* I want snprintf dammit */
+#define _GNU_SOURCE 1
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_SESSION
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+/* argument parsing */
+#define MKHOMEDIR_DEBUG 020 /* keep quiet about things */
+#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
+
+static unsigned int UMask = 0022;
+static char SkelDir[BUFSIZ] = "/etc/skel";
+
+/* some syslogging */
+static void _log_err(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-mkhomedir", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static int _pam_parse(int flags, int argc, const char **argv)
+{
+ int ctrl = 0;
+
+ /* does the appliction require quiet? */
+ if ((flags & PAM_SILENT) == PAM_SILENT)
+ ctrl |= MKHOMEDIR_QUIET;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv)
+ {
+ if (!strcmp(*argv, "silent"))
+ {
+ ctrl |= MKHOMEDIR_QUIET;
+ }
+ else if (!strncmp(*argv,"umask=",6))
+ UMask = strtol(*argv+6,0,0);
+ else if (!strncmp(*argv,"skel=",5))
+ strcpy(SkelDir,*argv+5);
+ else
+ {
+ _log_err(LOG_ERR, "unknown option; %s", *argv);
+ }
+ }
+
+ D(("ctrl = %o", ctrl));
+ return ctrl;
+}
+
+/* This common function is used to send a message to the applications
+ conversion function. Our only use is to ask the application to print
+ an informative message that we are creating a home directory */
+static int converse(pam_handle_t * pamh, int ctrl, int nargs
+ ,struct pam_message **message
+ ,struct pam_response **response)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("begin to converse"));
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS)
+ {
+
+ retval = conv->conv(nargs, (const struct pam_message **) message
+ ,response, conv->appdata_ptr);
+
+ D(("returned from application's conversation function"));
+
+ if (retval != PAM_SUCCESS && (ctrl & MKHOMEDIR_DEBUG))
+ {
+ _log_err(LOG_DEBUG, "conversation failure [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+
+ }
+ else
+ {
+ _log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+
+ D(("ready to return from module conversation"));
+
+ return retval; /* propagate error status */
+}
+
+/* Ask the application to display a short text string for us. */
+static int make_remark(pam_handle_t * pamh, int ctrl, const char *remark)
+{
+ int retval;
+
+ if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET)
+ {
+ struct pam_message msg[1], *mesg[1];
+ struct pam_response *resp = NULL;
+
+ mesg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ msg[0].msg = remark;
+
+ retval = converse(pamh, ctrl, 1, mesg, &resp);
+
+ msg[0].msg = NULL;
+ if (resp)
+ {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ else
+ {
+ D(("keeping quiet"));
+ retval = PAM_SUCCESS;
+ }
+
+ D(("returning %s", pam_strerror(pamh, retval)));
+ return retval;
+}
+
+/* Do the actual work of creating a home dir */
+static int create_homedir(pam_handle_t * pamh, int ctrl,
+ const struct passwd *pwd)
+{
+ char *remark;
+ DIR *D;
+ struct dirent *Dir;
+
+ /* Some scratch space */
+ remark = malloc(BUFSIZ);
+ if (remark == NULL)
+ {
+ D(("no memory for last login remark"));
+ return PAM_BUF_ERR;
+ }
+
+ /* Mention what is happening, if the notification fails that is OK */
+ if (snprintf(remark,BUFSIZ,"Creating home directory '%s'.",
+ pwd->pw_dir) == -1)
+ return PAM_PERM_DENIED;
+
+ make_remark(pamh, ctrl, remark);
+
+ /* Crete the home directory */
+ if (mkdir(pwd->pw_dir,0700) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to create home directory %s",pwd->pw_dir);
+ return PAM_PERM_DENIED;
+ }
+ if (chmod(pwd->pw_dir,0777 & (~UMask)) != 0 ||
+ chown(pwd->pw_dir,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to chance perms on home directory %s",pwd->pw_dir);
+ return PAM_PERM_DENIED;
+ }
+
+ /* See if we need to copy the skel dir over. */
+ if (SkelDir[0] == 0)
+ {
+ free(remark);
+ return PAM_SUCCESS;
+ }
+
+ /* Scan the directory */
+ D = opendir(SkelDir);
+ if (D == 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to read directory %s",SkelDir);
+ return PAM_PERM_DENIED;
+ }
+
+ for (Dir = readdir(D); Dir != 0; Dir = readdir(D))
+ {
+ int SrcFd;
+ int DestFd;
+ int Res;
+ struct stat St;
+
+ /* Skip some files.. */
+ if (strcmp(Dir->d_name,".") == 0 ||
+ strcmp(Dir->d_name,"..") == 0)
+ continue;
+
+ /* Check if it is a directory */
+ snprintf(remark,BUFSIZ,"%s/%s",SkelDir,Dir->d_name);
+ if (stat(remark,&St) != 0)
+ continue;
+ if (S_ISDIR(St.st_mode))
+ {
+ snprintf(remark,BUFSIZ,"%s/%s",pwd->pw_dir,Dir->d_name);
+ if (mkdir(remark,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ chmod(remark,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ chown(remark,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to change perms on copy %s",remark);
+ return PAM_PERM_DENIED;
+ }
+ continue;
+ }
+
+ /* Open the source file */
+ if ((SrcFd = open(remark,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to open src file %s",remark);
+ return PAM_PERM_DENIED;
+ }
+ stat(remark,&St);
+
+ /* Open the dest file */
+ snprintf(remark,BUFSIZ,"%s/%s",pwd->pw_dir,Dir->d_name);
+ if ((DestFd = open(remark,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0)
+ {
+ close(SrcFd);
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to open dest file %s",remark);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Set the proper ownership and permissions for the module. We make
+ the file a+w and then mask it with the set mask. This preseves
+ execute bits */
+ if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to chang perms on copy %s",remark);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Copy the file */
+ do
+ {
+ Res = read(SrcFd,remark,BUFSIZ);
+ if (Res < 0 || write(DestFd,remark,Res) != Res)
+ {
+ close(SrcFd);
+ close(DestFd);
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to perform IO");
+ return PAM_PERM_DENIED;
+ }
+ }
+ while (Res != 0);
+ close(SrcFd);
+ close(DestFd);
+ }
+
+ free(remark);
+ return PAM_SUCCESS;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc
+ ,const char **argv)
+{
+ int retval, ctrl;
+ const char *user;
+ const struct passwd *pwd;
+ struct stat St;
+
+ /* Parse the flag values */
+ ctrl = _pam_parse(flags, argc, argv);
+
+ /* Determine the user name so we can get the home directory */
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &user);
+ if (retval != PAM_SUCCESS || user == NULL || *user == '\0')
+ {
+ _log_err(LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Get the password entry */
+ pwd = getpwnam(user);
+ if (pwd == NULL)
+ {
+ D(("couldn't identify user %s", user));
+ return PAM_CRED_INSUFFICIENT;
+ }
+
+ /* Stat the home directory, if something exists then we assume it is
+ correct and return a success*/
+ if (stat(pwd->pw_dir,&St) == 0)
+ return PAM_SUCCESS;
+
+ return create_homedir(pamh,ctrl,pwd);
+}
+
+/* Ignore */
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t * pamh, int flags, int argc
+ ,const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+struct pam_module _pam_mkhomedir_modstruct =
+{
+ "pam_mkhomedir",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+
+#endif
diff --git a/contrib/libpam/modules/pam_motd/Makefile b/contrib/libpam/modules/pam_motd/Makefile
new file mode 100644
index 000000000000..fb83807a36da
--- /dev/null
+++ b/contrib/libpam/modules/pam_motd/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_motd
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_motd/pam_motd.c b/contrib/libpam/modules/pam_motd/pam_motd.c
new file mode 100644
index 000000000000..2434b2986c9b
--- /dev/null
+++ b/contrib/libpam/modules/pam_motd/pam_motd.c
@@ -0,0 +1,119 @@
+/* pam_motd module */
+
+/*
+ * Modified for pam_motd by Ben Collins <bcollins@debian.org>
+ *
+ * Based off of:
+ * $Id: pam_motd.c,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
+ *
+ * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#include <security/_pam_macros.h>
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_SESSION
+#define DEFAULT_MOTD "/etc/motd"
+
+#include <security/pam_modules.h>
+
+/* --- session management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval = PAM_IGNORE;
+ int fd;
+ char *mtmp=NULL, *motd_path=NULL;
+ struct pam_conv *conversation;
+ struct pam_message message;
+ struct pam_message *pmessage = &message;
+ struct pam_response *resp = NULL;
+ struct stat st;
+
+ if (flags & PAM_SILENT) {
+ return retval;
+ }
+
+ for (; argc-- > 0; ++argv) {
+ if (!strncmp(*argv,"motd=",5)) {
+ motd_path = (char *) strdup(5+*argv);
+ if (motd_path != NULL) {
+ D(("set motd path: %s", motd_path));
+ } else {
+ D(("failed to duplicate motd path - ignored"));
+ }
+ }
+ }
+
+ if (motd_path == NULL)
+ motd_path = DEFAULT_MOTD;
+
+ message.msg_style = PAM_TEXT_INFO;
+
+ if ((fd = open(motd_path, O_RDONLY, 0)) >= 0) {
+ /* fill in message buffer with contents of motd */
+ if ((fstat(fd, &st) < 0) || !st.st_size)
+ return retval;
+ message.msg = mtmp = malloc(st.st_size+1);
+ /* if malloc failed... */
+ if (!message.msg) return retval;
+ read(fd, mtmp, st.st_size);
+ if (mtmp[st.st_size-1] == '\n')
+ mtmp[st.st_size-1] = '\0';
+ else
+ mtmp[st.st_size] = '\0';
+ close(fd);
+ /* Use conversation function to give user contents of motd */
+ pam_get_item(pamh, PAM_CONV, (const void **)&conversation);
+ conversation->conv(1, (const struct pam_message **)&pmessage,
+ &resp, conversation->appdata_ptr);
+ free(mtmp);
+ if (resp)
+ _pam_drop_reply(resp, 1);
+ }
+
+ return retval;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_motd_modstruct = {
+ "pam_motd",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_nologin/Makefile b/contrib/libpam/modules/pam_nologin/Makefile
index 0769bb993120..2ad38ffd9609 100644
--- a/contrib/libpam/modules/pam_nologin/Makefile
+++ b/contrib/libpam/modules/pam_nologin/Makefile
@@ -1,86 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-TITLE=pam_nologin
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- mkdir -p ./dynamic
-endif
-ifdef STATIC
- mkdir -p ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- mkdir -p $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- install -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_nologin
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_nologin/README b/contrib/libpam/modules/pam_nologin/README
index ab7ccd7d9803..9b00e6923868 100644
--- a/contrib/libpam/modules/pam_nologin/README
+++ b/contrib/libpam/modules/pam_nologin/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/10/25 03:19:36 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
#
This module always lets root in; it lets other users in only if the file
diff --git a/contrib/libpam/modules/pam_nologin/pam_nologin.c b/contrib/libpam/modules/pam_nologin/pam_nologin.c
index 2788dcf8f39a..1359c18bfaf6 100644
--- a/contrib/libpam/modules/pam_nologin/pam_nologin.c
+++ b/contrib/libpam/modules/pam_nologin/pam_nologin.c
@@ -1,24 +1,10 @@
/* pam_nologin module */
/*
- * $Id: pam_nologin.c,v 1.4 1997/04/05 06:36:47 morgan Exp morgan $
+ * $Id: pam_nologin.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
*
- * $Log: pam_nologin.c,v $
- * Revision 1.4 1997/04/05 06:36:47 morgan
- * display message when the user is unknown
- *
- * Revision 1.3 1996/12/01 03:00:54 morgan
- * added prototype to conversation, gave static structure name of module
- *
- * Revision 1.2 1996/11/10 21:02:31 morgan
- * compile against .53
- *
- * Revision 1.1 1996/10/25 03:19:36 morgan
- * Initial revision
- *
- *
*/
#include <stdio.h>
diff --git a/contrib/libpam/modules/pam_permit/Makefile b/contrib/libpam/modules/pam_permit/Makefile
index 823b62472e35..49f3b3dd5e20 100644
--- a/contrib/libpam/modules/pam_permit/Makefile
+++ b/contrib/libpam/modules/pam_permit/Makefile
@@ -1,126 +1,15 @@
#
-# $Id: Makefile,v 1.8 1997/04/05 06:33:25 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.8 1997/04/05 06:33:25 morgan
-# fakeroot
-#
-# Revision 1.7 1997/02/15 19:02:27 morgan
-# updated email address
-#
-# Revision 1.6 1996/11/10 20:14:34 morgan
-# cross platform support
-#
-# Revision 1.5 1996/09/05 06:32:45 morgan
-# ld --> gcc
-#
-# Revision 1.4 1996/05/26 15:49:25 morgan
-# make dynamic and static dirs
-#
-# Revision 1.3 1996/05/26 04:04:26 morgan
-# automated static support
-#
-# Revision 1.2 1996/03/16 17:56:38 morgan
-# tidied up
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-#
-#
+include ../../Make.Rules
TITLE=pam_permit
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-endif
-
-ifdef DYNAMIC
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-endif
-
-ifdef STATIC
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_permit/README b/contrib/libpam/modules/pam_permit/README
index da179a34829c..52e7364e8753 100644
--- a/contrib/libpam/modules/pam_permit/README
+++ b/contrib/libpam/modules/pam_permit/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/03/16 18:12:51 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
#
this module always returns PAM_SUCCESS, it ignores all options.
diff --git a/contrib/libpam/modules/pam_permit/pam_permit.c b/contrib/libpam/modules/pam_permit/pam_permit.c
index 1bdd5644a63b..46e36eb97c24 100644
--- a/contrib/libpam/modules/pam_permit/pam_permit.c
+++ b/contrib/libpam/modules/pam_permit/pam_permit.c
@@ -1,20 +1,10 @@
/* pam_permit module */
/*
- * $Id: pam_permit.c,v 1.5 1997/02/15 19:03:15 morgan Exp $
+ * $Id: pam_permit.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
*
- * $Log: pam_permit.c,v $
- * Revision 1.5 1997/02/15 19:03:15 morgan
- * fixed email address
- *
- * Revision 1.4 1997/02/15 16:03:10 morgan
- * force a name for user
- *
- * Revision 1.3 1996/06/02 08:10:14 morgan
- * updated for new static protocol
- *
*/
#define DEFAULT_USER "nobody"
diff --git a/contrib/libpam/modules/pam_pwdb/BUGS b/contrib/libpam/modules/pam_pwdb/BUGS
index 397f367b5372..d51686e51d76 100644
--- a/contrib/libpam/modules/pam_pwdb/BUGS
+++ b/contrib/libpam/modules/pam_pwdb/BUGS
@@ -1,8 +1,3 @@
-$Id: BUGS,v 1.2 1996/09/05 06:36:16 morgan Exp $
-
-$Log: BUGS,v $
-Revision 1.2 1996/09/05 06:36:16 morgan
-revised for .52 to be released
-
+$Id: BUGS,v 1.2 2000/12/04 19:02:34 baggins Exp $
As of Linux-PAM-0.52 this is new. No known bugs yet.
diff --git a/contrib/libpam/modules/pam_pwdb/CHANGELOG b/contrib/libpam/modules/pam_pwdb/CHANGELOG
index 0cb21879120b..a36140319933 100644
--- a/contrib/libpam/modules/pam_pwdb/CHANGELOG
+++ b/contrib/libpam/modules/pam_pwdb/CHANGELOG
@@ -1,4 +1,4 @@
-$Header: /home/morgan/pam/Linux-PAM-0.52/modules/pam_unix/RCS/CHANGELOG,v 1.1 1996/08/29 13:23:29 morgan Exp $
+$Id: CHANGELOG,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
Tue Apr 23 12:28:09 EDT 1996 (Alexander O. Yuriev alex@bach.cis.temple.edu)
diff --git a/contrib/libpam/modules/pam_pwdb/Makefile b/contrib/libpam/modules/pam_pwdb/Makefile
index 7428bb439040..ec66f9e8269c 100644
--- a/contrib/libpam/modules/pam_pwdb/Makefile
+++ b/contrib/libpam/modules/pam_pwdb/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 1997/04/05 06:28:50 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of the pam_unix module
# for Linux-PAM. You should not modify this Makefile.
@@ -7,42 +7,20 @@
# <morgan@parc.power.net> 1996/11/6
#
-#
-# Note, the STATIC module is commented out because it doesn't work.
-# please fix!
-#
+include ../../Make.Rules
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-export HAVE_PWDBLIB=yes
-endif
+ifeq ($(HAVE_LIBPWDB),yes)
-ifeq ($(HAVE_PWDBLIB),yes)
+EXTRALS += -lpwdb
+EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
+
+ifeq ($(HAVE_LIBCRYPT),yes)
+ EXTRALS += -lcrypt
+endif
TITLE=pam_pwdb
CHKPWD=pwdb_chkpwd
-# compilation flags
-EXTRAS=
-# extra object files
-PLUS=
-# extra files that may be needed to be created
-CREATE=
-
-# NOTE: this module links dynamically to the libpwdb library.
-EXTRALS += -lpwdb
-EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
-
-########################### don't edit below ##########################
-
LIBSRC = $(TITLE).c
LIBOBJ = $(TITLE).o
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
@@ -50,7 +28,7 @@ LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBDEPS = pam_unix_acct.-c pam_unix_auth.-c pam_unix_passwd.-c \
pam_unix_sess.-c pam_unix_pwupd.-c support.-c bigcrypt.-c
-PLUS += md5.o md5_crypt.o
+PLUS += md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o
CFLAGS += $(EXTRAS)
ifdef DYNAMIC
@@ -73,11 +51,28 @@ info:
@echo "*** Building PAM_pwdb module..."
@echo
-$(CHKPWD): pwdb_chkpwd.o md5.o md5_crypt.o
+$(CHKPWD): pwdb_chkpwd.o md5_good.o md5_broken.o \
+ md5_crypt_good.o md5_crypt_broken.o
$(CC) -o $(CHKPWD) $^ -lpwdb
pwdb_chkpwd.o: pwdb_chkpwd.c pam_unix_md.-c bigcrypt.-c
+md5_good.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_broken.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_good.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_broken.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
dirs:
ifdef DYNAMIC
@$(MKDIR) ./dynamic
@@ -111,7 +106,7 @@ ifdef DYNAMIC
$(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
endif
$(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
- $(INSTALL) -m 4555 -o root -g root $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
+ $(INSTALL) -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
remove:
rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
@@ -119,37 +114,11 @@ remove:
clean:
rm -f $(CHKPWD) $(LIBOBJD) $(LIBOBJS) $(MOREDELS) core *~ *.o *.so
-
-extraclean: clean
rm -f *.a *.o *.so *.bak
+ rm -fr dynamic static
else
include ../dont_makefile
endif
-
-#####################################################################
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:28:50 morgan
-# fakeroot
-#
-# Revision 1.6 1997/02/15 17:25:32 morgan
-# update for .56 . extra commands for new helper binary
-#
-# Revision 1.5 1997/01/04 20:39:08 morgan
-# conditional on having libpwdb
-#
-# Revision 1.4 1996/12/01 03:02:03 morgan
-# changed banner, removed linking libraries
-#
-# Revision 1.3 1996/11/10 20:14:42 morgan
-# cross platform support
-#
-# Revision 1.2 1996/09/05 06:36:49 morgan
-# options added and use of LD altered
-#
-# Revision 1.1 1996/08/29 13:23:29 morgan
-# Initial revision
-#
-#
diff --git a/contrib/libpam/modules/pam_pwdb/README b/contrib/libpam/modules/pam_pwdb/README
index 351a706008e9..4f420855cded 100644
--- a/contrib/libpam/modules/pam_pwdb/README
+++ b/contrib/libpam/modules/pam_pwdb/README
@@ -7,7 +7,7 @@ passwords.
the license suggests -- use at your own risk.]
So far as I am concerned this module is now pretty stable. If you find
-any bugs, PLEASE tell me! <morgan@parc.power.net>
+any bugs, PLEASE tell me! <morgan@linux.kernel.org>
Options recognized by this module are as follows:
@@ -38,4 +38,4 @@ should read the source to find the appropriate #define that you will
need.
---------------------
-Andrew Morgan <morgan@parc.power.net>
+Andrew Morgan <morgan@linux.kernel.org>
diff --git a/contrib/libpam/modules/pam_pwdb/TODO b/contrib/libpam/modules/pam_pwdb/TODO
index 23eb4c163d08..520a262ec13c 100644
--- a/contrib/libpam/modules/pam_pwdb/TODO
+++ b/contrib/libpam/modules/pam_pwdb/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.3 1996/11/10 21:03:21 morgan Exp $
+$Id: TODO,v 1.1.1.1 2000/06/20 22:11:47 agmorgan Exp $
* get NIS working
* .. including "nonis" argument
diff --git a/contrib/libpam/modules/pam_pwdb/md5.c b/contrib/libpam/modules/pam_pwdb/md5.c
index fdfbdd88f389..4428294178ff 100644
--- a/contrib/libpam/modules/pam_pwdb/md5.c
+++ b/contrib/libpam/modules/pam_pwdb/md5.c
@@ -1,4 +1,4 @@
-/* $Id: md5.c,v 1.1 1996/09/05 06:43:31 morgan Exp $
+/* $Id: md5.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
@@ -15,10 +15,6 @@
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
- * $Log: md5.c,v $
- * Revision 1.1 1996/09/05 06:43:31 morgan
- * Initial revision
- *
*/
#include <string.h>
@@ -27,13 +23,13 @@
#ifndef HIGHFIRST
#define byteReverse(buf, len) /* Nothing */
#else
-void byteReverse(unsigned char *buf, unsigned longs);
+static void byteReverse(unsigned char *buf, unsigned longs);
#ifndef ASM_MD5
/*
* Note: this code is harmless on little-endian machines.
*/
-void byteReverse(unsigned char *buf, unsigned longs)
+static void byteReverse(unsigned char *buf, unsigned longs)
{
uint32 t;
do {
@@ -50,7 +46,7 @@ void byteReverse(unsigned char *buf, unsigned longs)
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
-void MD5Init(struct MD5Context *ctx)
+void MD5Name(MD5Init)(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301U;
ctx->buf[1] = 0xefcdab89U;
@@ -65,7 +61,7 @@ void MD5Init(struct MD5Context *ctx)
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
-void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
{
uint32 t;
@@ -90,7 +86,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
buf += t;
len -= t;
}
@@ -99,7 +95,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
buf += 64;
len -= 64;
}
@@ -113,7 +109,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
@@ -134,7 +130,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
@@ -148,7 +144,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
((uint32 *) ctx->in)[14] = ctx->bits[0];
((uint32 *) ctx->in)[15] = ctx->bits[1];
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
@@ -173,7 +169,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
-void MD5Transform(uint32 buf[4], uint32 const in[16])
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
{
register uint32 a, b, c, d;
diff --git a/contrib/libpam/modules/pam_pwdb/md5.h b/contrib/libpam/modules/pam_pwdb/md5.h
index 4949ade27e1f..75c4dbac85e1 100644
--- a/contrib/libpam/modules/pam_pwdb/md5.h
+++ b/contrib/libpam/modules/pam_pwdb/md5.h
@@ -1,11 +1,7 @@
#ifndef MD5_H
#define MD5_H
-#ifdef __alpha
typedef unsigned int uint32;
-#else
-typedef unsigned long uint32;
-#endif
struct MD5Context {
uint32 buf[4];
@@ -13,13 +9,17 @@ struct MD5Context {
unsigned char in[64];
};
-void MD5Init(struct MD5Context *);
-void MD5Update(struct MD5Context *, unsigned const char *, unsigned);
-void MD5Final(unsigned char digest[16], struct MD5Context *);
-void MD5Transform(uint32 buf[4], uint32 const in[16]);
-int i64c(int i);
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
-char *crypt_md5(const char *pw, const char *salt);
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
diff --git a/contrib/libpam/modules/pam_pwdb/md5_crypt.c b/contrib/libpam/modules/pam_pwdb/md5_crypt.c
index 88be13b7f001..826087f28093 100644
--- a/contrib/libpam/modules/pam_pwdb/md5_crypt.c
+++ b/contrib/libpam/modules/pam_pwdb/md5_crypt.c
@@ -1,4 +1,4 @@
-/* $Id: md5_crypt.c,v 1.1 1996/09/05 06:43:31 morgan Exp $
+/* $Id: md5_crypt.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
@@ -9,10 +9,6 @@
*
* Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
*
- * $Log: md5_crypt.c,v $
- * Revision 1.1 1996/09/05 06:43:31 morgan
- * Initial revision
- *
*/
#include <string.h>
@@ -31,34 +27,12 @@ to64(char *s, unsigned long v, int n)
}
/*
- * i64c - convert an integer to a radix 64 character
- */
-int i64c(int i)
-{
- if (i < 0)
- return ('.');
- else if (i > 63)
- return ('z');
- if (i == 0)
- return ('.');
- if (i == 1)
- return ('/');
- if (i >= 2 && i <= 11)
- return ('0' - 2 + i);
- if (i >= 12 && i <= 37)
- return ('A' - 12 + i);
- if (i >= 38 && i <= 63)
- return ('a' - 38 + i);
- return ('\0');
-}
-
-/*
* UNIX password
*
* Use MD5 for what it is best at...
*/
-char * crypt_md5(const char *pw, const char *salt)
+char * MD5Name(crypt_md5)(const char *pw, const char *salt)
{
const char *magic = "$1$";
/* This string is magic for this algorithm. Having
@@ -84,25 +58,25 @@ char * crypt_md5(const char *pw, const char *salt)
/* get the length of the true salt */
sl = ep - sp;
- MD5Init(&ctx);
+ MD5Name(MD5Init)(&ctx);
/* The password first, since that is what is most unknown */
- MD5Update(&ctx,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw));
/* Then our magic string */
- MD5Update(&ctx,(unsigned const char *)magic,strlen(magic));
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
/* Then the raw salt */
- MD5Update(&ctx,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
/* Then just as many characters of the MD5(pw,salt,pw) */
- MD5Init(&ctx1);
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Update(&ctx1,(unsigned const char *)sp,sl);
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Final(final,&ctx1);
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
for(pl = strlen(pw); pl > 0; pl -= 16)
- MD5Update(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
@@ -110,16 +84,16 @@ char * crypt_md5(const char *pw, const char *salt)
/* Then something really weird... */
for (j=0,i = strlen(pw); i ; i >>= 1)
if(i&1)
- MD5Update(&ctx, (unsigned const char *)final+j, 1);
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
else
- MD5Update(&ctx, (unsigned const char *)pw+j, 1);
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
/* Now make the output string */
strcpy(passwd,magic);
strncat(passwd,sp,sl);
strcat(passwd,"$");
- MD5Final(final,&ctx);
+ MD5Name(MD5Final)(final,&ctx);
/*
* and now, just to make sure things don't run too fast
@@ -127,23 +101,23 @@ char * crypt_md5(const char *pw, const char *salt)
* need 30 seconds to build a 1000 entry dictionary...
*/
for(i=0;i<1000;i++) {
- MD5Init(&ctx1);
+ MD5Name(MD5Init)(&ctx1);
if(i & 1)
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
else
- MD5Update(&ctx1,(unsigned const char *)final,16);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
if(i % 3)
- MD5Update(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
if(i % 7)
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
if(i & 1)
- MD5Update(&ctx1,(unsigned const char *)final,16);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
else
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Final(final,&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
}
p = passwd + strlen(passwd);
diff --git a/contrib/libpam/modules/pam_pwdb/pam_pwdb.c b/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
index a612f74037b4..8c75ac232e18 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
+++ b/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
@@ -1,5 +1,5 @@
/*
- * $Id: pam_pwdb.c,v 1.3 1997/01/04 20:38:33 morgan Exp morgan $
+ * $Id: pam_pwdb.c,v 1.3 2000/11/19 23:54:04 agmorgan Exp $
*
* This is the single file that will be compiled for pam_unix.
* it includes each of the modules that have beed defined in the .-c
@@ -13,37 +13,14 @@
* See the end of this file for Copyright information.
*/
-/*
- * $Log: pam_pwdb.c,v $
- * Revision 1.3 1997/01/04 20:38:33 morgan
- * this is not the unix module!
- *
- * Revision 1.2 1996/12/01 03:03:43 morgan
- * debugging code uses _pam_malloc
- *
- * Revision 1.1 1996/11/10 21:21:24 morgan
- * Initial revision
- *
- * Revision 1.3 1996/09/05 06:44:33 morgan
- * more debugging, fixed static structure name
- *
- * Revision 1.2 1996/09/01 01:05:12 morgan
- * Cristian Gafton's patches.
- *
- * Revision 1.1 1996/08/29 13:22:19 morgan
- * Initial revision
- *
- */
-
static const char rcsid[] =
-"$Id: pam_pwdb.c,v 1.3 1997/01/04 20:38:33 morgan Exp morgan $\n"
+"$Id: pam_pwdb.c,v 1.3 2000/11/19 23:54:04 agmorgan Exp $\n"
" - PWDB Pluggable Authentication module. <morgan@linux.kernel.org>"
;
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+/* #define DEBUG */
+
+#include <security/_pam_aconf.h>
#include <sys/types.h>
#include <stdarg.h>
@@ -56,9 +33,6 @@ static const char rcsid[] =
#include <fcntl.h>
#include <ctype.h>
-#define _SVID_SOURCE
-#define __USE_BSD
-#define _BSD_COMPAT
#include <sys/time.h>
#include <unistd.h>
@@ -100,6 +74,13 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags
retval = _unix_auth( pamh, ctrl );
pwdb_end();
+ if ( on(UNIX_LIKE_AUTH, ctrl) ) {
+ D(("recording return code for next time [%d]", retval));
+ pam_set_data(pamh, "pwdb_setcred_return", (void *) retval, NULL);
+ }
+
+ D(("done. [%s]", pam_strerror(pamh, retval)));
+
return retval;
}
@@ -113,9 +94,17 @@ PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags
pwdb_start();
ctrl = set_ctrl(flags, argc, argv);
- retval = _unix_set_credentials(pamh, ctrl) ;
+ retval = _unix_set_credentials(pamh, ctrl);
pwdb_end();
+ if ( on(UNIX_LIKE_AUTH, ctrl) ) {
+ int *pretval = &retval;
+
+ D(("recovering return code from auth call"));
+ pam_get_data(pamh, "pwdb_setcred_return", (const void **) pretval);
+ D(("recovered data indicates that old retval was %d", retval));
+ }
+
return retval;
}
@@ -203,6 +192,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = _unix_chauthtok(pamh, ctrl);
pwdb_end();
+ D(("done."));
+
return retval;
}
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
index dbd13855ed3c..adcb6538624f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
@@ -1,31 +1,11 @@
/*
- * $Id: pam_unix_acct.-c,v 1.6 1997/01/04 20:37:15 morgan Exp morgan $
- *
- * $Log: pam_unix_acct.-c,v $
- * Revision 1.6 1997/01/04 20:37:15 morgan
- * extra debugging
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:03:57 morgan
- * pwdb conversion
- *
- * Revision 1.3 1996/09/05 06:45:45 morgan
- * tidied shadow acct management
- *
- * Revision 1.2 1996/09/01 01:13:14 morgan
- * Cristian Gafton's patches
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
+ * $Id: pam_unix_acct.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* See end of file for copyright information
*/
static const char rcsid_acct[] =
-"$Id: pam_unix_acct.-c,v 1.6 1997/01/04 20:37:15 morgan Exp morgan $\n"
+"$Id: pam_unix_acct.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB account management <gafton@redhat.com>";
/* the shadow suite has accout managment.. */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
index 4a1eed0d6387..31230394c65f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
@@ -1,25 +1,11 @@
/*
- * $Id: pam_unix_auth.-c,v 1.4 1996/12/01 03:05:54 morgan Exp $
+ * $Id: pam_unix_auth.-c,v 1.1.1.1 2000/06/20 22:11:49 agmorgan Exp $
*
- * $Log: pam_unix_auth.-c,v $
- * Revision 1.4 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.3 1996/11/10 21:04:29 morgan
- * pwdb conversion
- *
- * Revision 1.2 1996/09/05 06:46:53 morgan
- * fixed comments. Added check for null passwd.
- * changed data item name
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
* See end of file for Copyright information.
*/
static const char rcsid_auth[] =
-"$Id: pam_unix_auth.-c,v 1.4 1996/12/01 03:05:54 morgan Exp $: pam_unix_auth.-c,v 1.2 1996/09/05 06:46:53 morgan Exp morgan $\n"
+"$Id: pam_unix_auth.-c,v 1.1.1.1 2000/06/20 22:11:49 agmorgan Exp $: pam_unix_auth.-c,v 1.2 1996/09/05 06:46:53 morgan Exp morgan $\n"
" - PAM_PWDB authentication functions. <morgan@parc.power.net>";
/*
@@ -42,8 +28,15 @@ static int _unix_auth(pam_handle_t *pamh, unsigned int ctrl)
retval = _unix_get_user(pamh, ctrl, NULL, &name);
if (retval != PAM_SUCCESS ) {
- if ( on(UNIX_DEBUG,ctrl) ) {
- _log_err(LOG_DEBUG, "auth could not identify user");
+ if (retval != PAM_CONV_AGAIN) {
+ if ( on(UNIX_DEBUG,ctrl) ) {
+ _log_err(LOG_DEBUG, "auth could not identify user");
+ }
+ } else {
+ D(("pam_get_user/conv() function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ retval to the value that indicates we're happy to resume. */
+ retval = PAM_INCOMPLETE;
}
return retval;
}
@@ -60,18 +53,27 @@ static int _unix_auth(pam_handle_t *pamh, unsigned int ctrl)
retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
, _UNIX_AUTHTOK, &p);
- if (retval != PAM_SUCCESS ) {
- _log_err(LOG_CRIT, "auth could not identify password for [%s]"
- , name);
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_CRIT, "auth could not identify password for [%s]"
+ , name);
+ } else {
+ D(("conversation function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ retval to the value that indicates we're happy to resume. */
+ retval = PAM_INCOMPLETE;
+ }
name = NULL;
return retval;
}
+ D(("user=%s, password=[%s]", name, p));
/* verify the password of this user */
-
retval = _unix_verify_password(pamh, name, p, ctrl);
name = p = NULL;
+ D(("done [%d]", retval));
+
return retval;
}
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
index cd90b0ff339b..d9b2c51b205a 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
@@ -25,7 +25,7 @@ struct cfns {
#define N_MDS 1
const static struct cfns cfn_list[N_MDS] = {
- { "$1$", 3, crypt_md5 },
+ { "$1$", 3, Goodcrypt_md5 },
};
static char *_pam_md(const char *key, const char *salt)
@@ -53,3 +53,21 @@ static char *_pam_md(const char *key, const char *salt)
return x; /* this must be deleted elsewhere */
}
+#ifndef PWDB_NO_MD_COMPAT
+static char *_pam_md_compat(const char *key, const char *salt)
+{
+ char *x,*e=NULL;
+
+ D(("called with key='%s', salt='%s'", key, salt));
+
+ if ( !strncmp("$1$", salt, 3) ) {
+ e = Brokencrypt_md5(key, salt);
+ x = x_strdup(e); /* put e in malloc()ed memory */
+ _pam_overwrite(e); /* clean up */
+ } else {
+ x = x_strdup("*");
+ }
+
+ return x; /* this must be deleted elsewhere */
+}
+#endif /* PWDB_NO_MD_COMPAT */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
index 402f7f349f88..eb43bcfa713f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
@@ -1,29 +1,7 @@
-/* $Id: pam_unix_passwd.-c,v 1.6 1997/04/05 06:31:06 morgan Exp morgan $ */
-
-/*
- * $Log: pam_unix_passwd.-c,v $
- * Revision 1.6 1997/04/05 06:31:06 morgan
- * mostly a reformat.
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:04:51 morgan
- * pwdb conversion
- *
- * Revision 1.3 1996/09/05 06:48:15 morgan
- * A lot has changed. I'd recommend you study the diff.
- *
- * Revision 1.2 1996/09/01 16:33:27 morgan
- * Cristian Gafton's changes
- *
- * Revision 1.1 1996/08/29 13:21:27 morgan
- * Initial revision
- *
- */
+/* $Id: pam_unix_passwd.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $ */
static const char rcsid_pass[] =
-"$Id: pam_unix_passwd.-c,v 1.6 1997/04/05 06:31:06 morgan Exp morgan $\n"
+"$Id: pam_unix_passwd.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB password module <morgan@parc.power.net>"
;
@@ -42,6 +20,28 @@ static const char rcsid_pass[] =
/* Implementation */
/*
+ * i64c - convert an integer to a radix 64 character
+ */
+static int i64c(int i)
+{
+ if (i < 0)
+ return ('.');
+ else if (i > 63)
+ return ('z');
+ if (i == 0)
+ return ('.');
+ if (i == 1)
+ return ('/');
+ if (i >= 2 && i <= 11)
+ return ('0' - 2 + i);
+ if (i >= 12 && i <= 37)
+ return ('A' - 12 + i);
+ if (i >= 38 && i <= 63)
+ return ('a' - 38 + i);
+ return ('\0');
+}
+
+/*
* FUNCTION: _pam_unix_chauthtok()
*
* this function works in two passes. The first, when UNIX__PRELIM is
@@ -259,15 +259,15 @@ static int _unix_chauthtok(pam_handle_t *pamh, unsigned int ctrl)
unsigned char tmp[16];
int i;
- MD5Init(&ctx);
+ GoodMD5Init(&ctx);
gettimeofday(&tv, (struct timezone *) 0);
- MD5Update(&ctx, (void *) &tv, sizeof tv);
+ GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
i = getpid();
- MD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
i = clock();
- MD5Update(&ctx, (void *) &i, sizeof i);
- MD5Update(&ctx, result, sizeof result);
- MD5Final(tmp, &ctx);
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, result, sizeof result);
+ GoodMD5Final(tmp, &ctx);
strcpy(cp, "$1$"); /* magic for the MD5 */
cp += strlen(cp);
for (i = 0; i < 8; i++)
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
index d50031dcb919..a1fc65ff5163 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
@@ -1,19 +1,7 @@
/*
- * $Id: pam_unix_pwupd.-c,v 1.4 1997/01/04 20:35:32 morgan Exp morgan $
+ * $Id: pam_unix_pwupd.-c,v 1.1.1.1 2000/06/20 22:11:51 agmorgan Exp $
*
* This file contains the routines to update the passwd databases.
- *
- * $Log: pam_unix_pwupd.-c,v $
- * Revision 1.4 1997/01/04 20:35:32 morgan
- * minor comment change
- *
- * Revision 1.3 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.2 1996/11/10 21:05:09 morgan
- * pwdb conversion
- *
- *
*/
/* Implementation */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
index 49ce96cbd16c..395bd9bba3a7 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
@@ -1,25 +1,11 @@
/*
- * $Id: pam_unix_sess.-c,v 1.4 1996/12/01 03:05:54 morgan Exp morgan $
- *
- * $Log: pam_unix_sess.-c,v $
- * Revision 1.4 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.3 1996/11/10 21:05:33 morgan
- * pwdb conversion
- *
- * Revision 1.2 1996/09/05 06:49:02 morgan
- * more informative logging
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
+ * $Id: pam_unix_sess.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* See end for Copyright information
*/
static const char rcsid_sess[] =
-"$Id: pam_unix_sess.-c,v 1.4 1996/12/01 03:05:54 morgan Exp morgan $\n"
+"$Id: pam_unix_sess.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB session management. morgan@parc.power.net";
/* Define internal functions */
diff --git a/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c b/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
index 6332eaa7e865..3b3c1d5f0f51 100644
--- a/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
+++ b/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
@@ -1,5 +1,5 @@
/*
- * $Id: pwdb_chkpwd.c,v 1.1 1997/02/15 17:26:18 morgan Exp $
+ * $Id: pwdb_chkpwd.c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
*
* This program is designed to run setuid(root) or with sufficient
* privilege to read all of the unix password databases. It is designed
@@ -11,19 +11,9 @@
*
* Copyright information is located at the end of the file.
*
- * $Log: pwdb_chkpwd.c,v $
- * Revision 1.1 1997/02/15 17:26:18 morgan
- * Initial revision
- *
- * Revision 1.1 1996/11/10 21:20:51 morgan
- * Initial revision
- *
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdarg.h>
#include <stdio.h>
@@ -54,6 +44,7 @@ static void _log_err(int err, const char *format, ...)
closelog();
}
+#define PWDB_NO_MD_COMPAT
#include "pam_unix_md.-c"
static int _unix_verify_passwd(const char *salt, const char *p)
@@ -92,12 +83,12 @@ static int _unix_verify_passwd(const char *salt, const char *p)
return retval;
}
-void main(void)
+int main(int argc, char **argv)
{
const struct pwdb *pw=NULL;
const struct pwdb_entry *pwe=NULL;
char pass[MAXPASS+1];
- int npass;
+ int npass, force_failure=0;
int retval=UNIX_FAILED;
/*
@@ -129,14 +120,26 @@ void main(void)
retval = UNIX_FAILED;
}
if (retval != UNIX_FAILED) {
- retval = pwdb_locate("user", PWDB_DEFAULT, PWDB_NAME_UNKNOWN
- , getuid(), &pw);
+ retval = pwdb_locate("user", PWDB_DEFAULT, PWDB_NAME_UNKNOWN,
+ getuid(), &pw);
}
if (retval != PWDB_SUCCESS) {
_log_err(LOG_ALERT, "could not identify user");
while (pwdb_end() != PWDB_SUCCESS);
exit(UNIX_FAILED);
}
+ if (argc == 2) {
+ if (pwdb_get_entry(pw, "user", &pwe) == PWDB_SUCCESS) {
+ if (pwe == NULL) {
+ force_failure = 1;
+ } else {
+ if (strcmp((const char *) pwe->value, argv[1])) {
+ force_failure = 1;
+ }
+ pwdb_entry_delete(&pwe);
+ }
+ }
+ }
/* read the password from stdin (a pipe from the pam_pwdb module) */
@@ -167,6 +170,10 @@ void main(void)
memset(pass, '\0', MAXPASS); /* clear memory of the password */
while (pwdb_end() != PWDB_SUCCESS);
+ if ((retval != UNIX_FAILED) && force_failure) {
+ retval = UNIX_FAILED;
+ }
+
/* return pass or fail */
exit(retval);
diff --git a/contrib/libpam/modules/pam_pwdb/support.-c b/contrib/libpam/modules/pam_pwdb/support.-c
index 71e212d64195..2b80f960cde7 100644
--- a/contrib/libpam/modules/pam_pwdb/support.-c
+++ b/contrib/libpam/modules/pam_pwdb/support.-c
@@ -1,18 +1,5 @@
/*
- * $Id: support.-c,v 1.7 1997/04/05 06:32:06 morgan Exp morgan $
- *
- * $Log: support.-c,v $
- * Revision 1.7 1997/04/05 06:32:06 morgan
- * new option and also deleted _readto
- *
- * Revision 1.6 1997/02/15 17:27:20 morgan
- * added helper binary to password checking
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:06:07 morgan
- * pwdb conversion
+ * $Id: support.-c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
*
* Copyright information at end of file.
*/
@@ -91,8 +78,9 @@ typedef struct {
#define UNIX_NODELAY 18 /* admin does not want a fail-delay */
#define UNIX_UNIX 19 /* wish to use /etc/passwd for pwd */
#define UNIX_BIGCRYPT 20 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 21 /* need to auth for setcred to work */
/* -------------- */
-#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 22 /* number of ctrl arguments defined */
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
@@ -118,8 +106,9 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
/* UNIX__SET_DB */ { NULL, _ALL_ON_, 0100000 },
/* UNIX_DEBUG */ { "debug", _ALL_ON_, 0200000 },
/* UNIX_NODELAY */ { "nodelay", _ALL_ON_, 0400000 },
-/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
+/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
/* UNIX_BIGCRYPT */ { "bigcrypt", _ALL_ON_^(020000), 02000000 },
+/* UNIX_LIKE_AUTH */ { "likeauth", _ALL_ON_, 04000000 },
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@@ -161,7 +150,7 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
, pam_strerror(pamh, retval));
}
- } else {
+ } else if (retval != PAM_CONV_AGAIN) {
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
}
@@ -322,13 +311,13 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
if ( !quiet && !err ) { /* under advisement from Sun,may go away */
/* log the number of authentication failures */
- if ( failure->count != 0 ) {
+ if ( failure->count > 1 ) {
(void) pam_get_item(pamh, PAM_SERVICE
, (const void **)&service);
_log_err(LOG_NOTICE
- , "%d authentication failure%s; %s(uid=%d) -> "
+ , "%d more authentication failure%s; %s(uid=%d) -> "
"%s for %s service"
- , failure->count, failure->count==1 ? "":"s"
+ , failure->count-1, failure->count==2 ? "":"s"
, failure->name
, failure->id
, failure->user
@@ -356,7 +345,8 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
#include <sys/types.h>
#include <sys/wait.h>
-static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
+static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ const char *user)
{
int retval, child, fds[2];
@@ -370,7 +360,7 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* fork */
child = fork();
if (child == 0) {
- static char *args[] = { NULL, NULL };
+ static char *args[] = { NULL, NULL, NULL };
static char *envp[] = { NULL };
/* XXX - should really tidy up PAM here too */
@@ -382,6 +372,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* exec binary helper */
args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
+
execve(CHKPWD_HELPER, args, envp);
/* should not get here: exit with error */
@@ -389,13 +381,14 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
exit(PWDB_SUCCESS+1);
} else if (child > 0) {
/* wait for child */
- close(fds[0]);
if (passwd != NULL) { /* send the password to the child */
write(fds[1], passwd, strlen(passwd)+1);
passwd = NULL;
} else {
write(fds[1], "", 1); /* blank password */
}
+ close(fds[0]); /* we close this after the write because we want
+ to avoid a possible SIGPIPE. */
close(fds[1]);
(void) waitpid(child, &retval, 0); /* wait for helper to complete */
retval = (retval == PWDB_SUCCESS) ? PAM_SUCCESS:PAM_AUTH_ERR;
@@ -408,8 +401,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
return retval;
}
-static int _unix_verify_password(pam_handle_t *pamh, const char *name
- , const char *p, unsigned int ctrl)
+static int _unix_verify_password(pam_handle_t *pamh, const char *name,
+ const char *p, unsigned int ctrl)
{
const struct pwdb *pw=NULL;
const struct pwdb_entry *pwe=NULL;
@@ -418,6 +411,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
char *pp;
char *data_name;
int retval;
+ int verify_result;
D(("called"));
@@ -474,7 +468,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (geteuid()) {
/* we are not root perhaps this is the reason? Run helper */
D(("running helper binary"));
- retval = pwdb_run_helper_binary(pamh, p);
+ retval = pwdb_run_helper_binary(pamh, p, name);
} else {
retval = PAM_AUTHINFO_UNAVAIL;
_log_err(LOG_ALERT, "get passwd; %s", pwdb_strerror(retval));
@@ -491,33 +485,56 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
* clear text...
*/
- if ( ( !salt ) && ( !p ) ) {
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
+ if ( data_name == NULL ) {
+ _log_err(LOG_CRIT, "no memory for data-name");
+ }
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
- /* the stored password is NULL */
+ if ( !( (salt && *salt) || (p && *p) ) ) {
- (void) pwdb_entry_delete(&pwe);
- (void) pwdb_delete(&pw);
+ D(("two null passwords to compare"));
+ /* the stored password is NULL */
+ pp = NULL;
if ( off(UNIX__NONULL, ctrl ) ) { /* this means we've succeeded */
- return PAM_SUCCESS;
+ verify_result = PAM_SUCCESS;
} else {
- return PAM_AUTH_ERR;
+ verify_result = PAM_AUTH_ERR;
}
- }
- pp = _pam_md(p, salt);
- p = NULL; /* no longer needed here */
+ } else if ( !( salt && p ) ) {
- data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
- if ( data_name == NULL ) {
- _log_err(LOG_CRIT, "no memory for data-name");
- }
- strcpy(data_name, FAIL_PREFIX);
- strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
+ D(("one of the two to compare are NULL"));
+
+ pp = NULL;
+ verify_result = PAM_AUTH_ERR;
+
+ } else {
- /* the moment of truth -- do we agree with the password? */
+ pp = _pam_md(p, salt);
- if ( strcmp( pp, salt ) == 0 ) {
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ _pam_delete(pp);
+ pp = _pam_md_compat(p, salt);
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ verify_result = PAM_AUTH_ERR;
+ }
+ }
+
+ p = NULL; /* no longer needed here */
+
+ }
+
+ if ( verify_result == PAM_SUCCESS ) {
retval = PAM_SUCCESS;
if (data_name) { /* reset failures */
@@ -538,7 +555,11 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (new != NULL) {
- /* any previous failures for this user ? */
+ new->user = x_strdup(name);
+ new->id = getuid();
+ new->name = x_strdup(getlogin() ? getlogin():"" );
+
+ /* any previous failures for this user ? */
pam_get_data(pamh, data_name, (const void **)&old );
if (old != NULL) {
@@ -547,11 +568,19 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
retval = PAM_MAXTRIES;
}
} else {
+ const char *service=NULL;
+ (void) pam_get_item(pamh, PAM_SERVICE
+ , (const void **)&service);
+ _log_err(LOG_NOTICE
+ , "authentication failure; %s(uid=%d) -> "
+ "%s for %s service"
+ , new->name
+ , new->id
+ , new->user
+ , service == NULL ? "**unknown**":service
+ );
new->count = 1;
}
- new->user = x_strdup(name);
- new->id = getuid();
- new->name = x_strdup(getlogin() ? getlogin():"" );
pam_set_data(pamh, data_name, new, _cleanup_failures);
@@ -568,6 +597,8 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
_pam_delete(data_name);
_pam_delete(pp);
+ D(("done [%d].", retval));
+
return retval;
}
@@ -596,8 +627,9 @@ static int _unix_get_user(pam_handle_t *pamh, unsigned int ctrl
* alphanumeric character.
*/
- if (!isalnum(**user)) {
- if (on(UNIX_DEBUG,ctrl) || **user) {
+ if (*user == NULL || !isalnum(**user)) {
+ D(("bad username"));
+ if (on(UNIX_DEBUG,ctrl)) {
_log_err(LOG_ERR, "bad username [%s]", *user);
}
return PAM_USER_UNKNOWN;
@@ -872,7 +904,7 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh
}
/* ****************************************************************** *
- * Copyright (c) Andrew G. Morgan, <morgan@parc.power.net> 1996.
+ * Copyright (c) Andrew G. Morgan 1996-8.
* Copyright (c) Alex O. Yuriev, 1996.
* Copyright (c) Cristian Gafton 1996.
*
diff --git a/contrib/libpam/modules/pam_radius/Makefile b/contrib/libpam/modules/pam_radius/Makefile
index a74b911f4e3b..aa149d3ee9b5 100644
--- a/contrib/libpam/modules/pam_radius/Makefile
+++ b/contrib/libpam/modules/pam_radius/Makefile
@@ -8,13 +8,15 @@
# STATIC modules are not supported
#
+include ../../Make.Rules
+
TITLE=pam_radius
CONFD=$(CONFIGED)/security
export CONFD
CONFILE=$(CONFD)/radius.conf
export CONFILE
-ifeq ($(HAVE_PWDBLIB),yes)
+ifeq ($(HAVE_LIBPWDB),yes)
#
@@ -41,11 +43,6 @@ endif
####################### don't edit below #######################
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
all: dirs $(LIBSHARED) $(LIBSTATIC) register
dirs:
@@ -85,9 +82,8 @@ remove:
clean:
rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
rm -f *.a *.o *.so *.bak dynamic/* static/*
+ rm -rf dynamic static
.c.o:
$(CC) $(CFLAGS) -c $<
diff --git a/contrib/libpam/modules/pam_radius/pam_radius.h b/contrib/libpam/modules/pam_radius/pam_radius.h
index 72b1da8aa0cb..67230243eed8 100644
--- a/contrib/libpam/modules/pam_radius/pam_radius.h
+++ b/contrib/libpam/modules/pam_radius/pam_radius.h
@@ -1,12 +1,17 @@
+/*
+ * $Id: pam_radius.h,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+ */
#ifndef PAM_RADIUS_H
#define PAM_RADIUS_H
-#define _GNU_SOURCE
-#include <features.h>
+#include <security/_pam_aconf.h>
#include <stdio.h>
+
+#ifndef __USE_POSIX2
#define __USE_POSIX2
+#endif /* __USE_POSIX2 */
#include <stdlib.h>
diff --git a/contrib/libpam/modules/pam_rhosts/Makefile b/contrib/libpam/modules/pam_rhosts/Makefile
index 93addbb68119..d12e00c0680e 100644
--- a/contrib/libpam/modules/pam_rhosts/Makefile
+++ b/contrib/libpam/modules/pam_rhosts/Makefile
@@ -1,94 +1,15 @@
-# This Makefile controls a build process of the pam_rhosts modules
-# for Linux-PAM. You should not modify this Makefile.
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
-LIBAUTHOBJ = pam_rhosts_auth.o
-LIBAUTHSRC = pam_rhosts_auth.c
-LIBSESSOBJ =
-LIBSESSSRC =
-LIBPASSWDSRC =
-LIBPASSWDOBJ =
-LIBOBJ = $(LIBAUTHOBJ) $(LIBSESSOBJ) $(LIBPASSWDOBJ)
-LIBSRC = $(LIBAUTHSRC) $(LIBSESSSRC) $(LIBPASSWDSRC)
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = libpam_rhosts.o
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-endif
+TITLE=pam_rhosts_auth
-ifdef DYNAMIC
-LIBSESSSH =
-LIBAUTHSH = pam_rhosts_auth.so
-LIBPASSWDSH =
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBSHARED = $(LIBSESSSH) $(LIBAUTHSH) $(LIBPASSWDSH)
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; \
- ./register_static pam_rhosts_auth pam_rhosts/libpam_rhosts.o )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-endif
-
-ifdef DYNAMIC
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-endif
-
-ifdef STATIC
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-
-endif
-
-#.c.o:
-# $(CC) -c $(CFLAGS) $<
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-# tidy up
-
-remove:
- cd $(FAKEROOT)$(SECUREDIR) && rm -f $(LIBSHARED)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) a.out core *~
-
-extraclean:
- rm -f *.a *.out *.o *.so *.bak dynamic/* static/*
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
index 10dfcf797119..b633a52989d7 100644
--- a/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
+++ b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
@@ -46,6 +46,10 @@
#include <endian.h>
#endif
+#ifdef NEED_FSUID_H
+#include <sys/fsuid.h>
+#endif /* NEED_FSUID_H */
+
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>
@@ -103,6 +107,7 @@ int innetgr(const char *, const char *, const char *,const char *);
struct _options {
int opt_no_hosts_equiv;
+ int opt_hosts_equiv_rootok;
int opt_no_rhosts;
int opt_debug;
int opt_nowarn;
@@ -111,6 +116,8 @@ struct _options {
int opt_promiscuous;
int opt_suppress;
int opt_private_group;
+ int opt_no_uid_check;
+ const char *superuser;
const char *last_error;
};
@@ -133,6 +140,11 @@ static void set_option (struct _options *opts, const char *arg)
return;
}
+ if (strcmp(arg, "hosts_equiv_rootok") == 0) {
+ opts->opt_hosts_equiv_rootok = 1;
+ return;
+ }
+
if (strcmp(arg, "no_rhosts") == 0) {
opts->opt_no_rhosts = 1;
return;
@@ -165,6 +177,15 @@ static void set_option (struct _options *opts, const char *arg)
return;
}
+ if (strcmp(arg, "no_uid_check") == 0) {
+ opts->opt_no_uid_check = 1; /* NIS optimization */
+ return;
+ }
+
+ if (strcmp(arg, "superuser=") == 0) {
+ opts->superuser = arg+sizeof("superuser=")-1;
+ return;
+ }
/*
* All other options are ignored at the present time.
*/
@@ -444,7 +465,7 @@ pam_iruserok(pam_handle_t *pamh,
int answer;
char pbuf[MAXPATHLEN]; /* potential buffer overrun */
- if ( !superuser && !opts->opt_no_hosts_equiv ) {
+ if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) {
/* try to open system hosts.equiv file */
hostf = fopen (_PATH_HEQUIV, "r");
@@ -677,8 +698,12 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
break;
}
+ if (opts.superuser && !strcmp(opts.superuser, luser)) {
+ as_root = 1;
+ }
+
/* check if the luser uid == 0... --cristiang */
- {
+ if (! opts.opt_no_uid_check) {
struct passwd *luser_pwd;
luser_pwd = getpwnam(luser);
@@ -759,30 +784,3 @@ struct pam_module _pam_rhosts_auth_modstruct = {
};
#endif
-
-/*
- * $Log: pam_rhosts_auth.c,v $
- * Revision 1.12 1997/09/27 14:34:01 morgan
- * fixed comment and renamed iruserok to pam_iruserok.
- *
- * Revision 1.11 1997/04/05 06:26:39 morgan
- * fairly major fixes and enhancements (see CHANGELOG for 0.57 release)
- *
- * Revision 1.10 1997/02/09 02:09:30 morgan
- * - implementation of 'debug' argument (Cristian Gafton)
- * - we check for uid=0 accounts instead of hardcoded 'root' (Cristian Gafton)
- *
- * Revision 1.9 1996/12/01 03:09:47 morgan
- * *** empty log message ***
- *
- * Revision 1.8 1996/11/12 06:08:59 morgan
- * Oliver Crow's "rootok" patch plus a little clean up of set_option
- * (AGM)
- *
- * Revision 1.7 1996/11/10 20:15:56 morgan
- * cross platform support
- *
- * Revision 1.6 1996/08/09 05:46:29 morgan
- * removed code for manually setting the remote username etc..
- *
- */
diff --git a/contrib/libpam/modules/pam_rootok/Makefile b/contrib/libpam/modules/pam_rootok/Makefile
index b37870801193..b908b1157ac2 100644
--- a/contrib/libpam/modules/pam_rootok/Makefile
+++ b/contrib/libpam/modules/pam_rootok/Makefile
@@ -1,111 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:25:20 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:25:20 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.6 1997/02/15 19:15:50 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:16:10 morgan
-# cross platform support
-#
-# Revision 1.4 1996/09/05 06:29:36 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:47:46 morgan
-# make dynamic/static dirs!
-#
-# Revision 1.2 1996/05/26 04:04:53 morgan
-# automated static support
-#
-# Revision 1.1 1996/05/05 17:14:15 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/5/5
-#
-
-TITLE=pam_rootok
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_rootok
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_rootok/README b/contrib/libpam/modules/pam_rootok/README
index d7010dd9738d..eee59ff02b0c 100644
--- a/contrib/libpam/modules/pam_rootok/README
+++ b/contrib/libpam/modules/pam_rootok/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/05/10 04:15:31 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:56 agmorgan Exp $
#
this module is an authentication module that performs one task: if the
diff --git a/contrib/libpam/modules/pam_rootok/pam_rootok.c b/contrib/libpam/modules/pam_rootok/pam_rootok.c
index 21327d42e5ea..54795e3c2b3d 100644
--- a/contrib/libpam/modules/pam_rootok/pam_rootok.c
+++ b/contrib/libpam/modules/pam_rootok/pam_rootok.c
@@ -1,22 +1,13 @@
/* pam_rootok module */
/*
- * $Id: pam_rootok.c,v 1.5 1997/02/15 17:32:47 morgan Exp $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_rootok.c,v $
- * Revision 1.5 1997/02/15 17:32:47 morgan
- * removed fixed syslog buffer
- *
- * Revision 1.4 1996/12/01 03:10:14 morgan
- * reformatted
- *
- * Revision 1.3 1996/06/02 08:11:01 morgan
- * updated for new static protocol
+ * $Id: pam_rootok.c,v 1.1.1.1 2000/06/20 22:11:56 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*/
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
diff --git a/contrib/libpam/modules/pam_securetty/Makefile b/contrib/libpam/modules/pam_securetty/Makefile
index d8a09ea13377..8ac853c595ff 100644
--- a/contrib/libpam/modules/pam_securetty/Makefile
+++ b/contrib/libpam/modules/pam_securetty/Makefile
@@ -1,83 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_securetty
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+TITLE=pam_securetty
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_securetty/pam_securetty.c b/contrib/libpam/modules/pam_securetty/pam_securetty.c
index 369fb03dd060..9e6121e8be97 100644
--- a/contrib/libpam/modules/pam_securetty/pam_securetty.c
+++ b/contrib/libpam/modules/pam_securetty/pam_securetty.c
@@ -8,18 +8,10 @@
* July 25, 1996.
* This code shamelessly ripped from the pam_rootok module.
* Slight modifications AGM. 1996/12/3
- * $Log: pam_securetty.c,v $
- * Revision 1.7 1997/04/05 06:24:23 morgan
- * changed return value on user unknown error
- *
- * Revision 1.6 1997/02/15 17:30:36 morgan
- * removed fixed length syslog buffer
- *
- * Revision 1.5 1997/02/09 02:22:24 morgan
- * added "debug" flag handling (Cristian Gafton)
- *
*/
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -28,7 +20,7 @@
#include <syslog.h>
#include <stdarg.h>
#include <pwd.h>
-#include <strings.h>
+#include <string.h>
#define PAM_SM_AUTH
@@ -97,13 +89,20 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
/* parse the arguments */
ctrl = _pam_parse(argc, argv);
- retval = pam_get_item(pamh,PAM_USER,(const void **)&username);
- if (retval == PAM_SUCCESS)
- retval = pam_get_item(pamh,PAM_TTY,(const void **)&uttyname);
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS || username == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine username");
+ }
+ return (retval == PAM_CONV_AGAIN
+ ? PAM_INCOMPLETE:PAM_SERVICE_ERR);
+ }
+
+ retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname);
if (retval != PAM_SUCCESS || uttyname == NULL) {
- /* If we couldn't get the username or the tty return error */
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_WARNING, "can not determine tty I'm running on !");
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine user's tty");
+ }
return PAM_SERVICE_ERR;
}
@@ -111,36 +110,24 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
uttyname += sizeof(TTY_PREFIX)-1;
- /* If we didn't get a username, get one */
- if(!username || (strlen(username) <= 0)) {
- /* Don't let them use a NULL username... */
- (void) pam_set_item(pamh, PAM_USER, NULL);
- pam_get_user(pamh,&username,NULL);
- if (retval != PAM_SUCCESS || username == NULL || *username == '\0') {
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_WARNING,
- "can not determine username for this service!");
- return PAM_SERVICE_ERR;
- }
- }
-
user_pwd = getpwnam(username);
- if (user_pwd == NULL)
+ if (user_pwd == NULL) {
return PAM_IGNORE;
- else if (user_pwd->pw_uid != 0) /* If the user is not root,
- securetty's does not apply to them */
+ } else if (user_pwd->pw_uid != 0) { /* If the user is not root,
+ securetty's does not apply
+ to them */
return PAM_SUCCESS;
+ }
- if(stat(SECURETTY_FILE,&ttyfileinfo)) {
- _pam_log(LOG_NOTICE,
- "Couldn't open " SECURETTY_FILE);
+ if (stat(SECURETTY_FILE, &ttyfileinfo)) {
+ _pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE);
return PAM_SUCCESS; /* for compatibility with old securetty handling,
this needs to succeed. But we still log the
error. */
}
- if((ttyfileinfo.st_mode & S_IWOTH)
- || !S_ISREG(ttyfileinfo.st_mode)) {
+ if ((ttyfileinfo.st_mode & S_IWOTH)
+ || !S_ISREG(ttyfileinfo.st_mode)) {
/* If the file is world writable or is not a
normal file, return error */
_pam_log(LOG_ERR, SECURETTY_FILE
diff --git a/contrib/libpam/modules/pam_shells/Makefile b/contrib/libpam/modules/pam_shells/Makefile
index 121b19a00863..f1d7ff515187 100644
--- a/contrib/libpam/modules/pam_shells/Makefile
+++ b/contrib/libpam/modules/pam_shells/Makefile
@@ -1,84 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_shells
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_shells
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_shells/pam_shells.c b/contrib/libpam/modules/pam_shells/pam_shells.c
index edc9134b3274..36dd1a917e4e 100644
--- a/contrib/libpam/modules/pam_shells/pam_shells.c
+++ b/contrib/libpam/modules/pam_shells/pam_shells.c
@@ -1,4 +1,4 @@
-/* pam_securetty module */
+/* pam_shells module */
#define SHELL_FILE "/etc/shells"
@@ -8,6 +8,8 @@
* This code shamelessly ripped from the pam_securetty module.
*/
+#define _BSD_SOURCE
+
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
@@ -71,21 +73,21 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
userShell = pw->pw_shell;
if(stat(SHELL_FILE,&sb)) {
- _pam_log(LOG_ERR, SHELL_FILE, " cannot be stat'd (it probably does "
- "not exist)");
+ _pam_log(LOG_ERR,
+ "%s cannot be stat'd (it probably does not exist)", SHELL_FILE);
return PAM_AUTH_ERR; /* must have /etc/shells */
}
if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
- _pam_log(LOG_ERR,
- SHELL_FILE " is either world writable or not a normal file");
- return PAM_AUTH_ERR;
+ _pam_log(LOG_ERR,
+ "%s is either world writable or not a normal file", SHELL_FILE);
+ return PAM_AUTH_ERR;
}
shellFile = fopen(SHELL_FILE,"r");
if(shellFile == NULL) { /* Check that we opened it successfully */
- _pam_log(LOG_ERR,
- "Error opening " SHELL_FILE);
+ _pam_log(LOG_ERR,
+ "Error opening %s", SHELL_FILE);
return PAM_SERVICE_ERR;
}
/* There should be no more errors from here on */
diff --git a/contrib/libpam/modules/pam_stress/Makefile b/contrib/libpam/modules/pam_stress/Makefile
index 52e8e21881a3..3512c853aef9 100644
--- a/contrib/libpam/modules/pam_stress/Makefile
+++ b/contrib/libpam/modules/pam_stress/Makefile
@@ -1,109 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:23:08 morgan Exp $
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:23:08 morgan
-# fakeroot
-#
-# Revision 1.6 1997/02/15 19:05:55 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:17:55 morgan
-# cross platform support
-#
-# Revision 1.4 1996/09/05 06:31:09 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:50:43 morgan
-# make dynamic and static dirs
-#
-# Revision 1.2 1996/05/26 04:11:56 morgan
-# automated static support
-#
-#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-TITLE=pam_stress
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_stress
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_stress/README b/contrib/libpam/modules/pam_stress/README
index 1cb7c14b73c3..b4273f501ff4 100644
--- a/contrib/libpam/modules/pam_stress/README
+++ b/contrib/libpam/modules/pam_stress/README
@@ -1,5 +1,5 @@
#
-# $Id: README,v 1.7 1997/02/15 19:07:08 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:57 agmorgan Exp $
#
# This describes the behavior of this module with respect to the
# /etc/pam.conf file.
diff --git a/contrib/libpam/modules/pam_stress/pam_stress.c b/contrib/libpam/modules/pam_stress/pam_stress.c
index 501541850461..52d9e8041ec8 100644
--- a/contrib/libpam/modules/pam_stress/pam_stress.c
+++ b/contrib/libpam/modules/pam_stress/pam_stress.c
@@ -1,34 +1,18 @@
/* pam_stress module */
-/* $Id: pam_stress.c,v 1.12 1997/02/15 19:06:30 morgan Exp morgan $
- *
- * created by Andrew Morgan <morgan@parc.power.net> 1996/3/12
- *
- * $Log: pam_stress.c,v $
- * Revision 1.12 1997/02/15 19:06:30 morgan
- * fixed email
- *
- * Revision 1.11 1997/02/15 17:33:24 morgan
- * removed fixed syslog buffer
- *
- * Revision 1.10 1996/12/01 03:11:35 morgan
- * using _pam_macros.h now
- *
- * Revision 1.9 1996/11/10 20:18:10 morgan
- * changes for .53 compilation
- *
- * Revision 1.8 1996/09/05 06:31:59 morgan
- * changed return value of wipe_up from int to void
- *
- * Revision 1.7 1996/06/02 08:12:28 morgan
- * updated for new static protocol, added STRESS to various user prompts
- * and added rootok flag for pam_sm_chauthtok to look out for
+/* $Id: pam_stress.c,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
*
+ * created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/12
*/
+#include <security/_pam_aconf.h>
+
#include <stdlib.h>
#include <stdio.h>
+
+#define __USE_BSD
#include <syslog.h>
+
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
diff --git a/contrib/libpam/modules/pam_tally/Makefile b/contrib/libpam/modules/pam_tally/Makefile
index ec17ff31fa8e..032b93416bd9 100644
--- a/contrib/libpam/modules/pam_tally/Makefile
+++ b/contrib/libpam/modules/pam_tally/Makefile
@@ -1,20 +1,19 @@
#
-# $Id: Makefile,v 1.1 1997/04/05 06:19:04 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
-# This Makefile controls a build process of $(TITLE) module for
-# Linux-PAM. You should not modify this Makefile (unless you know
-# what you are doing!).
-#
-# $Log: Makefile,v $
-# Revision 1.1 1997/04/05 06:19:04 morgan
-# Initial revision
+# This Makefile controls a build process of $(TITLE) module and
+# application for Linux-PAM. You should not modify this Makefile
+# (unless you know what you are doing!).
#
#
+include ../../Make.Rules
+
TITLE=pam_tally
#
-## Should add some more rules to make the application too.
+## Additional rules for making (and moving) the application added.
+## Assuming that all modules' applications are called $TITLE
#
LIBSRC = $(TITLE).c
@@ -22,6 +21,11 @@ LIBOBJ = $(TITLE).o
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBOBJS = $(addprefix static/,$(LIBOBJ))
+APPSRC = $(TITLE)_app.c
+APPOBJ = $(TITLE)_app.o
+APPOBJD = $(addprefix dynamic/,$(APPOBJ))
+APPOBJS = $(addprefix static/,$(APPOBJ))
+
dynamic/%.o : %.c
$(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
@@ -37,14 +41,12 @@ ifdef STATIC
LIBSTATIC = lib$(TITLE).o
endif
-####################### don't edit below #######################
+APPLICATION = $(TITLE)
+APPMODE = 755
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+####################### don't edit below #######################
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
+all: dirs $(LIBSHARED) $(LIBSTATIC) register $(APPLICATION)
dirs:
ifdef DYNAMIC
@@ -62,8 +64,12 @@ endif
ifdef DYNAMIC
$(LIBOBJD): $(LIBSRC)
-$(LIBSHARED): $(LIBOBJD)
+$(LIBSHARED): $(LIBOBJD)
$(LD_D) -o $@ $(LIBOBJD)
+
+$(APPLICATION): $(APPOBJD)
+ $(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
+
endif
ifdef STATIC
@@ -71,6 +77,9 @@ $(LIBOBJS): $(LIBSRC)
$(LIBSTATIC): $(LIBOBJS)
$(LD) -r -o $@ $(LIBOBJS)
+
+$(APPLICATION): $(APPOBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
endif
install: all
@@ -78,16 +87,17 @@ install: all
ifdef DYNAMIC
$(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
endif
+ $(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
+# $(INSTALL) -m $(APPMODE) $(APPLICATION) $(FAKEROOT)$(SUPLEMENTED)
remove:
rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ rm -f $(FAKEROOT)$(SUPLEMENTED)/$(TITLE)
clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
+ rm -f $(LIBOBJD) $(LIBOBJS) $(APPOBJD) $(APPOBJS) core *~
+ rm -f *.a *.o *.so *.bak dynamic/* static/* $(APPLICATION)
+ rm -rf dynamic static
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
+.c.o:
$(CC) $(CFLAGS) -c $<
-
diff --git a/contrib/libpam/modules/pam_tally/README b/contrib/libpam/modules/pam_tally/README
index aaa8512bade4..b58b24e45793 100644
--- a/contrib/libpam/modules/pam_tally/README
+++ b/contrib/libpam/modules/pam_tally/README
@@ -1,4 +1,3 @@
-
SUMMARY:
pam_tally:
@@ -12,10 +11,12 @@ SUMMARY:
* file=/where/to/keep/counts (default /var/log/faillog)
(auth)
+ Authentication phase increments attempted login counter.
* no_magic_root (root DOES increment counter. Use for
daemon-based stuff, like telnet/rsh/login)
(account)
+ Account phase can deny access and/or reset attempts counter.
* deny=n (deny access if tally for this user exceeds n;
The presence of deny=n changes the default for
reset/no_reset to reset, unless the user trying to
@@ -34,11 +35,54 @@ SUMMARY:
This is the default unless deny exists and the
user attempting access is NOT magic root.
- Also checks to make sure that the list file is a plain
+ * per_user (If /var/log/faillog contains a non-zero
+ .fail_max field for this user then use it
+ instead of deny=n parameter)
+
+ * no_lock_time (Don't use .fail_locktime filed in
+ /var/log/faillog for this user)
+
+ Also checks to make sure that the counts file is a plain
file and not world writable.
- - Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd.
- v0.1 5 March 1997
+ - Tim Baverstock <warwick@sable.demon.co.uk>, v0.1 5 March 1997
+
+LONGER:
+
+pam_tally comes in two parts: pam_tally.so and pam_tally.
+
+pam_tally.so sits in a pam config file, in the auth and account sections.
+
+In the auth section, it increments a per-uid counter for each attempted
+login, in the account section, it denies access if attempted logins
+exceed some threashold and/or resets that counter to zero on successful
+login.
+
+Root is treated specially:
+
+1. When a process already running as root tries to access some service, the
+access is `magic', and bypasses pam_tally's checks: handy for `su'ing from
+root into an account otherwise blocked. However, for services like telnet or
+login which always effectively run from the root account, root (ie everyone)
+shouldn't be granted this magic status, and the flag `no_magic_root' should
+be set in this situation, as noted in the summary above. [This option may
+be obsolete, with `sufficient root' processing.]
+
+2. Normally, failed attempts to access root will NOT cause the root
+account to become blocked, to prevent denial-of-service: if your users aren't
+given shell accounts and root may only login via `su' or at the machine
+console (not telnet/rsh, etc), this is safe. If you really want root to be
+blocked for some given service, use even_deny_root_account.
+
+pam_tally is an (optional) application which can be used to interrogate and
+manipulate the counter file. It can display users' counts, set individual
+counts, or clear all counts. Setting artificially high counts may be useful
+for blocking users without changing their passwords. I found it useful to
+clear all counts every midnight from a cron..
+
+The counts file is organised as a binary-word array, indexed by uid. You
+can probably make sense of it with `od', if you don't want to use the
+supplied appliction.
BUGS:
diff --git a/contrib/libpam/modules/pam_tally/faillog.h b/contrib/libpam/modules/pam_tally/faillog.h
new file mode 100644
index 000000000000..0f16261bbd9c
--- /dev/null
+++ b/contrib/libpam/modules/pam_tally/faillog.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * 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, this list of conditions and the following disclaimer.
+ * 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. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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.
+ */
+
+/*
+ * faillog.h - login failure logging file format
+ *
+ * $Id: faillog.h,v 1.1.1.1 2000/06/20 22:11:59 agmorgan Exp $
+ *
+ * The login failure file is maintained by login(1) and faillog(8)
+ * Each record in the file represents a separate UID and the file
+ * is indexed in that fashion.
+ */
+
+#ifndef _FAILLOG_H
+#define _FAILLOG_H
+
+struct faillog {
+ short fail_cnt; /* failures since last success */
+ short fail_max; /* failures before turning account off */
+ char fail_line[12]; /* last failure occured here */
+ time_t fail_time; /* last failure occured then */
+ /*
+ * If nonzero, the account will be re-enabled if there are no
+ * failures for fail_locktime seconds since last failure.
+ */
+ long fail_locktime;
+};
+
+#endif
diff --git a/contrib/libpam/modules/pam_tally/pam_tally.c b/contrib/libpam/modules/pam_tally/pam_tally.c
index a1b65c04e958..23067f794e6a 100644
--- a/contrib/libpam/modules/pam_tally/pam_tally.c
+++ b/contrib/libpam/modules/pam_tally/pam_tally.c
@@ -1,7 +1,7 @@
/*
* pam_tally.c
*
- * Revision history? :) 0.1
+ * $Id: pam_tally.c,v 1.5 2001/01/20 22:21:22 agmorgan Exp $
*/
@@ -11,21 +11,20 @@
* Stuff stolen from pam_rootok and pam_listfile
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <syslog.h>
#include <pwd.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
+#include "faillog.h"
#ifndef TRUE
#define TRUE 1L
@@ -67,6 +66,13 @@ enum TALLY_RESET {
# define FILENAME_MAX MAXPATHLEN
#endif
+struct fail_s {
+ struct faillog fs_faillog;
+#ifndef MAIN
+ time_t fs_fail_time;
+#endif /* ndef MAIN */
+};
+
/*---------------------------------------------------------------------*/
/* some syslogging */
@@ -131,19 +137,23 @@ static int pam_get_uid( pam_handle_t *pamh, uid_t *uid, const char **userp )
static int get_tally( tally_t *tally,
uid_t uid,
const char *filename,
- FILE **TALLY )
+ FILE **TALLY,
+ struct fail_s *fsp)
{
struct stat fileinfo;
int lstat_ret = lstat(filename,&fileinfo);
if ( lstat_ret && *tally!=TALLY_HI ) {
- if ( ( *TALLY=fopen(filename, "a") ) ) {
- /* Create file, or append-open in pathological case. */
+ int oldmask = umask(077);
+ *TALLY=fopen(filename, "a");
+ /* Create file, or append-open in pathological case. */
+ umask(oldmask);
+ if ( !*TALLY ) {
_pam_log(LOG_ALERT, "Couldn't create %s",filename);
return PAM_AUTH_ERR;
}
+ lstat_ret = fstat(fileno(*TALLY),&fileinfo);
fclose(*TALLY);
- lstat_ret = lstat(filename,&fileinfo);
}
if ( lstat_ret ) {
@@ -171,14 +181,18 @@ static int get_tally( tally_t *tally,
return PAM_AUTH_ERR;
}
- if ( fseek( *TALLY, uid * sizeof (tally_t), SEEK_SET ) ) {
- _pam_log(LOG_ALERT, "fseek failed %s", filename);
- return PAM_AUTH_ERR;
- }
-
- if ( ( fread(tally, sizeof(tally_t), 1, *TALLY) )==0 ) {
- *tally=0; /* Assuming a gappy filesystem */
+ if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) {
+ _pam_log(LOG_ALERT, "fseek failed %s", filename);
+ return PAM_AUTH_ERR;
+ }
+
+
+ if (( fread((char *) &fsp->fs_faillog,
+ sizeof(struct faillog), 1, *TALLY) )==0 ) {
+ *tally=0; /* Assuming a gappy filesystem */
}
+ *tally = fsp->fs_faillog.fail_cnt;
+
return PAM_SUCCESS;
}
@@ -189,16 +203,18 @@ static int get_tally( tally_t *tally,
static int set_tally( tally_t tally,
uid_t uid,
const char *filename,
- FILE **TALLY )
+ FILE **TALLY,
+ struct fail_s *fsp)
{
if ( tally!=TALLY_HI )
{
- if ( fseek( *TALLY, uid * sizeof(tally_t), SEEK_SET ) ) {
- _pam_log(LOG_ALERT, "fseek failed %s", filename);
- return PAM_AUTH_ERR;
+ if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) {
+ _pam_log(LOG_ALERT, "fseek failed %s", filename);
+ return PAM_AUTH_ERR;
}
-
- if ( fwrite(&tally, sizeof(tally_t), 1, *TALLY)==0 ) {
+ fsp->fs_faillog.fail_cnt = tally;
+ if (fwrite((char *) &fsp->fs_faillog,
+ sizeof(struct faillog), 1, *TALLY)==0 ) {
_pam_log(LOG_ALERT, "tally update (fputc) failed.", filename);
return PAM_AUTH_ERR;
}
@@ -284,12 +300,37 @@ static int tally_bump (int inc,
FILE
*TALLY = NULL;
const char
- *user = NULL;
+ *user = NULL,
+ *remote_host = NULL,
+ *cur_tty = NULL;
+ struct fail_s fs, *fsp = &fs;
int i=pam_get_uid(pamh, &uid, &user);
if ( i != PAM_SUCCESS ) RETURN_ERROR( i );
- i=get_tally( &tally, uid, filename, &TALLY );
+ i=get_tally( &tally, uid, filename, &TALLY, fsp );
+
+ /* to remember old fail time (for locktime) */
+ fsp->fs_fail_time = fsp->fs_faillog.fail_time;
+ fsp->fs_faillog.fail_time = (time_t) time( (time_t *) 0);
+ (void) pam_get_item(pamh, PAM_RHOST, (const void **)&remote_host);
+ if (!remote_host)
+ {
+ (void) pam_get_item(pamh, PAM_TTY, (const void **)&cur_tty);
+ if (!cur_tty)
+ strcpy(fsp->fs_faillog.fail_line, "unknown");
+ else {
+ strncpy(fsp->fs_faillog.fail_line, cur_tty,
+ (size_t)sizeof(fsp->fs_faillog.fail_line));
+ fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0;
+ }
+ }
+ else
+ {
+ strncpy(fsp->fs_faillog.fail_line, remote_host,
+ (size_t)sizeof(fsp->fs_faillog.fail_line));
+ fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0;
+ }
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
if ( no_magic_root || getuid() ) { /* no_magic_root kills uid test */
@@ -303,7 +344,7 @@ static int tally_bump (int inc,
}
}
- i=set_tally( tally, uid, filename, &TALLY );
+ i=set_tally( tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
}
@@ -370,6 +411,8 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
char
no_magic_root = FALSE,
even_deny_root_account = FALSE;
+ char per_user = FALSE; /* if true then deny=.fail_max for user */
+ char no_lock_time = FALSE; /* if true then don't use .fail_locktime */
const char
*user = NULL;
@@ -424,6 +467,14 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
else if ( ! strcmp( *argv, "onerr=succeed" ) ) {
fail_on_error=FALSE;
}
+ else if ( ! strcmp( *argv, "per_user" ) )
+ {
+ per_user = TRUE;
+ }
+ else if ( ! strcmp( *argv, "no_lock_time") )
+ {
+ no_lock_time = TRUE;
+ }
else {
_pam_log(LOG_ERR, MODULE_NAME ": unknown option; %s",*argv);
}
@@ -431,17 +482,38 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
}
{
+ struct fail_s fs, *fsp = &fs;
FILE *TALLY=0;
int i=pam_get_uid(pamh, &uid, &user);
if ( i != PAM_SUCCESS ) RETURN_ERROR( i );
- i=get_tally( &tally, uid, filename, &TALLY );
+ i=get_tally( &tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
if ( no_magic_root || getuid() ) { /* no_magic_root kills uid test */
/* To deny or not to deny; that is the question */
+ /* if there's .fail_max entry and per_user=TRUE then deny=.fail_max */
+
+ if ( (fsp->fs_faillog.fail_max) && (per_user) ) {
+ deny = fsp->fs_faillog.fail_max;
+ }
+ if (fsp->fs_faillog.fail_locktime && fsp->fs_fail_time
+ && (!no_lock_time) )
+ {
+ if ( (fsp->fs_faillog.fail_locktime + fsp->fs_fail_time)
+ > (time_t)time((time_t)0) )
+ {
+ _pam_log(LOG_NOTICE,
+ "user %s ("UID_FMT") has time limit [%lds left]"
+ " since last failure.",
+ user,uid,
+ fsp->fs_fail_time+fsp->fs_faillog.fail_locktime
+ -(time_t)time((time_t)0));
+ return PAM_AUTH_ERR;
+ }
+ }
if (
( deny != 0 ) && /* deny==0 means no deny */
( tally > deny ) && /* tally>deny means exceeded */
@@ -467,8 +539,12 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
if ( reset == TALLY_RESET_RESET ) { tally=0; }
}
-
- i=set_tally( tally, uid, filename, &TALLY );
+ if (tally == 0)
+ {
+ fsp->fs_faillog.fail_time = (time_t) 0;
+ strcpy(fsp->fs_faillog.fail_line, "");
+ }
+ i=set_tally( tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
}
@@ -557,6 +633,8 @@ static int getopts( int argc, char **argv ) {
int main ( int argc, char **argv ) {
+ struct fail_s fs, *fsp = &fs;
+
if ( ! getopts( argc, argv+1 ) ) {
printf("%s: [--file rooted-filename] [--user username] "
"[--reset[=n]] [--quiet]\n",
@@ -564,6 +642,8 @@ int main ( int argc, char **argv ) {
exit(0);
}
+ umask(077);
+
/*
* Major difference between individual user and all users:
* --user just handles one user, just like PAM.
@@ -580,7 +660,7 @@ int main ( int argc, char **argv ) {
exit(0);
}
- i=get_tally( &tally, uid, cline_filename, &TALLY );
+ i=get_tally( &tally, uid, cline_filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) {
if (TALLY) fclose(TALLY);
fprintf(stderr,"%s: %s\n",*argv,pam_errors(i));
@@ -591,7 +671,7 @@ int main ( int argc, char **argv ) {
printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",cline_user,uid,
(cline_reset!=TALLY_HI)?"had":"has",tally);
- i=set_tally( cline_reset, uid, cline_filename, &TALLY );
+ i=set_tally( cline_reset, uid, cline_filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) {
if (TALLY) fclose(TALLY);
fprintf(stderr,"%s: %s\n",*argv,pam_errors(i));
@@ -606,7 +686,13 @@ int main ( int argc, char **argv ) {
for ( ; !feof(TALLY); uid++ ) {
tally_t tally;
struct passwd *pw;
- if ( ! fread(&tally, sizeof(tally_t), 1, TALLY) || ! tally ) continue;
+ if ( ! fread((char *) &fsp->fs_faillog,
+ sizeof (struct faillog), 1, TALLY)
+ || ! fsp->fs_faillog.fail_cnt ) {
+ tally=fsp->fs_faillog.fail_cnt;
+ continue;
+ }
+ tally = fsp->fs_faillog.fail_cnt;
if ( ( pw=getpwuid(uid) ) ) {
printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",pw->pw_name,uid,
diff --git a/contrib/libpam/modules/pam_tally/pam_tally_app.c b/contrib/libpam/modules/pam_tally/pam_tally_app.c
new file mode 100644
index 000000000000..9e6e1fafd062
--- /dev/null
+++ b/contrib/libpam/modules/pam_tally/pam_tally_app.c
@@ -0,0 +1,7 @@
+/*
+ # This seemed like such a good idea at the time. :)
+ */
+
+#define MAIN
+#include "pam_tally.c"
+
diff --git a/contrib/libpam/modules/pam_time/Makefile b/contrib/libpam/modules/pam_time/Makefile
index bc297d4f9853..4aa4e2761ee0 100644
--- a/contrib/libpam/modules/pam_time/Makefile
+++ b/contrib/libpam/modules/pam_time/Makefile
@@ -1,121 +1,21 @@
-#
-# $Id: Makefile,v 1.6 1997/04/05 06:22:32 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.6 1997/04/05 06:22:32 morgan
-# fakeroot
-#
-# Revision 1.5 1997/02/15 19:16:16 morgan
-# fixed email
-#
-# Revision 1.4 1996/11/10 20:18:21 morgan
-# cross platform support
-#
-# Revision 1.3 1996/09/05 06:27:37 morgan
-# ld --> gcc
-#
-# Revision 1.2 1996/08/09 05:48:19 morgan
-# inherit installation files from parent
-#
-# Revision 1.1 1996/07/07 23:42:48 morgan
-# Initial revision
-#
-# Revision 1.1 1996/06/24 05:48:49 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/6/11
-#
-
-TITLE=pam_time
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/time.conf
-export CONFILE
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
+TITLE=pam_time
+LOCAL_CONFILE=./time.conf
+INSTALLED_CONFILE=$(SCONFIGD)/time.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_time/README b/contrib/libpam/modules/pam_time/README
index 0c3f976b4012..0228b907fc21 100644
--- a/contrib/libpam/modules/pam_time/README
+++ b/contrib/libpam/modules/pam_time/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.3 1997/01/04 20:42:43 morgan Exp $
+$Id: README,v 1.2 2000/12/04 19:02:35 baggins Exp $
This is a help file for the pam_time module. It explains the need for
pam_time and also the syntax of the /etc/security/time.conf file.
@@ -28,10 +28,3 @@ unrecognised rules are ignored (but an error is logged to syslog(3))
--------------------
Bugs to Andrew <morgan@parc.power.net> or the list <pam-list@redhat.com>
-
-########################################################################
-# $Log: README,v $
-# Revision 1.3 1997/01/04 20:42:43 morgan
-# I want email on parc now
-#
-# \ No newline at end of file
diff --git a/contrib/libpam/modules/pam_time/pam_time.c b/contrib/libpam/modules/pam_time/pam_time.c
index 489c1d734ae0..a517abf0e3d2 100644
--- a/contrib/libpam/modules/pam_time/pam_time.c
+++ b/contrib/libpam/modules/pam_time/pam_time.c
@@ -1,25 +1,19 @@
/* pam_time module */
/*
- * $Id: pam_time.c,v 1.7 1997/02/15 17:32:21 morgan Exp $
+ * $Id: pam_time.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/6/22
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/6/22
* (File syntax and much other inspiration from the shadow package
* shadow-960129)
- *
- * $Log: pam_time.c,v $
- * Revision 1.7 1997/02/15 17:32:21 morgan
- * time parsing more robust
- *
- * Revision 1.6 1997/01/04 20:43:15 morgan
- * fixed buffer underflow, reformatted to 4 spaces
- *
*/
const static char rcsid[] =
-"$Id: pam_time.c,v 1.7 1997/02/15 17:32:21 morgan Exp $;\n"
+"$Id: pam_time.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $;\n"
"\t\tVersion 0.22 for Linux-PAM\n"
-"Copyright (C) Andrew G. Morgan 1996 <morgan@parc.power.net>\n";
+"Copyright (C) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
+
+#include <security/_pam_aconf.h>
#include <sys/file.h>
#include <stdio.h>
@@ -34,7 +28,11 @@ const static char rcsid[] =
#include <sys/stat.h>
#include <fcntl.h>
-#define PAM_TIME_CONF CONFILE /* from external define */
+#ifdef DEFAULT_CONF_FILE
+# define PAM_TIME_CONF DEFAULT_CONF_FILE /* from external define */
+#else
+# define PAM_TIME_CONF "/etc/security/time.conf"
+#endif
#define PAM_TIME_BUFLEN 1000
#define FIELD_SEPARATOR ';' /* this is new as of .02 */
@@ -124,6 +122,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
_log_err("error reading " PAM_TIME_CONF);
return -1;
} else if (!i) {
+ close(fd);
fd = -1; /* end of file reached */
} else
*to += i;
@@ -167,6 +166,8 @@ static int read_field(int fd, char **buf, int *from, int *to)
if ((*buf)[i+1] == '\n') {
shift_bytes(i + *buf, 2, *to - (i+2));
*to -= 2;
+ } else {
+ ++i; /* we don't escape non-newline characters */
}
break;
case '!':
@@ -248,7 +249,7 @@ static int logic_member(const char *string, int *at)
default:
if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
- || c == '-' || c == '.') {
+ || c == '-' || c == '.' || c == '/') {
token = 1;
} else if (token) {
--to;
diff --git a/contrib/libpam/modules/pam_unix/CHANGELOG b/contrib/libpam/modules/pam_unix/CHANGELOG
index 37e4c8501c9d..509ce0a31a62 100644
--- a/contrib/libpam/modules/pam_unix/CHANGELOG
+++ b/contrib/libpam/modules/pam_unix/CHANGELOG
@@ -1,6 +1,55 @@
-$Id: CHANGELOG,v 1.1 1996/11/09 19:42:41 morgan Exp $
+$Id: CHANGELOG,v 1.1.1.1 2000/06/20 22:12:01 agmorgan Exp $
-$Log: CHANGELOG,v $
-Revision 1.1 1996/11/09 19:42:41 morgan
-Initial revision
+* Mon Aug 16 1999 Jan Rêkorajski <baggins@pld.org.pl>
+- fixed reentrancy problems
+
+* Sun Jul 4 21:03:42 PDT 1999
+
+- temporarily removed the crypt16 stuff. I'm really paranoid about
+ crypto stuff and exporting it, and there are a few too many 's-box'
+ references in the code for my liking..
+
+* Wed Jun 30 1999 Steve Langasek <vorlon@netexpress.net>
+- further NIS+ fixes
+
+* Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net>
+- fix to uid-handling code for NIS+
+
+* Sat Jun 26 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- merged MD5 fix and early failure syslog
+ by Andrey Vladimirovich Savochkin <saw@msu.ru>
+- minor fixes
+- added signal handler to unix_chkpwd
+
+* Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net>
+- reorganized the code to let it build as separate C files
+
+* Sun Jun 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- fixes in pam_unix_auth, it incorrectly saved and restored return
+ value when likeauth option was used
+
+* Tue Jun 15 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added NIS+ support
+
+* Mon Jun 14 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- total rewrite based on pam_pwdb module, now there is ONE pam_unix.so
+ module, it accepts the same options as pam_pwdb - all of them correctly ;)
+ (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means)
+
+* Tue Apr 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- Arghhh, pam_unix_passwd was not updating /etc/shadow when used with
+ pam_cracklib.
+
+* Mon Apr 19 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added "remember=XXX" option that means 'remember XXX old passwords'
+ Old passwords are stored in /etc/security/opasswd, there can be
+ maximum of 400 passwords per user.
+
+* Sat Mar 27 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm
+ is too lame to use it in real life)
+
+* Sun Mar 21 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- pam_unix_auth now correctly behave when user has NULL AUTHTOK
+- pam_unix_auth returns PAM_PERM_DENIED when seteuid fails
diff --git a/contrib/libpam/modules/pam_unix/Makefile b/contrib/libpam/modules/pam_unix/Makefile
index ad1f47f185e4..9329aa6e1006 100644
--- a/contrib/libpam/modules/pam_unix/Makefile
+++ b/contrib/libpam/modules/pam_unix/Makefile
@@ -1,100 +1,91 @@
-# $Header$
+# $Id: Makefile,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
#
# This Makefile controls a build process of the pam_unix modules
# for Linux-PAM. You should not modify this Makefile.
#
-# $Log$
-# Revision 1.1.1.2 1998/06/03 03:43:56 adam
-# Import from archive
-#
-# Revision 1.3 1998/05/31 23:48:13 adam
-# Link crypt library as necessary.
-#
-# Revision 1.3 1997/04/05 06:20:58 morgan
-# fakeroot and also lockpwdf is in libc now
-#
-# Revision 1.2 1996/11/10 20:18:59 morgan
-# cross platform support
-#
-# Revision 1.1 1996/11/09 19:44:16 morgan
-# Initial revision
-#
-#
+
+include ../../Make.Rules
########################################################################
# some options... uncomment to take effect
########################################################################
-# do you want shadow?
-USE_SHADOW=-D"HAVE_SHADOW_H"
-
+# Unless someone wants to work out how to make this work with the new
+# autoconf stuff, you should use a separate module for this type of thing
+# pam_cracklib perhaps..?
# do you want cracklib?
-ifeq ($(HAVE_CRACKLIB),yes)
-USE_CRACKLIB=-D"USE_CRACKLIB"
-endif
+#ifeq ($(HAVE_CRACKLIB),yes)
+#USE_CRACKLIB=-D"USE_CRACKLIB"
+#endif
# do you want to use lckpwdf?
+ifeq ($(WITH_LCKPWDF),yes)
USE_LCKPWDF=-D"USE_LCKPWDF"
-
# do you need to include the locking functions in the source?
-#NEED_LCKPWDF=-D"NEED_LCKPWDF"
-
-########################################################################
-
-CFLAGS += $(USE_SHADOW) $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF)
+ifeq ($(HAVE_LCKPWDF),no)
+ NEED_LCKPWDF=-D"NEED_LCKPWDF"
+endif
+endif
-ifdef DYNAMIC
-LIBSESSSH = pam_unix_session.so
-LIBAUTHSH = pam_unix_auth.so
-LIBPASSWDSH = pam_unix_passwd.so
-LIBACCOUNT = pam_unix_acct.so
+ifeq ($(HAVE_LIBNSL),yes)
+ LIBNSL = -lnsl
endif
-ifdef STATIC
-LIBSTATIC = libpam_unix.o
+ifeq ($(HAVE_LIBCRYPT),yes)
+ LIBCRYPT=-lcrypt
endif
+CHKPWD=unix_chkpwd
+
+EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
+
+########################################################################
+
+CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS)
+LDLIBS = $(EXTRALS)
+
ifdef USE_CRACKLIB
CRACKLIB = -lcrack
endif
-LIBAUTHOBJ = pam_unix_auth.o support.o
-LIBAUTHSRC = pam_unix_auth.c support.c
-LIBSESSOBJ = pam_unix_sess.o
-LIBSESSSRC = pam_unix_sess.c
-LIBPASSWDSRC = pam_unix_passwd.c
-LIBPASSWDOBJ = pam_unix_passwd.o
-LIBACCOUNTSRC = pam_unix_acct.c
-LIBACCOUNTOBJ = pam_unix_acct.o
-LIBOBJ = $(LIBAUTHOBJ) $(LIBSESSOBJ) $(LIBPASSWDOBJ) $(LIBACCOUNTOBJ)
-LIBSRC = $(LIBAUTHSRC) $(LIBSESSSRC) $(LIBPASSWDSRC) $(LIBACCOUNTSRC)
-
-LIBSHARED = $(LIBSESSSH) $(LIBAUTHSH) $(LIBPASSWDSH) $(LIBACCOUNT)
+LIBOBJ = pam_unix_auth.o pam_unix_acct.o pam_unix_sess.o pam_unix_passwd.o \
+ support.o
+LIBSRC = pam_unix_auth.c pam_unix_acct.c pam_unix_sess.c pam_unix_passwd.c \
+ support.c
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBOBJS = $(addprefix static/,$(LIBOBJ))
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) -c $< -o $@
+PLUS = md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o \
+ yppasswd_xdr.o bigcrypt.o
-static/%.o: %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) -c $< -o $@
+ifdef DYNAMIC
+LIBSHARED = pam_unix.so
+endif
+ifdef STATIC
+LIBSTATIC = libpam_unix.o
+endif
########################### don't edit below #######################
-dummy:
+all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) register
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+static/%.o: %.c
+ $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+dummy:
@echo "**** This is not a top-level Makefile "
exit
info:
@echo
- @echo "*** Building pam-unix(alpha) module of the framework..."
+ @echo "*** Building pam-unix module of the framework..."
@echo
-all: dirs info $(LIBSHARED) $(LIBSTATIC) register
-
dirs:
ifdef DYNAMIC
mkdir -p ./dynamic
@@ -105,50 +96,71 @@ endif
register:
ifdef STATIC
- ( cd .. ; \
- ./register_static pam_unix_auth pam_unix/$(LIBSTATIC) ; \
- ./register_static pam_unix_acct "" ; \
+ ( cd .. ; ./register_static pam_unix_auth pam_unix/$(LIBSTATIC) ; \
+ ./register_static pam_unix_acct "" ; \
+ ./register_static pam_unix_session "" ; \
+ ./register_static pam_unix_passwd "" ; \
)
endif
ifdef DYNAMIC
$(LIBOBJD): $(LIBSRC)
-$(LIBAUTHSH): $(LIBAUTHSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBAUTHOBJ)) -lcrypt
-
-$(LIBSESSSH): $(LIBSESSSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBSESSOBJ))
-
-$(LIBPASSWDSH): $(LIBPASSWDSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBPASSWDOBJ)) $(CRACKLIB) -lcrypt
-
-$(LIBACCOUNT): $(LIBACCOUNTSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBACCOUNTOBJ))
+$(LIBSHARED): $(LIBOBJD)
+ $(LD_D) -o $@ $(LIBOBJD) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT)
endif
-
ifdef STATIC
$(LIBOBJS): $(LIBSRC)
$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
+ $(LD) -r -o $@ $(LIBOBJS) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT)
endif
+$(CHKPWD): unix_chkpwd.o md5_good.o md5_broken.o \
+ md5_crypt_good.o md5_crypt_broken.o \
+ bigcrypt.o
+ $(CC) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
+
+unix_chkpwd.o: unix_chkpwd.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+md5_good.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_broken.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_good.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_broken.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
install: all
mkdir -p $(FAKEROOT)$(SECUREDIR)
ifdef DYNAMIC
install -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
+ for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\
+ do ln -sf $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)/$$x.so ; done
endif
+ $(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
+ install -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
remove:
- cd $(FAKEROOT)$(SECUREDIR) && rm -f $(LIBSHARED)
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(LIBSHARED)
+ for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\
+ do rm -f $(FAKEROOT)$(SECUREDIR)/$$x.so ; done
+ rm -f $(FAKEROOT)$(SUPLEMENTED)/$(CHKPWD)
clean:
- rm -f $(LIBOBJD) $(LIBOBJS) a.out core *~
-
-extraclean: clean
- rm -f *.a *.out *.o *.so *.bak
+ rm -f $(LIBOBJD) $(LIBOBJS) $(CHKPWD) *.o *.so core
+ rm -f *~ *.a *.out *.bak
+ rm -rf dynamic static
.c.o:
$(CC) -c $(CFLAGS) $<
diff --git a/contrib/libpam/modules/pam_unix/README b/contrib/libpam/modules/pam_unix/README
index 082e99697da2..ad4bc35e488a 100644
--- a/contrib/libpam/modules/pam_unix/README
+++ b/contrib/libpam/modules/pam_unix/README
@@ -1,39 +1,39 @@
-This is the README for pam_unix in Linux-PAM-0.53.
+This is the README for pam_unix in Linux-PAM-0.67.
--------------------------------------------------
-pam_unix comes as four separate modules:
+pam_unix now comes as one module pam_unix.so.
+The following links are left for compatibility with old versions:
pam_unix_auth: authentication module providing
- pam_authenticate() and pam_setcred() hooks
-
- NO options are recognized. Credential facilities are trivial
- (function simply returns)
-
+ pam_authenticate() and pam_setcred() hooks
pam_unix_sess: session module, providing session logging
-
- "debug" and "trace" arguments are accepted, which indicate the
- logging-level for syslog.
-
- "debug" -> LOG_DEBUG [ also default ]
- "trace" -> LOG_AUTHPRIV
-
pam_unix_acct: account management, providing shadow account
- managment features, password aging etc..
-
- NO options are recognized. Account managment trivial without
- shadow active.
-
+ managment features, password aging etc..
pam_unix_passwd: password updating facilities providing
- cracklib password strength checking facilities.
-
- if compiled, the default behavior is to check passwords
- strictly using CrackLib. This behavior can be turned off
- with the argument
-
- "strict=false"
+ cracklib password strength checking facilities.
+
+The following options are recognized:
+ debug - log more debugging info
+ audit - a little more extreme than debug
+ use_first_pass - don 't prompt the user for passwords
+ take them from PAM_ items instead
+ try_first_pass - don 't prompt the user for the passwords
+ unless PAM_(OLD)AUTHTOK is unset
+ use_authtok - like try_first_pass, but * fail * if the new
+ PAM_AUTHTOK has not been previously set.
+ (intended for stacking password modules only)
+ not_set_pass - don 't set the PAM_ items with the passwords
+ used by this module.
+ shadow - try to maintian a shadow based system.
+ md5 - when a user changes their password next,
+ encrypt it with the md5 algorithm.
+ bigcrypt - when a user changes their password next,
+ excrypt it with the DEC C2 - algorithm(0).
+ nodelay - used to prevent failed authentication
+ resulting in a delay of about 1 second.
+ nis - use NIS RPC for setting new password
+ remember=X - remember X old passwords, they are kept in
+ /etc/security/opasswd in MD5 crypted form
invalid arguments are logged to syslog.
-------------------------------
-- Andrew 1996/11/9
-------------------------------
diff --git a/contrib/libpam/modules/pam_unix/bigcrypt.c b/contrib/libpam/modules/pam_unix/bigcrypt.c
new file mode 100644
index 000000000000..b1568d6b340a
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/bigcrypt.c
@@ -0,0 +1,119 @@
+/*
+ * This function implements the "bigcrypt" algorithm specifically for
+ * Linux-PAM.
+ *
+ * This algorithm is algorithm 0 (default) shipped with the C2 secure
+ * implementation of Digital UNIX.
+ *
+ * Disclaimer: This work is not based on the source code to Digital
+ * UNIX, nor am I connected to Digital Equipment Corp, in any way
+ * other than as a customer. This code is based on published
+ * interfaces and reasonable guesswork.
+ *
+ * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8
+ * characters or less. Each block is encrypted using the standard UNIX
+ * libc crypt function. The result of the encryption for one block
+ * provides the salt for the suceeding block.
+ *
+ * Restrictions: The buffer used to hold the encrypted result is
+ * statically allocated. (see MAX_PASS_LEN below). This is necessary,
+ * as the returned pointer points to "static data that are overwritten
+ * by each call", (XPG3: XSI System Interface + Headers pg 109), and
+ * this is a drop in replacement for crypt();
+ *
+ * Andy Phillips <atp@mssl.ucl.ac.uk>
+ */
+
+#include <string.h>
+#include <security/_pam_macros.h>
+
+char *crypt(const char *key, const char *salt);
+char *bigcrypt(const char *key, const char *salt);
+
+/*
+ * Max cleartext password length in segments of 8 characters this
+ * function can deal with (16 segments of 8 chars= max 128 character
+ * password).
+ */
+
+#define MAX_PASS_LEN 16
+#define SEGMENT_SIZE 8
+#define SALT_SIZE 2
+#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE)
+#define ESEGMENT_SIZE 11
+#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1)
+
+char *bigcrypt(const char *key, const char *salt)
+{
+ static char dec_c2_cryptbuf[CBUF_SIZE]; /* static storage area */
+
+ unsigned long int keylen, n_seg, j;
+ char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr;
+ char keybuf[KEYBUF_SIZE + 1];
+
+ D(("called with key='%s', salt='%s'.", key, salt));
+
+ /* reset arrays */
+ memset(keybuf, 0, KEYBUF_SIZE + 1);
+ memset(dec_c2_cryptbuf, 0, CBUF_SIZE);
+
+ /* fill KEYBUF_SIZE with key */
+ strncpy(keybuf, key, KEYBUF_SIZE);
+
+ /* deal with case that we are doing a password check for a
+ conventially encrypted password: the salt will be
+ SALT_SIZE+ESEGMENT_SIZE long. */
+ if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE))
+ keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */
+
+ keylen = strlen(keybuf);
+
+ if (!keylen) {
+ n_seg = 1;
+ } else {
+ /* work out how many segments */
+ n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE);
+ }
+
+ if (n_seg > MAX_PASS_LEN)
+ n_seg = MAX_PASS_LEN; /* truncate at max length */
+
+ /* set up some pointers */
+ cipher_ptr = dec_c2_cryptbuf;
+ plaintext_ptr = keybuf;
+
+ /* do the first block with supplied salt */
+ tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */
+
+ /* and place in the static area */
+ strncpy(cipher_ptr, tmp_ptr, 13);
+ cipher_ptr += ESEGMENT_SIZE + SALT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */
+
+ /* change the salt (1st 2 chars of previous block) - this was found
+ by dowsing */
+
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+
+ /* so far this is identical to "return crypt(key, salt);", if
+ there is more than one block encrypt them... */
+
+ if (n_seg > 1) {
+ for (j = 2; j <= n_seg; j++) {
+
+ tmp_ptr = crypt(plaintext_ptr, salt_ptr);
+
+ /* skip the salt for seg!=0 */
+ strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE);
+
+ cipher_ptr += ESEGMENT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE;
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+ }
+ }
+ D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf));
+
+ /* this is the <NUL> terminated encrypted password */
+
+ return dec_c2_cryptbuf;
+}
diff --git a/contrib/libpam/modules/pam_unix/lckpwdf.-c b/contrib/libpam/modules/pam_unix/lckpwdf.-c
new file mode 100644
index 000000000000..b5ff45850b4b
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/lckpwdf.-c
@@ -0,0 +1,117 @@
+/*
+ * This is a hack, but until libc and glibc both include this function
+ * by default (libc only includes it if nys is not being used, at the
+ * moment, and glibc doesn't appear to have it at all) we need to have
+ * it here, too. :-(
+ *
+ * This should not become an official part of PAM.
+ *
+ * BEGIN_HACK
+ */
+
+/*
+ * lckpwdf.c -- prevent simultaneous updates of password files
+ *
+ * Before modifying any of the password files, call lckpwdf(). It may block
+ * for up to 15 seconds trying to get the lock. Return value is 0 on success
+ * or -1 on failure. When you are done, call ulckpwdf() to release the lock.
+ * The lock is also released automatically when the process exits. Only one
+ * process at a time may hold the lock.
+ *
+ * These functions are supposed to be conformant with AT&T SVID Issue 3.
+ *
+ * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
+ * public domain.
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+
+#define LOCKFILE "/etc/.pwd.lock"
+#define TIMEOUT 15
+
+static int lockfd = -1;
+
+static int set_close_on_exec(int fd)
+{
+ int flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
+ return -1;
+ flags |= FD_CLOEXEC;
+ return fcntl(fd, F_SETFD, flags);
+}
+
+static int do_lock(int fd)
+{
+ struct flock fl;
+
+ memset(&fl, 0, sizeof fl);
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ return fcntl(fd, F_SETLKW, &fl);
+}
+
+static void alarm_catch(int sig)
+{
+/* does nothing, but fcntl F_SETLKW will fail with EINTR */
+}
+
+static int lckpwdf(void)
+{
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
+
+ if (lockfd != -1)
+ return -1;
+
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ if (lockfd == -1)
+ return -1;
+ if (set_close_on_exec(lockfd) == -1)
+ goto cleanup_fd;
+
+ memset(&act, 0, sizeof act);
+ act.sa_handler = alarm_catch;
+ act.sa_flags = 0;
+ sigfillset(&act.sa_mask);
+ if (sigaction(SIGALRM, &act, &oldact) == -1)
+ goto cleanup_fd;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+ if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1)
+ goto cleanup_sig;
+
+ alarm(TIMEOUT);
+ if (do_lock(lockfd) == -1)
+ goto cleanup_alarm;
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ sigaction(SIGALRM, &oldact, NULL);
+ return 0;
+
+ cleanup_alarm:
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ cleanup_sig:
+ sigaction(SIGALRM, &oldact, NULL);
+ cleanup_fd:
+ close(lockfd);
+ lockfd = -1;
+ return -1;
+}
+
+static int ulckpwdf(void)
+{
+ unlink(LOCKFILE);
+ if (lockfd == -1)
+ return -1;
+
+ if (close(lockfd) == -1) {
+ lockfd = -1;
+ return -1;
+ }
+ lockfd = -1;
+ return 0;
+}
+/* END_HACK */
diff --git a/contrib/libpam/modules/pam_unix/md5.c b/contrib/libpam/modules/pam_unix/md5.c
new file mode 100644
index 000000000000..7ee9ed00cdea
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5.c
@@ -0,0 +1,256 @@
+/*
+ * $Id: md5.c,v 1.1.1.1 2000/06/20 22:12:03 agmorgan Exp $
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len) /* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301U;
+ ctx->buf[1] = 0xefcdab89U;
+ ctx->buf[2] = 0x98badcfeU;
+ ctx->buf[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *) ctx->in)[14] = ctx->bits[0];
+ ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
diff --git a/contrib/libpam/modules/pam_unix/md5.h b/contrib/libpam/modules/pam_unix/md5.h
new file mode 100644
index 000000000000..103f168a91c6
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5.h
@@ -0,0 +1,31 @@
+
+#ifndef MD5_H
+#define MD5_H
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
+
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* MD5_H */
diff --git a/contrib/libpam/modules/pam_unix/md5_crypt.c b/contrib/libpam/modules/pam_unix/md5_crypt.c
new file mode 100644
index 000000000000..257e4bb6bd06
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5_crypt.c
@@ -0,0 +1,149 @@
+/*
+ * $Id: md5_crypt.c,v 1.1.1.1 2000/06/20 22:12:03 agmorgan Exp $
+ *
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v & 0x3f];
+ v >>= 6;
+ }
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+
+char *MD5Name(crypt_md5)(const char *pw, const char *salt)
+{
+ const char *magic = "$1$";
+ /* This string is magic for this algorithm. Having
+ * it this way, we can get get better later on */
+ static char passwd[120], *p;
+ static const char *sp, *ep;
+ unsigned char final[16];
+ int sl, pl, i, j;
+ MD5_CTX ctx, ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if (!strncmp(sp, magic, strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Name(MD5Init)(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ for (pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ /* Then something really weird... */
+ for (j = 0, i = strlen(pw); i; i >>= 1)
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
+ else
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd, magic);
+ strncat(passwd, sp, sl);
+ strcat(passwd, "$");
+
+ MD5Name(MD5Final)(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ MD5Name(MD5Init)(&ctx1);
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+
+ if (i % 3)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+
+ if (i % 7)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[0] << 16) | (final[6] << 8) | final[12];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[1] << 16) | (final[7] << 8) | final[13];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[2] << 16) | (final[8] << 8) | final[14];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[3] << 16) | (final[9] << 8) | final[15];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[4] << 16) | (final[10] << 8) | final[5];
+ to64(p, l, 4);
+ p += 4;
+ l = final[11];
+ to64(p, l, 2);
+ p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ return passwd;
+}
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_acct.c b/contrib/libpam/modules/pam_unix/pam_unix_acct.c
index 5c0546aa1f8f..178b6037465a 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_acct.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_acct.c
@@ -1,5 +1,6 @@
/*
* Copyright Elliot Lee, 1996. All rights reserved.
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,73 +34,159 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* pam_unix_acct.c module, different track */
-
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#define __USE_MISC
-#include <pwd.h>
+#include <unistd.h>
#include <sys/types.h>
#include <syslog.h>
-#include <unistd.h>
-#ifdef HAVE_SHADOW_H
+#include <pwd.h>
#include <shadow.h>
-#endif
-#include <time.h>
+#include <time.h> /* for time() */
-#define PAM_SM_ACCOUNT
+#include <security/_pam_macros.h>
-#ifndef LINUX
-# include <security/pam_appl.h>
-#endif
+/* indicate that the following groups are defined */
+
+#define PAM_SM_ACCOUNT
-#define _PAM_EXTERN_FUNCTIONS
#include <security/pam_modules.h>
-PAM_EXTERN
-int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
+
+#include "support.h"
+
+/*
+ * PAM framework looks for this entry-point to pass control to the
+ * account management module.
+ */
+
+PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
-#ifdef HAVE_SHADOW_H
- const char *uname;
- int retval;
- time_t curdays;
- struct spwd *spent;
- struct passwd *pwent;
-
- setpwent();
- setspent();
- retval = pam_get_item(pamh,PAM_USER,(const void **)&uname);
- if(retval != PAM_SUCCESS || uname == NULL) {
- return PAM_SUCCESS; /* Couldn't get username, just ignore this
- (i.e. they don't have any expiry info available */
- }
- pwent = getpwnam(uname);
- if(!pwent)
- return PAM_USER_UNKNOWN;
- if(strcmp(pwent->pw_passwd,"x"))
- return PAM_SUCCESS; /* They aren't using shadow passwords & expiry
- info */
- spent = getspnam(uname);
- if(!spent)
- return PAM_SUCCESS; /* Couldn't get username from shadow, just ignore this
- (i.e. they don't have any expiry info available */
- curdays = time(NULL)/(60*60*24);
- if((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
- && (spent->sp_max != -1) && (spent->sp_inact != -1))
- return PAM_ACCT_EXPIRED;
- if((curdays > spent->sp_expire) && (spent->sp_expire != -1))
- return PAM_ACCT_EXPIRED;
- endspent();
- endpwent();
-#endif
- return PAM_SUCCESS;
+ unsigned int ctrl;
+ const char *uname;
+ int retval, daysleft;
+ time_t curdays;
+ struct spwd *spent;
+ struct passwd *pwent;
+ char buf[80];
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &uname);
+ D(("user = `%s'", uname));
+ if (retval != PAM_SUCCESS || uname == NULL) {
+ _log_err(LOG_ALERT, pamh
+ ,"could not identify user (from uid=%d)"
+ ,getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ pwent = getpwnam(uname);
+ if (!pwent) {
+ _log_err(LOG_ALERT, pamh
+ ,"could not identify user (from getpwnam(%s))"
+ ,uname);
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (!strcmp( pwent->pw_passwd, "*NP*" )) { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwent->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwent->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwent->pw_uid ) == -1)
+ return PAM_CRED_INSUFFICIENT;
+ }
+ }
+ spent = getspnam( uname );
+ if (save_uid == pwent->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+
+ } else if (!strcmp( pwent->pw_passwd, "x" )) {
+ spent = getspnam(uname);
+ } else {
+ return PAM_SUCCESS;
+ }
+
+ if (!spent)
+ return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from shadow */
+
+ curdays = time(NULL) / (60 * 60 * 24);
+ D(("today is %d, last change %d", curdays, spent->sp_lstchg));
+ if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)
+ && (spent->sp_lstchg != 0)) {
+ _log_err(LOG_NOTICE, pamh
+ ,"account %s has expired (account expired)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "Your account has expired; please contact your system administrator");
+ D(("account expired"));
+ return PAM_ACCT_EXPIRED;
+ }
+ if ((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
+ && (spent->sp_max != -1) && (spent->sp_inact != -1)
+ && (spent->sp_lstchg != 0)) {
+ _log_err(LOG_NOTICE, pamh
+ ,"account %s has expired (failed to change password)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "Your account has expired; please contact your system administrator");
+ D(("account expired 2"));
+ return PAM_ACCT_EXPIRED;
+ }
+ D(("when was the last change"));
+ if (spent->sp_lstchg == 0) {
+ _log_err(LOG_NOTICE, pamh
+ ,"expired password for user %s (root enforced)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You are required to change your password immediately (root enforced)");
+ D(("need a new password"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if (((spent->sp_lstchg + spent->sp_max) < curdays) && (spent->sp_max != -1)) {
+ _log_err(LOG_DEBUG, pamh
+ ,"expired password for user %s (password aged)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You are required to change your password immediately (password aged)");
+ D(("need a new password 2"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if ((curdays > (spent->sp_lstchg + spent->sp_max - spent->sp_warn))
+ && (spent->sp_max != -1) && (spent->sp_warn != -1)) {
+ daysleft = (spent->sp_lstchg + spent->sp_max) - curdays;
+ _log_err(LOG_DEBUG, pamh
+ ,"password for user %s will expire in %d days"
+ ,uname, daysleft);
+ snprintf(buf, 80, "Warning: your password will expire in %d day%.2s",
+ daysleft, daysleft == 1 ? "" : "s");
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
+ }
+
+ D(("all done"));
+
+ return PAM_SUCCESS;
}
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_auth.c b/contrib/libpam/modules/pam_unix/pam_unix_auth.c
index 95f13d0abdc6..f08ea515b4d4 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_auth.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_auth.c
@@ -1,8 +1,7 @@
-/* $Header: /home/morgan/pam/Linux-PAM-0.59/modules/pam_unix/RCS/pam_unix_auth.c,v 1.1 1996/11/09 19:44:35 morgan Exp morgan $ */
-
/*
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
* NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,217 +34,145 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-/*
- * $Log: pam_unix_auth.c,v $
- *
- * Revision 1.9 1996/05/26 04:13:04 morgan
- * added static support
- *
- * Revision 1.8 1996/05/21 03:51:58 morgan
- * added "const" to rcsid[] definition
- *
- * Revision 1.7 1996/04/19 03:25:57 alex
- * minor corrections.
- *
- * Revision 1.6 1996/04/17 01:05:05 alex
- * _pam_auth_unix() cleaned up - non-authentication code is made into funcs
- * and mostly moved out to support.c.
- *
- * Revision 1.5 1996/04/16 21:12:46 alex
- * unix authentication works on Bach again. This is a tranitional stage.
- * I really don't like that _pam_unix_auth() grew into a monster that does
- * prompts etc etc. They should go into other functions.
- *
- * Revision 1.4 1996/04/07 08:06:12 morgan
- * tidied up a little
- *
- * Revision 1.3 1996/04/07 07:34:07 morgan
- * added conversation support. Now the module is capable of obtaining a
- * username and a password all by itself.
- *
- * Revision 1.2 1996/03/29 02:31:19 morgan
- * Marek Michalkiewicz's small patches for shadow support.
- *
- * Revision 1.1 1996/03/09 09:10:57 morgan
- * Initial revision
- *
- */
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+/* #define DEBUG */
+
+#include <security/_pam_aconf.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
-#define __USE_BSD
#include <unistd.h>
-#include <pwd.h>
+#include <fcntl.h>
+#include <ctype.h>
#include <sys/types.h>
+#include <sys/stat.h>
-#ifndef NDEBUG
-
-#include <syslog.h>
-
-#endif /* NDEBUG */
-
-#ifdef HAVE_SHADOW_H
-
-#include <shadow.h>
-
-#endif /* HAVE_SHADOW_H */
-
-#ifndef LINUX
-
-#include <security/pam_appl.h>
+/* indicate the following groups are defined */
-#endif /* LINUX */
+#define PAM_SM_AUTH
#define _PAM_EXTERN_FUNCTIONS
+#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-static const char rcsid[] = "$Id: pam_unix_auth.c,v 1.1 1996/11/09 19:44:35 morgan Exp morgan $ pam_unix authentication functions. alex@bach.cis.temple.edu";
-
-/* Define function phototypes */
-
-extern char *crypt(const char *key, const char *salt); /* This should have
- been in unistd.h
- but it is not */
-extern int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response );
-
-extern int _set_auth_tok( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv );
-
-static int _pam_auth_unix( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv );
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
-static int _pam_set_credentials_unix ( pam_handle_t *pamh,
- int flags,
- int argc,
- const char ** argv ) ;
+#include "support.h"
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * authentication module.
+ */
/* Fun starts here :)
- *
- * _pam_auth_unix() actually performs UNIX/shadow authentication
+
+ * pam_sm_authenticate() performs UNIX/shadow authentication
*
- * First, if shadow support is available, attempt to perform
- * authentication using shadow passwords. If shadow is not
- * available, or user does not have a shadow password, fallback
- * onto a normal UNIX authentication
+ * First, if shadow support is available, attempt to perform
+ * authentication using shadow passwords. If shadow is not
+ * available, or user does not have a shadow password, fallback
+ * onto a normal UNIX authentication
*/
-static int _pam_auth_unix( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
+#define _UNIX_AUTHTOK "-UN*X-PASS"
+
+#define AUTH_RETURN \
+{ \
+ if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \
+ D(("recording return code for next time [%d]", \
+ retval)); \
+ pam_set_data(pamh, "unix_setcred_return", \
+ (void *) retval, NULL); \
+ } \
+ D(("done. [%s]", pam_strerror(pamh, retval))); \
+ return retval; \
+}
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
+ ,int argc, const char **argv)
{
- int retval;
- struct passwd *pw;
- const char *name;
- char *p, *pp;
- const char *salt;
+ unsigned int ctrl;
+ int retval, *ret_data = NULL;
+ const char *name, *p;
-#ifdef HAVE_SHADOW_H
+ D(("called."));
- struct spwd *sp;
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
-#endif
+ /* Get a few bytes so we can pass our return value to
+ pam_sm_setcred(). */
+ ret_data = malloc(sizeof(int));
/* get the user'name' */
- if ( (retval = pam_get_user( pamh, &name, "login: ") ) != PAM_SUCCESS )
- return retval;
-
- /*
- * at some point we will have to make this module pay
- * attention to arguments, like 'pam_first_pass' etc...
- */
-
- pw = getpwnam ( name );
+ retval = pam_get_user(pamh, &name, "login: ");
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't take
+ * any chances here. Require that the username starts with an
+ * alphanumeric character.
+ */
+ if (name == NULL || !isalnum(*name)) {
+ _log_err(LOG_ERR, pamh, "bad username [%s]", name);
+ retval = PAM_USER_UNKNOWN;
+ AUTH_RETURN
+ }
+ if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
+ D(("username [%s] obtained", name));
+ } else {
+ D(("trouble reading username"));
+ if (retval == PAM_CONV_AGAIN) {
+ D(("pam_get_user/conv() function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ }
+ AUTH_RETURN
+ }
- /* For NIS+, root cannot get password for lesser user */
- if (pw) {
- uid_t save_euid, save_uid;
+ /* if this user does not have a password... */
- save_uid = getuid ();
- save_euid = geteuid();
- if (setreuid (0,pw->pw_uid) >= 0) {
- pw = getpwnam ( name );
- setreuid (save_uid,save_euid);
- }
+ if (_unix_blankpasswd(ctrl, name)) {
+ D(("user '%s' has blank passwd", name));
+ name = NULL;
+ retval = PAM_SUCCESS;
+ AUTH_RETURN
}
-
- if ( pw && (!pw->pw_passwd || pw->pw_passwd[0] == '\0') &&
- !(flags & PAM_DISALLOW_NULL_AUTHTOK)) {
- return PAM_SUCCESS;
+ /* get this user's authentication token */
+
+ retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
+ ,_UNIX_AUTHTOK, &p);
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_CRIT, pamh, "auth could not identify password for [%s]"
+ ,name);
+ } else {
+ D(("conversation function is not ready yet"));
+ /*
+ * it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ }
+ name = NULL;
+ AUTH_RETURN
}
- pam_get_item( pamh, PAM_AUTHTOK, (void*) &p );
-
- if ( !p )
- {
- retval = _set_auth_tok( pamh, flags, argc, argv );
- if ( retval != PAM_SUCCESS )
- return retval;
- }
-
- /*
- We have to call pam_get_item() again because value of p should
- change
- */
-
- pam_get_item( pamh, PAM_AUTHTOK, (void*) &p );
+ D(("user=%s, password=[%s]", name, p));
+ /* verify the password of this user */
+ retval = _unix_verify_password(pamh, name, p, ctrl);
+ name = p = NULL;
- if (pw)
- {
-
-#ifdef HAVE_SHADOW_H
-
- /*
- * Support for shadow passwords on Linux and SVR4-based
- * systems. Shadow passwords are optional on Linux - if
- * there is no shadow password, use the non-shadow one.
- */
-
- sp = getspnam( name );
- if (sp && (!strcmp(pw->pw_passwd,"x")))
- {
- /* TODO: check if password has expired etc. */
- salt = sp->sp_pwdp;
- }
- else
-#endif
- salt = pw->pw_passwd;
- }
- else
- return PAM_USER_UNKNOWN;
-
- /* The 'always-encrypt' method does not make sense in PAM
- because the framework requires return of a different
- error code for non-existant users -- alex */
-
- if ( ( !pw->pw_passwd ) && ( !p ) )
- if ( flags && PAM_DISALLOW_NULL_AUTHTOK )
- return PAM_SUCCESS;
- else
- return PAM_AUTH_ERR;
-
- pp = crypt(p, salt);
-
- if ( strcmp( pp, salt ) == 0 )
- return PAM_SUCCESS;
-
- return PAM_AUTH_ERR;
+ AUTH_RETURN
}
+
/*
* The only thing _pam_set_credentials_unix() does is initialization of
* UNIX group IDs.
@@ -255,45 +182,35 @@ static int _pam_auth_unix( pam_handle_t *pamh,
* warned you. -- AOY
*/
-static int _pam_set_credentials_unix ( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-
-{ /* FIX ME: incorrect error code */
-
- return PAM_SUCCESS; /* This is a wrong result code. From what I
- remember from reafing one of the guides
- there's an error-level saying 'N/A func'
- -- AOY
- */
-}
-
-/*
- * PAM framework looks for these entry-points to pass control to the
- * authentication module.
- */
-
-PAM_EXTERN
-int pam_sm_authenticate( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- return _pam_auth_unix( pamh, flags, argc, argv );
-}
-
-PAM_EXTERN
-int pam_sm_setcred( 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)
{
- return _pam_set_credentials_unix ( pamh, flags, argc, argv ) ;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ /* FIXME: it shouldn't be necessary to parse the arguments again. The
+ only argument we need is UNIX_LIKE_AUTH: if it was set,
+ pam_get_data will succeed. If it wasn't, it will fail, and we
+ return PAM_SUCCESS. -SRL */
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+ retval = PAM_SUCCESS;
+
+ if (on(UNIX_LIKE_AUTH, ctrl)) {
+ int *pretval = NULL;
+
+ D(("recovering return code from auth call"));
+ pam_get_data(pamh, "unix_setcred_return", (const void **) pretval);
+ if(pretval) {
+ retval = *pretval;
+ free(pretval);
+ D(("recovered data indicates that old retval was %d", retval));
+ }
+ }
+ return retval;
}
-
-/* static module data */
#ifdef PAM_STATIC
struct pam_module _pam_unix_auth_modstruct = {
"pam_unix_auth",
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_passwd.c b/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
index de1345e85285..3fe8a27a6997 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
@@ -1,8 +1,7 @@
-
-/* Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
- Copyright (C) 1996. */
-
/*
+ * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ * Copyright (C) 1996.
+ * Copyright (c) Jan Rêkorajski, 1999.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -16,13 +15,13 @@
* 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
@@ -36,778 +35,970 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- How it works:
- Gets in username (has to be done) from the calling program
- Does authentication of user (only if we are not running as root)
- Gets new password/checks for sanity
- Sets it.
- */
-
-#define PAM_SM_PASSWORD
-
-/* #define DEBUG 1 */
+#include <security/_pam_aconf.h>
#include <stdio.h>
-#include <sys/time.h>
-#define _BSD_SOURCE
-#define _SVID_SOURCE
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
#include <errno.h>
-#define __USE_BSD
-#define _BSD_SOURCE
-#include <pwd.h>
#include <sys/types.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <shadow.h>
+#include <time.h> /* for time() */
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
-/* why not defined? */
-void setpwent(void);
-void endpwent(void);
-int chmod(const char *path, mode_t mode);
-struct passwd *fgetpwent(FILE *stream);
-int putpwent(const struct passwd *p, FILE *stream);
-
-#include <unistd.h>
-char *crypt(const char *key, const char *salt);
#ifdef USE_CRACKLIB
#include <crack.h>
#endif
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <string.h>
-#include <stdarg.h>
-#include <malloc.h>
+
#include <security/_pam_macros.h>
-#ifndef LINUX /* AGM added this as of 0.2 */
-#include <security/pam_appl.h>
-#endif /* ditto */
+/* indicate the following groups are defined */
+
+#define PAM_SM_PASSWORD
+
#include <security/pam_modules.h>
-#ifdef HAVE_SHADOW_H
-#include <shadow.h>
-#endif
-#define MAX_PASSWD_TRIES 3
-#define OLD_PASSWORD_PROMPT "Password: "
-#define NEW_PASSWORD_PROMPT "New password: "
-#define AGAIN_PASSWORD_PROMPT "New password (again): "
-#define PW_TMPFILE "/etc/npasswd"
-#define SH_TMPFILE "/etc/nshadow"
-#define CRACKLIB_DICTS "/usr/lib/cracklib_dict"
-
-/* Various flags for the getpass routine to send back in... */
-#define PPW_EXPIRED 1
-#define PPW_EXPIRING 2
-#define PPW_WILLEXPIRE 4
-#define PPW_NOSUCHUSER 8
-#define PPW_SHADOW 16
-#define PPW_TOOEARLY 32
-#define PPW_ERROR 64
-
-#ifndef DO_TEST
-#define STATIC static
-#else
-#define STATIC
-#endif
-/* Sets a password for the specified user to the specified password
- Returns flags PPW_*, or'd. */
-STATIC int _do_setpass(char *forwho, char *towhat, int flags);
-/* Gets a password for the specified user
- Returns flags PPW_*, or'd. */
-STATIC int _do_getpass(char *forwho, char **theirpass);
-/* Checks whether the password entered is same as listed in the database
- 'entered' should not be crypt()'d or anything (it should be as the
- user entered it...), 'listed' should be as it is listed in the
- password database file */
-STATIC int _do_checkpass(const char *entered, char *listed);
-
-/* sends a one-way message to the user, either error or info... */
-STATIC int conv_sendmsg(struct pam_conv *aconv, const char *message, int style);
-/* sends a message and returns the results of the conversation */
-STATIC int conv_getitem(struct pam_conv *aconv, char *message, int style,
- char **result);
-
-PAM_EXTERN
-int pam_sm_chauthtok( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv);
-
-static void _pam_log(int err, const char *format, ...)
-{
- va_list args;
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
- va_start(args, format);
- openlog("PAM-unix_passwd", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
- va_end(args);
- closelog();
-}
+#include "yppasswd.h"
+#include "md5.h"
+#include "support.h"
+
+#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
+extern int getrpcport(const char *host, unsigned long prognum,
+ unsigned long versnum, unsigned int proto);
+#endif /* GNU libc 2.1 */
+
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * password changing module.
+ */
#ifdef NEED_LCKPWDF
-/* This is a hack, but until libc and glibc both include this function
- * by default (libc only includes it if nys is not being used, at the
- * moment, and glibc doesn't appear to have it at all) we need to have
- * it here, too. :-(
- *
- * This should not become an official part of PAM.
- *
- * BEGIN_HACK
-*/
+#include "./lckpwdf.-c"
+#endif
+
+extern char *bigcrypt(const char *key, const char *salt);
/*
- * lckpwdf.c -- prevent simultaneous updates of password files
- *
- * Before modifying any of the password files, call lckpwdf(). It may block
- * for up to 15 seconds trying to get the lock. Return value is 0 on success
- * or -1 on failure. When you are done, call ulckpwdf() to release the lock.
- * The lock is also released automatically when the process exits. Only one
- * process at a time may hold the lock.
- *
- * These functions are supposed to be conformant with AT&T SVID Issue 3.
- *
- * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
- * public domain.
+ How it works:
+ Gets in username (has to be done) from the calling program
+ Does authentication of user (only if we are not running as root)
+ Gets new password/checks for sanity
+ Sets it.
*/
-#include <fcntl.h>
-#include <signal.h>
+/* passwd/salt conversion macros */
-#define LOCKFILE "/etc/.pwd.lock"
-#define TIMEOUT 15
+#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
+#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-static int lockfd = -1;
+/* data tokens */
-static int
-set_close_on_exec(int fd)
+#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS"
+#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS"
+
+#define MAX_PASSWD_TRIES 3
+#define PW_TMPFILE "/etc/npasswd"
+#define SH_TMPFILE "/etc/nshadow"
+#define CRACKLIB_DICTS "/usr/share/dict/cracklib_dict"
+#define OPW_TMPFILE "/etc/security/nopasswd"
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+
+/*
+ * i64c - convert an integer to a radix 64 character
+ */
+static int i64c(int i)
{
- int flags = fcntl(fd, F_GETFD, 0);
- if (flags == -1)
- return -1;
- flags |= FD_CLOEXEC;
- return fcntl(fd, F_SETFD, flags);
+ if (i < 0)
+ return ('.');
+ else if (i > 63)
+ return ('z');
+ if (i == 0)
+ return ('.');
+ if (i == 1)
+ return ('/');
+ if (i >= 2 && i <= 11)
+ return ('0' - 2 + i);
+ if (i >= 12 && i <= 37)
+ return ('A' - 12 + i);
+ if (i >= 38 && i <= 63)
+ return ('a' - 38 + i);
+ return ('\0');
}
-static int
-do_lock(int fd)
+static char *crypt_md5_wrapper(const char *pass_new)
{
- struct flock fl;
+ /*
+ * Code lifted from Marek Michalkiewicz's shadow suite. (CG)
+ * removed use of static variables (AGM)
+ */
+
+ struct timeval tv;
+ MD5_CTX ctx;
+ unsigned char result[16];
+ char *cp = (char *) result;
+ unsigned char tmp[16];
+ int i;
+ char *x, *e = NULL;
+
+ GoodMD5Init(&ctx);
+ gettimeofday(&tv, (struct timezone *) 0);
+ GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
+ i = getpid();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ i = clock();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, result, sizeof result);
+ GoodMD5Final(tmp, &ctx);
+ strcpy(cp, "$1$"); /* magic for the MD5 */
+ cp += strlen(cp);
+ for (i = 0; i < 8; i++)
+ *cp++ = i64c(tmp[i] & 077);
+ *cp = '\0';
+
+ /* no longer need cleartext */
+ e = Goodcrypt_md5(pass_new, (const char *) result);
+ x = x_strdup(e); /* put e in malloc()ed memory */
+ _pam_overwrite(e); /* clean up */
+
+ return x;
+}
- memset(&fl, 0, sizeof fl);
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- return fcntl(fd, F_SETLKW, &fl);
+static char *getNISserver(pam_handle_t *pamh)
+{
+ char *master;
+ char *domainname;
+ int port, err;
+
+ if ((err = yp_get_default_domain(&domainname)) != 0) {
+ _log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n",
+ yperr_string(err));
+ return NULL;
+ }
+ if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
+ _log_err(LOG_WARNING, pamh, "can't find the master ypserver: %s\n",
+ yperr_string(err));
+ return NULL;
+ }
+ port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
+ if (port == 0) {
+ _log_err(LOG_WARNING, pamh,
+ "yppasswdd not running on NIS master host\n");
+ return NULL;
+ }
+ if (port >= IPPORT_RESERVED) {
+ _log_err(LOG_WARNING, pamh,
+ "yppasswd daemon running on illegal port.\n");
+ return NULL;
+ }
+ return master;
}
-static void
-alarm_catch(int sig)
+static int check_old_password(const char *forwho, const char *newpass)
{
-/* does nothing, but fcntl F_SETLKW will fail with EINTR */
+ static char buf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas;
+ int retval = PAM_SUCCESS;
+ FILE *opwfile;
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf) - 1] = '\0';
+ s_luser = strtok(buf, ":,");
+ s_uid = strtok(NULL, ":,");
+ s_npas = strtok(NULL, ":,");
+ s_pas = strtok(NULL, ":,");
+ while (s_pas != NULL) {
+ if (!strcmp(Goodcrypt_md5(newpass, s_pas), s_pas)) {
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ s_pas = strtok(NULL, ":,");
+ }
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ return retval;
}
-static int lckpwdf(void)
+static int save_old_password(const char *forwho, const char *oldpass, int howmany)
{
- struct sigaction act, oldact;
- sigset_t set, oldset;
-
- if (lockfd != -1)
- return -1;
-
- lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
- if (lockfd == -1)
- return -1;
- if (set_close_on_exec(lockfd) == -1)
- goto cleanup_fd;
-
- memset(&act, 0, sizeof act);
- act.sa_handler = alarm_catch;
- act.sa_flags = 0;
- sigfillset(&act.sa_mask);
- if (sigaction(SIGALRM, &act, &oldact) == -1)
- goto cleanup_fd;
-
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
- if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1)
- goto cleanup_sig;
-
- alarm(TIMEOUT);
- if (do_lock(lockfd) == -1)
- goto cleanup_alarm;
- alarm(0);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- sigaction(SIGALRM, &oldact, NULL);
- return 0;
-
-cleanup_alarm:
- alarm(0);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
-cleanup_sig:
- sigaction(SIGALRM, &oldact, NULL);
-cleanup_fd:
- close(lockfd);
- lockfd = -1;
- return -1;
+ static char buf[16384];
+ static char nbuf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas, *pass;
+ int retval = 0, npas;
+ FILE *pwfile, *opwfile;
+ int err = 0;
+ int oldmask;
+ int found = 0;
+ struct passwd *pwd = NULL;
+
+ if (howmany < 0)
+ return retval;
+
+ if (oldpass == NULL)
+ return retval;
+
+ oldmask = umask(077);
+ pwfile = fopen(OPW_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(OPW_TMPFILE, 0, 0);
+ chmod(OPW_TMPFILE, 0600);
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf) - 1] = '\0';
+ s_luser = strtok(buf, ":");
+ s_uid = strtok(NULL, ":");
+ s_npas = strtok(NULL, ":");
+ s_pas = strtok(NULL, ":");
+ npas = strtol(s_npas, NULL, 10) + 1;
+ while (npas > howmany) {
+ s_pas = strpbrk(s_pas, ",");
+ if (s_pas != NULL)
+ s_pas++;
+ npas--;
+ }
+ pass = crypt_md5_wrapper(oldpass);
+ if (s_pas == NULL)
+ sprintf(nbuf, "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass);
+ else
+ sprintf(nbuf, "%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ break;
+ }
+ found = 1;
+ } else if (fputs(buf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ break;
+ }
+ }
+ fclose(opwfile);
+ if (!found) {
+ pwd = getpwnam(forwho);
+ if (pwd == NULL) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ } else {
+ pass = crypt_md5_wrapper(oldpass);
+ sprintf(nbuf, "%s:%d:1:%s\n", forwho, pwd->pw_uid, pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ }
+ }
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to old passwords file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ if (!err)
+ rename(OPW_TMPFILE, OLD_PASSWORDS_FILE);
+ else
+ unlink(OPW_TMPFILE);
+
+ return retval;
}
-static int
-ulckpwdf(void)
+static int _update_passwd(const char *forwho, const char *towhat)
{
- unlink(LOCKFILE);
- if (lockfd == -1)
- return -1;
+ struct passwd *tmpent = NULL;
+ FILE *pwfile, *opwfile;
+ int retval = 0;
+ int err = 0;
+ int oldmask;
+
+ oldmask = umask(077);
+ pwfile = fopen(PW_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen("/etc/passwd", "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(PW_TMPFILE, 0, 0);
+ chmod(PW_TMPFILE, 0644);
+ tmpent = fgetpwent(opwfile);
+ while (tmpent) {
+ if (!strcmp(tmpent->pw_name, forwho)) {
+ tmpent->pw_passwd = towhat;
+ }
+ if (putpwent(tmpent, pwfile)) {
+ fprintf(stderr, "error writing entry to password file: %s\n",
+ strerror(errno));
+ err = 1;
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ tmpent = fgetpwent(opwfile);
+ }
+ fclose(opwfile);
- if (close(lockfd) == -1) {
- lockfd = -1;
- return -1;
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to password file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
}
- lockfd = -1;
- return 0;
+ if (!err)
+ rename(PW_TMPFILE, "/etc/passwd");
+ else
+ unlink(PW_TMPFILE);
+
+ return retval;
}
-/* END_HACK */
-#endif
-#define PAM_FAIL_CHECK if(retval != PAM_SUCCESS) { return retval; }
+static int _update_shadow(const char *forwho, char *towhat)
+{
+ struct spwd *spwdent = NULL, *stmpent = NULL;
+ FILE *pwfile, *opwfile;
+ int retval = 0;
+ int err = 0;
+ int oldmask;
+
+ spwdent = getspnam(forwho);
+ if (spwdent == NULL)
+ return PAM_USER_UNKNOWN;
+ oldmask = umask(077);
+ pwfile = fopen(SH_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen("/etc/shadow", "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(SH_TMPFILE, 0, 0);
+ chmod(SH_TMPFILE, 0600);
+ stmpent = fgetspent(opwfile);
+ while (stmpent) {
+ if (!strcmp(stmpent->sp_namp, forwho)) {
+ stmpent->sp_pwdp = towhat;
+ stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
+
+ D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
+ }
+ if (putspent(stmpent, pwfile)) {
+ fprintf(stderr, "error writing entry to shadow file: %s\n",
+ strerror(errno));
+ err = 1;
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ stmpent = fgetspent(opwfile);
+ }
+ fclose(opwfile);
+
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to shadow file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ if (!err)
+ rename(SH_TMPFILE, "/etc/shadow");
+ else
+ unlink(SH_TMPFILE);
+
+ return retval;
+}
-PAM_EXTERN
-int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
+ char *towhat, unsigned int ctrl, int remember)
{
- char *usrname, *curpass, *newpass; /* pointers to the username,
- current password, and new password */
-
- struct pam_conv *appconv; /* conversation with the app */
- struct pam_message msg, *pmsg; /* Misc for conversations */
- struct pam_response *resp;
-
- int retval=0; /* Gets the return values for all our function calls */
- unsigned int pflags=0; /* Holds the flags from our getpass & setpass
- functions */
-
- const char *cmiscptr; /* Utility variables, used for different purposes at
- different times */
- char *miscptr; /* Utility variables, used for different purposes at
- different times */
- unsigned int miscint;
- int fascist = 1; /* Be fascist by default. If compiled with cracklib,
- call cracklib. Otherwise just check length... */
-
- char argbuf[256],argval[256];
- int i;
-
-
- retval = pam_get_item(pamh,PAM_CONV,(const void **) &appconv);
- PAM_FAIL_CHECK;
-
- retval = pam_get_item(pamh,PAM_USER,(const void **) &usrname);
- PAM_FAIL_CHECK;
- if(flags & PAM_PRELIM_CHECK) {
- pflags = _do_getpass(usrname,&miscptr);
- if(pflags & PPW_NOSUCHUSER)
- return PAM_USER_UNKNOWN;
- else if(pflags & ~(PPW_SHADOW|PPW_EXPIRING|PPW_WILLEXPIRE))
- return PAM_AUTHTOK_ERR;
- else
- return PAM_SUCCESS;
- } /* else... */
+ struct passwd *pwd = NULL;
+ int retval = 0;
+
+ D(("called"));
+
+ setpwent();
+ pwd = getpwnam(forwho);
+ endpwent();
+
+ if (pwd == NULL)
+ return PAM_AUTHTOK_ERR;
+
+ if (on(UNIX_NIS, ctrl)) {
+ struct timeval timeout;
+ struct yppasswd yppwd;
+ CLIENT *clnt;
+ char *master;
+ int status;
+ int err = 0;
+
+ /* Make RPC call to NIS server */
+ if ((master = getNISserver(pamh)) == NULL)
+ return PAM_TRY_AGAIN;
+
+ /* Initialize password information */
+ yppwd.newpw.pw_passwd = pwd->pw_passwd;
+ yppwd.newpw.pw_name = pwd->pw_name;
+ yppwd.newpw.pw_uid = pwd->pw_uid;
+ yppwd.newpw.pw_gid = pwd->pw_gid;
+ yppwd.newpw.pw_gecos = pwd->pw_gecos;
+ yppwd.newpw.pw_dir = pwd->pw_dir;
+ yppwd.newpw.pw_shell = pwd->pw_shell;
+ yppwd.oldpass = fromwhat;
+ yppwd.newpw.pw_passwd = towhat;
+
+ D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho));
+
+ /* The yppasswd.x file said `unix authentication required',
+ * so I added it. This is the only reason it is in here.
+ * My yppasswdd doesn't use it, but maybe some others out there
+ * do. --okir
+ */
+ clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
+ clnt->cl_auth = authunix_create_default();
+ memset((char *) &status, '\0', sizeof(status));
+ timeout.tv_sec = 25;
+ timeout.tv_usec = 0;
+ err = clnt_call(clnt, YPPASSWDPROC_UPDATE,
+ (xdrproc_t) xdr_yppasswd, (char *) &yppwd,
+ (xdrproc_t) xdr_int, (char *) &status,
+ timeout);
+
+ if (err) {
+ clnt_perrno(err);
+ retval = PAM_TRY_AGAIN;
+ } else if (status) {
+ fprintf(stderr, "Error while changing NIS password.\n");
+ retval = PAM_TRY_AGAIN;
+ }
+ printf("\nThe password has%s been changed on %s.\n",
+ (err || status) ? " not" : "", master);
+
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ if ((err || status) != 0) {
+ retval = PAM_TRY_AGAIN;
+ }
#ifdef DEBUG
- fprintf(stderr,"Got username of %s\n",usrname);
+ sleep(5);
#endif
- if((usrname == NULL) || (strlen(usrname) < 1)) {
- /* The app is supposed to get us the username! */
- retval = PAM_USER_UNKNOWN;
- PAM_FAIL_CHECK;
- }
-
- for(i=0; i < argc; i++) {
- {
- char *tmp = x_strdup(argv[i]);
- strncpy(argbuf,strtok(tmp ,"="),255);
- strncpy(argval,strtok(NULL,"="),255);
- free(tmp);
- }
-
- /* For PC functionality use "strict" -- historically "fascist" */
- if(!strcmp(argbuf,"strict") || !strcmp(argbuf, "fascist"))
-
- if(!strcmp(argval,"true"))
- fascist = 1;
- else if(!strcmp(argval,"false"))
- fascist = 0;
- else
- return PAM_SERVICE_ERR;
- else {
- _pam_log(LOG_ERR,"Unknown option: %s",argbuf);
- return PAM_SERVICE_ERR;
- }
- }
-
-
- /* Now we have all the initial information we need from the app to
- set things up (we assume that getting the username succeeded...) */
- retval = pam_get_item(pamh,PAM_OLDAUTHTOK,(const void **) &curpass);
- PAM_FAIL_CHECK;
- if(getuid()) { /* If this is being run by root, we don't need to get their
- old password.
- note */
- /* If we haven't been given a password yet, prompt for one... */
- miscint=0;
- while((curpass == NULL) && (miscint++ < MAX_PASSWD_TRIES)) {
- pflags = _do_getpass(usrname,&miscptr);
- if(pflags & PPW_NOSUCHUSER)
- return PAM_USER_UNKNOWN; /* If the user that was passed in doesn't
- exist, say so and exit (app passes in
- username) */
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = OLD_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- curpass = resp->resp;
- free (resp);
- if(_do_checkpass(curpass?curpass:"",miscptr)) {
- int abortme = 0;
-
- /* password is incorrect... */
- if (curpass && curpass[0] == '\0') {
- /* ...and it was zero-length; user wishes to abort change */
- abortme = 1;
- }
- if (curpass) { free (curpass); }
- curpass = NULL;
- if (abortme) {
- conv_sendmsg(appconv,"Password change aborted.",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- }
- }
-
- if(curpass == NULL)
- return PAM_AUTH_ERR; /* They didn't seem to enter the right password
- for three tries - error */
- pam_set_item(pamh, PAM_OLDAUTHTOK, (void *)curpass);
- } else {
-#ifdef DEBUG
- fprintf(stderr,"I am ROOT!\n");
-#endif
- pflags = _do_getpass(usrname,&curpass);
- if(curpass == NULL)
- curpass = x_strdup("");
- }
- if(pflags & PPW_TOOEARLY) {
- conv_sendmsg(appconv,"You must wait longer to change your password",
- PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(pflags & PPW_WILLEXPIRE)
- conv_sendmsg(appconv,"Your password is about to expire",PAM_TEXT_INFO);
- else if(pflags & PPW_EXPIRED)
- return PAM_ACCT_EXPIRED; /* If their account has expired, we can't auth
- them to change their password */
- if(!(pflags & PPW_EXPIRING) && (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
- return PAM_SUCCESS;
- /* If we haven't been given a password yet, prompt for one... */
- miscint=0;
- pam_get_item(pamh,PAM_AUTHTOK,(const void **)&newpass);
- cmiscptr = NULL;
- while((newpass == NULL) && (miscint++ < MAX_PASSWD_TRIES)) {
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = NEW_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- newpass = resp->resp;
- free (resp);
+ return retval;
+ }
+ /* first, save old password */
+ if (save_old_password(forwho, fromwhat, remember)) {
+ return PAM_AUTHTOK_ERR;
+ }
+ if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) {
+ retval = _update_shadow(forwho, towhat);
+ if (retval == PAM_SUCCESS)
+ retval = _update_passwd(forwho, "x");
+ } else {
+ retval = _update_passwd(forwho, towhat);
+ }
-#ifdef DEBUG
- if(newpass)
- fprintf(stderr,"Got password of %s\n",newpass);
- else
- fprintf(stderr,"No new password...\n");
-#endif
- if (newpass[0] == '\0') { free (newpass); newpass = (char *) 0; }
- cmiscptr=NULL;
- if(newpass) {
+ return retval;
+}
+
+static int _unix_verify_shadow(const char *user, unsigned int ctrl)
+{
+ struct passwd *pwd = NULL; /* Password and shadow password */
+ struct spwd *spwdent = NULL; /* file entries for the user */
+ time_t curdays;
+ int retval = PAM_SUCCESS;
+
+ /* UNIX passwords area */
+ setpwent();
+ pwd = getpwnam(user); /* Get password file entry... */
+ endpwent();
+ if (pwd == NULL)
+ return PAM_AUTHINFO_UNAVAIL; /* We don't need to do the rest... */
+
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /* ...and shadow password file entry for this user, if shadowing
+ is enabled */
+ setspent();
+ spwdent = getspnam(user);
+ endspent();
+
+ if (spwdent == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ } else {
+ if (strcmp(pwd->pw_passwd,"*NP*") == 0) { /* NIS+ */
+ uid_t save_uid;
+
+ save_uid = geteuid();
+ seteuid (pwd->pw_uid);
+ spwdent = getspnam( user );
+ seteuid (save_uid);
+
+ if (spwdent == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ } else
+ spwdent = NULL;
+ }
+
+ if (spwdent != NULL) {
+ /* We have the user's information, now let's check if their account
+ has expired (60 * 60 * 24 = number of seconds in a day) */
+
+ if (off(UNIX__IAMROOT, ctrl)) {
+ /* Get the current number of days since 1970 */
+ curdays = time(NULL) / (60 * 60 * 24);
+ if ((curdays < (spwdent->sp_lstchg + spwdent->sp_min))
+ && (spwdent->sp_min != -1))
+ retval = PAM_AUTHTOK_ERR;
+ else if ((curdays > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
+ && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1)
+ && (spwdent->sp_lstchg != 0))
+ /*
+ * Their password change has been put off too long,
+ */
+ retval = PAM_ACCT_EXPIRED;
+ else if ((curdays > spwdent->sp_expire) && (spwdent->sp_expire != -1)
+ && (spwdent->sp_lstchg != 0))
+ /*
+ * OR their account has just plain expired
+ */
+ retval = PAM_ACCT_EXPIRED;
+ }
+ }
+ return retval;
+}
+
+static int _pam_unix_approve_pass(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *pass_old
+ ,const char *pass_new)
+{
+ const char *user;
+ const char *remark = NULL;
+ int retval = PAM_SUCCESS;
+
+ D(("&new=%p, &old=%p", pass_old, pass_new));
+ D(("new=[%s]", pass_new));
+ D(("old=[%s]", pass_old));
+
+ if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_DEBUG, pamh, "bad authentication token");
+ }
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
+ "No password supplied" : "Password unchanged");
+ return PAM_AUTHTOK_ERR;
+ }
+ /*
+ * if one wanted to hardwire authentication token strength
+ * checking this would be the place - AGM
+ */
+
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &user);
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_ERR, pamh, "Can not get username");
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+ if (off(UNIX__IAMROOT, ctrl)) {
#ifdef USE_CRACKLIB
- if(fascist && getuid())
- cmiscptr = FascistCheck(newpass,CRACKLIB_DICTS);
+ remark = FascistCheck(pass_new, CRACKLIB_DICTS);
+ D(("called cracklib [%s]", remark));
#else
- if(fascist && getuid() && strlen(newpass) < 6)
- cmiscptr = "You must choose a longer password";
+ if (strlen(pass_new) < 6)
+ remark = "You must choose a longer password";
+ D(("lenth check [%s]", remark));
#endif
- if(curpass)
- if(!strcmp(curpass,newpass)) {
- cmiscptr="You must choose a new password.";
- newpass=NULL;
+ if (on(UNIX_REMEMBER_PASSWD, ctrl))
+ if ((retval = check_old_password(user, pass_new)) != PAM_SUCCESS)
+ remark = "Password has been already used. Choose another.";
}
- } else {
- /* We want to abort the password change */
- conv_sendmsg(appconv,"Password change aborted",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(!cmiscptr) {
- /* We ask them to enter their password again... */
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = AGAIN_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- miscptr = resp->resp;
- free (resp);
- if (miscptr[0] == '\0') { free (miscptr); miscptr = (char *) 0; }
- if(!miscptr) { /* Aborting password change... */
- conv_sendmsg(appconv,"Password change aborted",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(!strcmp(newpass,miscptr)) {
- miscptr=NULL;
- break;
- }
- conv_sendmsg(appconv,"You must enter the same password twice.",
- PAM_ERROR_MSG);
- miscptr=NULL;
- newpass=NULL;
- }
- else {
- conv_sendmsg(appconv,cmiscptr,PAM_ERROR_MSG);
- newpass = NULL;
- }
- }
- if(cmiscptr) {
- /* conv_sendmsg(appconv,cmiscptr,PAM_ERROR_MSG); */
- return PAM_AUTHTOK_ERR;
- } else if(newpass == NULL)
- return PAM_AUTHTOK_ERR; /* They didn't seem to enter the right password
- for three tries - error */
-#ifdef DEBUG
- printf("Changing password for sure!\n");
-#endif
- /* From now on, we are bound and determined to get their password
- changed :-) */
- pam_set_item(pamh, PAM_AUTHTOK, (void *)newpass);
- retval = _do_setpass(usrname,newpass,pflags);
-#ifdef DEBUG
- fprintf(stderr,"retval was %d\n",retval);
-#endif
- if(retval & ~PPW_SHADOW) {
- conv_sendmsg(appconv,"Error: Password NOT changed",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- } else {
- conv_sendmsg(appconv,"Password changed",PAM_TEXT_INFO);
- return PAM_SUCCESS;
- }
+ if (remark) {
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
+ retval = PAM_AUTHTOK_ERR;
+ }
+ return retval;
}
-/* _do_checkpass() returns 0 on success, non-0 on failure */
-STATIC int _do_checkpass(const char *entered, char *listed)
+
+PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
- char salt[3];
- if ((strlen(listed) == 0) &&(strlen(entered) == 0)) {
- /* no password in database; no password entered */
- return (0);
- }
- salt[0]=listed[0]; salt[1]=listed[1]; salt[2]='\0';
- return strcmp(crypt(entered,salt),listed);
-}
+ unsigned int ctrl, lctrl;
+ int retval, i;
+ int remember = -1;
-STATIC char mksalt(int seed) {
- int num = seed % 64;
-
- if (num < 26)
- return 'a' + num;
- else if (num < 52)
- return 'A' + (num - 26);
- else if (num < 62)
- return '0' + (num - 52);
- else if (num == 63)
- return '.';
- else
- return '/';
-}
+ /* <DO NOT free() THESE> */
+ const char *user;
+ char *pass_old, *pass_new;
+ /* </DO NOT free() THESE> */
-STATIC int _do_setpass(char *forwho, char *towhat,int flags)
-{
- struct passwd *pwd=NULL, *tmpent=NULL;
- FILE *pwfile,*opwfile;
- char thesalt[3];
- int retval=0;
- struct timeval time1;
- int err = 0;
-#ifdef HAVE_SHADOW_H
- struct spwd *spwdent=NULL, *stmpent=NULL;
+ D(("called."));
+
+#ifdef USE_LCKPWDF
+ /* our current locking system requires that we lock the
+ entire password database. This avoids both livelock
+ and deadlock. */
+ /* These values for the number of attempts and the sleep time
+ are, of course, completely arbitrary.
+ My reading of the PAM docs is that, once pam_chauthtok() has been
+ called with PAM_UPDATE_AUTHTOK, we are obliged to take any
+ reasonable steps to make sure the token is updated; so retrying
+ for 1/10 sec. isn't overdoing it.
+ The other possibility is to call lckpwdf() on the first
+ pam_chauthtok() pass, and hold the lock until released in the
+ second pass--but is this guaranteed to work? -SRL */
+ i=0;
+ while((retval = lckpwdf()) != 0 && i < 100) {
+ usleep(1000);
+ }
+ if(retval != 0) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
#endif
- if(flags & PPW_SHADOW) { retval |= PPW_SHADOW; }
- gettimeofday(&time1, NULL);
- srand(time1.tv_usec);
- thesalt[0]=mksalt(rand());
- thesalt[1]=mksalt(rand());
- thesalt[2]='\0';
-
- /* lock the entire password subsystem */
+ ctrl = _set_ctrl(pamh, flags, &remember, argc, argv);
+
+ /*
+ * First get the name of a user
+ */
+ retval = pam_get_user(pamh, &user, "Username: ");
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't take
+ * any chances here. Require that the username starts with an
+ * alphanumeric character.
+ */
+ if (user == NULL || !isalnum(*user)) {
+ _log_err(LOG_ERR, pamh, "bad username [%s]", user);
#ifdef USE_LCKPWDF
- lckpwdf();
+ ulckpwdf();
#endif
- setpwent();
- pwd = getpwnam(forwho);
-#ifdef DEBUG
- printf("Got %p, for %s (salt %s)\n",pwd,
- forwho,thesalt);
+ return PAM_USER_UNKNOWN;
+ }
+ if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh, "username [%s] obtained",
+ user);
+ } else {
+ if (on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh,
+ "password - could not identify user");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- if(pwd == NULL)
- return PPW_NOSUCHUSER;
- endpwent();
-
-#ifdef HAVE_SHADOW_H
- if(flags & PPW_SHADOW) {
- spwdent = getspnam(forwho);
- if(spwdent == NULL)
- return PPW_NOSUCHUSER;
- spwdent->sp_pwdp = towhat;
- spwdent->sp_lstchg = time(NULL)/(60*60*24);
- pwfile = fopen(SH_TMPFILE,"w");
- opwfile = fopen("/etc/shadow","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(SH_TMPFILE,0,0);
- chmod(SH_TMPFILE,0600);
- stmpent=fgetspent(opwfile);
- while(stmpent) {
- if(!strcmp(stmpent->sp_namp,forwho)) {
- stmpent->sp_pwdp = crypt(towhat,thesalt);
- stmpent->sp_lstchg = time(NULL)/(60*60*24);
-#ifdef DEBUG
- fprintf(stderr,"Set password %s for %s\n",stmpent->sp_pwdp,
- forwho);
+ return retval;
+ }
+
+ D(("Got username of %s", user));
+
+ /*
+ * This is not an AUTH module!
+ */
+ if (on(UNIX__NONULL, ctrl))
+ set(UNIX__NULLOK, ctrl);
+
+ if (on(UNIX__PRELIM, ctrl)) {
+ /*
+ * obtain and verify the current password (OLDAUTHTOK) for
+ * the user.
+ */
+ char *Announce;
+
+ D(("prelim check"));
+
+ if (_unix_blankpasswd(ctrl, user)) {
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- }
- if (putspent(stmpent,pwfile)) {
- fprintf(stderr, "error writing entry to shadow file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- stmpent=fgetspent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to shadow file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(SH_TMPFILE,"/etc/shadow");
- else
- unlink(SH_TMPFILE);
- } else {
- pwd->pw_passwd = towhat;
- pwfile = fopen(PW_TMPFILE,"w");
- opwfile = fopen("/etc/passwd","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(PW_TMPFILE,0,0);
- chmod(PW_TMPFILE,0644);
- tmpent=fgetpwent(opwfile);
- while(tmpent) {
- if(!strcmp(tmpent->pw_name,forwho)) {
- tmpent->pw_passwd = crypt(towhat,thesalt);
- }
- if (putpwent(tmpent,pwfile)) {
- fprintf(stderr, "error writing entry to password file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- tmpent=fgetpwent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to password file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(PW_TMPFILE,"/etc/passwd");
- else
- unlink(PW_TMPFILE);
- }
-#else
- pwd->pw_passwd = towhat;
- pwfile = fopen(PW_TMPFILE,"w");
- opwfile = fopen("/etc/passwd","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(PW_TMPFILE,0,0);
- chmod(PW_TMPFILE,0644);
- tmpent=fgetpwent(opwfile);
- while(tmpent) {
- if(!strcmp(tmpent->pw_name,forwho)) {
- tmpent->pw_passwd = crypt(towhat,thesalt);
- }
- if (putpwent(tmpent,pwfile)) {
- fprintf(stderr, "error writing entry to shadow file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- tmpent=fgetpwent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to password file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(PW_TMPFILE,"/etc/passwd");
- else
- unlink(PW_TMPFILE);
+ return PAM_SUCCESS;
+ } else if (off(UNIX__IAMROOT, ctrl)) {
+
+ /* instruct user what is happening */
+#define greeting "Changing password for "
+ Announce = (char *) malloc(sizeof(greeting) + strlen(user));
+ if (Announce == NULL) {
+ _log_err(LOG_CRIT, pamh,
+ "password - out of memory");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- /* unlock the entire password subsystem */
+ return PAM_BUF_ERR;
+ }
+ (void) strcpy(Announce, greeting);
+ (void) strcpy(Announce + sizeof(greeting) - 1, user);
+#undef greeting
+
+ lctrl = ctrl;
+ set(UNIX__OLD_PASSWD, lctrl);
+ retval = _unix_read_password(pamh, lctrl
+ ,Announce
+ ,"(current) UNIX password: "
+ ,NULL
+ ,_UNIX_OLD_AUTHTOK
+ ,(const char **) &pass_old);
+ free(Announce);
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh
+ ,"password - (old) token not obtained");
#ifdef USE_LCKPWDF
- ulckpwdf();
+ ulckpwdf();
#endif
- return retval;
-}
-
-STATIC int _do_getpass(char *forwho, char **theirpass)
-{
- struct passwd *pwd=NULL; /* Password and shadow password */
-#ifdef HAVE_SHADOW_H
- struct spwd *spwdent=NULL; /* file entries for the user */
- time_t curdays;
+ return retval;
+ }
+ /* verify that this is the password for this user */
+
+ retval = _unix_verify_password(pamh, user, pass_old, ctrl);
+ } else {
+ D(("process run by root so do nothing this time around"));
+ pass_old = NULL;
+ retval = PAM_SUCCESS; /* root doesn't have too */
+ }
+
+ if (retval != PAM_SUCCESS) {
+ D(("Authentication failed"));
+ pass_old = NULL;
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- int retval=0;
- /* UNIX passwords area */
- setpwent();
- pwd = getpwnam(forwho); /* Get password file entry... */
- endpwent();
- if(pwd == NULL)
- return PPW_NOSUCHUSER; /* We don't need to do the rest... */
-#ifdef HAVE_SHADOW_H
- if(!strcmp(pwd->pw_passwd,"x")) {
- /* ...and shadow password file entry for this user, if shadowing
- is enabled */
- retval |= PPW_SHADOW;
- setspent();
- spwdent = getspnam(forwho);
- endspent();
- if(spwdent == NULL)
- return PPW_NOSUCHUSER;
- *theirpass = x_strdup(spwdent->sp_pwdp);
-
- /* We have the user's information, now let's check if their account
- has expired (60 * 60 * 24 = number of seconds in a day) */
-
- /* Get the current number of days since 1970 */
- curdays = time(NULL)/(60*60*24);
- if((curdays < (spwdent->sp_lstchg + spwdent->sp_min))
- && (spwdent->sp_min != -1))
- retval |= PPW_TOOEARLY;
- else if((curdays
- > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
- && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1))
- /* Their password change has been put off too long,
- OR their account has just plain expired */
- retval |= PPW_EXPIRED;
- else if((curdays > (spwdent->sp_lstchg + spwdent->sp_max))
- && (spwdent->sp_max != -1))
- /* Their passwd needs to be changed */
- retval |= PPW_EXPIRING;
- else if((curdays > (spwdent->sp_lstchg
- + spwdent->sp_max - spwdent->sp_warn))
- && (spwdent->sp_max != -1) && (spwdent->sp_warn != -1))
- retval |= PPW_WILLEXPIRE;
-/* if(spwdent->sp_lstchg < 0)
- retval &= ~(PPW_WILLEXPIRE | PPW_EXPIRING | PPW_EXPIRED);
- if(spwdent->sp_max < 0)
- retval &= ~(PPW_EXPIRING | PPW_EXPIRED); */
- } else {
- *theirpass = (char *)x_strdup(pwd->pw_passwd);
- }
-
-#else
- *theirpass = (char *) x_strdup(pwd->pw_passwd);
+ return retval;
+ }
+ retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
+ pass_old = NULL;
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "failed to set PAM_OLDAUTHTOK");
+ }
+ retval = _unix_verify_shadow(user, ctrl);
+ if (retval == PAM_AUTHTOK_ERR) {
+ if (off(UNIX__IAMROOT, ctrl))
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You must wait longer to change your password");
+ else
+ retval = PAM_SUCCESS;
+ }
+ } else if (on(UNIX__UPDATE, ctrl)) {
+ /*
+ * tpass is used below to store the _pam_md() return; it
+ * should be _pam_delete()'d.
+ */
+
+ char *tpass = NULL;
+ int retry = 0;
+
+ /*
+ * obtain the proposed password
+ */
+
+ D(("do update"));
+
+ /*
+ * get the old token back. NULL was ok only if root [at this
+ * point we assume that this has already been enforced on a
+ * previous call to this function].
+ */
+
+ if (off(UNIX_NOT_SET_PASS, ctrl)) {
+ retval = pam_get_item(pamh, PAM_OLDAUTHTOK
+ ,(const void **) &pass_old);
+ } else {
+ retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK
+ ,(const void **) &pass_old);
+ if (retval == PAM_NO_MODULE_DATA) {
+ retval = PAM_SUCCESS;
+ pass_old = NULL;
+ }
+ }
+ D(("pass_old [%s]", pass_old));
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh, "user not authenticated");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ retval = _unix_verify_shadow(user, ctrl);
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh, "user not authenticated 2");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ D(("get new password now"));
+
+ lctrl = ctrl;
+
+ if (on(UNIX_USE_AUTHTOK, lctrl)) {
+ set(UNIX_USE_FIRST_PASS, lctrl);
+ }
+ retry = 0;
+ retval = PAM_AUTHTOK_ERR;
+ while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) {
+ /*
+ * use_authtok is to force the use of a previously entered
+ * password -- needed for pluggable password strength checking
+ */
+
+ retval = _unix_read_password(pamh, lctrl
+ ,NULL
+ ,"Enter new UNIX password: "
+ ,"Retype new UNIX password: "
+ ,_UNIX_NEW_AUTHTOK
+ ,(const char **) &pass_new);
+
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_ALERT, pamh
+ ,"password - new password not obtained");
+ }
+ pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ D(("returned to _unix_chauthtok"));
+
+ /*
+ * At this point we know who the user is and what they
+ * propose as their new password. Verify that the new
+ * password is acceptable.
+ */
+
+ if (pass_new[0] == '\0') { /* "\0" password = NULL */
+ pass_new = NULL;
+ }
+ retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+ }
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh,
+ "new password not acceptable");
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ pass_new = pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ /*
+ * By reaching here we have approved the passwords and must now
+ * rebuild the password database file.
+ */
+
+ /*
+ * First we encrypt the new password.
+ */
+
+ if (on(UNIX_MD5_PASS, ctrl)) {
+ tpass = crypt_md5_wrapper(pass_new);
+ } else {
+ /*
+ * Salt manipulation is stolen from Rick Faith's passwd
+ * program. Sorry Rick :) -- alex
+ */
+
+ time_t tm;
+ char salt[3];
+
+ time(&tm);
+ salt[0] = bin_to_ascii(tm & 0x3f);
+ salt[1] = bin_to_ascii((tm >> 6) & 0x3f);
+ salt[2] = '\0';
+
+ if (off(UNIX_BIGCRYPT, ctrl) && strlen(pass_new) > 8) {
+ /*
+ * to avoid using the _extensions_ of the bigcrypt()
+ * function we truncate the newly entered password
+ */
+ char *temp = malloc(9);
+ char *e;
+
+ if (temp == NULL) {
+ _log_err(LOG_CRIT, pamh,
+ "out of memory for password");
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ pass_new = pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
+ return PAM_BUF_ERR;
+ }
+ /* copy first 8 bytes of password */
+ strncpy(temp, pass_new, 8);
+ temp[8] = '\0';
+
+ /* no longer need cleartext */
+ e = bigcrypt(temp, salt);
+ tpass = x_strdup(e);
+
+ _pam_overwrite(e);
+ _pam_delete(temp); /* tidy up */
+ } else {
+ char *e;
+
+ /* no longer need cleartext */
+ e = bigcrypt(pass_new, salt);
+ tpass = x_strdup(e);
+
+ _pam_overwrite(e);
+ }
+ }
+
+ D(("password processed"));
+
+ /* update the password database(s) -- race conditions..? */
+
+ retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
+ remember);
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ _pam_delete(tpass);
+ pass_old = pass_new = NULL;
+ } else { /* something has broken with the module */
+ _log_err(LOG_ALERT, pamh,
+ "password received unknown request");
+ retval = PAM_ABORT;
+ }
- return retval;
-}
+ D(("retval was %d", retval));
-STATIC int conv_sendmsg(struct pam_conv *aconv, const char *message, int style)
-{
- struct pam_message msg,*pmsg;
- struct pam_response *resp;
- int retval;
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = style;
- msg.msg = message;
- resp = NULL;
-
- retval = aconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, aconv->appdata_ptr);
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
- return retval;
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
}
-STATIC int conv_getitem(struct pam_conv *aconv, char *message, int style,
- char **result)
-{
- struct pam_message msg,*pmsg;
- struct pam_response *resp;
- int retval;
-
- D(("called."));
-
- /* Get the password from the user... */
- pmsg = &msg;
- msg.msg_style = style;
- msg.msg = message;
- resp = NULL;
-
- retval = aconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, aconv->appdata_ptr);
- if(retval != PAM_SUCCESS)
- return retval;
- if(resp != NULL) {
- *result = resp->resp; free(resp);
- return PAM_SUCCESS;
- }
- else
- return PAM_SERVICE_ERR;
-}
+/* static module data */
+#ifdef PAM_STATIC
+struct pam_module _pam_unix_passwd_modstruct = {
+ "pam_unix_passwd",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_chauthtok,
+};
+#endif
+
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_sess.c b/contrib/libpam/modules/pam_unix/pam_unix_sess.c
index 319b2ed6288e..d0785006772c 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_sess.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_sess.c
@@ -1,9 +1,8 @@
-/*
- * $Header: /home/morgan/pam/Linux-PAM-0.53/modules/pam_unix/RCS/pam_unix_sess.c,v 1.1 1996/11/09 19:44:35 morgan Exp $
- */
-
/*
+ * $Id: pam_unix_sess.c,v 1.3 2000/12/20 05:15:05 vorlon Exp $
+ *
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,145 +36,106 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Log: pam_unix_sess.c,v $
- * Revision 1.1 1996/11/09 19:44:35 morgan
- * Initial revision
- *
- * Revision 1.4 1996/05/21 03:55:17 morgan
- * added "const" to definition of rcsid[]
- *
- * Revision 1.3 1996/04/23 16:32:28 alex
- * nothing really got changed.
- *
- * Revision 1.2 1996/04/19 03:23:33 alex
- * session code implemented. account management moved into pam_unix_acct.c
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pwd.h>
+#include <security/_pam_aconf.h>
-#ifndef LINUX /* AGM added this as of 0.2 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
- #include <security/pam_appl.h>
+/* indicate the following groups are defined */
-#endif /* ditto */
+#define PAM_SM_SESSION
+#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-#include <syslog.h>
-#include <unistd.h>
-#ifndef LOG_AUTHPRIV
-#define LOG_AUTHPRIV LOG_AUTH
-#endif
-
-static const char rcsid[] = "$Id: pam_unix_sess.c,v 1.1 1996/11/09 19:44:35 morgan Exp $ pam_unix session management. alex@bach.cis.temple.edu";
-
-/* Define internal functions */
-static int _get_log_level( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
-
-int _pam_unix_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
-int _pam_unix_close_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+#include "support.h"
-/* Implementation */
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * session module.
+ */
-static int _get_log_level( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
+PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
- int i = argc;
- int log_level = LOG_DEBUG;
-
- while ( i-- )
- {
- if ( strcmp( *argv, "debug" ) == 0 )
- log_level = LOG_DEBUG;
- else if ( strcmp ( *argv, "trace" ) == 0 )
- log_level = LOG_AUTHPRIV;
- argv++;
- }
-
- return log_level;
-}
+ char *user_name, *service;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "open_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "open_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ _log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)"
+ ,user_name
+ ,PAM_getlogin() == NULL ? "" : PAM_getlogin(), getuid());
-int _pam_unix_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- int log_level;
- char *user_name, *service;
-
-
- log_level = _get_log_level( pamh, flags, argc, argv );
-
- pam_get_item( pamh, PAM_USER, (void*) &user_name );
- if ( !user_name )
- return PAM_CONV_ERR; /* How did we get authenticated with
- no username?! */
-
- pam_get_item( pamh, PAM_SERVICE, (void*) &service );
- if ( !service )
- return PAM_CONV_ERR;
-
- syslog ( log_level,
- "pam_unix authentication session started, user %s, service %s\n",
- user_name, service );
-
return PAM_SUCCESS;
}
-int _pam_unix_close_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)
{
- int log_level;
- char *user_name, *service;
-
- log_level = _get_log_level( pamh, flags, argc, argv );
-
- pam_get_item( pamh, PAM_USER, (void*) &user_name );
- if ( !user_name )
- return PAM_CONV_ERR; /* How did we get authenticated with
- no username?! */
-
- pam_get_item( pamh, PAM_SERVICE, (void*) &service );
- if ( !service )
- return PAM_CONV_ERR;
-
- syslog ( log_level,
- "pam_unix authentication session finished, user %s, service %s\n",
- user_name, service );
-
- return PAM_SUCCESS;
-}
+ char *user_name, *service;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "close_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "close_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ _log_err(LOG_INFO, pamh, "session closed for user %s"
+ ,user_name);
-int pam_sm_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- return _pam_unix_open_session( pamh, flags, argc, argv ) ;
+ return PAM_SUCCESS;
}
-int pam_sm_close_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- return _pam_unix_close_session( pamh, flags, argc, argv ) ;
-}
+/* static module data */
+#ifdef PAM_STATIC
+struct pam_module _pam_unix_session_modstruct = {
+ "pam_unix_session",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+#endif
diff --git a/contrib/libpam/modules/pam_unix/support.c b/contrib/libpam/modules/pam_unix/support.c
index a2fafcd2c13e..f7d221f18006 100644
--- a/contrib/libpam/modules/pam_unix/support.c
+++ b/contrib/libpam/modules/pam_unix/support.c
@@ -1,152 +1,882 @@
/*
- * $Header: /home/morgan/pam/Linux-PAM-0.53/modules/pam_unix/RCS/support.c,v 1.1 1996/11/09 19:44:35 morgan Exp $
+ * $Id: support.c,v 1.8 2001/02/11 06:33:53 agmorgan Exp $
+ *
+ * Copyright information at end of file.
*/
-
+
+#define _BSD_SOURCE
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <limits.h>
+#include <utmp.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+
+#include "md5.h"
+#include "support.h"
+
+extern char *crypt(const char *key, const char *salt);
+extern char *bigcrypt(const char *key, const char *salt);
+
+/* syslogging function for errors and other information */
+
+void _log_err(int err, pam_handle_t *pamh, const char *format,...)
+{
+ char *service = NULL;
+ char logname[256];
+ va_list args;
+
+ pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (service) {
+ strncpy(logname, service, sizeof(logname));
+ logname[sizeof(logname) - 1 - strlen("(pam_unix)")] = '\0';
+ strncat(logname, "(pam_unix)", strlen("(pam_unix)"));
+ } else {
+ strncpy(logname, "pam_unix", sizeof(logname) - 1);
+ }
+
+ va_start(args, format);
+ openlog(logname, LOG_CONS | LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* this is a front-end for module-application conversations */
+
+static int converse(pam_handle_t * pamh, int ctrl, int nargs
+ ,struct pam_message **message
+ ,struct pam_response **response)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("begin to converse"));
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS) {
+
+ retval = conv->conv(nargs, (const struct pam_message **) message
+ ,response, conv->appdata_ptr);
+
+ D(("returned from application's conversation function"));
+
+ if (retval != PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_DEBUG, pamh, "conversation failure [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+ } else if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_ERR, pamh
+ ,"couldn't obtain coversation function [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+ D(("ready to return from module conversation"));
+
+ return retval; /* propagate error status */
+}
+
+int _make_remark(pam_handle_t * pamh, unsigned int ctrl
+ ,int type, const char *text)
+{
+ int retval = PAM_SUCCESS;
+
+ if (off(UNIX__QUIET, ctrl)) {
+ struct pam_message *pmsg[1], msg[1];
+ struct pam_response *resp;
+
+ pmsg[0] = &msg[0];
+ msg[0].msg = text;
+ msg[0].msg_style = type;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+
+ if (resp) {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ return retval;
+}
+
+ /*
+ * Beacause getlogin() is braindead and sometimes it just
+ * doesn't work, we reimplement it here.
+ */
+char *PAM_getlogin(void)
+{
+ struct utmp *ut, line;
+ char *curr_tty, *retval;
+ static char curr_user[sizeof(ut->ut_user) + 4];
+
+ retval = NULL;
+
+ curr_tty = ttyname(0);
+ if (curr_tty != NULL) {
+ D(("PAM_getlogin ttyname: %s", curr_tty));
+ curr_tty += 5;
+ setutent();
+ strncpy(line.ut_line, curr_tty, sizeof line.ut_line);
+ if ((ut = getutline(&line)) != NULL) {
+ strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
+ retval = curr_user;
+ }
+ endutent();
+ }
+ D(("PAM_getlogin retval: %s", retval));
+
+ return retval;
+}
+
/*
- * Copyright Andrew Morgan, 1996. All rights reserved.
- * Modified by Alexander O. Yuriev
- *
- * 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.
+ * set the control flags for the UNIX module.
*/
+int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
+ const char **argv)
+{
+ unsigned int ctrl;
+
+ D(("called."));
+
+ ctrl = UNIX_DEFAULTS; /* the default selection of options */
+
+ /* set some flags manually */
+
+ if (getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) {
+ D(("IAMROOT"));
+ set(UNIX__IAMROOT, ctrl);
+ }
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ D(("UPDATE_AUTHTOK"));
+ set(UNIX__UPDATE, ctrl);
+ }
+ if (flags & PAM_PRELIM_CHECK) {
+ D(("PRELIM_CHECK"));
+ set(UNIX__PRELIM, ctrl);
+ }
+ if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
+ D(("DISALLOW_NULL_AUTHTOK"));
+ set(UNIX__NONULL, ctrl);
+ }
+ if (flags & PAM_SILENT) {
+ D(("SILENT"));
+ set(UNIX__QUIET, ctrl);
+ }
+ /* now parse the arguments to this module */
+
+ while (argc-- > 0) {
+ int j;
+
+ D(("pam_unix arg: %s", *argv));
+
+ for (j = 0; j < UNIX_CTRLS_; ++j) {
+ if (unix_args[j].token
+ && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) {
+ break;
+ }
+ }
+
+ if (j >= UNIX_CTRLS_) {
+ _log_err(LOG_ERR, pamh,
+ "unrecognized option [%s]", *argv);
+ } else {
+ ctrl &= unix_args[j].mask; /* for turning things off */
+ ctrl |= unix_args[j].flag; /* for turning things on */
+
+ if (remember != NULL) {
+ if (j == UNIX_REMEMBER_PASSWD) {
+ *remember = strtol(*argv + 9, NULL, 10);
+ if ((*remember == LONG_MIN) || (*remember == LONG_MAX))
+ *remember = -1;
+ if (*remember > 400)
+ *remember = 400;
+ }
+ }
+ }
+
+ ++argv; /* step to next argument */
+ }
+
+ /* auditing is a more sensitive version of debug */
+
+ if (on(UNIX_AUDIT, ctrl)) {
+ set(UNIX_DEBUG, ctrl);
+ }
+ /* return the set of flags */
+
+ D(("done."));
+ return ctrl;
+}
+
+static void _cleanup(pam_handle_t * pamh, void *x, int error_status)
+{
+ _pam_delete(x);
+}
+
+/* ************************************************************** *
+ * Useful non-trivial functions *
+ * ************************************************************** */
+
+ /*
+ * the following is used to keep track of the number of times a user fails
+ * to authenticate themself.
+ */
+
+#define FAIL_PREFIX "-UN*X-FAIL-"
+#define UNIX_MAX_RETRIES 3
+
+struct _pam_failed_auth {
+ char *user; /* user that's failed to be authenticated */
+ char *name; /* attempt from user with name */
+ int uid; /* uid of calling user */
+ int euid; /* euid of calling process */
+ int count; /* number of failures so far */
+};
+
+#ifndef PAM_DATA_REPLACE
+#error "Need to get an updated libpam 0.52 or better"
+#endif
+
+static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
+{
+ int quiet;
+ const char *service = NULL;
+ const char *ruser = NULL;
+ const char *rhost = NULL;
+ const char *tty = NULL;
+ struct _pam_failed_auth *failure;
+
+ D(("called"));
+
+ quiet = err & PAM_DATA_SILENT; /* should we log something? */
+ err &= PAM_DATA_REPLACE; /* are we just replacing data? */
+ failure = (struct _pam_failed_auth *) fl;
+
+ if (failure != NULL) {
+
+ if (!quiet && !err) { /* under advisement from Sun,may go away */
+
+ /* log the number of authentication failures */
+ if (failure->count > 1) {
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ (const void **)&service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ (const void **)&ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ (const void **)&rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ (const void **)&tty);
+ _log_err(LOG_NOTICE, pamh,
+ "%d more authentication failure%s; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ failure->count - 1, failure->count == 2 ? "" : "s",
+ failure->name, failure->uid, failure->euid,
+ tty ? tty : "", ruser ? ruser : "",
+ rhost ? rhost : "",
+ (failure->user && failure->user[0] != '\0')
+ ? " user=" : "", failure->user
+ );
+
+ if (failure->count > UNIX_MAX_RETRIES) {
+ _log_err(LOG_ALERT, pamh
+ ,"service(%s) ignoring max retries; %d > %d"
+ ,service == NULL ? "**unknown**" : service
+ ,failure->count
+ ,UNIX_MAX_RETRIES);
+ }
+ }
+ }
+ _pam_delete(failure->user); /* tidy up */
+ _pam_delete(failure->name); /* tidy up */
+ free(failure);
+ }
+}
+
/*
- * $Log: support.c,v $
- * Revision 1.1 1996/11/09 19:44:35 morgan
- * Initial revision
- *
- * Revision 1.1 1996/04/17 01:11:08 alex
- * Initial revision
+ * _unix_blankpasswd() is a quick check for a blank password
*
+ * returns TRUE if user does not have a password
+ * - to avoid prompting for one in such cases (CG)
*/
-
-#include <stdlib.h> /* define NULL */
-#ifndef LINUX
+int _unix_blankpasswd(unsigned int ctrl, const char *name)
+{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ int retval;
- #include <security/pam_appl.h>
+ D(("called"));
-#endif /* LINUX */
+ /*
+ * This function does not have to be too smart if something goes
+ * wrong, return FALSE and let this case to be treated somewhere
+ * else (CG)
+ */
-#include <security/pam_modules.h>
+ if (on(UNIX__NONULL, ctrl))
+ return 0; /* will fail but don't let on yet */
+
+ /* UNIX passwords area */
+ pwd = getpwnam(name); /* Get password file entry... */
+
+ if (pwd != NULL) {
+ if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwd->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwd->pw_uid ) == -1)
+ /* Will fail elsewhere. */
+ return 0;
+ }
+ }
+
+ spwdent = getspnam( name );
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+ } else if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ spwdent = getspnam(name);
+ }
+ if (spwdent)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ salt = x_strdup(pwd->pw_passwd);
+ }
+ /* Does this user have a password? */
+ if (salt == NULL) {
+ retval = 0;
+ } else {
+ if (strlen(salt) == 0)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ /* tidy up */
-#ifndef NDEBUG
+ if (salt)
+ _pam_delete(salt);
- #include <syslog.h>
+ return retval;
+}
-#endif /* NDEBUG */
+/*
+ * verify the password of a user
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ unsigned int ctrl, const char *user)
+{
+ int retval, child, fds[2];
+ D(("called."));
+ /* create a pipe for the password */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ return PAM_AUTH_ERR;
+ }
-/* Phototype declarations */
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL };
-int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response );
+ /* XXX - should really tidy up PAM here too */
-int _set_auth_tok( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+ /* reopen stdin as pipe */
+ close(fds[1]);
+ dup2(fds[0], STDIN_FILENO);
-/* Implementation */
+ /* exec binary helper */
+ args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
-int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response )
+ execve(CHKPWD_HELPER, args, envp);
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ exit(PAM_AUTHINFO_UNAVAIL);
+ } else if (child > 0) {
+ /* wait for child */
+ /* if the stored password is NULL */
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ write(fds[1], "nullok\0\0", 8);
+ } else {
+ write(fds[1], "nonull\0\0", 8);
+ }
+ if (passwd != NULL) { /* send the password to the child */
+ write(fds[1], passwd, strlen(passwd)+1);
+ passwd = NULL;
+ } else {
+ write(fds[1], "", 1); /* blank password */
+ }
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ (void) waitpid(child, &retval, 0); /* wait for helper to complete */
+ retval = (retval == 0) ? PAM_SUCCESS:PAM_AUTH_ERR;
+ } else {
+ D(("fork failed"));
+ retval = PAM_AUTH_ERR;
+ }
+
+ D(("returning %d", retval));
+ return retval;
+}
+
+int _unix_verify_password(pam_handle_t * pamh, const char *name
+ ,const char *p, unsigned int ctrl)
{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ char *pp = NULL;
+ char *data_name;
int retval;
- struct pam_conv *conv;
- retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
- if ( retval == PAM_SUCCESS )
- {
- retval = conv->conv( nargs,
- ( const struct pam_message ** ) message,
- response,
- conv->appdata_ptr );
- }
+ D(("called"));
+
+#ifdef HAVE_PAM_FAIL_DELAY
+ if (off(UNIX_NODELAY, ctrl)) {
+ D(("setting delay"));
+ (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */
+ }
+#endif
+
+ /* locate the entry for this user */
+
+ D(("locating user's record"));
+
+ /* UNIX passwords area */
+ pwd = getpwnam(name); /* Get password file entry... */
+
+ if (pwd != NULL) {
+ if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwd->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwd->pw_uid ) == -1)
+ return PAM_CRED_INSUFFICIENT;
+ }
+ }
+
+ spwdent = getspnam( name );
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+ } else if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ spwdent = getspnam(name);
+ }
+ if (spwdent)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ salt = x_strdup(pwd->pw_passwd);
+ }
+
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name));
+ if (data_name == NULL) {
+ _log_err(LOG_CRIT, pamh, "no memory for data-name");
+ } else {
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name);
+ }
+
+ retval = PAM_SUCCESS;
+ if (pwd == NULL || salt == NULL || !strcmp(salt, "x")) {
+ if (geteuid()) {
+ /* we are not root perhaps this is the reason? Run helper */
+ D(("running helper binary"));
+ retval = _unix_run_helper_binary(pamh, p, ctrl, name);
+ if (pwd == NULL && !on(UNIX_AUDIT,ctrl)
+ && retval != PAM_SUCCESS)
+ {
+ name = NULL;
+ }
+ } else {
+ D(("user's record unavailable"));
+ if (on(UNIX_AUDIT, ctrl)) {
+ /* this might be a typo and the user has given a password
+ instead of a username. Careful with this. */
+ _log_err(LOG_ALERT, pamh,
+ "check pass; user (%s) unknown", name);
+ } else {
+ name = NULL;
+ _log_err(LOG_ALERT, pamh,
+ "check pass; user unknown");
+ }
+ p = NULL;
+ retval = PAM_AUTHINFO_UNAVAIL;
+ }
+ } else {
+ if (!strlen(salt)) {
+ /* the stored password is NULL */
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ D(("user has empty password - access granted"));
+ retval = PAM_SUCCESS;
+ } else {
+ D(("user has empty password - access denied"));
+ retval = PAM_AUTH_ERR;
+ }
+ } else if (!p) {
+ retval = PAM_AUTH_ERR;
+ } else {
+ if (!strncmp(salt, "$1$", 3)) {
+ pp = Goodcrypt_md5(p, salt);
+ if (strcmp(pp, salt) != 0) {
+ pp = Brokencrypt_md5(p, salt);
+ }
+ } else {
+ pp = bigcrypt(p, salt);
+ }
+ p = NULL; /* no longer needed here */
+
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if (strcmp(pp, salt) == 0) {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
+ }
+ }
+
+ if (retval == PAM_SUCCESS) {
+ if (data_name) /* reset failures */
+ pam_set_data(pamh, data_name, NULL, _cleanup_failures);
+ } else {
+ if (data_name != NULL) {
+ struct _pam_failed_auth *new = NULL;
+ const struct _pam_failed_auth *old = NULL;
+
+ /* get a failure recorder */
+
+ new = (struct _pam_failed_auth *)
+ malloc(sizeof(struct _pam_failed_auth));
+
+ if (new != NULL) {
+
+ new->user = x_strdup(name ? name : "");
+ new->uid = getuid();
+ new->euid = geteuid();
+ new->name = x_strdup(PAM_getlogin()? PAM_getlogin() : "");
+
+ /* any previous failures for this user ? */
+ pam_get_data(pamh, data_name, (const void **) &old);
+
+ if (old != NULL) {
+ new->count = old->count + 1;
+ if (new->count >= UNIX_MAX_RETRIES) {
+ retval = PAM_MAXTRIES;
+ }
+ } else {
+ const char *service=NULL;
+ const char *ruser=NULL;
+ const char *rhost=NULL;
+ const char *tty=NULL;
+
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ (const void **)&service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ (const void **)&ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ (const void **)&rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ (const void **)&tty);
+
+ _log_err(LOG_NOTICE, pamh,
+ "authentication failure; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ new->name, new->uid, new->euid,
+ tty ? tty : "",
+ ruser ? ruser : "",
+ rhost ? rhost : "",
+ (new->user && new->user[0] != '\0')
+ ? " user=" : "",
+ new->user
+ );
+ new->count = 1;
+ }
+
+ pam_set_data(pamh, data_name, new, _cleanup_failures);
+
+ } else {
+ _log_err(LOG_CRIT, pamh,
+ "no memory for failure recorder");
+ }
+ }
+ }
+
+ if (data_name)
+ _pam_delete(data_name);
+ if (salt)
+ _pam_delete(salt);
+ if (pp)
+ _pam_overwrite(pp);
+
+ D(("done [%d].", retval));
+
return retval;
}
-/***************************************************************************/
-/* prompt user for a using conversation calls */
-/***************************************************************************/
+/*
+ * obtain a password from the user
+ */
-int _set_auth_tok( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv )
+int _unix_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char *data_name
+ ,const char **pass)
{
- int retval;
- char *p;
-
- struct pam_message msg[1],*pmsg[1];
- struct pam_response *resp;
+ int authtok_flag;
+ int retval;
+ const char *item;
+ char *token;
+
+ D(("called"));
+
+ /*
+ * make sure nothing inappropriate gets returned
+ */
+
+ *pass = token = NULL;
+
+ /*
+ * which authentication token are we getting?
+ */
+
+ authtok_flag = on(UNIX__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK;
+
+ /*
+ * should we obtain the password from a PAM item ?
+ */
- /* set up conversation call */
+ if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) {
+ retval = pam_get_item(pamh, authtok_flag, (const void **) &item);
+ if (retval != PAM_SUCCESS) {
+ /* very strange. */
+ _log_err(LOG_ALERT, pamh
+ ,"pam_get_item returned error to unix-read-password"
+ );
+ return retval;
+ } else if (item != NULL) { /* we have a password! */
+ *pass = item;
+ item = NULL;
+ return PAM_SUCCESS;
+ } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
+ return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ } else if (on(UNIX_USE_AUTHTOK, ctrl)
+ && off(UNIX__OLD_PASSWD, ctrl)) {
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+ }
+ /*
+ * getting here implies we will have to get the password from the
+ * user directly.
+ */
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = "Password: ";
- resp = NULL;
+ {
+ struct pam_message msg[3], *pmsg[3];
+ struct pam_response *resp;
+ int i, replies;
- if ( ( retval = converse( pamh, 1 , pmsg, &resp ) ) != PAM_SUCCESS )
+ /* prepare to converse */
+
+ if (comment != NULL && off(UNIX__QUIET, ctrl)) {
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ msg[0].msg = comment;
+ i = 1;
+ } else {
+ i = 0;
+ }
+
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = prompt1;
+ replies = 1;
+
+ if (prompt2 != NULL) {
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = prompt2;
+ ++replies;
+ }
+ /* so call the conversation expecting i responses */
+ resp = NULL;
+ retval = converse(pamh, ctrl, i, pmsg, &resp);
+
+ if (resp != NULL) {
+
+ /* interpret the response */
+
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+
+ token = x_strdup(resp[i - replies].resp);
+ if (token != NULL) {
+ if (replies == 2) {
+
+ /* verify that password entered correctly */
+ if (!resp[i - 1].resp
+ || strcmp(token, resp[i - 1].resp)) {
+ _pam_delete(token); /* mistyped */
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ _make_remark(pamh, ctrl
+ ,PAM_ERROR_MSG, MISTYPED_PASS);
+ }
+ }
+ } else {
+ _log_err(LOG_NOTICE, pamh
+ ,"could not recover authentication token");
+ }
+
+ }
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ * -- what is it for anyway? AGM
+ */
+
+ _pam_drop_reply(resp, i);
+
+ } else {
+ retval = (retval == PAM_SUCCESS)
+ ? PAM_AUTHTOK_RECOVER_ERR : retval;
+ }
+ }
+
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh,
+ "unable to obtain a password");
return retval;
+ }
+ /* 'token' is the entered password */
+
+ if (off(UNIX_NOT_SET_PASS, ctrl)) {
+
+ /* we store this password as an item */
+
+ retval = pam_set_item(pamh, authtok_flag, token);
+ _pam_delete(token); /* clean it up */
+ if (retval != PAM_SUCCESS
+ || (retval = pam_get_item(pamh, authtok_flag
+ ,(const void **) &item))
+ != PAM_SUCCESS) {
+
+ _log_err(LOG_CRIT, pamh, "error manipulating password");
+ return retval;
+
+ }
+ } else {
+ /*
+ * then store it as data specific to this module. pam_end()
+ * will arrange to clean it up.
+ */
+
+ retval = pam_set_data(pamh, data_name, (void *) token, _cleanup);
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh
+ ,"error manipulating password data [%s]"
+ ,pam_strerror(pamh, retval));
+ _pam_delete(token);
+ return retval;
+ }
+ item = token;
+ token = NULL; /* break link to password */
+ }
+
+ *pass = item;
+ item = NULL; /* break link to password */
- if ( resp )
- {
- if ( ( flags & PAM_DISALLOW_NULL_AUTHTOK ) &&
- resp[0].resp == NULL )
- {
- free( resp );
- return PAM_AUTH_ERR;
- }
-
- p = resp[ 0 ].resp;
-
- /* This could be a memory leak. If resp[0].resp
- is malloc()ed, then it has to be free()ed!
- -- alex
- */
-
- resp[ 0 ].resp = NULL;
-
- }
- else
- return PAM_CONV_ERR;
-
- free( resp );
- pam_set_item( pamh, PAM_AUTHTOK, p );
return PAM_SUCCESS;
}
+
+/* ****************************************************************** *
+ * Copyright (c) Jan Rêkorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ *
+ * 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.
+ */
diff --git a/contrib/libpam/modules/pam_unix/support.h b/contrib/libpam/modules/pam_unix/support.h
new file mode 100644
index 000000000000..80f0b405d8bb
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/support.h
@@ -0,0 +1,144 @@
+/*
+ * $Id: support.h,v 1.3 2000/12/20 05:15:05 vorlon Exp $
+ */
+
+#ifndef _PAM_UNIX_SUPPORT_H
+#define _PAM_UNIX_SUPPORT_H
+
+
+/*
+ * here is the string to inform the user that the new passwords they
+ * typed were not the same.
+ */
+
+#define MISTYPED_PASS "Sorry, passwords do not match"
+
+/* type definition for the control options */
+
+typedef struct {
+ const char *token;
+ unsigned int mask; /* shall assume 32 bits of flags */
+ unsigned int flag;
+} UNIX_Ctrls;
+
+/*
+ * macro to determine if a given flag is on
+ */
+
+#define on(x,ctrl) (unix_args[x].flag & ctrl)
+
+/*
+ * macro to determine that a given flag is NOT on
+ */
+
+#define off(x,ctrl) (!on(x,ctrl))
+
+/*
+ * macro to turn on/off a ctrl flag manually
+ */
+
+#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag)
+#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag))
+
+/* the generic mask */
+
+#define _ALL_ON_ (~0U)
+
+/* end of macro definitions definitions for the control flags */
+
+/* ****************************************************************** *
+ * ctrl flags proper..
+ */
+
+/*
+ * here are the various options recognized by the unix module. They
+ * are enumerated here and then defined below. Internal arguments are
+ * given NULL tokens.
+ */
+
+#define UNIX__OLD_PASSWD 0 /* internal */
+#define UNIX__VERIFY_PASSWD 1 /* internal */
+#define UNIX__IAMROOT 2 /* internal */
+
+#define UNIX_AUDIT 3 /* print more things than debug..
+ some information may be sensitive */
+#define UNIX_USE_FIRST_PASS 4
+#define UNIX_TRY_FIRST_PASS 5
+#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */
+
+#define UNIX__PRELIM 7 /* internal */
+#define UNIX__UPDATE 8 /* internal */
+#define UNIX__NONULL 9 /* internal */
+#define UNIX__QUIET 10 /* internal */
+#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */
+#define UNIX_SHADOW 12 /* signal shadow on */
+#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */
+#define UNIX__NULLOK 14 /* Null token ok */
+#define UNIX_DEBUG 15 /* send more info to syslog(3) */
+#define UNIX_NODELAY 16 /* admin does not want a fail-delay */
+#define UNIX_NIS 17 /* wish to use NIS for pwd */
+#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */
+#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */
+/* -------------- */
+#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
+
+
+static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
+{
+/* symbol token name ctrl mask ctrl *
+ * ----------------------- ------------------- --------------------- -------- */
+
+/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01},
+/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02},
+/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04},
+/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010},
+/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020},
+/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040},
+/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100},
+/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200},
+/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400},
+/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000},
+/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000},
+/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000},
+/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000},
+/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0400000), 020000},
+/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0},
+/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000},
+/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000},
+/* UNIX_NIS */ {"nis", _ALL_ON_^(010000), 0200000},
+/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000},
+/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000},
+/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000},
+};
+
+#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
+
+
+/* use this to free strings. ESPECIALLY password strings */
+
+#define _pam_delete(xx) \
+{ \
+ _pam_overwrite(xx); \
+ _pam_drop(xx); \
+}
+
+extern char *PAM_getlogin(void);
+extern void _log_err(int err, pam_handle_t *pamh, const char *format,...);
+extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl
+ ,int type, const char *text);
+extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int argc,
+ const char **argv);
+extern int _unix_blankpasswd(unsigned int ctrl, const char *name);
+extern int _unix_verify_password(pam_handle_t * pamh, const char *name
+ ,const char *p, unsigned int ctrl);
+extern int _unix_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char *data_name
+ ,const char **pass);
+
+#endif /* _PAM_UNIX_SUPPORT_H */
+
diff --git a/contrib/libpam/modules/pam_unix/unix_chkpwd.c b/contrib/libpam/modules/pam_unix/unix_chkpwd.c
new file mode 100644
index 000000000000..e232e759453c
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/unix_chkpwd.c
@@ -0,0 +1,314 @@
+/*
+ * $Id: unix_chkpwd.c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
+ *
+ * This program is designed to run setuid(root) or with sufficient
+ * privilege to read all of the unix password databases. It is designed
+ * to provide a mechanism for the current user (defined by this
+ * process' uid) to verify their own password.
+ *
+ * The password is read from the standard input. The exit status of
+ * this program indicates whether the user is authenticated or not.
+ *
+ * Copyright information is located at the end of the file.
+ *
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <signal.h>
+
+#define MAXPASS 200 /* the maximum length of a password */
+
+#include <security/_pam_macros.h>
+
+#include "md5.h"
+
+extern char *crypt(const char *key, const char *salt);
+extern char *bigcrypt(const char *key, const char *salt);
+
+#define UNIX_PASSED 0
+#define UNIX_FAILED 1
+
+/* syslogging function for errors and other information */
+
+static void _log_err(int err, const char *format,...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("unix_chkpwd", LOG_CONS | LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static void su_sighandler(int sig)
+{
+ if (sig > 0) {
+ _log_err(LOG_NOTICE, "caught signal %d.", sig);
+ exit(sig);
+ }
+}
+
+static void setup_signals(void)
+{
+ struct sigaction action; /* posix signal structure */
+
+ /*
+ * Setup signal handlers
+ */
+ (void) memset((void *) &action, 0, sizeof(action));
+ action.sa_handler = su_sighandler;
+ action.sa_flags = SA_RESETHAND;
+ (void) sigaction(SIGILL, &action, NULL);
+ (void) sigaction(SIGTRAP, &action, NULL);
+ (void) sigaction(SIGBUS, &action, NULL);
+ (void) sigaction(SIGSEGV, &action, NULL);
+ action.sa_handler = SIG_IGN;
+ action.sa_flags = 0;
+ (void) sigaction(SIGTERM, &action, NULL);
+ (void) sigaction(SIGHUP, &action, NULL);
+ (void) sigaction(SIGINT, &action, NULL);
+ (void) sigaction(SIGQUIT, &action, NULL);
+}
+
+static int _unix_verify_password(const char *name, const char *p, int opt)
+{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ char *pp = NULL;
+ int retval = UNIX_FAILED;
+
+ /* UNIX passwords area */
+ setpwent();
+ pwd = getpwnam(name); /* Get password file entry... */
+ endpwent();
+ if (pwd != NULL) {
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ setspent();
+ spwdent = getspnam(name);
+ endspent();
+ if (spwdent != NULL)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ pwd = NULL;
+ } else {
+ if (strcmp(pwd->pw_passwd, "*NP*") == 0) { /* NIS+ */
+ uid_t save_uid;
+
+ save_uid = geteuid();
+ seteuid(pwd->pw_uid);
+ spwdent = getspnam(name);
+ seteuid(save_uid);
+
+ salt = x_strdup(spwdent->sp_pwdp);
+ } else {
+ salt = x_strdup(pwd->pw_passwd);
+ }
+ }
+ }
+ if (pwd == NULL || salt == NULL) {
+ _log_err(LOG_ALERT, "check pass; user unknown");
+ p = NULL;
+ return retval;
+ }
+
+ if (strlen(salt) == 0)
+ return (opt == 0) ? UNIX_FAILED : UNIX_PASSED;
+
+ /* the moment of truth -- do we agree with the password? */
+ retval = UNIX_FAILED;
+ if (!strncmp(salt, "$1$", 3)) {
+ pp = Goodcrypt_md5(p, salt);
+ if (strcmp(pp, salt) == 0) {
+ retval = UNIX_PASSED;
+ } else {
+ pp = Brokencrypt_md5(p, salt);
+ if (strcmp(pp, salt) == 0)
+ retval = UNIX_PASSED;
+ }
+ } else {
+ pp = bigcrypt(p, salt);
+ if (strcmp(pp, salt) == 0) {
+ retval = UNIX_PASSED;
+ }
+ }
+ p = NULL; /* no longer needed here */
+
+ /* clean up */
+ {
+ char *tp = pp;
+ if (pp != NULL) {
+ while (tp && *tp)
+ *tp++ = '\0';
+ }
+ pp = tp = NULL;
+ }
+
+ return retval;
+}
+
+static char *getuidname(uid_t uid)
+{
+ struct passwd *pw;
+ static char username[32];
+
+ pw = getpwuid(uid);
+ if (pw == NULL)
+ return NULL;
+
+ memset(username, 0, 32);
+ strncpy(username, pw->pw_name, 32);
+ username[31] = '\0';
+
+ return username;
+}
+
+int main(int argc, char *argv[])
+{
+ char pass[MAXPASS + 1];
+ char option[8];
+ int npass, opt;
+ int force_failure = 0;
+ int retval = UNIX_FAILED;
+ char *user;
+
+ /*
+ * Catch or ignore as many signal as possible.
+ */
+ setup_signals();
+
+ /*
+ * we establish that this program is running with non-tty stdin.
+ * this is to discourage casual use. It does *NOT* prevent an
+ * intruder from repeatadly running this program to determine the
+ * password of the current user (brute force attack, but one for
+ * which the attacker must already have gained access to the user's
+ * account).
+ */
+
+ if (isatty(STDIN_FILENO)) {
+
+ _log_err(LOG_NOTICE
+ ,"inappropriate use of Unix helper binary [UID=%d]"
+ ,getuid());
+ fprintf(stderr
+ ,"This binary is not designed for running in this way\n"
+ "-- the system administrator has been informed\n");
+ sleep(10); /* this should discourage/annoy the user */
+ return UNIX_FAILED;
+ }
+
+ /*
+ * determine the current user's name is
+ */
+ user = getuidname(getuid());
+ if (argc == 2) {
+ /* if the caller specifies the username, verify that user
+ matches it */
+ if (strcmp(user, argv[1])) {
+ force_failure = 1;
+ }
+ }
+
+ /* read the nollok/nonull option */
+
+ npass = read(STDIN_FILENO, option, 8);
+
+ if (npass < 0) {
+ _log_err(LOG_DEBUG, "no option supplied");
+ return UNIX_FAILED;
+ } else {
+ option[7] = '\0';
+ if (strncmp(option, "nullok", 8) == 0)
+ opt = 1;
+ else
+ opt = 0;
+ }
+
+ /* read the password from stdin (a pipe from the pam_unix module) */
+
+ npass = read(STDIN_FILENO, pass, MAXPASS);
+
+ if (npass < 0) { /* is it a valid password? */
+
+ _log_err(LOG_DEBUG, "no password supplied");
+
+ } else if (npass >= MAXPASS) {
+
+ _log_err(LOG_DEBUG, "password too long");
+
+ } else {
+ if (npass == 0) {
+ /* the password is NULL */
+
+ retval = _unix_verify_password(user, NULL, opt);
+
+ } else {
+ /* does pass agree with the official one? */
+
+ pass[npass] = '\0'; /* NUL terminate */
+ retval = _unix_verify_password(user, pass, opt);
+
+ }
+ }
+
+ memset(pass, '\0', MAXPASS); /* clear memory of the password */
+
+ /* return pass or fail */
+
+ if ((retval != UNIX_PASSED) || force_failure) {
+ return UNIX_FAILED;
+ } else {
+ return UNIX_PASSED;
+ }
+}
+
+/*
+ * Copyright (c) Andrew G. Morgan, 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.
+ */
diff --git a/contrib/libpam/modules/pam_unix/yppasswd.h b/contrib/libpam/modules/pam_unix/yppasswd.h
new file mode 100644
index 000000000000..6b414be09a57
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/yppasswd.h
@@ -0,0 +1,51 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#ifndef _YPPASSWD_H_
+#define _YPPASSWD_H_
+
+#define YPPASSWDPROG ((u_long)100009)
+#define YPPASSWDVERS ((u_long)1)
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+
+/*
+ * The password struct passed by the update call. I renamed it to
+ * xpasswd to avoid a type clash with the one defined in <pwd.h>.
+ */
+#ifndef __sgi
+typedef struct xpasswd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+} xpasswd;
+
+#else
+#include <pwd.h>
+typedef struct xpasswd xpasswd;
+#endif
+
+/* The updated password information, plus the old password.
+ */
+typedef struct yppasswd {
+ char *oldpass;
+ xpasswd newpw;
+} yppasswd;
+
+/* XDR encoding/decoding routines */
+bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp);
+bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp);
+
+#endif /* _YPPASSWD_H_ */
diff --git a/contrib/libpam/modules/pam_unix/yppasswd_xdr.c b/contrib/libpam/modules/pam_unix/yppasswd_xdr.c
new file mode 100644
index 000000000000..b1a60b4ce11e
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/yppasswd_xdr.c
@@ -0,0 +1,38 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include "yppasswd.h"
+
+bool_t
+xdr_xpasswd(XDR * xdrs, xpasswd * objp)
+{
+ return xdr_string(xdrs, &objp->pw_name, ~0)
+ && xdr_string(xdrs, &objp->pw_passwd, ~0)
+ && xdr_int(xdrs, &objp->pw_uid)
+ && xdr_int(xdrs, &objp->pw_gid)
+ && xdr_string(xdrs, &objp->pw_gecos, ~0)
+ && xdr_string(xdrs, &objp->pw_dir, ~0)
+ && xdr_string(xdrs, &objp->pw_shell, ~0);
+}
+
+
+bool_t
+xdr_yppasswd(XDR * xdrs, yppasswd * objp)
+{
+ return xdr_string(xdrs, &objp->oldpass, ~0)
+ && xdr_xpasswd(xdrs, &objp->newpw);
+}
diff --git a/contrib/libpam/modules/pam_userdb/Makefile b/contrib/libpam/modules/pam_userdb/Makefile
new file mode 100644
index 000000000000..ebdcff9cd335
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/Makefile
@@ -0,0 +1,35 @@
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+
+# $Id: Makefile,v 1.4 2001/02/18 03:03:31 agmorgan Exp $
+# Created by Cristian Gafton <gafton@redhat.com>
+
+include ../../Make.Rules
+
+TITLE=pam_userdb
+
+ifeq ($(HAVE_NDBM_H),yes)
+ WHICH_DB=ndbm
+ MODULE_SIMPLE_EXTRALIBS = -lndbm
+else
+ifeq ($(HAVE_LIBDB),yes)
+ WHICH_DB=db
+ MODULE_SIMPLE_EXTRALIBS = -ldb
+else
+ WHICH_DB=none
+endif
+endif
+
+ifeq ($(WHICH_DB),none)
+
+include ../dont_makefile
+
+else
+
+MODULE_SIMPLE_EXTRAFILES = conv
+
+include ../Simple.Rules
+
+endif
diff --git a/contrib/libpam/modules/pam_userdb/README b/contrib/libpam/modules/pam_userdb/README
new file mode 100644
index 000000000000..af78d47b1309
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/README
@@ -0,0 +1,30 @@
+pam_userdb:
+ Look up users in a .db database and verify their password against
+ what is contained in that database.
+
+RECOGNIZED ARGUMENTS:
+ debug write a message to syslog indicating success or
+ failure.
+
+ db=[path] use the [path] database for performing lookup. There
+ is no default; the module will return PAM_IGNORE if
+ no database is provided.
+
+ icase make the password verification to be case insensitive
+ (ie when working with registration numbers and such)
+
+ dump dump all the entries in the database to the log (eek,
+ don't do this by default!)
+
+MODULE SERVICES PROVIDED:
+ auth _authetication and _setcred (blank)
+
+EXAMPLE USE:
+ auth sufficient pam_userdb.so icase db=/tmp/dbtest.db
+
+AUTHOR:
+ Cristian Gafton <gafton@redhat.com>
+
+
+
+$Id: README,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $
diff --git a/contrib/libpam/modules/pam_userdb/conv.c b/contrib/libpam/modules/pam_userdb/conv.c
new file mode 100644
index 000000000000..0f13d03a4fc4
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/conv.c
@@ -0,0 +1,125 @@
+/*
+ * Conversation related functions
+ */
+
+/* $Id */
+/* Copyright at the end of the file */
+
+#define _BSD_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+#include "pam_userdb.h"
+
+/*
+ * dummy conversation function sending exactly one prompt
+ * and expecting exactly one response from the other party
+ */
+static int converse(pam_handle_t *pamh,
+ struct pam_message **message,
+ struct pam_response **response)
+{
+ int retval;
+ const struct pam_conv *conv;
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ;
+ if (retval == PAM_SUCCESS)
+ retval = conv->conv(1, (const struct pam_message **)message,
+ response, conv->appdata_ptr);
+
+ return retval; /* propagate error status */
+}
+
+
+static char *_pam_delete(register char *xx)
+{
+ _pam_overwrite(xx);
+ _pam_drop(xx);
+ return NULL;
+}
+
+/*
+ * This is a conversation function to obtain the user's password
+ */
+int conversation(pam_handle_t *pamh)
+{
+ struct pam_message msg[2],*pmsg[2];
+ struct pam_response *resp;
+ int retval;
+ char * token = NULL;
+
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = "Password: ";
+
+ /* so call the conversation expecting i responses */
+ resp = NULL;
+ retval = converse(pamh, pmsg, &resp);
+
+ if (resp != NULL) {
+ const char * item;
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token = x_strdup(resp[0].resp);
+ if (token == NULL) {
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+ }
+
+ /* set the auth token */
+ retval = pam_set_item(pamh, PAM_AUTHTOK, token);
+ token = _pam_delete(token); /* clean it up */
+ if ( (retval != PAM_SUCCESS) ||
+ (retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item))
+ != PAM_SUCCESS ) {
+ return retval;
+ }
+
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS)
+ ? PAM_AUTHTOK_RECOVER_ERR:retval ;
+ }
+
+ return retval;
+}
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * 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.
+ */
diff --git a/contrib/libpam/modules/pam_userdb/create.pl b/contrib/libpam/modules/pam_userdb/create.pl
new file mode 100644
index 000000000000..0e1687dfef65
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/create.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+# this program creates a database in ARGV[1] from pairs given on
+# stdandard input
+#
+# $Id: create.pl,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $
+
+use DB_File;
+
+my $database = $ARGV[0];
+die "Use: check,pl <database>\n" unless ($database);
+print "Using database: $database\n";
+
+my %lusers = ();
+
+tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ;
+while (<STDIN>) {
+ my ($user, $pass) = split;
+
+ $lusers{$user} = $pass;
+}
+untie %lusers;
+
+
diff --git a/contrib/libpam/modules/pam_userdb/pam_userdb.c b/contrib/libpam/modules/pam_userdb/pam_userdb.c
new file mode 100644
index 000000000000..9da93705e514
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/pam_userdb.c
@@ -0,0 +1,304 @@
+/* pam_userdb module */
+
+/*
+ * $Id: pam_userdb.c,v 1.4 2000/12/04 15:02:16 baggins Exp $
+ * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
+ * See the end of the file for Copyright Information
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "pam_userdb.h"
+
+#ifdef HAVE_NDBM_H
+# include <ndbm.h>
+#else
+# ifdef HAVE_DB_H
+# define DB_DBM_HSEARCH 1 /* use the dbm interface */
+# include <db.h>
+# else
+# error "failed to find a libdb or equivalent"
+# endif
+#endif
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+char * database = NULL;
+static int ctrl = 0;
+
+static int _pam_parse(int argc, const char **argv)
+{
+ /* step through arguments */
+ for (ctrl = 0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcasecmp(*argv, "icase"))
+ ctrl |= PAM_ICASE_ARG;
+ else if (!strcasecmp(*argv, "dump"))
+ ctrl |= PAM_DUMP_ARG;
+ else if (!strncasecmp(*argv,"db=", 3)) {
+ database = strdup((*argv) + 3);
+ if (database == NULL)
+ _pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
+ *argv);
+ } else {
+ _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+
+/*
+ * Looks up an user name in a database and checks the password
+ *
+ * return values:
+ * 1 = User not found
+ * 0 = OK
+ * -1 = Password incorrect
+ * -2 = System error
+ */
+static int user_lookup(const char *user, const char *pass)
+{
+ DBM *dbm;
+ datum key, data;
+
+ /* Open the DB file. */
+ dbm = dbm_open(database, O_RDONLY, 0644);
+ if (dbm == NULL) {
+ _pam_log(LOG_ERR, "user_lookup: could not open database `%s'",
+ database);
+ return -2;
+ }
+
+ if (ctrl &PAM_DUMP_ARG) {
+ _pam_log(LOG_INFO, "Database dump:");
+ for (key = dbm_firstkey(dbm); key.dptr != NULL;
+ key = dbm_nextkey(dbm)) {
+ data = dbm_fetch(dbm, key);
+ _pam_log(LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'",
+ key.dsize, key.dptr, data.dsize, data.dptr);
+ }
+ }
+ /* do some more init work */
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ key.dptr = x_strdup(user);
+ key.dsize = strlen(user);
+ user = NULL;
+
+ if (key.dptr) {
+ data = dbm_fetch(dbm, key);
+ memset(key.dptr, 0, key.dsize);
+ free(key.dptr);
+ }
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "password in database is [%p]`%s', len is %d",
+ data.dptr, (char *) data.dptr, data.dsize);
+ }
+
+ if (data.dptr != NULL) {
+ int compare = 0;
+ /* bingo, got it */
+ if (ctrl & PAM_ICASE_ARG)
+ compare = strncasecmp(pass, data.dptr, data.dsize);
+ else
+ compare = strncmp(pass, data.dptr, data.dsize);
+ dbm_close(dbm);
+ if (compare == 0)
+ return 0; /* match */
+ else
+ return -1; /* wrong */
+ } else {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "error returned by dbm_fetch: %s",
+ strerror(errno));
+ }
+ dbm_close(dbm);
+ /* probably we should check dbm_error() here */
+ return 1; /* not found */
+ }
+
+ /* NOT REACHED */
+ return -2;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *username;
+ const char *password;
+ int retval = PAM_AUTH_ERR;
+
+ /* parse arguments */
+ ctrl = _pam_parse(argc, argv);
+
+ /* Get the username */
+ retval = pam_get_user(pamh, &username, NULL);
+ if ((retval != PAM_SUCCESS) || (!username)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"can not get the username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Converse just to be sure we have the password */
+ retval = conversation(pamh);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_ERR, "could not obtain password for `%s'",
+ username);
+ return -2;
+ }
+
+ /* Get the password */
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_ERR, "Could not retrive user's password");
+ return -2;
+ }
+
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_INFO, "Verify user `%s' with password `%s'",
+ username, password);
+
+ /* Now use the username to look up password in the database file */
+ retval = user_lookup(username, password);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password */
+ _pam_log(LOG_WARNING,
+ "user `%s' denied access (incorrect password)",
+ username);
+ return PAM_AUTH_ERR;
+ case 1:
+ /* the user does not exist in the database */
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_NOTICE, "user `%s' not found in the database",
+ username);
+ return PAM_USER_UNKNOWN;
+ case 0:
+ /* Otherwise, the authentication looked good */
+ _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
+ return PAM_SUCCESS;
+ default:
+ /* we don't know anything about this return value */
+ _pam_log(LOG_ERR,
+ "internal module error (retval = %d, user = `%s'",
+ retval, username);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* should not be reached */
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_userdb_modstruct = {
+ "pam_userdb",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * 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.
+ */
diff --git a/contrib/libpam/modules/pam_userdb/pam_userdb.h b/contrib/libpam/modules/pam_userdb/pam_userdb.h
new file mode 100644
index 000000000000..542cdf57943f
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/pam_userdb.h
@@ -0,0 +1,61 @@
+
+#ifndef _PAM_USERSDB_H
+#define _PAM_USERSDB_H
+/* $Id: pam_userdb.h,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $ */
+
+/* Header files */
+#include <security/pam_appl.h>
+
+/* argument parsing */
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_ICASE_ARG 0x0002
+#define PAM_DUMP_ARG 0x0004
+
+/* Useful macros */
+#define x_strdup(s) ( (s) ? strdup(s):NULL )
+
+/* The name of the module we are compiling */
+#ifndef MODULE_NAME
+#define MODULE_NAME "pam_userdb"
+#endif /* MODULE_NAME */
+
+/* function prototypes */
+int conversation(pam_handle_t *);
+
+#endif /* _PAM_USERSDB_H */
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * 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.
+ */
diff --git a/contrib/libpam/modules/pam_warn/Makefile b/contrib/libpam/modules/pam_warn/Makefile
index 167af5a370ac..b1420538d577 100644
--- a/contrib/libpam/modules/pam_warn/Makefile
+++ b/contrib/libpam/modules/pam_warn/Makefile
@@ -1,96 +1,15 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:20:16 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:06 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:20:16 morgan
-# fixed fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1996/12/01 03:12:22 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/11/14
-#
-
-TITLE=pam_warn
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-dummy:
+include ../../Make.Rules
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_warn
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_warn/README b/contrib/libpam/modules/pam_warn/README
index f45b271c0d77..3c4bde8af20d 100644
--- a/contrib/libpam/modules/pam_warn/README
+++ b/contrib/libpam/modules/pam_warn/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/12/01 03:12:22 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
#
This module is an authentication module that does not authenticate.
@@ -15,7 +15,10 @@ Recognized arguments:
module services provided:
- auth _autheticate and _setcred (blank)
+ auth _authenticate and _setcred (blank)
+ acct _acct_mgmt [mapped to _authenticate]
+ session _open_session and
+ _close_session [mapped to _authenticate ]
password _chauthtok [mapped to _authenticate]
diff --git a/contrib/libpam/modules/pam_warn/pam_warn.c b/contrib/libpam/modules/pam_warn/pam_warn.c
index 2a0a23d6e989..a9bcc9e70c5c 100644
--- a/contrib/libpam/modules/pam_warn/pam_warn.c
+++ b/contrib/libpam/modules/pam_warn/pam_warn.c
@@ -1,20 +1,13 @@
/* pam_warn module */
/*
- * $Id: pam_warn.c,v 1.2 1997/02/15 17:19:08 morgan Exp $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_warn.c,v $
- * Revision 1.2 1997/02/15 17:19:08 morgan
- * corrected many bugs and removed fixed buffer logging
- *
- * Revision 1.1 1996/12/01 03:12:22 morgan
- * Initial revision
- *
+ * $Id: pam_warn.c,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
@@ -93,18 +86,45 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc
return pam_sm_authenticate(pamh, flags, argc, argv);
}
+PAM_EXTERN int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
#ifdef PAM_STATIC
/* static module data */
struct pam_module _pam_warn_modstruct = {
- "pam_warn",
- pam_sm_authenticate,
- pam_sm_setcred,
- NULL,
- NULL,
- NULL,
- pam_sm_chauthtok,
+ "pam_warn",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ pam_sm_acct_mgmt,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ pam_sm_chauthtok,
};
#endif
diff --git a/contrib/libpam/modules/pam_wheel/Makefile b/contrib/libpam/modules/pam_wheel/Makefile
index 553e32199668..67947f814101 100644
--- a/contrib/libpam/modules/pam_wheel/Makefile
+++ b/contrib/libpam/modules/pam_wheel/Makefile
@@ -1,94 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:06 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@sorosis.ro> 1996/09/10
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-ifeq ($(HAVE_PWDBLIB),yes)
+include ../../Make.Rules
TITLE=pam_wheel
-CFLAGS += -DHAVE_PWDBLIB
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-#LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-EXTRALS = -lpwdb
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-#static/%.o : %.c
-# $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-#ifdef STATIC
-#LIBSTATIC = lib$(TITLE).o
-#endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-#ifdef STATIC
-# $(MKDIR) ./static
-#endif
-
-register:
-#ifdef STATIC
-# ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-#endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALS)
-endif
-
-#ifdef STATIC
-#$(LIBOBJS): $(LIBSRC)
-#
-#$(LIBSTATIC): $(LIBOBJS)
-# $(LD) -r -o $@ $(LIBOBJS) $(EXTRALS)
-#endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-else
-include ../dont_makefile
-endif
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_wheel/pam_wheel.c b/contrib/libpam/modules/pam_wheel/pam_wheel.c
index db262d83d8c9..add72bc43f48 100644
--- a/contrib/libpam/modules/pam_wheel/pam_wheel.c
+++ b/contrib/libpam/modules/pam_wheel/pam_wheel.c
@@ -21,20 +21,16 @@
* a wheel member.
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
-#define __USE_BSD
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <sys/types.h>
-#ifdef HAVE_PWDBLIB
-# include <pwdb/pwdb_public.h>
-#else
-# include <pwd.h>
-# include <grp.h>
-#endif
-
+#include <pwd.h>
+#include <grp.h>
/*
* here, we make a definition for the externally accessible function
@@ -47,9 +43,6 @@
#include <security/pam_modules.h>
-/* variables */
-static char use_group[BUFSIZ];
-
/* some syslogging */
static void _pam_log(int err, const char *format, ...)
@@ -82,7 +75,7 @@ static int is_on_list(char * const *list, const char *member)
#define PAM_TRUST_ARG 0x0004
#define PAM_DENY_ARG 0x0010
-static int _pam_parse(int argc, const char **argv)
+static int _pam_parse(int argc, const char **argv, char *use_group)
{
int ctrl=0;
@@ -122,11 +115,12 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
struct passwd *pwd, *tpwd;
struct group *grp;
int retval = PAM_AUTH_ERR;
+ char use_group[BUFSIZ];
/* Init the optional group */
- bzero(use_group,sizeof(use_group));
+ bzero(use_group,BUFSIZ);
- ctrl = _pam_parse(argc, argv);
+ ctrl = _pam_parse(argc, argv, use_group);
retval = pam_get_user(pamh,&username,NULL);
if ((retval != PAM_SUCCESS) || (!username)) {
if (ctrl & PAM_DEBUG_ARG)
@@ -171,10 +165,12 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
}
}
- if (!use_group[0])
- grp = getgrgid(0);
- else
- grp = getgrnam(use_group);
+ if (!use_group[0]) {
+ if ((grp = getgrnam("wheel")) == NULL) {
+ grp = getgrgid(0);
+ }
+ } else
+ grp = getgrnam(use_group);
if (!grp || !grp->gr_mem) {
if (ctrl & PAM_DEBUG_ARG) {