summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_unix
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_unix')
-rw-r--r--Linux-PAM/modules/pam_unix/Makefile191
-rw-r--r--Linux-PAM/modules/pam_unix/Makefile.am61
-rw-r--r--Linux-PAM/modules/pam_unix/Makefile.in859
-rw-r--r--Linux-PAM/modules/pam_unix/README179
-rw-r--r--Linux-PAM/modules/pam_unix/README.xml41
-rw-r--r--Linux-PAM/modules/pam_unix/bigcrypt.c8
-rw-r--r--Linux-PAM/modules/pam_unix/bigcrypt.h1
-rw-r--r--Linux-PAM/modules/pam_unix/bigcrypt_main.c2
-rw-r--r--Linux-PAM/modules/pam_unix/lckpwdf.-c25
-rw-r--r--Linux-PAM/modules/pam_unix/md5_broken.c4
-rw-r--r--Linux-PAM/modules/pam_unix/md5_good.c5
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix.8143
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix.8.xml342
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix_acct.c234
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix_auth.c42
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix_passwd.c635
-rw-r--r--Linux-PAM/modules/pam_unix/pam_unix_sess.c29
-rw-r--r--Linux-PAM/modules/pam_unix/support.c377
-rw-r--r--Linux-PAM/modules/pam_unix/support.h8
-rwxr-xr-xLinux-PAM/modules/pam_unix/tst-pam_unix2
-rw-r--r--Linux-PAM/modules/pam_unix/unix_chkpwd.880
-rw-r--r--Linux-PAM/modules/pam_unix/unix_chkpwd.c320
-rw-r--r--Linux-PAM/modules/pam_unix/yppasswd_xdr.c2
23 files changed, 2811 insertions, 779 deletions
diff --git a/Linux-PAM/modules/pam_unix/Makefile b/Linux-PAM/modules/pam_unix/Makefile
deleted file mode 100644
index 7f32e073..00000000
--- a/Linux-PAM/modules/pam_unix/Makefile
+++ /dev/null
@@ -1,191 +0,0 @@
-# $Id: Makefile,v 1.8 2004/11/08 08:58:37 kukuk Exp $
-#
-# This Makefile controls a build process of the pam_unix modules
-# for Linux-PAM. You should not modify this Makefile.
-#
-
-include ../../Make.Rules
-
-########################################################################
-# some options... uncomment to take effect
-########################################################################
-
-# 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 ($(shell if [ -f /usr/lib/cracklib_dict.hwm ]; then echo yes ; fi),yes)
- CRACKLIB_DICTPATH=/usr/lib/cracklib_dict
-else
- CRACKLIB_DICTPATH=/usr/share/dict/cracklib_dict
-endif
-EXTRAS += -DCRACKLIB_DICTS=\"$(CRACKLIB_DICTPATH)\"
-
-ifeq ($(HAVE_LIBCRYPT),yes)
- EXTRALS += -lcrypt
-endif
-ifeq ($(HAVE_LIBNSL),yes)
- EXTRALS += -lnsl
-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?
-ifeq ($(HAVE_LCKPWDF),no)
- NEED_LCKPWDF=-D"NEED_LCKPWDF"
-endif
-endif
-
-ifeq ($(HAVE_LIBNSL),yes)
- LIBNSL = -lnsl
-endif
-
-ifeq ($(HAVE_LIBCRYPT),yes)
- LIBCRYPT=-lcrypt
-endif
-
-CHKPWD=unix_chkpwd
-
-BIGCRYPT=bigcrypt
-
-EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
-
-LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
-INCLUDE_PAMMODUTILS = -I../pammodutil/include
-
-########################################################################
-
-CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS) \
- $(INCLUDE_PAMMODUTILS)
-
-LDLIBS = $(EXTRALS) $(LINK_PAMMODUTILS)
-
-ifdef USE_CRACKLIB
-CRACKLIB = -lcrack
-endif
-
-
-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))
-
-PLUS = md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o \
- yppasswd_xdr.o bigcrypt.o
-
-ifdef DYNAMIC
-LIBSHARED = pam_unix.so
-endif
-ifdef STATIC
-LIBSTATIC = libpam_unix.o
-endif
-
-
-########################### don't edit below #######################
-
-all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) $(BIGCRYPT) \
- 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 module of the framework..."
- @echo
-
-dirs:
-ifdef DYNAMIC
- mkdir -p ./dynamic
-endif
-ifdef STATIC
- mkdir -p ./static
-endif
-
-register:
-ifdef STATIC
- ( 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)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT) $(NEED_LINK_LIB_C) -L../../libpam -lpam
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(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) $(CFLAGS) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
-
-$(BIGCRYPT): bigcrypt_main.o bigcrypt.o
- $(CC) -o $(BIGCRYPT) $^ $(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:
- 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) $(CHKPWD) $(BIGCRYPT) *.o *.so core
- rm -f *~ *.a *.out *.bak
- rm -rf dynamic static
-
-.c.o:
- $(CC) -c $(CFLAGS) $<
-
diff --git a/Linux-PAM/modules/pam_unix/Makefile.am b/Linux-PAM/modules/pam_unix/Makefile.am
new file mode 100644
index 00000000..83b6c0b3
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/Makefile.am
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+
+EXTRA_DIST = README md5.c md5_crypt.c lckpwdf.-c $(MANS) CHANGELOG \
+ tst-pam_unix $(XMLS)
+
+man_MANS = pam_unix.8 unix_chkpwd.8
+XMLS = README.xml pam_unix.8.xml
+
+TESTS = tst-pam_unix
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\"
+
+if HAVE_LIBSELINUX
+ AM_CFLAGS += -D"WITH_SELINUX"
+endif
+if HAVE_LIBCRACK
+ AM_CFLAGS += -D"USE_CRACKLIB"
+endif
+
+pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module \
+ @LIBCRACK@ @LIBNSL@ -L$(top_builddir)/libpam -lpam \
+ @LIBCRYPT@ @LIBSELINUX@
+if HAVE_VERSIONING
+ pam_unix_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_unix.la
+
+noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h
+
+sbin_PROGRAMS = unix_chkpwd
+
+noinst_PROGRAMS = bigcrypt
+
+pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \
+ pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \
+ yppasswd_xdr.c md5_good.c md5_broken.c
+
+bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c
+bigcrypt_CFLAGS = $(AM_CFLAGS)
+bigcrypt_LDFLAGS = @LIBCRYPT@
+
+unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c
+unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
+unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@ -L$(top_builddir)/libpam -lpam \
+ @LIBCRYPT@ @LIBSELINUX@
+
+if ENABLE_REGENERATE_MAN
+noinst_DATA = README
+README: pam_unix.8.xml
+-include $(top_srcdir)/Make.xml.rules
+endif
+
diff --git a/Linux-PAM/modules/pam_unix/Makefile.in b/Linux-PAM/modules/pam_unix/Makefile.in
new file mode 100644
index 00000000..e3b34afb
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/Makefile.in
@@ -0,0 +1,859 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_LIBSELINUX_TRUE@am__append_1 = -D"WITH_SELINUX"
+@HAVE_LIBCRACK_TRUE@am__append_2 = -D"USE_CRACKLIB"
+@HAVE_VERSIONING_TRUE@am__append_3 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = unix_chkpwd$(EXEEXT)
+noinst_PROGRAMS = bigcrypt$(EXEEXT)
+subdir = modules/pam_unix
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" \
+ "$(DESTDIR)$(man8dir)"
+securelibLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_unix_la_LIBADD =
+am_pam_unix_la_OBJECTS = bigcrypt.lo pam_unix_acct.lo pam_unix_auth.lo \
+ pam_unix_passwd.lo pam_unix_sess.lo support.lo yppasswd_xdr.lo \
+ md5_good.lo md5_broken.lo
+pam_unix_la_OBJECTS = $(am_pam_unix_la_OBJECTS)
+pam_unix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(pam_unix_la_LDFLAGS) $(LDFLAGS) -o $@
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS)
+am_bigcrypt_OBJECTS = bigcrypt-bigcrypt.$(OBJEXT) \
+ bigcrypt-bigcrypt_main.$(OBJEXT)
+bigcrypt_OBJECTS = $(am_bigcrypt_OBJECTS)
+bigcrypt_LDADD = $(LDADD)
+bigcrypt_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(bigcrypt_CFLAGS) $(CFLAGS) \
+ $(bigcrypt_LDFLAGS) $(LDFLAGS) -o $@
+am_unix_chkpwd_OBJECTS = unix_chkpwd-unix_chkpwd.$(OBJEXT) \
+ unix_chkpwd-md5_good.$(OBJEXT) \
+ unix_chkpwd-md5_broken.$(OBJEXT) \
+ unix_chkpwd-bigcrypt.$(OBJEXT)
+unix_chkpwd_OBJECTS = $(am_unix_chkpwd_OBJECTS)
+unix_chkpwd_LDADD = $(LDADD)
+unix_chkpwd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(unix_chkpwd_CFLAGS) \
+ $(CFLAGS) $(unix_chkpwd_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \
+ $(unix_chkpwd_SOURCES)
+DIST_SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \
+ $(unix_chkpwd_SOURCES)
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(noinst_DATA)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FO2PDF = @FO2PDF@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_KEY_MANAGEMENT = @HAVE_KEY_MANAGEMENT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_DEBUG = @WITH_DEBUG@
+WITH_PAMLOCKING = @WITH_PAMLOCKING@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libc_cv_fpie = @libc_cv_fpie@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_cv_ld_as_needed = @pam_cv_ld_as_needed@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+EXTRA_DIST = README md5.c md5_crypt.c lckpwdf.-c $(MANS) CHANGELOG \
+ tst-pam_unix $(XMLS)
+
+man_MANS = pam_unix.8 unix_chkpwd.8
+XMLS = README.xml pam_unix.8.xml
+TESTS = tst-pam_unix
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include \
+ -I$(top_srcdir)/libpamc/include \
+ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" $(am__append_1) \
+ $(am__append_2)
+pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module @LIBCRACK@ \
+ @LIBNSL@ -L$(top_builddir)/libpam -lpam @LIBCRYPT@ \
+ @LIBSELINUX@ $(am__append_3)
+securelib_LTLIBRARIES = pam_unix.la
+noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h
+pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \
+ pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \
+ yppasswd_xdr.c md5_good.c md5_broken.c
+
+bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c
+bigcrypt_CFLAGS = $(AM_CFLAGS)
+bigcrypt_LDFLAGS = @LIBCRYPT@
+unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c
+unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@
+unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@ -L$(top_builddir)/libpam -lpam \
+ @LIBCRYPT@ @LIBSELINUX@
+
+@ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_unix/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_unix/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(securelibdir)" || $(MKDIR_P) "$(DESTDIR)$(securelibdir)"
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(securelibdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$p"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES)
+ $(pam_unix_la_LINK) -rpath $(securelibdir) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+ done
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+bigcrypt$(EXEEXT): $(bigcrypt_OBJECTS) $(bigcrypt_DEPENDENCIES)
+ @rm -f bigcrypt$(EXEEXT)
+ $(bigcrypt_LINK) $(bigcrypt_OBJECTS) $(bigcrypt_LDADD) $(LIBS)
+unix_chkpwd$(EXEEXT): $(unix_chkpwd_OBJECTS) $(unix_chkpwd_DEPENDENCIES)
+ @rm -f unix_chkpwd$(EXEEXT)
+ $(unix_chkpwd_LINK) $(unix_chkpwd_OBJECTS) $(unix_chkpwd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt_main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_broken.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_good.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_acct.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_auth.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_passwd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_sess.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-bigcrypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_broken.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_good.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yppasswd_xdr.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+bigcrypt-bigcrypt.o: bigcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt.o -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt.Tpo -c -o bigcrypt-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bigcrypt-bigcrypt.Tpo $(DEPDIR)/bigcrypt-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt.c' object='bigcrypt-bigcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+
+bigcrypt-bigcrypt.obj: bigcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt.obj -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt.Tpo -c -o bigcrypt-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bigcrypt-bigcrypt.Tpo $(DEPDIR)/bigcrypt-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt.c' object='bigcrypt-bigcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+
+bigcrypt-bigcrypt_main.o: bigcrypt_main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt_main.o -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo -c -o bigcrypt-bigcrypt_main.o `test -f 'bigcrypt_main.c' || echo '$(srcdir)/'`bigcrypt_main.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo $(DEPDIR)/bigcrypt-bigcrypt_main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt_main.c' object='bigcrypt-bigcrypt_main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt_main.o `test -f 'bigcrypt_main.c' || echo '$(srcdir)/'`bigcrypt_main.c
+
+bigcrypt-bigcrypt_main.obj: bigcrypt_main.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt_main.obj -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo -c -o bigcrypt-bigcrypt_main.obj `if test -f 'bigcrypt_main.c'; then $(CYGPATH_W) 'bigcrypt_main.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt_main.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo $(DEPDIR)/bigcrypt-bigcrypt_main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt_main.c' object='bigcrypt-bigcrypt_main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt_main.obj `if test -f 'bigcrypt_main.c'; then $(CYGPATH_W) 'bigcrypt_main.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt_main.c'; fi`
+
+unix_chkpwd-unix_chkpwd.o: unix_chkpwd.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-unix_chkpwd.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo -c -o unix_chkpwd-unix_chkpwd.o `test -f 'unix_chkpwd.c' || echo '$(srcdir)/'`unix_chkpwd.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo $(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='unix_chkpwd.c' object='unix_chkpwd-unix_chkpwd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-unix_chkpwd.o `test -f 'unix_chkpwd.c' || echo '$(srcdir)/'`unix_chkpwd.c
+
+unix_chkpwd-unix_chkpwd.obj: unix_chkpwd.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-unix_chkpwd.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo -c -o unix_chkpwd-unix_chkpwd.obj `if test -f 'unix_chkpwd.c'; then $(CYGPATH_W) 'unix_chkpwd.c'; else $(CYGPATH_W) '$(srcdir)/unix_chkpwd.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo $(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='unix_chkpwd.c' object='unix_chkpwd-unix_chkpwd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-unix_chkpwd.obj `if test -f 'unix_chkpwd.c'; then $(CYGPATH_W) 'unix_chkpwd.c'; else $(CYGPATH_W) '$(srcdir)/unix_chkpwd.c'; fi`
+
+unix_chkpwd-md5_good.o: md5_good.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_good.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_good.Tpo -c -o unix_chkpwd-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-md5_good.Tpo $(DEPDIR)/unix_chkpwd-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='md5_good.c' object='unix_chkpwd-md5_good.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+
+unix_chkpwd-md5_good.obj: md5_good.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_good.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_good.Tpo -c -o unix_chkpwd-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-md5_good.Tpo $(DEPDIR)/unix_chkpwd-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='md5_good.c' object='unix_chkpwd-md5_good.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+
+unix_chkpwd-md5_broken.o: md5_broken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_broken.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_broken.Tpo -c -o unix_chkpwd-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-md5_broken.Tpo $(DEPDIR)/unix_chkpwd-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='md5_broken.c' object='unix_chkpwd-md5_broken.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+
+unix_chkpwd-md5_broken.obj: md5_broken.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_broken.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_broken.Tpo -c -o unix_chkpwd-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-md5_broken.Tpo $(DEPDIR)/unix_chkpwd-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='md5_broken.c' object='unix_chkpwd-md5_broken.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+
+unix_chkpwd-bigcrypt.o: bigcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-bigcrypt.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo -c -o unix_chkpwd-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo $(DEPDIR)/unix_chkpwd-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt.c' object='unix_chkpwd-bigcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+
+unix_chkpwd-bigcrypt.obj: bigcrypt.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-bigcrypt.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo -c -o unix_chkpwd-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo $(DEPDIR)/unix_chkpwd-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bigcrypt.c' object='unix_chkpwd-bigcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ skipped="($$skip tests were not run)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-man uninstall-man8 \
+ uninstall-sbinPROGRAMS uninstall-securelibLTLIBRARIES
+
+@ENABLE_REGENERATE_MAN_TRUE@README: pam_unix.8.xml
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Linux-PAM/modules/pam_unix/README b/Linux-PAM/modules/pam_unix/README
index afeee3da..3421eb31 100644
--- a/Linux-PAM/modules/pam_unix/README
+++ b/Linux-PAM/modules/pam_unix/README
@@ -1,37 +1,142 @@
-pam_unix 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
-pam_unix_sess: session module, providing session logging
-pam_unix_acct: account management, providing shadow account
- managment features, password aging etc..
-pam_unix_passwd: password updating facilities providing
- 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
- broken_shadow - ignore errors reading shadow information for
- users in the account management module
-
- invalid arguments are logged to syslog.
+pam_unix — Module for traditional password authentication
+
+â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
+
+DESCRIPTION
+
+This is the standard Unix authentication module. It uses standard calls from
+the system's libraries to retrieve and set account information as well as
+authentication. Usually this is obtained from the /etc/passwd and the /etc/
+shadow file as well if shadow is enabled.
+
+The account component performs the task of establishing the status of the
+user's account and password based on the following shadow elements: expire,
+last_change, max_change, min_change, warn_change. In the case of the latter, it
+may offer advice to the user on changing their password or, through the
+PAM_AUTHTOKEN_REQD return, delay giving service to the user until they have
+established a new password. The entries listed above are documented in the
+shadow(5) manual page. Should the user's record not contain one or more of
+these entries, the corresponding shadow check is not performed.
+
+The authentication component performs the task of checking the users
+credentials (password). The default action of this module is to not permit the
+user access to a service if their official password is blank.
+
+A helper binary, unix_chkpwd(8), is provided to check the user's password when
+it is stored in a read protected database. This binary is very simple and will
+only check the password of the user invoking it. It is called transparently on
+behalf of the user by the authenticating component of this module. In this way
+it is possible for applications like xlock(1) to work without being
+setuid-root. The module, by default, will temporarily turn off SIGCHLD handling
+for the duration of execution of the helper binary. This is generally the right
+thing to do, as many applications are not prepared to handle this signal from a
+child they didn't know was fork()d. The noreap module argument can be used to
+suppress this temporary shielding and may be needed for use with certain
+applications.
+
+The password component of this module performs the task of updating the user's
+password.
+
+The session component of this module logs when a user logins or leave the
+system.
+
+Remaining arguments, supported by others functions of this module, are silently
+ignored. Other arguments are logged as errors through syslog(3).
+
+OPTIONS
+
+debug
+
+ Turns on debugging via syslog(3).
+
+audit
+
+ A little more extreme than debug.
+
+nullok
+
+ The default action of this module is to not permit the user access to a
+ service if their official password is blank. The nullok argument overrides
+ this default.
+
+try_first_pass
+
+ Before prompting the user for their password, the module first tries the
+ previous stacked module's password in case that satisfies this module as
+ well.
+
+use_first_pass
+
+ The argument use_first_pass forces the module to use a previous stacked
+ modules password and will never prompt the user - if no password is
+ available or the password is not appropriate, the user will be denied
+ access.
+
+nodelay
+
+ This argument can be used to discourage the authentication component from
+ requesting a delay should the authentication as a whole fail. The default
+ action is for the module to request a delay-on-failure of the order of two
+ second.
+
+use_authtok
+
+ When password changing enforce the module to set the new password to the
+ one provided by a previously stacked password module (this is used in the
+ example of the stacking of the pam_cracklib module documented above).
+
+not_set_pass
+
+ This argument is used to inform the module that it is not to pay attention
+ to/make available the old or new passwords from/to other (stacked) password
+ modules.
+
+nis
+
+ NIS RPC is used for setting new passwords.
+
+remember=n
+
+ The last n passwords for each user are saved in /etc/security/opasswd in
+ order to force password change history and keep the user from alternating
+ between the same password too frequently.
+
+shadow
+
+ Try to maintain 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, encrypt it with the DEC C2
+ algorithm.
+
+broken_shadow
+
+ Ignore errors reading shadow inforation for users in the account management
+ module.
+
+Invalid arguments are logged with syslog(3).
+
+EXAMPLES
+
+An example usage for /etc/pam.d/login would be:
+
+# Authenticate the user
+auth required pam_unix.so
+# Ensure users account and password are still active
+account required pam_unix.so
+# Change the users password, but at first check the strength
+# with pam_cracklib(8)
+password required pam_cracklib.so retry=3 minlen=6 difok=3
+password required pam_unix.so use_authtok nullok md5
+session required pam_unix.so
+
+
+AUTHOR
+
+pam_unix was written by various people.
+
diff --git a/Linux-PAM/modules/pam_unix/README.xml b/Linux-PAM/modules/pam_unix/README.xml
new file mode 100644
index 00000000..7fd340b3
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_unix.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_unix-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/Linux-PAM/modules/pam_unix/bigcrypt.c b/Linux-PAM/modules/pam_unix/bigcrypt.c
index 6b73f3d2..d825bc71 100644
--- a/Linux-PAM/modules/pam_unix/bigcrypt.c
+++ b/Linux-PAM/modules/pam_unix/bigcrypt.c
@@ -24,12 +24,16 @@
* Andy Phillips <atp@mssl.ucl.ac.uk>
*/
+#include "config.h"
+
#include <string.h>
#include <stdlib.h>
#include <security/_pam_macros.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
-char *crypt(const char *key, const char *salt);
-char *bigcrypt(const char *key, const char *salt);
+#include "bigcrypt.h"
/*
* Max cleartext password length in segments of 8 characters this
diff --git a/Linux-PAM/modules/pam_unix/bigcrypt.h b/Linux-PAM/modules/pam_unix/bigcrypt.h
new file mode 100644
index 00000000..a66a96e6
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/bigcrypt.h
@@ -0,0 +1 @@
+extern char *bigcrypt(const char *key, const char *salt);
diff --git a/Linux-PAM/modules/pam_unix/bigcrypt_main.c b/Linux-PAM/modules/pam_unix/bigcrypt_main.c
index 70819072..fab212d9 100644
--- a/Linux-PAM/modules/pam_unix/bigcrypt_main.c
+++ b/Linux-PAM/modules/pam_unix/bigcrypt_main.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <string.h>
-extern const char *bigcrypt(const char *password, const char *salt);
+#include "bigcrypt.h"
int
main(int argc, char **argv)
diff --git a/Linux-PAM/modules/pam_unix/lckpwdf.-c b/Linux-PAM/modules/pam_unix/lckpwdf.-c
index b5ff4585..7145617e 100644
--- a/Linux-PAM/modules/pam_unix/lckpwdf.-c
+++ b/Linux-PAM/modules/pam_unix/lckpwdf.-c
@@ -26,6 +26,9 @@
#include <fcntl.h>
#include <signal.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
#define LOCKFILE "/etc/.pwd.lock"
#define TIMEOUT 15
@@ -64,6 +67,28 @@ static int lckpwdf(void)
if (lockfd != -1)
return -1;
+#ifdef WITH_SELINUX
+ if(is_selinux_enabled()>0)
+ {
+ lockfd = open(LOCKFILE, O_WRONLY);
+ if(lockfd == -1 && errno == ENOENT)
+ {
+ security_context_t create_context;
+ int rc;
+
+ if(getfilecon("/etc/passwd", &create_context))
+ return -1;
+ rc = setfscreatecon(create_context);
+ freecon(create_context);
+ if(rc)
+ return -1;
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ if(setfscreatecon(NULL))
+ return -1;
+ }
+ }
+ else
+#endif
lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
if (lockfd == -1)
return -1;
diff --git a/Linux-PAM/modules/pam_unix/md5_broken.c b/Linux-PAM/modules/pam_unix/md5_broken.c
new file mode 100644
index 00000000..193daebb
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/md5_broken.c
@@ -0,0 +1,4 @@
+#define MD5Name(x) Broken##x
+
+#include "md5.c"
+#include "md5_crypt.c"
diff --git a/Linux-PAM/modules/pam_unix/md5_good.c b/Linux-PAM/modules/pam_unix/md5_good.c
new file mode 100644
index 00000000..131e4516
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/md5_good.c
@@ -0,0 +1,5 @@
+#define HIGHFIRST
+#define MD5Name(x) Good##x
+
+#include "md5.c"
+#include "md5_crypt.c"
diff --git a/Linux-PAM/modules/pam_unix/pam_unix.8 b/Linux-PAM/modules/pam_unix/pam_unix.8
new file mode 100644
index 00000000..e57de221
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/pam_unix.8
@@ -0,0 +1,143 @@
+.\" Title: pam_unix
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.70.1 <http://docbook.sf.net/>
+.\" Date: 09/20/2006
+.\" Manual: Linux\-PAM Manual
+.\" Source: Linux\-PAM Manual
+.\"
+.TH "PAM_UNIX" "8" "09/20/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+pam_unix \- Module for traditional password authentication
+.SH "SYNOPSIS"
+.HP 12
+\fBpam_unix.so\fR [...]
+.SH "DESCRIPTION"
+.PP
+This is the standard Unix authentication module. It uses standard calls from the system's libraries to retrieve and set account information as well as authentication. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled.
+.PP
+The account component performs the task of establishing the status of the user's account and password based on the following
+\fIshadow\fR
+elements: expire, last_change, max_change, min_change, warn_change. In the case of the latter, it may offer advice to the user on changing their password or, through the
+\fBPAM_AUTHTOKEN_REQD\fR
+return, delay giving service to the user until they have established a new password. The entries listed above are documented in the
+\fBshadow\fR(5)
+manual page. Should the user's record not contain one or more of these entries, the corresponding
+\fIshadow\fR
+check is not performed.
+.PP
+The authentication component performs the task of checking the users credentials (password). The default action of this module is to not permit the user access to a service if their official password is blank.
+.PP
+A helper binary,
+\fBunix_chkpwd\fR(8), is provided to check the user's password when it is stored in a read protected database. This binary is very simple and will only check the password of the user invoking it. It is called transparently on behalf of the user by the authenticating component of this module. In this way it is possible for applications like
+\fBxlock\fR(1)
+to work without being setuid\-root. The module, by default, will temporarily turn off SIGCHLD handling for the duration of execution of the helper binary. This is generally the right thing to do, as many applications are not prepared to handle this signal from a child they didn't know was
+\fBfork()\fRd. The
+\fBnoreap\fR
+module argument can be used to suppress this temporary shielding and may be needed for use with certain applications.
+.PP
+The password component of this module performs the task of updating the user's password.
+.PP
+The session component of this module logs when a user logins or leave the system.
+.PP
+Remaining arguments, supported by others functions of this module, are silently ignored. Other arguments are logged as errors through
+\fBsyslog\fR(3).
+.SH "OPTIONS"
+.TP 3n
+\fBdebug\fR
+Turns on debugging via
+\fBsyslog\fR(3).
+.TP 3n
+\fBaudit\fR
+A little more extreme than debug.
+.TP 3n
+\fBnullok\fR
+The default action of this module is to not permit the user access to a service if their official password is blank. The
+\fBnullok\fR
+argument overrides this default.
+.TP 3n
+\fBtry_first_pass\fR
+Before prompting the user for their password, the module first tries the previous stacked module's password in case that satisfies this module as well.
+.TP 3n
+\fBuse_first_pass\fR
+The argument
+\fBuse_first_pass\fR
+forces the module to use a previous stacked modules password and will never prompt the user \- if no password is available or the password is not appropriate, the user will be denied access.
+.TP 3n
+\fBnodelay\fR
+This argument can be used to discourage the authentication component from requesting a delay should the authentication as a whole fail. The default action is for the module to request a delay\-on\-failure of the order of two second.
+.TP 3n
+\fBuse_authtok\fR
+When password changing enforce the module to set the new password to the one provided by a previously stacked
+\fBpassword\fR
+module (this is used in the example of the stacking of the
+\fBpam_cracklib\fR
+module documented above).
+.TP 3n
+\fBnot_set_pass\fR
+This argument is used to inform the module that it is not to pay attention to/make available the old or new passwords from/to other (stacked) password modules.
+.TP 3n
+\fBnis\fR
+NIS RPC is used for setting new passwords.
+.TP 3n
+\fBremember=\fR\fB\fIn\fR\fR
+The last
+\fIn\fR
+passwords for each user are saved in
+\fI/etc/security/opasswd\fR
+in order to force password change history and keep the user from alternating between the same password too frequently.
+.TP 3n
+\fBshadow\fR
+Try to maintain a shadow based system.
+.TP 3n
+\fBmd5\fR
+When a user changes their password next, encrypt it with the MD5 algorithm.
+.TP 3n
+\fBbigcrypt\fR
+When a user changes their password next, encrypt it with the DEC C2 algorithm.
+.TP 3n
+\fBbroken_shadow\fR
+Ignore errors reading shadow inforation for users in the account management module.
+.PP
+Invalid arguments are logged with
+\fBsyslog\fR(3).
+.SH "MODULE SERVICES PROVIDED"
+.PP
+All service are supported.
+.SH "RETURN VALUES"
+.TP 3n
+PAM_IGNORE
+Ignore this module.
+.SH "EXAMPLES"
+.PP
+An example usage for
+\fI/etc/pam.d/login\fR
+would be:
+.sp
+.RS 3n
+.nf
+# Authenticate the user
+auth required pam_unix.so
+# Ensure users account and password are still active
+account required pam_unix.so
+# Change the users password, but at first check the strength
+# with pam_cracklib(8)
+password required pam_cracklib.so retry=3 minlen=6 difok=3
+password required pam_unix.so use_authtok nullok md5
+session required pam_unix.so
+
+.fi
+.RE
+.sp
+.SH "SEE ALSO"
+.PP
+
+\fBpam.conf\fR(5),
+\fBpam.d\fR(8),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_unix was written by various people.
diff --git a/Linux-PAM/modules/pam_unix/pam_unix.8.xml b/Linux-PAM/modules/pam_unix/pam_unix.8.xml
new file mode 100644
index 00000000..41757977
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/pam_unix.8.xml
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_unix">
+
+ <refmeta>
+ <refentrytitle>pam_unix</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_unix-name">
+ <refname>pam_unix</refname>
+ <refpurpose>Module for traditional password authentication</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_unix-cmdsynopsis">
+ <command>pam_unix.so</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_unix-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This is the standard Unix authentication module. It uses standard
+ calls from the system's libraries to retrieve and set account
+ information as well as authentication. Usually this is obtained
+ from the /etc/passwd and the /etc/shadow file as well if shadow is
+ enabled.
+ </para>
+
+ <para>
+ The account component performs the task of establishing the status
+ of the user's account and password based on the following
+ <emphasis>shadow</emphasis> elements: expire, last_change, max_change,
+ min_change, warn_change. In the case of the latter, it may offer advice
+ to the user on changing their password or, through the
+ <emphasis remap='B'>PAM_AUTHTOKEN_REQD</emphasis> return, delay
+ giving service to the user until they have established a new password.
+ The entries listed above are documented in the <citerefentry>
+ <refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> manual page. Should the user's record not contain
+ one or more of these entries, the corresponding
+ <emphasis>shadow</emphasis> check is not performed.
+ </para>
+
+ <para>
+ The authentication component performs the task of checking the
+ users credentials (password). The default action of this module
+ is to not permit the user access to a service if their official
+ password is blank.
+ </para>
+
+ <para>
+ A helper binary, <citerefentry>
+ <refentrytitle>unix_chkpwd</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>, is provided
+ to check the user's password when it is stored in a read
+ protected database. This binary is very simple and will only
+ check the password of the user invoking it. It is called
+ transparently on behalf of the user by the authenticating
+ component of this module. In this way it is possible
+ for applications like <citerefentry>
+ <refentrytitle>xlock</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> to work without
+ being setuid-root. The module, by default, will temporarily turn
+ off SIGCHLD handling for the duration of execution of the helper
+ binary. This is generally the right thing to do, as many applications
+ are not prepared to handle this signal from a child they didn't know
+ was <function>fork()</function>d. The <option>noreap</option> module
+ argument can be used to suppress this temporary shielding and may be
+ needed for use with certain applications.
+ </para>
+
+ <para>
+ The password component of this module performs the task of updating
+ the user's password.
+ </para>
+
+ <para>
+ The session component of this module logs when a user logins
+ or leave the system.
+ </para>
+
+ <para>
+ Remaining arguments, supported by others functions of this
+ module, are silently ignored. Other arguments are logged as
+ errors through <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_unix-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>audit</option>
+ </term>
+ <listitem>
+ <para>
+ A little more extreme than debug.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>nullok</option>
+ </term>
+ <listitem>
+ <para>
+ The default action of this module is to not permit the
+ user access to a service if their official password is blank.
+ The <option>nullok</option> argument overrides this default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>try_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Before prompting the user for their password, the module first
+ tries the previous stacked module's password in case that
+ satisfies this module as well.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ The argument <option>use_first_pass</option> forces the module
+ to use a previous stacked modules password and will never prompt
+ the user - if no password is available or the password is not
+ appropriate, the user will be denied access.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nodelay</option>
+ </term>
+ <listitem>
+ <para>
+ This argument can be used to discourage the authentication
+ component from requesting a delay should the authentication
+ as a whole fail. The default action is for the module to
+ request a delay-on-failure of the order of two second.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_authtok</option>
+ </term>
+ <listitem>
+ <para>
+ When password changing enforce the module to set the new
+ password to the one provided by a previously stacked
+ <option>password</option> module (this is used in the
+ example of the stacking of the <command>pam_cracklib</command>
+ module documented above).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>not_set_pass</option>
+ </term>
+ <listitem>
+ <para>
+ This argument is used to inform the module that it is not to
+ pay attention to/make available the old or new passwords from/to
+ other (stacked) password modules.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nis</option>
+ </term>
+ <listitem>
+ <para>
+ NIS RPC is used for setting new passwords.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>remember=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>n</replaceable> passwords for each
+ user are saved in <filename>/etc/security/opasswd</filename>
+ in order to force password change history and keep the user
+ from alternating between the same password too frequently.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>shadow</option>
+ </term>
+ <listitem>
+ <para>
+ Try to maintain a shadow based system.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>md5</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next, encrypt
+ it with the MD5 algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>bigcrypt</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the DEC C2 algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>broken_shadow</option>
+ </term>
+ <listitem>
+ <para>
+ Ignore errors reading shadow inforation for
+ users in the account management module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Invalid arguments are logged with <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_unix-services">
+ <title>MODULE SERVICES PROVIDED</title>
+ <para>
+ All service are supported.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ Ignore this module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_unix-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ An example usage for <filename>/etc/pam.d/login</filename>
+ would be:
+ <programlisting>
+# Authenticate the user
+auth required pam_unix.so
+# Ensure users account and password are still active
+account required pam_unix.so
+# Change the users password, but at first check the strength
+# with pam_cracklib(8)
+password required pam_cracklib.so retry=3 minlen=6 difok=3
+password required pam_unix.so use_authtok nullok md5
+session required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_unix was written by various people.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/Linux-PAM/modules/pam_unix/pam_unix_acct.c b/Linux-PAM/modules/pam_unix/pam_unix_acct.c
index 02e07ba6..cb2550df 100644
--- a/Linux-PAM/modules/pam_unix/pam_unix_acct.c
+++ b/Linux-PAM/modules/pam_unix/pam_unix_acct.c
@@ -14,13 +14,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
@@ -34,7 +34,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
@@ -45,6 +45,12 @@
#include <pwd.h>
#include <shadow.h>
#include <time.h> /* for time() */
+#include <errno.h>
+#include <sys/wait.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#define SELINUX_ENABLED is_selinux_enabled()>0
+#endif
#include <security/_pam_macros.h>
@@ -53,14 +59,130 @@
#define PAM_SM_ACCOUNT
#include <security/pam_modules.h>
-#include <security/_pam_modutil.h>
-
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif /* LINUX_PAM */
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
#include "support.h"
-
+
+#ifdef WITH_SELINUX
+
+struct spwd spwd;
+
+struct spwd *_unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user)
+{
+ int retval=0, child, fds[2];
+ void (*sighandler)(int) = NULL;
+ D(("running verify_binary"));
+
+ /* create a pipe for the messages */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ pam_syslog(pamh, LOG_ERR, "Could not make pipe: %m");
+ return NULL;
+ }
+ D(("called."));
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ *
+ * The "noreap" module argument is provided so that the admin can
+ * override this behavior.
+ */
+ sighandler = signal(SIGCHLD, SIG_DFL);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ size_t i=0;
+ struct rlimit rlim;
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL, NULL };
+
+ close(0); close(1);
+ /* reopen stdin as pipe */
+ close(fds[0]);
+ dup2(fds[1], STDOUT_FILENO);
+
+ /* XXX - should really tidy up PAM here too */
+
+ if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
+ for (i=2; i < rlim.rlim_max; i++) {
+ if ((unsigned int)fds[1] != i) {
+ close(i);
+ }
+ }
+ }
+
+ if (SELINUX_ENABLED && geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ setuid(0);
+ }
+
+ /* exec binary helper */
+ args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
+ args[2] = x_strdup("verify");
+
+ execve(CHKPWD_HELPER, args, envp);
+
+ pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m");
+ /* should not get here: exit with error */
+ close (fds[1]);
+ D(("helper binary is not available"));
+ exit(PAM_AUTHINFO_UNAVAIL);
+ } else {
+ close(fds[1]);
+ if (child > 0) {
+ char buf[1024];
+ int rc=0;
+ rc=waitpid(child, &retval, 0); /* wait for helper to complete */
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ if (retval != PAM_AUTHINFO_UNAVAIL) {
+ rc = pam_modutil_read(fds[0], buf, sizeof(buf) - 1);
+ if(rc > 0) {
+ buf[rc] = '\0';
+ if (sscanf(buf,"%ld:%ld:%ld:%ld:%ld:%ld",
+ &spwd.sp_lstchg, /* last password change */
+ &spwd.sp_min, /* days until change allowed. */
+ &spwd.sp_max, /* days before change required */
+ &spwd.sp_warn, /* days warning for expiration */
+ &spwd.sp_inact, /* days before account inactive */
+ &spwd.sp_expire) /* date when account expires */ != 6 ) retval = PAM_AUTH_ERR;
+ }
+ else {
+ pam_syslog(pamh, LOG_ERR, " ERROR %d: %m", rc); retval = PAM_AUTH_ERR;
+ }
+ }
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Fork failed: %m");
+ D(("fork failed"));
+ retval = PAM_AUTH_ERR;
+ }
+ close(fds[0]);
+ }
+ if (sighandler != SIG_ERR) {
+ (void) signal(SIGCHLD, sighandler); /* restore old signal handler */
+ }
+ D(("Returning %d",retval));
+ if (retval != PAM_SUCCESS) {
+ return NULL;
+ }
+ return &spwd;
+}
+
+#endif
+
+
/*
* PAM framework looks for this entry-point to pass control to the
* account management module.
@@ -70,31 +192,33 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
int argc, const char **argv)
{
unsigned int ctrl;
+ const void *void_uname;
const char *uname;
int retval, daysleft;
time_t curdays;
struct spwd *spent;
struct passwd *pwent;
- char buf[80];
+ char buf[256];
D(("called."));
ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
- retval = pam_get_item(pamh, PAM_USER, (const void **) &uname);
+ retval = pam_get_item(pamh, PAM_USER, &void_uname);
+ uname = 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());
+ pam_syslog(pamh, LOG_ALERT,
+ "could not identify user (from uid=%lu)",
+ (unsigned long int)getuid());
return PAM_USER_UNKNOWN;
}
- pwent = _pammodutil_getpwnam(pamh, uname);
+ pwent = pam_modutil_getpwnam(pamh, uname);
if (!pwent) {
- _log_err(LOG_ALERT, pamh
- ,"could not identify user (from getpwnam(%s))"
- ,uname);
+ pam_syslog(pamh, LOG_ALERT,
+ "could not identify user (from getpwnam(%s))",
+ uname);
return PAM_USER_UNKNOWN;
}
@@ -114,7 +238,7 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
return PAM_CRED_INSUFFICIENT;
}
}
- spent = _pammodutil_getspnam (pamh, uname);
+ spent = pam_modutil_getspnam (pamh, uname);
if (save_uid == pwent->pw_uid)
setreuid( save_uid, save_euid );
else {
@@ -124,10 +248,15 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
}
} else if (_unix_shadowed (pwent))
- spent = _pammodutil_getspnam (pamh, uname);
+ spent = pam_modutil_getspnam (pamh, uname);
else
return PAM_SUCCESS;
+#ifdef WITH_SELINUX
+ if (!spent && SELINUX_ENABLED )
+ spent = _unix_run_verify_binary(pamh, ctrl, uname);
+#endif
+
if (!spent)
if (on(UNIX_BROKEN_SHADOW,ctrl))
return PAM_SUCCESS;
@@ -138,58 +267,75 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
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)) {
- _log_err(LOG_NOTICE, pamh
- ,"account %s has expired (account expired)"
- ,uname);
+ pam_syslog(pamh, LOG_NOTICE,
+ "account %s has expired (account expired)",
+ uname);
_make_remark(pamh, ctrl, PAM_ERROR_MSG,
- "Your account has expired; please contact your system administrator");
+ _("Your account has expired; please contact your system administrator"));
D(("account expired"));
return PAM_ACCT_EXPIRED;
}
if (spent->sp_lstchg == 0) {
- _log_err(LOG_NOTICE, pamh
- ,"expired password for user %s (root enforced)"
- ,uname);
+ pam_syslog(pamh, LOG_NOTICE,
+ "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)");
+ _("You are required to change your password immediately (root enforced)"));
D(("need a new password"));
return PAM_NEW_AUTHTOK_REQD;
}
if (curdays < spent->sp_lstchg) {
- _log_err(LOG_DEBUG, pamh
- ,"account %s has password changed in future"
- ,uname);
+ pam_syslog(pamh, LOG_DEBUG,
+ "account %s has password changed in future",
+ uname);
return PAM_SUCCESS;
}
if ((curdays - spent->sp_lstchg > spent->sp_max)
&& (curdays - spent->sp_lstchg > spent->sp_inact)
&& (curdays - spent->sp_lstchg > spent->sp_max + spent->sp_inact)
&& (spent->sp_max != -1) && (spent->sp_inact != -1)) {
- _log_err(LOG_NOTICE, pamh
- ,"account %s has expired (failed to change password)"
- ,uname);
+ pam_syslog(pamh, LOG_NOTICE,
+ "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");
+ _("Your account has expired; please contact your system administrator"));
D(("account expired 2"));
return PAM_ACCT_EXPIRED;
}
if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) {
- _log_err(LOG_DEBUG, pamh
- ,"expired password for user %s (password aged)"
- ,uname);
+ pam_syslog(pamh, LOG_DEBUG,
+ "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)");
+ _("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");
+ pam_syslog(pamh, LOG_DEBUG,
+ "password for user %s will expire in %d days",
+ uname, daysleft);
+#ifdef HAVE_DNGETTEXT
+ snprintf (buf, sizeof (buf),
+ dngettext(PACKAGE,
+ "Warning: your password will expire in %d day",
+ "Warning: your password will expire in %d days",
+ daysleft),
+ daysleft);
+#else
+ if (daysleft == 1)
+ snprintf(buf, sizeof (buf),
+ _("Warning: your password will expire in %d day"),
+ daysleft);
+ else
+ snprintf(buf, sizeof (buf),
+ /* TRANSLATORS: only used if dngettext is not support
+ed */
+ _("Warning: your password will expire in %d days"),
+ daysleft);
+#endif
_make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
}
diff --git a/Linux-PAM/modules/pam_unix/pam_unix_auth.c b/Linux-PAM/modules/pam_unix/pam_unix_auth.c
index 39e0cde5..3004bee8 100644
--- a/Linux-PAM/modules/pam_unix/pam_unix_auth.c
+++ b/Linux-PAM/modules/pam_unix/pam_unix_auth.c
@@ -37,7 +37,7 @@
/* #define DEBUG */
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
@@ -48,6 +48,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <syslog.h>
/* indicate the following groups are defined */
@@ -56,10 +57,7 @@
#define _PAM_EXTERN_FUNCTIONS
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif /* LINUX_PAM */
+#include <security/pam_ext.h>
#include "support.h"
@@ -95,7 +93,8 @@ do { \
} while (0)
-static void setcred_free (pam_handle_t * pamh, void *ptr, int err)
+static void
+setcred_free (pam_handle_t *pamh UNUSED, void *ptr, int err UNUSED)
{
if (ptr)
free (ptr);
@@ -107,7 +106,8 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
{
unsigned int ctrl;
int retval, *ret_data = NULL;
- const char *name, *p;
+ const char *name;
+ const void *p;
D(("called."));
@@ -124,12 +124,11 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
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.
+ * '+' or '-' as the first character of a user name. Don't
+ * allow this characters here.
*/
- if (name == NULL || !isalnum(*name)) {
- _log_err(LOG_ERR, pamh, "bad username [%s]", name);
+ if (name == NULL || name[0] == '-' || name[0] == '+') {
+ pam_syslog(pamh, LOG_ERR, "bad username [%s]", name);
retval = PAM_USER_UNKNOWN;
AUTH_RETURN;
}
@@ -157,12 +156,12 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
}
/* get this user's authentication token */
- retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
+ 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);
+ pam_syslog(pamh, LOG_CRIT,
+ "auth could not identify password for [%s]", name);
} else {
D(("conversation function is not ready yet"));
/*
@@ -193,11 +192,12 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
* warned you. -- AOY
*/
-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 UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
{
int retval;
- int *pretval = NULL;
+ const void *pretval = NULL;
D(("called."));
@@ -206,9 +206,9 @@ PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
D(("recovering return code from auth call"));
/* We will only find something here if UNIX_LIKE_AUTH is set --
don't worry about an explicit check of argv. */
- pam_get_data(pamh, "unix_setcred_return", (const void **) &pretval);
- if(pretval) {
- retval = *pretval;
+ if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+ && pretval) {
+ retval = *(const int *)pretval;
pam_set_data(pamh, "unix_setcred_return", NULL, NULL);
D(("recovered data indicates that old retval was %d", retval));
}
diff --git a/Linux-PAM/modules/pam_unix/pam_unix_passwd.c b/Linux-PAM/modules/pam_unix/pam_unix_passwd.c
index 2ea57cc6..8921d1cc 100644
--- a/Linux-PAM/modules/pam_unix/pam_unix_passwd.c
+++ b/Linux-PAM/modules/pam_unix/pam_unix_passwd.c
@@ -35,7 +35,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
@@ -57,6 +57,16 @@
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+#ifdef WITH_SELINUX
+static int selinux_enabled=-1;
+#include <selinux/selinux.h>
+static security_context_t prev_context=NULL;
+#define SELINUX_ENABLED (selinux_enabled!=-1 ? selinux_enabled : (selinux_enabled=is_selinux_enabled()>0))
+#endif
+
#ifdef USE_CRACKLIB
#include <crack.h>
#endif
@@ -68,16 +78,13 @@
#define PAM_SM_PASSWORD
#include <security/pam_modules.h>
-
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif /* LINUX_PAM */
-
-#include <security/_pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
#include "yppasswd.h"
#include "md5.h"
#include "support.h"
+#include "bigcrypt.h"
#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
extern int getrpcport(const char *host, unsigned long prognum,
@@ -89,12 +96,10 @@ extern int getrpcport(const char *host, unsigned long prognum,
* password changing module.
*/
-#ifdef NEED_LCKPWDF
+#if defined(USE_LCKPWDF) && !defined(HAVE_LCKPWDF)
# include "./lckpwdf.-c"
#endif
-extern char *bigcrypt(const char *key, const char *salt);
-
/*
How it works:
Gets in username (has to be done) from the calling program
@@ -117,7 +122,7 @@ extern char *bigcrypt(const char *key, const char *salt);
#define PW_TMPFILE "/etc/npasswd"
#define SH_TMPFILE "/etc/nshadow"
#ifndef CRACKLIB_DICTS
-#define CRACKLIB_DICTS "/usr/share/dict/cracklib_dict"
+#define CRACKLIB_DICTS NULL
#endif
#define OPW_TMPFILE "/etc/security/nopasswd"
#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
@@ -187,29 +192,131 @@ static char *getNISserver(pam_handle_t *pamh)
int port, err;
if ((err = yp_get_default_domain(&domainname)) != 0) {
- _log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n",
+ pam_syslog(pamh, LOG_WARNING, "can't get local yp domain: %s",
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",
+ pam_syslog(pamh, LOG_WARNING, "can't find the master ypserver: %s",
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");
+ pam_syslog(pamh, LOG_WARNING,
+ "yppasswdd not running on NIS master host");
return NULL;
}
if (port >= IPPORT_RESERVED) {
- _log_err(LOG_WARNING, pamh,
- "yppasswd daemon running on illegal port.\n");
+ pam_syslog(pamh, LOG_WARNING,
+ "yppasswd daemon running on illegal port");
return NULL;
}
return master;
}
+#ifdef WITH_SELINUX
+
+static int _unix_run_shadow_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, const char *fromwhat, const char *towhat)
+{
+ int retval, child, fds[2];
+ void (*sighandler)(int) = NULL;
+
+ D(("called."));
+ /* create a pipe for the password */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ return PAM_AUTH_ERR;
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ *
+ * The "noreap" module argument is provided so that the admin can
+ * override this behavior.
+ */
+ sighandler = signal(SIGCHLD, SIG_DFL);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ size_t i=0;
+ struct rlimit rlim;
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL, NULL };
+
+ /* XXX - should really tidy up PAM here too */
+
+ close(0); close(1);
+ /* reopen stdin as pipe */
+ close(fds[1]);
+ dup2(fds[0], STDIN_FILENO);
+
+ if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
+ for (i=2; i < rlim.rlim_max; i++) {
+ if ((unsigned int)fds[0] != i)
+ close(i);
+ }
+ }
+
+ if (SELINUX_ENABLED && geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ setuid(0);
+ }
+
+ /* exec binary helper */
+ args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
+ args[2] = x_strdup("shadow");
+
+ 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 */
+ int rc=0;
+ if (fromwhat)
+ pam_modutil_write(fds[1], fromwhat, strlen(fromwhat)+1);
+ else
+ pam_modutil_write(fds[1], "", 1);
+ if (towhat) {
+ pam_modutil_write(fds[1], towhat, strlen(towhat)+1);
+ }
+ else
+ pam_modutil_write(fds[1], "", 1);
+
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ rc=waitpid(child, &retval, 0); /* wait for helper to complete */
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ }
+ } else {
+ D(("fork failed"));
+ close(fds[0]);
+ close(fds[1]);
+ retval = PAM_AUTH_ERR;
+ }
+
+ if (sighandler != SIG_ERR) {
+ (void) signal(SIGCHLD, sighandler); /* restore old signal handler */
+ }
+
+ return retval;
+}
+#endif
+
static int check_old_password(const char *forwho, const char *newpass)
{
static char buf[16384];
@@ -270,37 +377,58 @@ static int save_old_password(pam_handle_t *pamh,
}
oldmask = umask(077);
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ security_context_t passwd_context=NULL;
+ if (getfilecon("/etc/passwd",&passwd_context)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon(&prev_context)<0) {
+ freecon(passwd_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon(passwd_context)) {
+ freecon(passwd_context);
+ freecon(prev_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(passwd_context);
+ }
+#endif
pwfile = fopen(OPW_TMPFILE, "w");
umask(oldmask);
if (pwfile == NULL) {
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
opwfile = fopen(OLD_PASSWORDS_FILE, "r");
if (opwfile == NULL) {
fclose(pwfile);
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
- if (fstat (fileno (opwfile), &st) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
- if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
- if (fchmod (fileno (pwfile), st.st_mode) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
while (fgets(buf, 16380, opwfile)) {
if (!strncmp(buf, forwho, strlen(forwho))) {
@@ -337,13 +465,13 @@ static int save_old_password(pam_handle_t *pamh,
fclose(opwfile);
if (!found) {
- pwd = _pammodutil_getpwnam(pamh, forwho);
+ pwd = pam_modutil_getpwnam(pamh, forwho);
if (pwd == NULL) {
err = 1;
} else {
pass = crypt_md5_wrapper(oldpass);
- snprintf(nbuf, sizeof(nbuf), "%s:%d:1:%s\n",
- forwho, pwd->pw_uid, pass);
+ snprintf(nbuf, sizeof(nbuf), "%s:%lu:1:%s\n",
+ forwho, (unsigned long)pwd->pw_uid, pass);
_pam_delete(pass);
if (fputs(nbuf, pwfile) < 0) {
err = 1;
@@ -352,19 +480,31 @@ static int save_old_password(pam_handle_t *pamh,
}
if (fclose(pwfile)) {
- D(("error writing entries to old passwords file: %s\n",
- strerror(errno)));
+ D(("error writing entries to old passwords file: %m"));
err = 1;
}
+done:
if (!err) {
- if (!rename(OPW_TMPFILE, OLD_PASSWORDS_FILE)) {
- return PAM_SUCCESS;
- }
+ if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE))
+ err = 1;
+ }
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon(prev_context)) {
+ err = 1;
+ }
+ if (prev_context)
+ freecon(prev_context);
+ prev_context=NULL;
+ }
+#endif
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(OPW_TMPFILE);
+ return PAM_AUTHTOK_ERR;
}
-
- unlink(OPW_TMPFILE);
- return PAM_AUTHTOK_ERR;
}
static int _update_passwd(pam_handle_t *pamh,
@@ -377,38 +517,59 @@ static int _update_passwd(pam_handle_t *pamh,
int oldmask;
oldmask = umask(077);
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ security_context_t passwd_context=NULL;
+ if (getfilecon("/etc/passwd",&passwd_context)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon(&prev_context)<0) {
+ freecon(passwd_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon(passwd_context)) {
+ freecon(passwd_context);
+ freecon(prev_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(passwd_context);
+ }
+#endif
pwfile = fopen(PW_TMPFILE, "w");
umask(oldmask);
if (pwfile == NULL) {
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
opwfile = fopen("/etc/passwd", "r");
if (opwfile == NULL) {
fclose(pwfile);
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
- if (fstat (fileno (opwfile), &st) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
- if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
- if (fchmod (fileno (pwfile), st.st_mode) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- }
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
- tmpent = fgetpwent (opwfile);
+ tmpent = fgetpwent(opwfile);
while (tmpent) {
if (!strcmp(tmpent->pw_name, forwho)) {
/* To shut gcc up */
@@ -422,7 +583,7 @@ static int _update_passwd(pam_handle_t *pamh,
err = 0;
}
if (putpwent(tmpent, pwfile)) {
- D(("error writing entry to password file: %s\n", strerror(errno)));
+ D(("error writing entry to password file: %m"));
err = 1;
break;
}
@@ -431,19 +592,33 @@ static int _update_passwd(pam_handle_t *pamh,
fclose(opwfile);
if (fclose(pwfile)) {
- D(("error writing entries to password file: %s\n", strerror(errno)));
+ D(("error writing entries to password file: %m"));
err = 1;
}
+done:
if (!err) {
- if (!rename(PW_TMPFILE, "/etc/passwd")) {
- _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho);
- return PAM_SUCCESS;
- }
+ if (!rename(PW_TMPFILE, "/etc/passwd"))
+ pam_syslog(pamh, LOG_NOTICE, "password changed for %s", forwho);
+ else
+ err = 1;
+ }
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon(prev_context)) {
+ err = 1;
+ }
+ if (prev_context)
+ freecon(prev_context);
+ prev_context=NULL;
+ }
+#endif
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(PW_TMPFILE);
+ return PAM_AUTHTOK_ERR;
}
-
- unlink(PW_TMPFILE);
- return PAM_AUTHTOK_ERR;
}
static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
@@ -459,37 +634,58 @@ static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
return PAM_USER_UNKNOWN;
}
oldmask = umask(077);
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ security_context_t shadow_context=NULL;
+ if (getfilecon("/etc/shadow",&shadow_context)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon(&prev_context)<0) {
+ freecon(shadow_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon(shadow_context)) {
+ freecon(shadow_context);
+ freecon(prev_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(shadow_context);
+ }
+#endif
pwfile = fopen(SH_TMPFILE, "w");
umask(oldmask);
if (pwfile == NULL) {
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
opwfile = fopen("/etc/shadow", "r");
if (opwfile == NULL) {
fclose(pwfile);
- return PAM_AUTHTOK_ERR;
+ err = 1;
+ goto done;
}
- if (fstat (fileno (opwfile), &st) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
- if (fchown (fileno (pwfile), st.st_uid, st.st_gid) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
- if (fchmod (fileno (pwfile), st.st_mode) == -1)
- {
- fclose (opwfile);
- fclose (pwfile);
- return PAM_AUTHTOK_ERR;
- }
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
stmpent = fgetspent(opwfile);
while (stmpent) {
@@ -502,7 +698,7 @@ static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
}
if (putspent(stmpent, pwfile)) {
- D(("error writing entry to shadow file: %s\n", strerror(errno)));
+ D(("error writing entry to shadow file: %m"));
err = 1;
break;
}
@@ -512,26 +708,45 @@ static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
fclose(opwfile);
if (fclose(pwfile)) {
- D(("error writing entries to shadow file: %s\n", strerror(errno)));
+ D(("error writing entries to shadow file: %m"));
err = 1;
}
+ done:
if (!err) {
- if (!rename(SH_TMPFILE, "/etc/shadow")) {
- _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho);
- return PAM_SUCCESS;
- }
+ if (!rename(SH_TMPFILE, "/etc/shadow"))
+ pam_syslog(pamh, LOG_NOTICE, "password changed for %s", forwho);
+ else
+ err = 1;
+ }
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon(prev_context)) {
+ err = 1;
+ }
+ if (prev_context)
+ freecon(prev_context);
+ prev_context=NULL;
}
+#endif
- unlink(SH_TMPFILE);
- return PAM_AUTHTOK_ERR;
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(SH_TMPFILE);
+ return PAM_AUTHTOK_ERR;
+ }
}
-static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
+static int _do_setpass(pam_handle_t* pamh, const char *forwho,
+ const char *fromwhat,
char *towhat, unsigned int ctrl, int remember)
{
struct passwd *pwd = NULL;
int retval = 0;
+ int unlocked = 0;
+ char *master = NULL;
D(("called"));
@@ -542,35 +757,19 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
goto done;
}
- if (_unix_comesfromsource(pamh, forwho, 1, 0)) {
- /* first, save old password */
- if (save_old_password(pamh, forwho, fromwhat, remember)) {
- retval = PAM_AUTHTOK_ERR;
- goto done;
- }
- if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) {
- retval = _update_shadow(pamh, forwho, towhat);
- if (retval == PAM_SUCCESS)
- if (!_unix_shadowed(pwd))
- retval = _update_passwd(pamh, forwho, "x");
- } else {
- retval = _update_passwd(pamh, forwho, towhat);
- }
- } else if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) {
+ if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) {
+ if ((master=getNISserver(pamh)) != NULL) {
struct timeval timeout;
struct yppasswd yppwd;
CLIENT *clnt;
- char *master;
int status;
- int err = 0;
+ enum clnt_stat err;
/* Unlock passwd file to avoid deadlock */
#ifdef USE_LCKPWDF
ulckpwdf();
#endif
- /* Make RPC call to NIS server */
- if ((master = getNISserver(pamh)) == NULL)
- return PAM_TRY_AGAIN;
+ unlocked = 1;
/* Initialize password information */
yppwd.newpw.pw_passwd = pwd->pw_passwd;
@@ -580,7 +779,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
yppwd.newpw.pw_gecos = pwd->pw_gecos;
yppwd.newpw.pw_dir = pwd->pw_dir;
yppwd.newpw.pw_shell = pwd->pw_shell;
- yppwd.oldpass = fromwhat ? fromwhat : "";
+ yppwd.oldpass = fromwhat ? strdup (fromwhat) : strdup ("");
yppwd.newpw.pw_passwd = towhat;
D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho));
@@ -600,29 +799,73 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
(xdrproc_t) xdr_int, (char *) &status,
timeout);
+ free (yppwd.oldpass);
+
if (err) {
- clnt_perrno(err);
- retval = PAM_TRY_AGAIN;
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO,
+ clnt_sperrno(err));
} else if (status) {
D(("Error while changing NIS password.\n"));
- retval = PAM_TRY_AGAIN;
}
D(("The password has%s been changed on %s.",
(err || status) ? " not" : "", master));
- _log_err(LOG_NOTICE, pamh, "password%s changed for %s on %s",
+ pam_syslog(pamh, LOG_NOTICE, "password%s changed for %s on %s",
(err || status) ? " not" : "", pwd->pw_name, master);
auth_destroy(clnt->cl_auth);
clnt_destroy(clnt);
- if ((err || status) != 0) {
+ if (err || status) {
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO,
+ _("NIS password could not be changed."));
retval = PAM_TRY_AGAIN;
}
#ifdef DEBUG
sleep(5);
#endif
- return retval;
+ } else {
+ retval = PAM_TRY_AGAIN;
+ }
}
+ if (_unix_comesfromsource(pamh, forwho, 1, 0)) {
+#ifdef USE_LCKPWDF
+ if(unlocked) {
+ int i = 0;
+ /* 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. */
+ while((retval = lckpwdf()) != 0 && i < 100) {
+ usleep(1000);
+ i++;
+ }
+ if(retval != 0) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
+ }
+#endif
+ /* first, save old password */
+ if (save_old_password(pamh, forwho, fromwhat, remember)) {
+ retval = PAM_AUTHTOK_ERR;
+ goto done;
+ }
+ if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) {
+ retval = _update_shadow(pamh, forwho, towhat);
+#ifdef WITH_SELINUX
+ if (retval != PAM_SUCCESS && SELINUX_ENABLED)
+ retval = _unix_run_shadow_binary(pamh, ctrl, forwho, fromwhat, towhat);
+#endif
+ if (retval == PAM_SUCCESS)
+ if (!_unix_shadowed(pwd))
+ retval = _update_passwd(pamh, forwho, "x");
+ } else {
+ retval = _update_passwd(pamh, forwho, towhat);
+ }
+ }
+
+
done:
#ifdef USE_LCKPWDF
ulckpwdf();
@@ -631,7 +874,7 @@ done:
return retval;
}
-static int _unix_verify_shadow(const char *user, unsigned int ctrl)
+static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl)
{
struct passwd *pwd = NULL; /* Password and shadow password */
struct spwd *spwdent = NULL; /* file entries for the user */
@@ -650,6 +893,10 @@ static int _unix_verify_shadow(const char *user, unsigned int ctrl)
spwdent = getspnam(user);
endspent();
+#ifdef WITH_SELINUX
+ if (spwdent == NULL && SELINUX_ENABLED )
+ spwdent = _unix_run_verify_binary(pamh, ctrl, user);
+#endif
if (spwdent == NULL)
return PAM_AUTHINFO_UNAVAIL;
} else {
@@ -674,10 +921,22 @@ static int _unix_verify_shadow(const char *user, unsigned int ctrl)
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))
+ if (curdays < spwdent->sp_lstchg) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "account %s has password changed in future",
+ user);
+ curdays = spwdent->sp_lstchg;
+ }
+ if ((curdays - spwdent->sp_lstchg < spwdent->sp_min)
+ && (spwdent->sp_min != -1))
+ /*
+ * The last password change was too recent.
+ */
retval = PAM_AUTHTOK_ERR;
- else if ((curdays > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
+ else if ((curdays - spwdent->sp_lstchg > spwdent->sp_max)
+ && (curdays - spwdent->sp_lstchg > spwdent->sp_inact)
+ && (curdays - spwdent->sp_lstchg >
+ spwdent->sp_max + spwdent->sp_inact)
&& (spwdent->sp_max != -1) && (spwdent->sp_inact != -1)
&& (spwdent->sp_lstchg != 0))
/*
@@ -700,7 +959,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
,const char *pass_old
,const char *pass_new)
{
- const char *user;
+ const void *user;
const char *remark = NULL;
int retval = PAM_SUCCESS;
@@ -710,10 +969,10 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) {
if (on(UNIX_DEBUG, ctrl)) {
- _log_err(LOG_DEBUG, pamh, "bad authentication token");
+ pam_syslog(pamh, LOG_DEBUG, "bad authentication token");
}
_make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
- "No password supplied" : "Password unchanged");
+ _("No password supplied") : _("Password unchanged"));
return PAM_AUTHTOK_ERR;
}
/*
@@ -721,27 +980,27 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
* checking this would be the place - AGM
*/
- retval = pam_get_item(pamh, PAM_USER, (const void **) &user);
+ retval = pam_get_item(pamh, PAM_USER, &user);
if (retval != PAM_SUCCESS) {
if (on(UNIX_DEBUG, ctrl)) {
- _log_err(LOG_ERR, pamh, "Can not get username");
+ pam_syslog(pamh, LOG_ERR, "Can not get username");
return PAM_AUTHTOK_ERR;
}
}
if (off(UNIX__IAMROOT, ctrl)) {
#ifdef USE_CRACKLIB
- remark = FascistCheck(pass_new, CRACKLIB_DICTS);
+ remark = FascistCheck (pass_new, CRACKLIB_DICTS);
D(("called cracklib [%s]", remark));
#else
if (strlen(pass_new) < 6)
- remark = "You must choose a longer password";
+ remark = _("You must choose a longer password");
D(("length check [%s]", remark));
#endif
if (on(UNIX_REMEMBER_PASSWD, ctrl)) {
if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
- remark = "Password has been already used. Choose another.";
+ remark = _("Password has been already used. Choose another.");
if (retval == PAM_ABORT) {
- _log_err(LOG_ERR, pamh, "can't open %s file to check old passwords",
+ pam_syslog(pamh, LOG_ERR, "can't open %s file to check old passwords",
OLD_PASSWORDS_FILE);
return retval;
}
@@ -764,7 +1023,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
/* <DO NOT free() THESE> */
const char *user;
- char *pass_old, *pass_new;
+ const void *pass_old, *pass_new;
/* </DO NOT free() THESE> */
D(("called."));
@@ -778,20 +1037,19 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
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.
+ * '+' or '-' as the first character of a user name. Don't
+ * allow them.
*/
- if (user == NULL || !isalnum(*user)) {
- _log_err(LOG_ERR, pamh, "bad username [%s]", user);
+ if (user == NULL || user[0] == '-' || user[0] == '+') {
+ pam_syslog(pamh, LOG_ERR, "bad username [%s]", user);
return PAM_USER_UNKNOWN;
}
if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
- _log_err(LOG_DEBUG, pamh, "username [%s] obtained",
+ pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained",
user);
} else {
if (on(UNIX_DEBUG, ctrl))
- _log_err(LOG_DEBUG, pamh,
+ pam_syslog(pamh, LOG_DEBUG,
"password - could not identify user");
return retval;
}
@@ -805,23 +1063,23 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
* getpwnam() doesn't tell you *where* the information it gives you
* came from, nor should it. That's our job.
*/
- if (_unix_comesfromsource(pamh, user, 1, 1) == 0) {
- _log_err(LOG_DEBUG, pamh,
- "user \"%s\" does not exist in /etc/passwd or NIS",
- user);
+ if (_unix_comesfromsource(pamh, user, 1, on(UNIX_NIS, ctrl)) == 0) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "user \"%s\" does not exist in /etc/passwd%s",
+ user, on(UNIX_NIS, ctrl) ? " or NIS" : "");
return PAM_USER_UNKNOWN;
} else {
struct passwd *pwd;
_unix_getpwnam(pamh, user, 1, 1, &pwd);
if (pwd == NULL) {
- _log_err(LOG_DEBUG, pamh,
+ pam_syslog(pamh, LOG_DEBUG,
"user \"%s\" has corrupted passwd entry",
user);
return PAM_USER_UNKNOWN;
}
if (!_unix_shadowed(pwd) &&
(strchr(pwd->pw_passwd, '*') != NULL)) {
- _log_err(LOG_DEBUG, pamh,
+ pam_syslog(pamh, LOG_DEBUG,
"user \"%s\" does not have modifiable password",
user);
return PAM_USER_UNKNOWN;
@@ -846,32 +1104,27 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
if (_unix_blankpasswd(pamh, ctrl, user)) {
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,
+ if (asprintf(&Announce, _("Changing password for %s."),
+ user) < 0) {
+ pam_syslog(pamh, LOG_CRIT,
"password - out of memory");
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: "
+ ,_("(current) UNIX password: ")
,NULL
,_UNIX_OLD_AUTHTOK
- ,(const char **) &pass_old);
+ ,&pass_old);
free(Announce);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, pamh
- ,"password - (old) token not obtained");
+ pam_syslog(pamh, LOG_NOTICE,
+ "password - (old) token not obtained");
return retval;
}
/* verify that this is the password for this user */
@@ -891,14 +1144,14 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
pass_old = NULL;
if (retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"failed to set PAM_OLDAUTHTOK");
}
- retval = _unix_verify_shadow(user, ctrl);
+ retval = _unix_verify_shadow(pamh,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");
+ _("You must wait longer to change your password"));
else
retval = PAM_SUCCESS;
}
@@ -925,10 +1178,10 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
if (off(UNIX_NOT_SET_PASS, ctrl)) {
retval = pam_get_item(pamh, PAM_OLDAUTHTOK
- ,(const void **) &pass_old);
+ ,&pass_old);
} else {
retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK
- ,(const void **) &pass_old);
+ ,&pass_old);
if (retval == PAM_NO_MODULE_DATA) {
retval = PAM_SUCCESS;
pass_old = NULL;
@@ -937,7 +1190,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
D(("pass_old [%s]", pass_old));
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, pamh, "user not authenticated");
+ pam_syslog(pamh, LOG_NOTICE, "user not authenticated");
return retval;
}
@@ -958,15 +1211,15 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
retval = _unix_read_password(pamh, lctrl
,NULL
- ,"Enter new UNIX password: "
- ,"Retype new UNIX password: "
+ ,_("Enter new UNIX password: ")
+ ,_("Retype new UNIX password: ")
,_UNIX_NEW_AUTHTOK
- ,(const char **) &pass_new);
+ ,&pass_new);
if (retval != PAM_SUCCESS) {
if (on(UNIX_DEBUG, ctrl)) {
- _log_err(LOG_ALERT, pamh
- ,"password - new password not obtained");
+ pam_syslog(pamh, LOG_ALERT,
+ "password - new password not obtained");
}
pass_old = NULL; /* tidy up */
return retval;
@@ -979,14 +1232,14 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
* password is acceptable.
*/
- if (pass_new[0] == '\0') { /* "\0" password = NULL */
+ if (*(const char *)pass_new == '\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,
+ pam_syslog(pamh, LOG_NOTICE,
"new password not acceptable");
pass_new = pass_old = NULL; /* tidy up */
return retval;
@@ -1011,7 +1264,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
if (pass_old) {
retval = _unix_verify_password(pamh, user, pass_old, ctrl);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, pamh, "user password changed by another process");
+ pam_syslog(pamh, LOG_NOTICE, "user password changed by another process");
#ifdef USE_LCKPWDF
ulckpwdf();
#endif
@@ -1019,9 +1272,9 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
}
}
- retval = _unix_verify_shadow(user, ctrl);
+ retval = _unix_verify_shadow(pamh, user, ctrl);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, pamh, "user not authenticated 2");
+ pam_syslog(pamh, LOG_NOTICE, "user not authenticated 2");
#ifdef USE_LCKPWDF
ulckpwdf();
#endif
@@ -1030,7 +1283,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_NOTICE, pamh,
+ pam_syslog(pamh, LOG_NOTICE,
"new password not acceptable 2");
pass_new = pass_old = NULL; /* tidy up */
#ifdef USE_LCKPWDF
@@ -1074,7 +1327,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
char *temp = malloc(9);
if (temp == NULL) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"out of memory for password");
pass_new = pass_old = NULL; /* tidy up */
#ifdef USE_LCKPWDF
@@ -1106,7 +1359,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
_pam_delete(tpass);
pass_old = pass_new = NULL;
} else { /* something has broken with the module */
- _log_err(LOG_ALERT, pamh,
+ pam_syslog(pamh, LOG_ALERT,
"password received unknown request");
retval = PAM_ABORT;
}
diff --git a/Linux-PAM/modules/pam_unix/pam_unix_sess.c b/Linux-PAM/modules/pam_unix/pam_unix_sess.c
index a29a7085..b7af4503 100644
--- a/Linux-PAM/modules/pam_unix/pam_unix_sess.c
+++ b/Linux-PAM/modules/pam_unix/pam_unix_sess.c
@@ -1,5 +1,5 @@
/*
- * $Id: pam_unix_sess.c,v 1.5 2005/03/23 14:35:21 t8m Exp $
+ * $Id: pam_unix_sess.c,v 1.9 2006/06/17 16:44:58 kukuk Exp $
*
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
* Copyright Jan Rêkorajski, 1999. All rights reserved.
@@ -36,7 +36,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
@@ -53,11 +53,8 @@
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-#include <security/_pam_modutil.h>
-
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif /* LINUX_PAM */
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
#include "support.h"
@@ -80,23 +77,23 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags,
retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"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 || *service == '\0' || retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"open_session - error recovering service");
return PAM_SESSION_ERR;
}
- login_name = _pammodutil_getlogin(pamh);
+ login_name = pam_modutil_getlogin(pamh);
if (login_name == NULL) {
login_name = "";
}
- _log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)",
- user_name, login_name, getuid());
+ pam_syslog(pamh, LOG_INFO, "session opened for user %s by %s(uid=%lu)",
+ user_name, login_name, (unsigned long)getuid());
return PAM_SUCCESS;
}
@@ -114,19 +111,19 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags,
retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"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 || *service == '\0' || retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"close_session - error recovering service");
return PAM_SESSION_ERR;
}
- _log_err(LOG_INFO, pamh, "session closed for user %s"
- ,user_name);
+ pam_syslog(pamh, LOG_INFO, "session closed for user %s",
+ user_name);
return PAM_SUCCESS;
}
diff --git a/Linux-PAM/modules/pam_unix/support.c b/Linux-PAM/modules/pam_unix/support.c
index 1584f2f1..954f2c73 100644
--- a/Linux-PAM/modules/pam_unix/support.c
+++ b/Linux-PAM/modules/pam_unix/support.c
@@ -1,10 +1,8 @@
-/*
- * $Id: support.c,v 1.25 2005/01/10 09:45:37 kukuk Exp $
- *
+/*
* Copyright information at end of file.
*/
-#define _BSD_SOURCE
+#include "config.h"
#include <stdlib.h>
#include <unistd.h>
@@ -19,94 +17,34 @@
#include <errno.h>
#include <signal.h>
#include <ctype.h>
+#include <syslog.h>
+#include <sys/resource.h>
#include <rpcsvc/ypclnt.h>
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-#include <security/_pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.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();
-}
+#include "bigcrypt.h"
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#define SELINUX_ENABLED is_selinux_enabled()>0
+#else
+#define SELINUX_ENABLED 0
+#endif
/* 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 _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);
- }
+ retval = pam_prompt(pamh, type, NULL, "%s", text);
}
return retval;
}
@@ -157,7 +95,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
}
if (j >= UNIX_CTRLS_) {
- _log_err(LOG_ERR, pamh,
+ pam_syslog(pamh, LOG_ERR,
"unrecognized option [%s]", *argv);
} else {
ctrl &= unix_args[j].mask; /* for turning things off */
@@ -193,7 +131,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
return ctrl;
}
-static void _cleanup(pam_handle_t * pamh, void *x, int error_status)
+static void _cleanup(pam_handle_t * pamh UNUSED, void *x, int error_status UNUSED)
{
_pam_delete(x);
}
@@ -225,10 +163,10 @@ struct _pam_failed_auth {
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;
+ const void *service = NULL;
+ const void *ruser = NULL;
+ const void *rhost = NULL;
+ const void *tty = NULL;
struct _pam_failed_auth *failure;
D(("called"));
@@ -244,32 +182,32 @@ static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
/* log the number of authentication failures */
if (failure->count > 1) {
(void) pam_get_item(pamh, PAM_SERVICE,
- (const void **)&service);
+ &service);
(void) pam_get_item(pamh, PAM_RUSER,
- (const void **)&ruser);
+ &ruser);
(void) pam_get_item(pamh, PAM_RHOST,
- (const void **)&rhost);
+ &rhost);
(void) pam_get_item(pamh, PAM_TTY,
- (const void **)&tty);
- _log_err(LOG_NOTICE, pamh,
+ &tty);
+ pam_syslog(pamh, LOG_NOTICE,
"%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 : "",
+ tty ? (const char *)tty : "", ruser ? (const char *)ruser : "",
+ rhost ? (const char *)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_syslog(pamh, LOG_ALERT,
+ "service(%s) ignoring max retries; %d > %d",
+ service == NULL ? "**unknown**" : (const char *)service,
+ failure->count,
+ UNIX_MAX_RETRIES);
}
}
}
@@ -282,7 +220,7 @@ static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
/*
* _unix_getpwnam() searches only /etc/passwd and NIS to find user information
*/
-static void _unix_cleanup(pam_handle_t *pamh, void *data, int error_status)
+static void _unix_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED)
{
free(data);
}
@@ -327,7 +265,7 @@ int _unix_getpwnam(pam_handle_t *pamh, const char *name,
i = yp_match(domain, "passwd.byname", name,
strlen(name), &userinfo, &len);
yp_unbind(domain);
- if ((i == YPERR_SUCCESS) && (len < sizeof(buf))) {
+ if ((i == YPERR_SUCCESS) && ((size_t)len < sizeof(buf))) {
strncpy(buf, userinfo, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
matched = 1;
@@ -391,7 +329,7 @@ int _unix_getpwnam(pam_handle_t *pamh, const char *name,
memset(*ret, '\0', buflen);
(*ret)->pw_uid = strtol(suid, &p, 10);
- if ((strlen(sgid) == 0) || (*p != '\0')) {
+ if ((strlen(suid) == 0) || (*p != '\0')) {
free(*ret);
*ret = NULL;
return matched;
@@ -467,13 +405,13 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
/* UNIX passwords area */
/* Get password file entry... */
- pwd = _pammodutil_getpwnam (pamh, name);
+ pwd = pam_modutil_getpwnam (pamh, name);
if (pwd != NULL) {
if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
- { /* NIS+ */
+ { /* NIS+ */
uid_t save_euid, save_uid;
-
+
save_euid = geteuid();
save_uid = getuid();
if (save_uid == pwd->pw_uid)
@@ -488,8 +426,8 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
return 0;
}
}
-
- spwdent = _pammodutil_getspnam (pamh, name);
+
+ spwdent = pam_modutil_getspnam (pamh, name);
if (save_uid == pwd->pw_uid)
setreuid( save_uid, save_euid );
else {
@@ -502,7 +440,7 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
* ...and shadow password file entry for this user,
* if shadowing is enabled
*/
- spwdent = _pammodutil_getspnam(pamh, name);
+ spwdent = pam_modutil_getspnam(pamh, name);
}
if (spwdent)
salt = x_strdup(spwdent->sp_pwdp);
@@ -562,18 +500,39 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
/* fork */
child = fork();
if (child == 0) {
+ int i=0;
+ struct rlimit rlim;
static char *envp[] = { NULL };
- char *args[] = { NULL, NULL, NULL };
+ char *args[] = { NULL, NULL, NULL, NULL };
/* XXX - should really tidy up PAM here too */
+ close(0); close(1);
/* reopen stdin as pipe */
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
+ if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
+ for (i=2; i < (int)rlim.rlim_max; i++) {
+ if (fds[0] != i)
+ close(i);
+ }
+ }
+
+ if (SELINUX_ENABLED && geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ setuid(0);
+ }
+
/* exec binary helper */
- args[0] = x_strdup(CHKPWD_HELPER);
+ args[0] = strdup(CHKPWD_HELPER);
args[1] = x_strdup(user);
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ args[2]=strdup("nullok");
+ } else {
+ args[2]=strdup("nonull");
+ }
execve(CHKPWD_HELPER, args, envp);
@@ -583,11 +542,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
} 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);
- }
+ int rc=0;
if (passwd != NULL) { /* send the password to the child */
write(fds[1], passwd, strlen(passwd)+1);
passwd = NULL;
@@ -596,14 +551,21 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
}
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;
+ rc=waitpid(child, &retval, 0); /* wait for helper to complete */
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ }
} else {
D(("fork failed"));
+ close(fds[0]);
+ close(fds[1]);
retval = PAM_AUTH_ERR;
}
- if (sighandler != NULL) {
+ if (sighandler != SIG_ERR) {
(void) signal(SIGCHLD, sighandler); /* restore old signal handler */
}
@@ -621,6 +583,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
char *data_name;
int retval;
+
D(("called"));
#ifdef HAVE_PAM_FAIL_DELAY
@@ -635,13 +598,13 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
D(("locating user's record"));
/* UNIX passwords area */
- pwd = _pammodutil_getpwnam (pamh, name); /* Get password file entry... */
+ pwd = pam_modutil_getpwnam (pamh, name); /* Get password file entry... */
if (pwd != NULL) {
if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
- { /* NIS+ */
+ { /* NIS+ */
uid_t save_euid, save_uid;
-
+
save_euid = geteuid();
save_uid = getuid();
if (save_uid == pwd->pw_uid)
@@ -655,8 +618,8 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
return PAM_CRED_INSUFFICIENT;
}
}
-
- spwdent = _pammodutil_getspnam (pamh, name);
+
+ spwdent = pam_modutil_getspnam (pamh, name);
if (save_uid == pwd->pw_uid)
setreuid( save_uid, save_euid );
else {
@@ -669,7 +632,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
* ...and shadow password file entry for this user,
* if shadowing is enabled
*/
- spwdent = _pammodutil_getspnam (pamh, name);
+ spwdent = pam_modutil_getspnam (pamh, name);
}
if (spwdent)
salt = x_strdup(spwdent->sp_pwdp);
@@ -679,7 +642,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name));
if (data_name == NULL) {
- _log_err(LOG_CRIT, pamh, "no memory for data-name");
+ pam_syslog(pamh, LOG_CRIT, "no memory for data-name");
} else {
strcpy(data_name, FAIL_PREFIX);
strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name);
@@ -687,15 +650,11 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
retval = PAM_SUCCESS;
if (pwd == NULL || salt == NULL || !strcmp(salt, "x") || ((salt[0] == '#') && (salt[1] == '#') && !strcmp(salt + 2, name))) {
- if (geteuid()) {
+
+ if (pwd != NULL && (geteuid() || SELINUX_ENABLED)) {
/* 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"));
p = NULL;
@@ -706,12 +665,12 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
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,
+ pam_syslog(pamh, LOG_ALERT,
"check pass; user (%s) unknown", name);
} else {
name = NULL;
if (on(UNIX_DEBUG, ctrl) || pwd == NULL) {
- _log_err(LOG_ALERT, pamh,
+ pam_syslog(pamh, LOG_ALERT,
"check pass; user unknown");
} else {
/* don't log failure as another pam module can succeed */
@@ -730,7 +689,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
D(("user has empty password - access denied"));
retval = PAM_AUTH_ERR;
}
- } else if (!p || (*salt == '*') || (salt_len < 13)) {
+ } else if (!p || (*salt == '*')) {
retval = PAM_AUTH_ERR;
} else {
if (!strncmp(salt, "$1$", 3)) {
@@ -739,24 +698,24 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
_pam_delete(pp);
pp = Brokencrypt_md5(p, salt);
}
- } else {
+ } else if (*salt != '$' && salt_len >= 13) {
pp = bigcrypt(p, salt);
+ if (strlen(pp) > salt_len) {
+ pp[salt_len] = '\0';
+ }
+ } else {
+ /*
+ * Ok, we don't know the crypt algorithm, but maybe
+ * libcrypt nows about it? We should try it.
+ */
+ pp = x_strdup (crypt(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));
- /*
- * Note, we are comparing the bigcrypt of the password with
- * the contents of the password field. If the latter was
- * encrypted with regular crypt (and not bigcrypt) it will
- * have been truncated for storage relative to the output
- * of bigcrypt here. As such we need to compare only the
- * stored string with the subset of bigcrypt's result.
- * Bug 521314: The strncmp comparison is for legacy support.
- */
- if (strncmp(pp, salt, salt_len) == 0) {
+ if (strcmp(pp, salt) == 0) {
retval = PAM_SUCCESS;
} else {
retval = PAM_AUTH_ERR;
@@ -780,8 +739,10 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
if (new != NULL) {
const char *login_name;
+ const void *void_old;
+
- login_name = _pammodutil_getlogin(pamh);
+ login_name = pam_modutil_getlogin(pamh);
if (login_name == NULL) {
login_name = "";
}
@@ -792,7 +753,11 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
new->name = x_strdup(login_name);
/* any previous failures for this user ? */
- pam_get_data(pamh, data_name, (const void **) &old);
+ if (pam_get_data(pamh, data_name, &void_old)
+ == PAM_SUCCESS)
+ old = void_old;
+ else
+ old = NULL;
if (old != NULL) {
new->count = old->count + 1;
@@ -800,29 +765,29 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
retval = PAM_MAXTRIES;
}
} else {
- const char *service=NULL;
- const char *ruser=NULL;
- const char *rhost=NULL;
- const char *tty=NULL;
+ const void *service=NULL;
+ const void *ruser=NULL;
+ const void *rhost=NULL;
+ const void *tty=NULL;
(void) pam_get_item(pamh, PAM_SERVICE,
- (const void **)&service);
+ &service);
(void) pam_get_item(pamh, PAM_RUSER,
- (const void **)&ruser);
+ &ruser);
(void) pam_get_item(pamh, PAM_RHOST,
- (const void **)&rhost);
+ &rhost);
(void) pam_get_item(pamh, PAM_TTY,
- (const void **)&tty);
+ &tty);
- _log_err(LOG_NOTICE, pamh,
+ pam_syslog(pamh, LOG_NOTICE,
"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 : "",
+ tty ? (const char *)tty : "",
+ ruser ? (const char *)ruser : "",
+ rhost ? (const char *)rhost : "",
(new->user && new->user[0] != '\0')
? " user=" : "",
new->user
@@ -833,7 +798,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name
pam_set_data(pamh, data_name, new, _cleanup_failures);
} else {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"no memory for failure recorder");
}
}
@@ -862,10 +827,10 @@ int _unix_read_password(pam_handle_t * pamh
,const char *prompt1
,const char *prompt2
,const char *data_name
- ,const char **pass)
+ ,const void **pass)
{
int authtok_flag;
- int retval;
+ int retval = PAM_SUCCESS;
char *token;
D(("called"));
@@ -887,17 +852,17 @@ int _unix_read_password(pam_handle_t * pamh
*/
if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) {
- retval = pam_get_item(pamh, authtok_flag, (const void **) pass);
+ retval = pam_get_item(pamh, authtok_flag, pass);
if (retval != PAM_SUCCESS) {
/* very strange. */
- _log_err(LOG_ALERT, pamh
- ,"pam_get_item returned error to unix-read-password"
+ pam_syslog(pamh, LOG_ALERT,
+ "pam_get_item returned error to unix-read-password"
);
return retval;
} else if (*pass != NULL) { /* we have a password! */
return PAM_SUCCESS;
} else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ return PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
} else if (on(UNIX_USE_AUTHTOK, ctrl)
&& off(UNIX__OLD_PASSWD, ctrl)) {
return PAM_AUTHTOK_ERR;
@@ -909,77 +874,62 @@ int _unix_read_password(pam_handle_t * pamh
*/
{
- struct pam_message msg[3], *pmsg[3];
- struct pam_response *resp;
- int i, replies;
-
- /* prepare to converse */
+ int replies=1;
+ char *resp[2] = { NULL, NULL };
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;
+ retval = pam_info(pamh, "%s", comment);
}
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt1;
- replies = 1;
+ if (retval == PAM_SUCCESS) {
+ retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF,
+ &resp[0], "%s", prompt1);
- if (prompt2 != NULL) {
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt2;
- ++replies;
+ if (retval == PAM_SUCCESS && prompt2 != NULL) {
+ retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF,
+ &resp[1], "%s", prompt2);
+ ++replies;
+ }
}
- /* so call the conversation expecting i responses */
- resp = NULL;
- retval = converse(pamh, ctrl, i, pmsg, &resp);
-
- if (resp != NULL) {
+ if (resp[0] != NULL && resp[replies-1] != NULL) {
/* interpret the response */
if (retval == PAM_SUCCESS) { /* a good conversation */
- token = x_strdup(resp[i - replies].resp);
+ token = resp[0];
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);
+ if (strcmp(token, resp[replies - 1])) {
+ /* mistyped */
+ retval = PAM_AUTHTOK_RECOVERY_ERR;
+ _make_remark(pamh, ctrl,
+ PAM_ERROR_MSG, MISTYPED_PASS);
}
}
} else {
- _log_err(LOG_NOTICE, pamh
- ,"could not recover authentication token");
+ pam_syslog(pamh, LOG_NOTICE,
+ "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;
+ ? PAM_AUTHTOK_RECOVERY_ERR : retval;
}
+
+ resp[0] = NULL;
+ if (replies > 1)
+ _pam_delete(resp[1]);
}
if (retval != PAM_SUCCESS) {
+ _pam_delete(token);
+
if (on(UNIX_DEBUG, ctrl))
- _log_err(LOG_DEBUG, pamh,
+ pam_syslog(pamh, LOG_DEBUG,
"unable to obtain a password");
return retval;
}
@@ -992,12 +942,11 @@ int _unix_read_password(pam_handle_t * pamh
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 **) pass))
+ || (retval = pam_get_item(pamh, authtok_flag, pass))
!= PAM_SUCCESS) {
*pass = NULL;
- _log_err(LOG_CRIT, pamh, "error manipulating password");
+ pam_syslog(pamh, LOG_CRIT, "error manipulating password");
return retval;
}
@@ -1009,9 +958,9 @@ int _unix_read_password(pam_handle_t * pamh
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_syslog(pamh, LOG_CRIT,
+ "error manipulating password data [%s]",
+ pam_strerror(pamh, retval));
_pam_delete(token);
return retval;
}
@@ -1055,13 +1004,13 @@ int _unix_shadowed(const struct passwd *pwd)
* 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
diff --git a/Linux-PAM/modules/pam_unix/support.h b/Linux-PAM/modules/pam_unix/support.h
index 39abadd5..1eb662fc 100644
--- a/Linux-PAM/modules/pam_unix/support.h
+++ b/Linux-PAM/modules/pam_unix/support.h
@@ -1,5 +1,5 @@
/*
- * $Id: support.h,v 1.8 2004/10/06 13:42:36 kukuk Exp $
+ * $Id: support.h,v 1.12 2005/09/26 14:27:09 t8m Exp $
*/
#ifndef _PAM_UNIX_SUPPORT_H
@@ -110,7 +110,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
/* 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_NIS */ {"nis", _ALL_ON_, 0200000},
/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000},
/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000},
/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000},
@@ -129,7 +129,6 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
_pam_drop(xx); \
}
-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,
@@ -149,7 +148,8 @@ extern int _unix_read_password(pam_handle_t * pamh
,const char *prompt1
,const char *prompt2
,const char *data_name
- ,const char **pass);
+ ,const void **pass);
extern int _unix_shadowed(const struct passwd *pwd);
+extern struct spwd *_unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user);
#endif /* _PAM_UNIX_SUPPORT_H */
diff --git a/Linux-PAM/modules/pam_unix/tst-pam_unix b/Linux-PAM/modules/pam_unix/tst-pam_unix
new file mode 100755
index 00000000..22922800
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/tst-pam_unix
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_unix.so
diff --git a/Linux-PAM/modules/pam_unix/unix_chkpwd.8 b/Linux-PAM/modules/pam_unix/unix_chkpwd.8
new file mode 100644
index 00000000..02ccfe4a
--- /dev/null
+++ b/Linux-PAM/modules/pam_unix/unix_chkpwd.8
@@ -0,0 +1,80 @@
+.\" Copyright (C) 2003 International Business Machines Corporation
+.\" This file is distributed according to the GNU General Public License.
+.\" See the file COPYING in the top level source directory for details.
+.\"
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "UNIX_CHKPWD" 8 "2003-03-21" "Linux-PAM 0.76" "Linux-PAM Manual"
+.SH NAME
+unix_chkpwd \- helper binary that verifies the password of the current user
+.SH "SYNOPSIS"
+.ad l
+.hy 0
+
+/sbin/unix_chkpwd [\fIusername\fR]
+.sp
+.ad
+.hy
+.SH "DESCRIPTION"
+.PP
+\fBunix_chkpwd\fR is a helper program for the pam_unix module that verifies
+the password of the current user. It is not intended to be run directly from
+the command line and logs a security violation if done so.
+
+It is typically installed setuid root or setgid shadow.
+
+.SH "OPTIONS"
+.PP
+unix_pwdchk optionally takes the following argument:
+.TP
+\fIusername\fR
+The username of the user whose password you want to check: this must match the current user id.
+
+.SH "INPUTS"
+.PP
+unix_pwdchk expects the following inputs via stdin:
+.TP
+\fIoption\fR
+Either nullok or nonull, depending on whether the user can have an empty password.
+.TP
+\fIpassword\fR
+The password to verify.
+
+.SH "RETURN CODES"
+.PP
+\fBunix_chkpwd\fR has the following return codes:
+.TP
+1
+unix_chkpwd was inappropriately called from the command line or the password is incorrect.
+
+.TP
+0
+The password is correct.
+
+.SH "HISTORY"
+Written by Andrew Morgan
+
+.SH "SEE ALSO"
+
+.PP
+\fBpam\fR(8)
+
+.SH AUTHOR
+Emily Ratliff.
+
diff --git a/Linux-PAM/modules/pam_unix/unix_chkpwd.c b/Linux-PAM/modules/pam_unix/unix_chkpwd.c
index be32348f..87d29256 100644
--- a/Linux-PAM/modules/pam_unix/unix_chkpwd.c
+++ b/Linux-PAM/modules/pam_unix/unix_chkpwd.c
@@ -1,6 +1,4 @@
/*
- * $Id: unix_chkpwd.c,v 1.11 2004/11/16 14:27:42 toady 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
@@ -13,13 +11,7 @@
*
*/
-#include <security/_pam_aconf.h>
-
-#ifdef MEMORY_DEBUG
-# undef exit
-# undef strdup
-# undef free
-#endif /* MEMORY_DEBUG */
+#include "config.h"
#include <stdarg.h>
#include <stdio.h>
@@ -28,21 +20,27 @@
#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <pwd.h>
#include <shadow.h>
#include <signal.h>
+#include <time.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#define SELINUX_ENABLED (selinux_enabled!=-1 ? selinux_enabled : (selinux_enabled=is_selinux_enabled()>0))
+static security_context_t prev_context=NULL;
+static int selinux_enabled=-1;
+#else
+#define SELINUX_ENABLED 0
+#endif
#define MAXPASS 200 /* the maximum length of a password */
+#include <security/_pam_types.h>
#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
+#include "bigcrypt.h"
/* syslogging function for errors and other information */
@@ -51,7 +49,7 @@ 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);
+ openlog("unix_chkpwd", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
vsyslog(err, format, args);
va_end(args);
closelog();
@@ -112,13 +110,40 @@ static void setup_signals(void)
(void) sigaction(SIGQUIT, &action, NULL);
}
+static int _verify_account(const char * const uname)
+{
+ struct spwd *spent;
+ struct passwd *pwent;
+
+ pwent = getpwnam(uname);
+ if (!pwent) {
+ _log_err(LOG_ALERT, "could not identify user (from getpwnam(%s))", uname);
+ return PAM_USER_UNKNOWN;
+ }
+
+ spent = getspnam( uname );
+ if (!spent) {
+ _log_err(LOG_ALERT, "could not get username from shadow (%s))", uname);
+ return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from shadow */
+ }
+ printf("%ld:%ld:%ld:%ld:%ld:%ld",
+ spent->sp_lstchg, /* last password change */
+ spent->sp_min, /* days until change allowed. */
+ spent->sp_max, /* days before change required */
+ spent->sp_warn, /* days warning for expiration */
+ spent->sp_inact, /* days before account inactive */
+ spent->sp_expire); /* date when account expires */
+
+ return PAM_SUCCESS;
+}
+
static int _unix_verify_password(const char *name, const char *p, int nullok)
{
struct passwd *pwd = NULL;
struct spwd *spwdent = NULL;
char *salt = NULL;
char *pp = NULL;
- int retval = UNIX_FAILED;
+ int retval = PAM_AUTH_ERR;
int salt_len;
/* UNIX passwords area */
@@ -156,28 +181,39 @@ static int _unix_verify_password(const char *name, const char *p, int nullok)
if (pwd == NULL || salt == NULL) {
_log_err(LOG_ALERT, "check pass; user unknown");
p = NULL;
- return retval;
+ return PAM_USER_UNKNOWN;
}
salt_len = strlen(salt);
- if (salt_len == 0)
- return (nullok == 0) ? UNIX_FAILED : UNIX_PASSED;
- else if (p == NULL || strlen(p) == 0)
- return UNIX_FAILED;
+ if (salt_len == 0) {
+ return (nullok == 0) ? PAM_AUTH_ERR : PAM_SUCCESS;
+ }
+ if (p == NULL || strlen(p) == 0) {
+ return PAM_AUTHTOK_ERR;
+ }
/* the moment of truth -- do we agree with the password? */
- retval = UNIX_FAILED;
+ retval = PAM_AUTH_ERR;
if (!strncmp(salt, "$1$", 3)) {
pp = Goodcrypt_md5(p, salt);
if (strcmp(pp, salt) == 0) {
- retval = UNIX_PASSED;
+ retval = PAM_SUCCESS;
} else {
pp = Brokencrypt_md5(p, salt);
if (strcmp(pp, salt) == 0)
- retval = UNIX_PASSED;
+ retval = PAM_SUCCESS;
+ }
+ } else if (*salt == '$') {
+ /*
+ * Ok, we don't know the crypt algorithm, but maybe
+ * libcrypt nows about it? We should try it.
+ */
+ pp = x_strdup (crypt(p, salt));
+ if (strcmp(pp, salt) == 0) {
+ retval = PAM_SUCCESS;
}
} else if ((*salt == '*') || (salt_len < 13)) {
- retval = UNIX_FAILED;
+ retval = PAM_AUTH_ERR;
} else {
pp = bigcrypt(p, salt);
/*
@@ -190,7 +226,7 @@ static int _unix_verify_password(const char *name, const char *p, int nullok)
* Bug 521314: the strncmp comparison is for legacy support.
*/
if (strncmp(pp, salt, salt_len) == 0) {
- retval = UNIX_PASSED;
+ retval = PAM_SUCCESS;
}
}
p = NULL; /* no longer needed here */
@@ -220,17 +256,178 @@ static char *getuidname(uid_t uid)
strncpy(username, pw->pw_name, sizeof(username));
username[sizeof(username) - 1] = '\0';
-
+
return username;
}
+#define SH_TMPFILE "/etc/nshadow"
+static int _update_shadow(const char *forwho)
+{
+ struct spwd *spwdent = NULL, *stmpent = NULL;
+ FILE *pwfile, *opwfile;
+ int err = 1;
+ int oldmask;
+ struct stat st;
+ char pass[MAXPASS + 1];
+ char towhat[MAXPASS + 1];
+ int npass=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");
+ return PAM_AUTHTOK_ERR;
+
+ } else if (npass >= MAXPASS) {
+
+ _log_err(LOG_DEBUG, "password too long");
+ return PAM_AUTHTOK_ERR;
+
+ } else {
+ /* does pass agree with the official one? */
+ int retval=0;
+ pass[npass] = '\0'; /* NUL terminate */
+ retval = _unix_verify_password(forwho, pass, 0);
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+ }
+
+ /* read the password from stdin (a pipe from the pam_unix module) */
+
+ npass = read(STDIN_FILENO, towhat, MAXPASS);
+
+ if (npass < 0) { /* is it a valid password? */
+
+ _log_err(LOG_DEBUG, "no new password supplied");
+ return PAM_AUTHTOK_ERR;
+
+ } else if (npass >= MAXPASS) {
+
+ _log_err(LOG_DEBUG, "new password too long");
+ return PAM_AUTHTOK_ERR;
+
+ }
+
+ towhat[npass] = '\0'; /* NUL terminate */
+ spwdent = getspnam(forwho);
+ if (spwdent == NULL) {
+ return PAM_USER_UNKNOWN;
+ }
+ oldmask = umask(077);
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ security_context_t shadow_context=NULL;
+ if (getfilecon("/etc/shadow",&shadow_context)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon(&prev_context)<0) {
+ freecon(shadow_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon(shadow_context)) {
+ freecon(shadow_context);
+ freecon(prev_context);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(shadow_context);
+ }
+#endif
+ pwfile = fopen(SH_TMPFILE, "w");
+ umask(oldmask);
+ if (pwfile == NULL) {
+ err = 1;
+ goto done;
+ }
+
+ opwfile = fopen("/etc/shadow", "r");
+ if (opwfile == NULL) {
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ stmpent = fgetspent(opwfile);
+ while (stmpent) {
+
+ if (!strcmp(stmpent->sp_namp, forwho)) {
+ stmpent->sp_pwdp = towhat;
+ stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
+ err = 0;
+ D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
+ }
+
+ if (putspent(stmpent, pwfile)) {
+ D(("error writing entry to shadow file: %m"));
+ err = 1;
+ break;
+ }
+
+ stmpent = fgetspent(opwfile);
+ }
+ fclose(opwfile);
+
+ if (fclose(pwfile)) {
+ D(("error writing entries to shadow file: %m"));
+ err = 1;
+ }
+
+ done:
+ if (!err) {
+ if (rename(SH_TMPFILE, "/etc/shadow"))
+ err = 1;
+ }
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon(prev_context)) {
+ err = 1;
+ }
+ if (prev_context)
+ freecon(prev_context);
+ prev_context=NULL;
+ }
+#endif
+
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(SH_TMPFILE);
+ return PAM_AUTHTOK_ERR;
+ }
+}
+
int main(int argc, char *argv[])
{
char pass[MAXPASS + 1];
- char option[8];
+ char *option;
int npass, nullok;
int force_failure = 0;
- int retval = UNIX_FAILED;
+ int retval = PAM_AUTH_ERR;
char *user;
/*
@@ -247,8 +444,7 @@ int main(int argc, char *argv[])
* account).
*/
- if (isatty(STDIN_FILENO)) {
-
+ if (isatty(STDIN_FILENO) || argc != 3 ) {
_log_err(LOG_NOTICE
,"inappropriate use of Unix helper binary [UID=%d]"
,getuid());
@@ -256,36 +452,45 @@ int main(int argc, char *argv[])
,"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;
+ return PAM_SYSTEM_ERR;
}
/*
- * determine the current user's name is
+ * Determine what the current user's name is.
+ * On a SELinux enabled system with a strict policy leaving the
+ * existing check prevents shadow password authentication from working.
+ * We must thus skip the check if the real uid is 0.
*/
- 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;
- }
+ if (SELINUX_ENABLED && getuid() == 0) {
+ user=argv[1];
+ }
+ else {
+ user = getuidname(getuid());
+ /* if the caller specifies the username, verify that user
+ matches it */
+ if (strcmp(user, argv[1])) {
+ return PAM_AUTH_ERR;
+ }
}
- /* read the nullok/nonull option */
+ option=argv[2];
- npass = read(STDIN_FILENO, option, 8);
+ if (strncmp(argv[2], "verify", 8) == 0) {
+ /* Get the account information from the shadow file */
+ return _verify_account(argv[1]);
+ }
- if (npass < 0) {
- _log_err(LOG_DEBUG, "no option supplied");
- return UNIX_FAILED;
- } else {
- option[7] = '\0';
- if (strncmp(option, "nullok", 8) == 0)
- nullok = 1;
- else
- nullok = 0;
+ if (strncmp(option, "shadow", 8) == 0) {
+ /* Attempting to change the password */
+ return _update_shadow(argv[1]);
}
+ /* read the nullok/nonull option */
+ if (strncmp(option, "nullok", 8) == 0)
+ nullok = 1;
+ else
+ nullok = 0;
+
/* read the password from stdin (a pipe from the pam_unix module) */
npass = read(STDIN_FILENO, pass, MAXPASS);
@@ -317,10 +522,11 @@ int main(int argc, char *argv[])
/* return pass or fail */
- if ((retval != UNIX_PASSED) || force_failure) {
- return UNIX_FAILED;
+ if ((retval != PAM_SUCCESS) || force_failure) {
+ _log_err(LOG_NOTICE, "password check failed for user (%s)", user);
+ return PAM_AUTH_ERR;
} else {
- return UNIX_PASSED;
+ return PAM_SUCCESS;
}
}
@@ -339,13 +545,13 @@ int main(int argc, char *argv[])
* 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
diff --git a/Linux-PAM/modules/pam_unix/yppasswd_xdr.c b/Linux-PAM/modules/pam_unix/yppasswd_xdr.c
index b1a60b4c..bf3f2fc6 100644
--- a/Linux-PAM/modules/pam_unix/yppasswd_xdr.c
+++ b/Linux-PAM/modules/pam_unix/yppasswd_xdr.c
@@ -10,7 +10,7 @@
* editied manually.
*/
-#include <security/_pam_aconf.h>
+#include "config.h"
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>