PSARC/2016/427 PAM_PKCS11 0.6.8 s11u3-sru
authorHuie-Ying Lee <huieying.lee@oracle.com>
Tue, 20 Sep 2016 12:05:25 -0700
branchs11u3-sru
changeset 6937 1366743d2272
parent 6927 af9bb41e858d
child 6947 08b09d8a757a
PSARC/2016/427 PAM_PKCS11 0.6.8 PSARC/2016/513 ISA specification for pam_pkcs11.conf PSARC/2016/521 OpenLDAP for Solaris 11.3 pam_pkcs11 23210165 Upgrade pam_pkcs11 to 0.6.8 24533324 Add ISA support to module paths in pam_pkcs11.conf 24393960 add OpenLDAP version of ldap_mapper.so to pam_pkcs11 in S11.3 22835291 pam_pkcs11 should be 64-bit
components/pam_pkcs11/Makefile
components/pam_pkcs11/pam_pkcs11.conf
components/pam_pkcs11/pam_pkcs11.p5m
components/pam_pkcs11/patches/01-solaris_build.patch
components/pam_pkcs11/patches/02-man_pages.patch
components/pam_pkcs11/patches/03-module_ISA_fix.patch
components/pam_pkcs11/patches/pam_pkcs11.patch
--- a/components/pam_pkcs11/Makefile	Mon Sep 19 15:30:46 2016 -0700
+++ b/components/pam_pkcs11/Makefile	Tue Sep 20 12:05:25 2016 -0700
@@ -18,31 +18,78 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 include ../../make-rules/shared-macros.mk
 
 COMPONENT_NAME=		pam_pkcs11
-COMPONENT_VERSION=	0.6.0
-COMPONENT_PROJECT_URL=	http://www.opensc-project.org/
+COMPONENT_VERSION=	0.6.8
+COMPONENT_PROJECT_URL=	https://sourceforge.net/projects/opensc/
 COMPONENT_SRC=		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
 COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
 COMPONENT_ARCHIVE_HASH=	\
-    sha256:170db26eb9610dde5d3307771ed0e0e14cc0778aaacd3b3d4e71240ccb61cec6
+    sha256:9d942e542ef35d0e1f990d9ff5bf9df0af84c828ed081add2eb1b4d84f0efbda
 COMPONENT_ARCHIVE_URL=	$(COMPONENT_PROJECT_URL)files/$(COMPONENT_NAME)/$(COMPONENT_ARCHIVE)
 COMPONENT_BUGDB=	library/pam-pkcs11
 
-TPNO=			17173
+TPNO=			28155
 
 include $(WS_MAKE_RULES)/prep.mk
 include $(WS_MAKE_RULES)/configure.mk
 include $(WS_MAKE_RULES)/ips.mk
 
-CONFIGURE_OPTIONS +=	CFLAGS="$(CFLAGS)"
-CONFIGURE_OPTIONS += --with-pcsclite=no
-CONFIGURE_OPTIONS += --with-included-gettext=yes
+# Force regeneration of ancient autoconf scripts to fix 64-bit build detection
+# and due to patches to autoconf and automake files.
+COMPONENT_PREP_ACTION += (cd $(@D); autoreconf -fiv)
+
+# Enable ASLR for this component
+ASLR_MODE = $(ASLR_ENABLE)
+
+# We build two different variants of pam_pkcs11 for our users. 
+VARIANT_OPENLDAP =       $(BUILD_DIR)/openldap
+VARIANT_MOZILLALDAP =    $(BUILD_DIR)/mozillaldap
+
+VARIANTS = $(VARIANT_OPENLDAP) $(VARIANT_MOZILLALDAP)
+
+BUILD_32 = $(VARIANTS:%=%/$(MACH32)/.built)
+BUILD_64 = $(VARIANTS:%=%/$(MACH64)/.built)
+BUILD_32_and_64 = $(BUILD_32) $(BUILD_64)
+
+$(VARIANT_OPENLDAP)/$(MACH64)/.configured: BITS=64
+$(VARIANT_MOZILLALDAP)/$(MACH64)/.configured:  BITS=64
+
+# Configure options for mozillaldap variant
+$(VARIANT_MOZILLALDAP)/%/.configured: \
+    CONFIGURE_OPTIONS += --enable-openldap=no
+$(VARIANT_MOZILLALDAP)/%/.configured: \
+    CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS) -DMODULE_ISA_FIX"
+
+# Configure options for openldap variant
+$(VARIANT_OPENLDAP)/%/.configured: \
+    CONFIGURE_OPTIONS += --enable-openldap=yes
+$(VARIANT_OPENLDAP)/%/.configured: \
+    CONFIGURE_OPTIONS += \
+    CFLAGS="$(CFLAGS) -I/usr/include/openldap -DMODULE_ISA_FIX"
+
+# Common configure options
+CONFIGURE_BINDIR.32= $(USRLIBDIR)/pam_pkcs11
+CONFIGURE_BINDIR.64= $(USRLIBDIR64)/pam_pkcs11
+
 CONFIGURE_OPTIONS += --localstatedir=/var
-CONFIGURE_OPTIONS += OPENSSL_LIBS="-lssl -lcrypto -lsocket -lnsl"
+CONFIGURE_OPTIONS += --with-confdir=/etc/security/pam_pkcs11
+CONFIGURE_OPTIONS += --docdir=/etc/security/pam_pkcs11
+CONFIGURE_OPTIONS += OPENSSL_LIBS="-lssl -lcrypto -lsocket"
+CONFIGURE_OPTIONS.32 += --with-pcsclite=no
+CONFIGURE_OPTIONS.64 += --with-pcsclite=yes
+CONFIGURE_OPTIONS.64 += PCSC_CFLAGS="-I/usr/include/PCSC"
+CONFIGURE_OPTIONS.64 += PCSC_LIBS="-lpcsclite"
+
+# We install only the MozillaLDAP variant. We will cherry-pick binaries built
+# against OpenLDAP out of the build directory to avoid re-installing
+# everything.
+INSTALL_32 = $(VARIANT_MOZILLALDAP)/$(MACH32)/.installed
+INSTALL_64 = $(VARIANT_MOZILLALDAP)/$(MACH64)/.installed
+INSTALL_32_and_64 = $(INSTALL_32) $(INSTALL_64)
 
 # common targets
 build:		$(BUILD_32_and_64)
@@ -51,7 +98,10 @@
 
 test:		$(NO_TESTS)
 
-
+REQUIRED_PACKAGES += library/openldap
 REQUIRED_PACKAGES += library/security/openssl
+REQUIRED_PACKAGES += library/security/pcsc/pcsclite
 REQUIRED_PACKAGES += shell/bash
 REQUIRED_PACKAGES += system/library
+REQUIRED_PACKAGES += system/linker
+
--- a/components/pam_pkcs11/pam_pkcs11.conf	Mon Sep 19 15:30:46 2016 -0700
+++ b/components/pam_pkcs11/pam_pkcs11.conf	Tue Sep 20 12:05:25 2016 -0700
@@ -14,7 +14,7 @@
   use_pkcs11_module = default;
 
   pkcs11_module default {
-    module = /usr/lib/libpkcs11.so;
+    module = /usr/lib/$ISA/libpkcs11.so;
     description = "Solaris PKCS#11 Cryptographic Framework library";
 
     # Which slot to use?
@@ -36,7 +36,7 @@
     #
     # On Solaris OS, an administrator can use the "cryotoadm list -v" command
     # to find all the available slots and their slot descriptions. For more 
-    # information, see the libpkcs11(3LIB) and cryptoadm(1m) man pages.
+    # information, see the libpkcs11(3LIB) and cryptoadm(8) man pages.
     #
     slot_description = "none";
 
@@ -79,6 +79,13 @@
     # The value of the token_type parameter will be used in the user prompt
     # messages.  The default value is "Smart card".
     token_type = "Secure token";
+
+    # The err_display_time option suspends execution for an interval of time
+    # in seconds after each PAM message is shown. 
+    err_display_time = 0;
+
+    # The quiet option can be used to disable error messages.
+    quiet = false;
   }
 
   # Which mappers ( Cert to login ) to use?
@@ -109,7 +116,7 @@
   # value as module search path
   # TODO:
   # This is not still functional: use absolute pathnames or LD_LIBRARY_PATH 
-  mapper_search_path = /usr/lib/pam_pkcs11;
+  mapper_search_path = /usr/lib/pam_pkcs11/$ISA;
 
   # 
   # Generic certificate contents mapper
@@ -138,13 +145,13 @@
   # Search public keys from $HOME/.ssh/authorized_keys to match users
   mapper openssh {
 	debug = false;
-	module = /usr/lib/pam_pkcs11/openssh_mapper.so;
+	module = /usr/lib/pam_pkcs11/$ISA/openssh_mapper.so;
   }
 
   # Search certificates from $HOME/.eid/authorized_certificates to match users
   mapper opensc {
 	debug = false;
-	module = /usr/lib/pam_pkcs11/opensc_mapper.so;
+	module = /usr/lib/pam_pkcs11/$ISA/opensc_mapper.so;
   }
 
   # Certificate Common Name ( CN ) to getpwent() mapper
@@ -167,7 +174,25 @@
   # Directory ( ldap style ) mapper
   mapper ldap {
 	debug = false;
-	module = /usr/lib/pam_pkcs11/ldap_mapper.so;
+
+	# The path of the ldap_mapper.so module
+	#
+	# Two versions of ldap_mapper.so are available:
+	#
+	# - ldap_mapper.so built with the Mozilla LDAP
+	#   libraries and the default.
+	#
+	# - openldap_mapper.so built only for Solaris 11 with
+	#   the OpenLDAP libraries.
+	#
+	#   Mozilla LDAP version:
+	#     /usr/lib/pam_pcks11/$ISA/ldap_mapper.so
+	#
+	#   OpenLDAP version for Solaris 11 only:
+	#     /usr/lib/pam_pkcs11/$ISA/openldap_mapper.so;
+	#
+	module = /usr/lib/pam_pkcs11/$ISA/ldap_mapper.so;
+
 	# hostname of ldap server (use LDAP-URI for more then one)
 	ldaphost = "";
 	# Port on ldap server to connect, this is also the default
--- a/components/pam_pkcs11/pam_pkcs11.p5m	Mon Sep 19 15:30:46 2016 -0700
+++ b/components/pam_pkcs11/pam_pkcs11.p5m	Tue Sep 20 12:05:25 2016 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
+# Bypass the mangler for these files because they are pre-Solarified.
+<transform file path=usr/share/man/.+$ -> add mangler.bypass true >
 set name=pkg.fmri \
     value=pkg:/library/security/pam/module/pam-pkcs11@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
 set name=pkg.summary value="The OpenSC PKCS#11 PAM Login Tools"
@@ -29,51 +31,58 @@
 set name=info.classification value=org.opensolaris.category.2008:System/Security
 set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
 set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
-set name=org.opensolaris.arc-caseid value=PSARC/2006/283
+set name=org.opensolaris.arc-caseid value=PSARC/2006/283 value=PSARC/2016/427 \
+    value=PSARC/2016/513 value=PSARC/2016/521
 set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
-dir  path=etc
-dir  path=etc/security
-dir  path=etc/security/pam_pkcs11
 dir  path=etc/security/pam_pkcs11/cacerts
+file path=etc/security/pam_pkcs11/card_eventmgr.conf.example
 dir  path=etc/security/pam_pkcs11/crls
-file usr/share/pam_pkcs11/digest_mapping.example \
-    path=etc/security/pam_pkcs11/digest_mapping.example
-file usr/share/pam_pkcs11/mail_mapping.example \
-    path=etc/security/pam_pkcs11/mail_mapping.example
-file usr/bin/make_hash_link.sh path=etc/security/pam_pkcs11/make_hash_link.sh \
-    mode=0555
+# The other example files such as pam_d.login.example and
+# pam_pkcs11.conf.example, are intentionally omitted here either because the
+# examples are not applicable to Solaris or we already provide default
+# configuration.
+file path=etc/security/pam_pkcs11/digest_mapping.example
+file path=etc/security/pam_pkcs11/mail_mapping.example
 file pam_pkcs11.conf path=etc/security/pam_pkcs11/pam_pkcs11.conf mode=0644 \
     original_name=SUNWpampkcs11:etc/security/pam_pkcs11/pam_pkcs11.conf \
     preserve=renamenew
-file usr/share/pam_pkcs11/subject_mapping.example \
-    path=etc/security/pam_pkcs11/subject_mapping.example
-dir  path=usr
-dir  path=usr/lib
-dir  path=usr/lib/pam_pkcs11
-dir  path=usr/lib/pam_pkcs11/$(MACH64)
+file usr/lib/pam_pkcs11/pkcs11_make_hash_link \
+    path=etc/security/pam_pkcs11/pkcs11_make_hash_link mode=0555
+file path=etc/security/pam_pkcs11/subject_mapping.example
 file usr/lib/$(MACH64)/pam_pkcs11/ldap_mapper.so \
     path=usr/lib/pam_pkcs11/$(MACH64)/ldap_mapper.so
+file build/openldap/$(MACH64)/src/mappers/.libs/ldap_mapper.so \
+    path=usr/lib/pam_pkcs11/$(MACH64)/openldap_mapper.so
 file usr/lib/$(MACH64)/pam_pkcs11/opensc_mapper.so \
     path=usr/lib/pam_pkcs11/$(MACH64)/opensc_mapper.so
 file usr/lib/$(MACH64)/pam_pkcs11/openssh_mapper.so \
     path=usr/lib/pam_pkcs11/$(MACH64)/openssh_mapper.so
-file path=usr/lib/pam_pkcs11/ldap_mapper.so
+link path=usr/lib/pam_pkcs11/32 target=.
+link path=usr/lib/pam_pkcs11/64 target=$(MACH64)
+file usr/lib/$(MACH64)/pam_pkcs11/card_eventmgr \
+    path=usr/lib/pam_pkcs11/card_eventmgr mode=0555
+file usr/lib/pam_pkcs11/ldap_mapper.so path=usr/lib/pam_pkcs11/ldap_mapper.so
+file build/openldap/$(MACH32)/src/mappers/.libs/ldap_mapper.so \
+    path=usr/lib/pam_pkcs11/openldap_mapper.so
 file path=usr/lib/pam_pkcs11/opensc_mapper.so
 file path=usr/lib/pam_pkcs11/openssh_mapper.so
-file usr/bin/pkcs11_inspect path=usr/lib/pam_pkcs11/pkcs11_inspect mode=0555
-file usr/bin/pklogin_finder path=usr/lib/pam_pkcs11/pklogin_finder mode=0555
-dir  path=usr/lib/security
-dir  path=usr/lib/security/$(MACH64)
+file usr/lib/$(MACH64)/pam_pkcs11/pkcs11_inspect \
+    path=usr/lib/pam_pkcs11/pkcs11_inspect mode=0555
+file usr/lib/$(MACH64)/pam_pkcs11/pklogin_finder \
+    path=usr/lib/pam_pkcs11/pklogin_finder mode=0555
 file usr/lib/$(MACH64)/security/pam_pkcs11.so \
     path=usr/lib/security/$(MACH64)/pam_pkcs11.so
-file usr/lib/security/pam_pkcs11.so path=usr/lib/security/pam_pkcs11.so
-dir  path=usr/share
-dir  path=usr/share/doc
-dir  path=usr/share/doc/pam_pkcs11
+file path=usr/lib/security/pam_pkcs11.so
+file doc/README.eventmgr path=usr/share/doc/pam_pkcs11/README.eventmgr
 file doc/mappers_api.html path=usr/share/doc/pam_pkcs11/mappers_api.html
 file doc/pam_pkcs11.html path=usr/share/doc/pam_pkcs11/pam_pkcs11.html
-dir  path=usr/share/locale
-dir  path=usr/share/locale/fr
-dir  path=usr/share/locale/fr/LC_MESSAGES
+file path=usr/share/locale/de/LC_MESSAGES/pam_pkcs11.mo
 file path=usr/share/locale/fr/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/locale/nl/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/locale/pl/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/locale/pt_br/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/locale/ru/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/locale/tr/LC_MESSAGES/pam_pkcs11.mo
+file path=usr/share/man/man1/card_eventmgr.1
+file path=usr/share/man/man1/pkcs11_make_hash_link.1
 license pam_pkcs11.license license=LGPLv2.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/pam_pkcs11/patches/01-solaris_build.patch	Tue Sep 20 12:05:25 2016 -0700
@@ -0,0 +1,62 @@
+#
+# This patch contains changes for Solaris build.   This is for Solaris only,
+# so we will not contribute back this change to the upstream community. 
+#
+--- pam_pkcs11-0.6.8_ORIG/configure.in	Fri Jul 15 15:05:17 2016
++++ pam_pkcs11-0.6.8_NEW/configure.in	Wed Jul 27 14:14:43 2016
+@@ -15,7 +15,7 @@
+ 
+ AM_MAINTAINER_MODE
+ 
+-AM_GNU_GETTEXT_VERSION([0.17])
++AM_GNU_GETTEXT_VERSION([0.16])
+ AM_GNU_GETTEXT([external])
+ 
+ dnl Add the languages which your application supports here.
+@@ -87,12 +87,10 @@
+ AC_SUBST(confdir)
+ 
+ # Add argument for using ldap
+-AC_ARG_WITH(ldap,
+-  AC_HELP_STRING([--with-ldap], [use ldap (default=yes)]))
+-if test "$with_ldap" = "no" -o "$with_ldap" = "false"
++AC_ARG_ENABLE(ldap,
++  AC_HELP_STRING([--enable-openldap], [use openldap or mozilla_ldap (default=yes)]))
++if test "$enable_openldap" = "no" -o "$enable_openldap" = "false"
+ then
+-  with_ldap=no
+-else
+   AC_CHECK_LIB( ldap, ldap_init,
+ 	[
+ 	with_ldap=yes
+@@ -101,7 +99,17 @@
+ 	AC_MSG_WARN([Cannot find LDAP libraries. LDAP support disabled])
+ 	with_ldap=no
+ 	])
++else
++  AC_CHECK_LIB( ldap, ldap_init,
++	[
++	with_ldap=yes
++	LIBS="$LIBS -lldap_r"
++	],[
++	AC_MSG_WARN([Cannot find LDAP libraries. LDAP support disabled])
++	with_ldap=no
++	])
+ fi
++
+ if test "$with_ldap" \!= "no"; then
+   AC_CHECK_FUNCS(ldap_init ldap_initialize)
+   AC_CHECK_FUNCS(ldap_set_option ldap_get_option)  
+--- pam_pkcs11-0.6.8_ORIG/src/pam_pkcs11/Makefile.am	Fri Jul 15 15:05:19 2016
++++ pam_pkcs11-0.6.8_NEW/src/pam_pkcs11/Makefile.am	Fri Jul 22 15:36:51 2016
+@@ -2,8 +2,8 @@
+ 
+ MAINTAINERCLEANFILES = Makefile.in
+ 
+-AM_CFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
+-AM_CPPFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
++AM_CFLAGS = -v -fno-strict-aliasing $(CRYPTO_CFLAGS)
++AM_CPPFLAGS = -v -fno-strict-aliasing $(CRYPTO_CFLAGS)
+ 
+ pamdir=$(libdir)/security
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/pam_pkcs11/patches/02-man_pages.patch	Tue Sep 20 12:05:25 2016 -0700
@@ -0,0 +1,60 @@
+#
+# This patch contains changes to the card_eventmgr.1 and 
+# pkcs11_make_hash_link.1 man pages.  The changes are Solaris only, so they
+# will not be contributed back to upstream. 
+#
+--- pam_pkcs11-0.6.8_ORIG/doc/card_eventmgr.1	Sat Oct 23 11:36:37 2010
++++ pam_pkcs11-0.6.8_NEW/doc/card_eventmgr.1	Fri Jul  1 14:46:36 2016
+@@ -2,7 +2,7 @@
+ .SH NAME
+ card_eventmgr \- PCSC\-Lite Event Manager
+ .SH SYNTAX
+-.B card_eventmgr
++.B /usr/lib/pam_pkcs11/card_eventmgr
+ .RB [ debug ]
+ .RB [[ no ] daemon ]
+ .RB [ timeout=\fI<msecs>\fP ]
+@@ -32,7 +32,7 @@
+ .TP 
+ .BI config_file= "<configuration file>"
+ Sets de configuration file. Default value is
+-.IR /etc/pam_pkcs11/card_eventmgr.conf .
++.IR /etc/security/pam_pkcs11/card_eventmgr.conf .
+ .TP
+ .BI pidfile= <pidfile>
+ Store the
+@@ -49,7 +49,7 @@
+ to use
+ .BR kill .
+ .SH FILES
+-\fI/etc/pam_pkcs11/card_eventmgr.conf\fP 
++\fI/etc/security/pam_pkcs11/card_eventmgr.conf\fP 
+ .SH EXAMPLES
+ To run this program the standard way type:
+ .P
+@@ -81,5 +81,4 @@
+ Ludovic Rousseau <[email protected]>
+ .SH "SEE ALSO"
+ .BR pam_pkcs11 (8),
+-.BR pkcs11_eventmgr (1),
+ README.eventmgr, PAM\-PKCS11 User Manual
+--- pam_pkcs11-0.6.8_ORIG/doc/pkcs11_make_hash_link.1	Sat Oct 23 11:36:37 2010
++++ pam_pkcs11-0.6.8_NEW/doc/pkcs11_make_hash_link.1	Fri Jul  1 16:23:13 2016
+@@ -4,7 +4,7 @@
+ pkcs11_make_hash_link \- SmartCard PKCS#11 create a CA certificate link
+ .SH "SYNTAX"
+ .LP 
+-pkcs11_make_hash_link
++/etc/security/pam_pkcs11/pkcs11_make_hash_link
+ .SH "DESCRIPTION"
+ .LP 
+ pkcs11_make_hash_link creates a symbolic hash-link for each CA certificate
+@@ -11,7 +11,7 @@
+ and each CRL in the given directory.
+ .SH "EXAMPLE"
+ .nf
+-$ cd /etc/pam_pkcs11/cacerts
++$ cd /etc/security/pam_pkcs11/cacerts
+ $ ls \-l
+ total 4
+ \-rw\-r\-\-r\-\- 1 root root 985 avr  4  2007 testCA\-cacert.der
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/pam_pkcs11/patches/03-module_ISA_fix.patch	Tue Sep 20 12:05:25 2016 -0700
@@ -0,0 +1,258 @@
+#
+# This patch is to add the ISA (Instruction Set Architecture) support to 
+# module paths in the pam_pkcs11.conf configuration file of the PAM_PKCS11
+# component, so that the PAM_PKCS11 module can be used for both 32 and 
+# 64 bit applications at the same time. This patch is for Solaris only. 
+#
+--- pam_pkcs11-0.6.8_ORIG/src/common/strings.h	Sat Oct 23 11:36:36 2010
++++ pam_pkcs11-0.6.8_NEW/src/common/strings.h	Thu Sep  1 13:47:52 2016
+@@ -125,6 +125,16 @@
+  */
+ M_EXTERN char *trim(const char *str);
+ 
++#ifdef MODULE_ISA_FIX
++/**
++ * Expand PAM_ISA ("/$ISA/") in a path. 
++ * For example, /usr/lib/$ISA/libpkcs11.so will be expanded to 
++ * /usr/lib/64/libpkcs11.so for 64 bit applications and to 
++ * /usr/lib/32/libpkcs11.so for 32 bit applications. 
++ */
++M_EXTERN  int expand_isa_path(const char *in, char *out, size_t out_len);
++#endif
++
+ #undef M_EXTERN
+ 
+ #endif
+--- pam_pkcs11-0.6.8_ORIG/src/common/strings.c	Sat Oct 23 11:36:36 2010
++++ pam_pkcs11-0.6.8_NEW/src/common/strings.c	Fri Sep  2 10:08:11 2016
+@@ -34,6 +34,17 @@
+ #include <unistd.h>
+ #include "strings.h"
+ 
++#ifdef MODULE_ISA_FIX
++#include <sys/param.h>
++
++#define	PAM_ISA		"/$ISA/"
++#ifdef	_LP64
++#define	PAM_ISA_DIR	"/64/"
++#else	/* !_LP64 */
++#define	PAM_ISA_DIR	"/32/"
++#endif	/* _LP64 */
++#endif
++
+ /*
+ check for null or blank string
+ */
+@@ -182,4 +193,33 @@
+         return res;
+ }
+ 
++
++#ifdef MODULE_ISA_FIX
++/*
++ * Expand PAM_ISA ("/$ISA/") in a module path. 
++ */
++int expand_isa_path(const char *in, char *out, size_t out_len) {
++        char *isa;
++        char buf[MAXPATHLEN];
++
++        if (strlcpy(buf, in, sizeof (buf)) >= sizeof (buf)) { /* too long */
++                return 1;
++	}
++
++	/* Check for Instruction Set Architecture indicator */
++	if ((isa = strstr(buf, PAM_ISA)) != NULL) {
++		*isa = '\000';
++		isa += strlen(PAM_ISA);
++		if (snprintf(out, out_len, "%s%s%s", buf, PAM_ISA_DIR,
++		    isa) >= out_len) {
++		        return 1;
++		}
++	} else if (strlcpy(out, in, out_len) >= out_len) {
++		return 1;
++	}
++
++	return 0;
++}
++#endif
++
+ #endif /* __STRINGS_C_ */
+--- pam_pkcs11-0.6.8_ORIG/src/pam_pkcs11/pam_pkcs11.c	Sat Apr  7 09:55:19 2012
++++ pam_pkcs11-0.6.8_NEW/src/pam_pkcs11/pam_pkcs11.c	Thu Sep  1 13:54:27 2016
+@@ -57,6 +57,10 @@
+ #endif
+ #define LOGNAME   "PAM-PKCS11"  /* name for log-file entries */
+ 
++#ifdef MODULE_ISA_FIX
++#include <sys/param.h>
++#endif
++
+ /*
+ * comodity function that returns 1 on null, empty o spaced string
+ */
+@@ -198,6 +202,9 @@
+   char env_temp[256] = "";
+   char **issuer, **serial;
+   const char *login_token_name = NULL;
++#ifdef MODULE_ISA_FIX
++  char real_pkcs11_modulepath[MAXPATHLEN];
++#endif
+ 
+   pam_prompt(pamh, PAM_TEXT_INFO , NULL, _("Smartcard authentification starts"));
+ 
+@@ -315,9 +322,28 @@
+     return PAM_IGNORE;
+   }
+ 
++#ifdef MODULE_ISA_FIX
++  /* get the real pkcs11 module path */  
++  rv = expand_isa_path(configuration->pkcs11_modulepath,
++      real_pkcs11_modulepath, sizeof (real_pkcs11_modulepath));
++  if (rv) {
++          pam_syslog(pamh, LOG_ERR, 
++              "load_pkcs11_module(): problem with pkcs11 module path");
++	  return PAM_AUTHINFO_UNAVAIL;
++  } else {
++          DBG1("The real PKCS11 module path is %s", real_pkcs11_modulepath);
++  }
++#endif
++
+   /* load pkcs #11 module */
+   DBG("loading pkcs #11 module...");
++
++#ifdef MODULE_ISA_FIX
++  rv = load_pkcs11_module(real_pkcs11_modulepath, &ph);
++#else
+   rv = load_pkcs11_module(configuration->pkcs11_modulepath, &ph);
++#endif
++
+   if (rv != 0) {
+     ERR2("load_pkcs11_module() failed loading %s: %s",
+ 		configuration->pkcs11_modulepath, get_error());
+--- pam_pkcs11-0.6.8_ORIG/src/pam_pkcs11/mapper_mgr.c	Sat Jul  9 05:20:48 2011
++++ pam_pkcs11-0.6.8_NEW/src/pam_pkcs11/mapper_mgr.c	Thu Sep  1 13:57:17 2016
+@@ -38,6 +38,10 @@
+ #include "../mappers/mapperlist.h"
+ #include "mapper_mgr.h"
+ 
++#ifdef MODULE_ISA_FIX
++#include <sys/param.h>
++#endif
++
+ struct mapper_listitem *root_mapper_list;
+ 
+ /*
+@@ -54,6 +58,9 @@
+ 	int old_level=get_debug_level();
+ 	const char *libname = NULL;
+ 	mapper_module * res = NULL;
++#ifdef MODULE_ISA_FIX
++	char real_libname[MAXPATHLEN];
++#endif
+ 
+ 	/* get module info */
+ 	root = scconf_find_block(ctx,NULL,"pam_pkcs11");
+@@ -93,7 +100,17 @@
+ 	    }
+ 	} else if (blk) { /* assume dynamic module */
+ 	    DBG1("Loading dynamic module for mapper '%s'",name);
++#ifdef MODULE_ISA_FIX
++	    if (expand_isa_path(libname, real_libname, sizeof (real_libname))) {
++	        DBG1("Problem in module path %s", libname);
++                return NULL;
++	    } else {
++	        DBG1("Module path is %s", real_libname);
++	    }
++	    handler= dlopen(real_libname, RTLD_NOW);
++#else
+ 	    handler= dlopen(libname,RTLD_NOW);
++#endif
+ 	    if (!handler) {
+ 		DBG3("dlopen failed for module:  %s path: %s Error: %s",name,libname,dlerror());
+ 		return NULL;
+--- pam_pkcs11-0.6.8_ORIG/src/tools/pkcs11_inspect.c	Fri Apr  6 13:08:25 2012
++++ pam_pkcs11-0.6.8_NEW/src/tools/pkcs11_inspect.c	Thu Sep  1 13:58:46 2016
+@@ -32,6 +32,10 @@
+ #include "../pam_pkcs11/pam_config.h"
+ #include "../pam_pkcs11/mapper_mgr.h"
+ 
++#ifdef MODULE_ISA_FIX
++#include <sys/param.h>
++#endif
++
+ int main(int argc, const char **argv) {
+   int i, rv;
+   pkcs11_handle_t *ph;
+@@ -39,6 +43,9 @@
+   unsigned int slot_num = 0;
+   cert_object_t **certs;
+   int cert_count;
++#ifdef MODULE_ISA_FIX
++  char real_pkcs11_modulepath[MAXPATHLEN];
++#endif
+ 
+   /* first of all check whether debugging should be enabled */
+   for (i = 0; i < argc; i++)
+@@ -67,7 +74,19 @@
+ 
+   /* load pkcs #11 module */
+   DBG("loading pkcs #11 module...");
++
++#ifdef MODULE_ISA_FIX
++  rv = expand_isa_path(configuration->pkcs11_modulepath,
++      real_pkcs11_modulepath, sizeof (real_pkcs11_modulepath));
++  if (rv) {
++      ERR("Error in the PKCS11 module path");
++      return 1;
++  }
++  rv = load_pkcs11_module(real_pkcs11_modulepath, &ph);
++#else
+   rv = load_pkcs11_module(configuration->pkcs11_modulepath, &ph);
++#endif
++
+   if (rv != 0) {
+     ERR2("load_pkcs11_module(%s) failed: %s", configuration->pkcs11_modulepath,
+       get_error());
+--- pam_pkcs11-0.6.8_ORIG/src/tools/pklogin_finder.c	Fri Apr  6 13:08:25 2012
++++ pam_pkcs11-0.6.8_NEW/src/tools/pklogin_finder.c	Thu Sep  1 13:59:18 2016
+@@ -32,6 +32,10 @@
+ #include "../pam_pkcs11/pam_config.h"
+ #include "../pam_pkcs11/mapper_mgr.h"
+ 
++#ifdef MODULE_ISA_FIX
++#include <sys/param.h>
++#endif
++
+ int main(int argc, const char **argv) {
+   int i, rv;
+   char *user = NULL;
+@@ -40,6 +44,9 @@
+   cert_object_t **certs;
+   int cert_count;
+   unsigned int slot_num = 0;
++#ifdef MODULE_ISA_FIX
++  char real_pkcs11_modulepath[MAXPATHLEN];
++#endif
+ 
+ 
+   /* first of all check whether debugging should be enabled */
+@@ -69,7 +76,19 @@
+ 
+   /* load pkcs #11 module */
+   DBG("loading pkcs #11 module...");
++
++#ifdef MODULE_ISA_FIX
++  rv = expand_isa_path(configuration->pkcs11_modulepath,
++      real_pkcs11_modulepath, sizeof (real_pkcs11_modulepath));
++  if (rv) {
++      ERR("Error in the PKCS11 module path");
++      return 1;
++  }
++  rv = load_pkcs11_module(real_pkcs11_modulepath, &ph);
++#else
+   rv = load_pkcs11_module(configuration->pkcs11_modulepath, &ph);
++#endif
++
+   if (rv != 0) {
+     DBG1("load_pkcs11_module() failed: %s", get_error());
+     return 1;
--- a/components/pam_pkcs11/patches/pam_pkcs11.patch	Mon Sep 19 15:30:46 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1574 +0,0 @@
-*** pam_pkcs11-0.6.0-ORIG/configure.in	Mon Jun 11 05:17:38 2007
---- pam_pkcs11-WS/configure.in	Mon Sep 28 16:06:48 2009
-***************
-*** 237,243 ****
-  AC_FUNC_REALLOC
-  AC_FUNC_STAT
-  AC_FUNC_VPRINTF
-! AC_CHECK_FUNCS([memset strdup strerror])
-  
-  
-  AC_CONFIG_FILES([ 
---- 237,243 ----
-  AC_FUNC_REALLOC
-  AC_FUNC_STAT
-  AC_FUNC_VPRINTF
-! AC_CHECK_FUNCS([memset strdup strerror daemon])
-  
-  
-  AC_CONFIG_FILES([ 
-*** pam_pkcs11-0.6.0-ORIG/po/Makefile.in.in	Tue May 22 00:54:56 2007
---- pam_pkcs11-WS/po/Makefile.in.in	Mon Sep 28 16:06:48 2009
-***************
-*** 46,61 ****
-  GMSGFMT_ = @GMSGFMT@
-  GMSGFMT_no = @GMSGFMT@
-  GMSGFMT_yes = @GMSGFMT_015@
-! GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-  MSGFMT_ = @MSGFMT@
-  MSGFMT_no = @MSGFMT@
-  MSGFMT_yes = @MSGFMT_015@
-  MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-! XGETTEXT_ = @XGETTEXT@
-  XGETTEXT_no = @XGETTEXT@
-  XGETTEXT_yes = @XGETTEXT_015@
-  XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-! MSGMERGE = msgmerge
-  MSGMERGE_UPDATE = @MSGMERGE@ --update
-  MSGINIT = msginit
-  MSGCONV = msgconv
---- 46,61 ----
-  GMSGFMT_ = @GMSGFMT@
-  GMSGFMT_no = @GMSGFMT@
-  GMSGFMT_yes = @GMSGFMT_015@
-! GMSGFMT = msgfmt
-  MSGFMT_ = @MSGFMT@
-  MSGFMT_no = @MSGFMT@
-  MSGFMT_yes = @MSGFMT_015@
-  MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-! XGETTEXT_ = /bin/xgettext
-  XGETTEXT_no = @XGETTEXT@
-  XGETTEXT_yes = @XGETTEXT_015@
-  XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-! MSGMERGE = /usr/lib/intltool/gettext-tools/msgmerge
-  MSGMERGE_UPDATE = @MSGMERGE@ --update
-  MSGINIT = msginit
-  MSGCONV = msgconv
-***************
-*** 87,94 ****
-  .po.gmo:
-  	@lang=`echo $* | sed -e 's,.*/,,'`; \
-  	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
-! 	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
-! 	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-  
-  .sin.sed:
-  	sed -e '/^#/d' $< > t-$@
---- 87,94 ----
-  .po.gmo:
-  	@lang=`echo $* | sed -e 's,.*/,,'`; \
-  	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
-! 	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -o $${lang}.gmo $${lang}.po"; \
-! 	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-  
-  .sin.sed:
-  	sed -e '/^#/d' $< > t-$@
-***************
-*** 135,145 ****
-  	else \
-  	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
-  	fi; \
-! 	$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
-! 	  --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
-! 	  --files-from=$(srcdir)/POTFILES.in \
-! 	  --copyright-holder='$(COPYRIGHT_HOLDER)' \
-! 	  --msgid-bugs-address="$$msgid_bugs_address"
-  	test ! -f $(DOMAIN).po || { \
-  	  if test -f $(srcdir)/$(DOMAIN).pot; then \
-  	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
---- 135,142 ----
-  	else \
-  	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
-  	fi; \
-! 	$(XGETTEXT) -ns -c TRANSLATORS: -m "" -d $(DOMAIN) \
-! 	  ../src/pam_pkcs11/pam_pkcs11.c
-  	test ! -f $(DOMAIN).po || { \
-  	  if test -f $(srcdir)/$(DOMAIN).pot; then \
-  	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
-*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.h	Mon May 21 02:46:19 2007
---- pam_pkcs11-WS/src/common/pkcs11_lib.h	Mon Sep 28 16:06:48 2009
-***************
-*** 36,46 ****
-  PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h,
-                                        int slot_num, const char *slot_label,
-                                        unsigned int *slot);
-! PKCS11_EXTERN const char *get_slot_label(pkcs11_handle_t *h);
-  PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h,
-                                   int wanted_slot_num, 
-                                   const char *wanted_slot_label,
-                                   unsigned int *slot);
-  PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert);
-  PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h);
-  PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot);
---- 36,57 ----
-  PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h,
-                                        int slot_num, const char *slot_label,
-                                        unsigned int *slot);
-! PKCS11_EXTERN const char *get_slot_tokenlabel(pkcs11_handle_t *h);
-  PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h,
-                                   int wanted_slot_num, 
-+                                  const char *wanted_token_label,
-+                                  unsigned int *slot);
-+ PKCS11_EXTERN int find_slot_by_slotlabel(pkcs11_handle_t *h,
-                                   const char *wanted_slot_label,
-                                   unsigned int *slot);
-+ PKCS11_EXTERN int find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
-+                                  const char *wanted_slot_label,
-+                                  const char *wanted_token_label,
-+                                  unsigned int *slot);
-+ PKCS11_EXTERN int wait_for_token_by_slotlabel(pkcs11_handle_t *h,
-+                                  const char *wanted_slot_label, 
-+                                  const char *wanted_token_label,
-+                                  unsigned int *slot);
-  PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert);
-  PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h);
-  PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot);
-*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.c	Wed Jun  6 02:33:10 2007
---- pam_pkcs11-WS/src/common/pkcs11_lib.c	Mon Sep 28 16:06:48 2009
-***************
-*** 67,77 ****
---- 67,138 ----
-    return 0;
-  }
-  
-+ /*
-+  * memcmp_pad_max() is a specialized version of memcmp() which compares two
-+  * pieces of data up to a maximum length.  If the two data match up the
-+  * maximum length, they are considered matching.  Trailing blanks do not cause
-+  * the match to fail if one of the data is shorted.
-+  *
-+  * Examples of matches:
-+  *	"one"           |
-+  *	"one      "     |
-+  *	                ^maximum length
-+  *
-+  *	"Number One     |  X"	(X is beyond maximum length)
-+  *	"Number One   " |
-+  *	                ^maximum length
-+  *
-+  * Examples of mismatches:
-+  *	" one"
-+  *	"one"
-+  *
-+  *	"Number One    X|"
-+  *	"Number One     |"
-+  *	                ^maximum length
-+  */
-+ static int
-+ memcmp_pad_max(void *d1, size_t d1_len, void *d2, size_t d2_len,
-+     size_t max_sz)
-+ {
-+ 	size_t		len, extra_len;
-+ 	char		*marker;
-+ 
-+ 	/* No point in comparing anything beyond max_sz */
-+ 	if (d1_len > max_sz)
-+ 		d1_len = max_sz;
-+ 	if (d2_len > max_sz)
-+ 		d2_len = max_sz;
-+ 
-+ 	/* Find shorter of the two data. */
-+ 	if (d1_len <= d2_len) {
-+ 		len = d1_len;
-+ 		extra_len = d2_len;
-+ 		marker = d2;
-+ 	} else {	/* d1_len > d2_len */
-+ 		len = d2_len;
-+ 		extra_len = d1_len;
-+ 		marker = d1;
-+ 	}
-+ 
-+ 	/* Have a match in the shortest length of data? */
-+ 	if (memcmp(d1, d2, len) != 0)
-+ 		/* CONSTCOND */
-+ 		return (1);
-+ 
-+ 	/* If the rest of longer data is nulls or blanks, call it a match. */
-+ 	while (len < extra_len && marker[len])
-+ 		if (!isspace(marker[len++]))
-+ 			/* CONSTCOND */
-+ 			return (1);
-+ 	return (0);
-+ }
-+ 
-  #ifdef HAVE_NSS
-  /*
-   * Using NSS to find the manage the PKCS #11 modules
-   */
-  #include "nss.h"
-+ #include "nspr.h"
-  #include "cert.h"
-  #include "secmod.h"
-  #include "pk11pub.h"
-***************
-*** 287,294 ****
-    /* we're configured for a specific module and token, see if it's present */
-    slot_num--;
-    if (slot_num >= 0 && slot_num < module->slotCount && module->slots &&
-!       module->slots[i] && PK11_IsPresent(module->slots[i])) {
-!     h->slot = PK11_ReferenceSlot(module->slots[i]);
-      *slotID = PK11_GetSlotID(h->slot);
-      return 0;
-    }
---- 348,355 ----
-    /* we're configured for a specific module and token, see if it's present */
-    slot_num--;
-    if (slot_num >= 0 && slot_num < module->slotCount && module->slots &&
-!       module->slots[slot_num] && PK11_IsPresent(module->slots[slot_num])) {
-!     h->slot = PK11_ReferenceSlot(module->slots[slot_num]);
-      *slotID = PK11_GetSlotID(h->slot);
-      return 0;
-    }
-***************
-*** 301,327 ****
-   */
-  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
-  				  int wanted_slot_id,
-! 				  const char *wanted_slot_label,
-                                    unsigned int *slot_num)
-  {
-    int rv;
-!   const char *slot_label = NULL;
-    PK11SlotInfo *slot = NULL;
-  
-    /* we want a specific slot id, or we don't kare about the label */
-!   if ((wanted_slot_label == NULL) || (wanted_slot_id != 0)) {
-      rv = find_slot_by_number(h, wanted_slot_id, slot_num);
-  
-      /* if we don't care about the label, or we failed, we're done */
-!     if ((wanted_slot_label == NULL) || (rv != 0)) {
-        return rv;
-      }
-  
-      /* verify it's the label we want */
-!     slot_label = PK11_GetTokenName(h->slot);
-  
-!     if ((slot_label != NULL) && 
-!         (strcmp (wanted_slot_label, slot_label) == 0)) {
-        return 0;
-      }
-      return -1;
---- 362,388 ----
-   */
-  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
-  				  int wanted_slot_id,
-! 				  const char *wanted_token_label,
-                                    unsigned int *slot_num)
-  {
-    int rv;
-!   const char *token_label = NULL;
-    PK11SlotInfo *slot = NULL;
-  
-    /* we want a specific slot id, or we don't kare about the label */
-!   if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) {
-      rv = find_slot_by_number(h, wanted_slot_id, slot_num);
-  
-      /* if we don't care about the label, or we failed, we're done */
-!     if ((wanted_token_label == NULL) || (rv != 0)) {
-        return rv;
-      }
-  
-      /* verify it's the label we want */
-!     token_label = PK11_GetTokenName(h->slot);
-  
-!     if ((token_label != NULL) && 
-!         (strcmp (wanted_token_label, token_label) == 0)) {
-        return 0;
-      }
-      return -1;
-***************
-*** 328,334 ****
-    }
-  
-    /* we want a specific slot by label only */
-!   slot = PK11_FindSlotByName(wanted_slot_label);
-    if (!slot) {
-      return -1;
-    }
---- 389,395 ----
-    }
-  
-    /* we want a specific slot by label only */
-!   slot = PK11_FindSlotByName(wanted_token_label);
-    if (!slot) {
-      return -1;
-    }
-***************
-*** 350,356 ****
-  
-  int wait_for_token(pkcs11_handle_t *h, 
-                     int wanted_slot_id,
-!                    const char *wanted_slot_label,
-                     unsigned int *slot_num)
-  {
-    int rv;
---- 411,417 ----
-  
-  int wait_for_token(pkcs11_handle_t *h, 
-                     int wanted_slot_id,
-!                    const char *wanted_token_label,
-                     unsigned int *slot_num)
-  {
-    int rv;
-***************
-*** 358,364 ****
-    rv = -1;
-    do {
-      /* see if the card we're looking for is inserted */
-!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_slot_label,
-                                          slot_num);
-      if (rv !=  0) {
-        PK11SlotInfo *slot;
---- 419,425 ----
-    rv = -1;
-    do {
-      /* see if the card we're looking for is inserted */
-!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_token_label,
-                                          slot_num);
-      if (rv !=  0) {
-        PK11SlotInfo *slot;
-***************
-*** 385,390 ****
---- 446,592 ----
-    return rv;
-  }
-  
-+ /* 
-+  * This function will search the slot list to find a slot based on the slot
-+  * label.  If the wanted_slot_label is "none", then we will return the first
-+  * slot with the token presented.
-+  * 
-+  * This function return 0 if it found a matching slot; otherwise, it returns
-+  * -1.
-+  */
-+ int
-+ find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label,
-+     unsigned int *slotID)
-+ {
-+   SECMODModule *module = h->module;
-+   PK11SlotInfo *slot;
-+   int rv;
-+   int i;
-+ 
-+   if (slotID == NULL || wanted_slot_label == NULL ||
-+       strlen(wanted_slot_label) == 0 || module == NULL)
-+     return (-1);
-+ 
-+   if (strcmp(wanted_slot_label, "none") == 0) {
-+     rv = find_slot_by_number(h, 0, slotID);
-+     return (rv);
-+   } else {
-+     /* wanted_slot_label is not "none"  */
-+     for (i = 0; i < module->slotCount; i++) {
-+       if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
-+         const char *slot_label;
-+ 
-+ 	slot = PK11_ReferenceSlot(module->slots[i]);
-+ 	slot_label = PK11_GetSlotName(slot);	
-+ 	if (memcmp_pad_max((void *)slot_label, strlen(slot_label),
-+ 	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) {
-+ 	  h->slot = slot;
-+ 	  *slotID = PK11_GetSlotID(slot);
-+ 	  return 0;
-+         }
-+       }
-+     }
-+   }
-+ 
-+   return (-1);
-+ }
-+ 
-+ int
-+ find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
-+     const char *wanted_slot_label, const char *wanted_token_label,
-+     unsigned int *slot_num)
-+ {
-+   SECMODModule *module = h->module;
-+   PK11SlotInfo *slot;
-+   unsigned long i;
-+   int rv;
-+ 
-+   if (slot_num == NULL || module == NULL)
-+     return (-1);
-+ 
-+   if (wanted_token_label == NULL){ 
-+     rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num);
-+     return (rv);
-+   }
-+ 
-+   /* wanted_token_label != NULL */
-+   if (strcmp(wanted_slot_label, "none") == 0) { 
-+     for (i = 0; i < module->slotCount; i++) {
-+       if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
-+ 	const char *token_label;
-+ 	slot = PK11_ReferenceSlot(module->slots[i]);
-+ 	token_label = PK11_GetTokenName(slot);
-+ 	if (memcmp_pad_max((void *) token_label, strlen(token_label),
-+ 	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0) {
-+           h->slot =  slot;
-+           *slot_num =  PK11_GetSlotID(slot);
-+ 	  return (0);
-+         }
-+       }
-+     }
-+     return (-1);
-+   } else {
-+     for (i = 0; i < module->slotCount; i++) {
-+       if (module->slots[i] && PK11_IsPresent(module->slots[i])) {
-+ 	const char *slot_label;
-+ 	const char *token_label;
-+ 
-+ 	slot = PK11_ReferenceSlot(module->slots[i]);
-+ 	slot_label = PK11_GetSlotName(slot);
-+ 	token_label = PK11_GetTokenName(slot);
-+ 	if ((memcmp_pad_max((void *)slot_label, strlen(slot_label),
-+ 	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) &&
-+             (memcmp_pad_max((void *)token_label, strlen(token_label),
-+ 	    (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0))
-+ 	{
-+           h->slot =  slot;
-+           *slot_num =  PK11_GetSlotID(slot);
-+ 	  return (0);
-+         }
-+       }
-+     }
-+     return (-1);
-+   }
-+ }
-+ 
-+ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, 
-+                    const char *wanted_slot_label,
-+                    const char *wanted_token_label,
-+                    unsigned int *slot_num)
-+ {
-+   int rv;
-+ 
-+   rv = -1;
-+   do {
-+     /* see if the card we're looking for is inserted */
-+     rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label,
-+ 	wanted_token_label, slot_num);
-+   
-+     if (rv !=  0) {
-+       PK11SlotInfo *slot;
-+       PRIntervalTime slot_poll_interval; /* only for legacy hardware */
-+ 
-+       /* if the card is not inserted, then block until something happens */
-+       slot_poll_interval = PR_MillisecondsToInterval(PAM_PKCS11_POLL_TIME);
-+       slot = SECMOD_WaitForAnyTokenEvent(h->module, 0 /* flags */,
-+                                          slot_poll_interval);
-+ 
-+       /* unexpected error */
-+       if (slot == NULL) {
-+         break;
-+       }
-+ 
-+       /* something happened, continue loop and check if the card
-+        * we're looking for is inserted
-+        */
-+       PK11_FreeSlot(slot);
-+       continue;
-+     }
-+   } while (rv != 0);
-+ 
-+   return rv;
-+ }
-+ 
-  void release_pkcs11_module(pkcs11_handle_t *h) 
-  {
-    SECStatus rv;
-***************
-*** 470,476 ****
-    return 0;
-  }
-  
-! const char *get_slot_label(pkcs11_handle_t *h)
-  {
-    if (!h->slot) {
-      return NULL;
---- 672,678 ----
-    return 0;
-  }
-  
-! const char *get_slot_tokenlabel(pkcs11_handle_t *h)
-  {
-    if (!h->slot) {
-      return NULL;
-***************
-*** 613,619 ****
-    return (rv == SECSuccess) ? 0 : -1;
-  }
-  
-- #include "nspr.h"
-  
-  struct tuple_str {
-      PRErrorCode	 errNum;
---- 815,820 ----
-***************
-*** 708,714 ****
-  typedef struct {
-    CK_SLOT_ID id;
-    CK_BBOOL token_present;
-!   CK_UTF8CHAR label[33];
-  } slot_t;
-  
-  struct pkcs11_handle_str {
---- 909,916 ----
-  typedef struct {
-    CK_SLOT_ID id;
-    CK_BBOOL token_present;
-!   CK_UTF8CHAR label[33]; /* token label */
-!   CK_UTF8CHAR slotDescription[64];
-  } slot_t;
-  
-  struct pkcs11_handle_str {
-***************
-*** 758,764 ****
-    DBG3("module permissions: uid = %d, gid = %d, mode = %o",
-        module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777);
-    if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH
-!       || module_stat.st_uid != 0 || module_stat.st_gid != 0) {
-      set_error("the pkcs #11 module MUST be owned by root and MUST NOT "
-                "be writeable by the group or others");
-      free(h);
---- 960,966 ----
-    DBG3("module permissions: uid = %d, gid = %d, mode = %o",
-        module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777);
-    if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH
-!       || module_stat.st_uid != 0) {
-      set_error("the pkcs #11 module MUST be owned by root and MUST NOT "
-                "be writeable by the group or others");
-      free(h);
-***************
-*** 807,812 ****
---- 1009,1018 ----
-        set_error("C_GetSlotInfo() failed: %x", rv);
-        return -1;
-      }
-+ 
-+     (void) memcpy(h->slots[i].slotDescription, sinfo.slotDescription,
-+ 		sizeof(h->slots[i].slotDescription));
-+ 
-      DBG1("- description: %.64s", sinfo.slotDescription);
-      DBG1("- manufacturer: %.32s", sinfo.manufacturerID);
-      DBG1("- flags: %04lx", sinfo.flags);
-***************
-*** 945,971 ****
-  	
-  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
-  				  int wanted_slot_id,
-! 				  const char *wanted_slot_label,
-                                    unsigned int *slot_num)
-  {
-    unsigned int slot_index;
-    int rv;
-!   const char *slot_label = NULL;
-  
-    /* we want a specific slot id, or we don't care about the label */
-!   if ((wanted_slot_label == NULL) || (wanted_slot_id != 0)) {
-      rv = find_slot_by_number(h, wanted_slot_id, slot_num);
-  
-      /* if we don't care about the label, or we failed, we're done */
-!     if ((wanted_slot_label == NULL) || (rv != 0)) {
-        return rv;
-      }
-  
-      /* verify it's the label we want */
-!     slot_label = h->slots[*slot_num].label;
-  
-!     if ((slot_label != NULL) && 
-!         (strcmp (wanted_slot_label, slot_label) == 0)) {
-        return 0;
-      }
-      return -1;
---- 1151,1177 ----
-  	
-  int find_slot_by_number_and_label(pkcs11_handle_t *h, 
-  				  int wanted_slot_id,
-! 				  const char *wanted_token_label,
-                                    unsigned int *slot_num)
-  {
-    unsigned int slot_index;
-    int rv;
-!   const char *token_label = NULL;
-  
-    /* we want a specific slot id, or we don't care about the label */
-!   if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) {
-      rv = find_slot_by_number(h, wanted_slot_id, slot_num);
-  
-      /* if we don't care about the label, or we failed, we're done */
-!     if ((wanted_token_label == NULL) || (rv != 0)) {
-        return rv;
-      }
-  
-      /* verify it's the label we want */
-!     token_label = h->slots[*slot_num].label;
-  
-!     if ((token_label != NULL) && 
-!         (strcmp (wanted_token_label, token_label) == 0)) {
-        return 0;
-      }
-      return -1;
-***************
-*** 974,982 ****
-    /* look up the slot by it's label from the list */
-    for (slot_index = 0; slot_index < h->slot_count; slot_index++) {
-      if (h->slots[slot_index].token_present) {
-!       slot_label = h->slots[slot_index].label;
-!       if ((slot_label != NULL) && 
-!           (strcmp (wanted_slot_label, slot_label) == 0)) {
-          *slot_num = slot_index;
-          return 0;
-        }
---- 1180,1188 ----
-    /* look up the slot by it's label from the list */
-    for (slot_index = 0; slot_index < h->slot_count; slot_index++) {
-      if (h->slots[slot_index].token_present) {
-!       token_label = h->slots[slot_index].label;
-!       if ((token_label != NULL) && 
-!           (strcmp (wanted_token_label, token_label) == 0)) {
-          *slot_num = slot_index;
-          return 0;
-        }
-***************
-*** 985,993 ****
-    return -1;
-  }
-  
-  int wait_for_token(pkcs11_handle_t *h, 
-                     int wanted_slot_id,
-!                    const char *wanted_slot_label,
-                     unsigned int *slot_num)
-  {
-    int rv;
---- 1191,1310 ----
-    return -1;
-  }
-  
-+ /* 
-+  * This function will search the slot list to find a slot based on the slot
-+  * label.  If the wanted_slot_label is "none", then we will return the first
-+  * slot with the token presented.
-+  * 
-+  * This function return 0 if it found a matching slot; otherwise, it returns
-+  * -1.
-+  */
-+ int
-+ find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label,
-+     unsigned int *slot_num)
-+ {
-+   unsigned long index;
-+   size_t len;
-+ 
-+   if (slot_num == NULL || wanted_slot_label == NULL ||
-+       strlen(wanted_slot_label) == 0)
-+     return (-1);
-+ 
-+   if (strcmp(wanted_slot_label, "none") == 0) {
-+     for (index = 0; index < h->slot_count; index++) {
-+       if (h->slots[index].token_present) {
-+ 	*slot_num = index;
-+ 	return (0);
-+       }
-+     }
-+   } else {
-+     /* Look up the slot by it's slotDescription */
-+     len = strlen(wanted_slot_label);
-+     for (index = 0; index < h->slot_count; index++) {
-+       if (memcmp_pad_max(h->slots[index].slotDescription, 64,
-+ 	  (void *)wanted_slot_label, len, 64) == 0) {
-+ 	*slot_num = index;
-+ 	return (0);
-+       }
-+     }
-+   }
-+ 
-+   return (-1);
-+ }
-+ 
-+ 
-+ int
-+ find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h,
-+     const char *wanted_slot_label, const char *wanted_token_label,
-+     unsigned int *slot_num)
-+ {
-+   unsigned long i;
-+   int rv;
-+ 
-+   if (slot_num == NULL)
-+     return (-1);
-+ 
-+   if (wanted_token_label == NULL) {
-+     rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num);
-+     return (rv);
-+   }
-+ 
-+   /* wanted_token_label != NULL */
-+   if (strcmp(wanted_slot_label, "none") == 0) { 
-+     for (i= 0; i < h->slot_count; i++) {
-+       if (h->slots[i].token_present &&
-+ 	  strcmp(wanted_token_label, h->slots[i].label) == 0) {
-+ 	*slot_num = i;
-+ 	return (0);
-+       }
-+     }
-+     return (-1);
-+   } else {
-+     for (i = 0; i < h->slot_count; i++) {
-+       if (h->slots[i].token_present) {
-+         const char *slot_label = h->slots[i].slotDescription;
-+         const char *token_label = h->slots[i].label;
-+ 
-+ 	if ((memcmp_pad_max((void *)slot_label, strlen(slot_label),
-+ 	    (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) &&
-+             (memcmp_pad_max((void *)token_label, strlen(token_label),
-+             (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0))
-+         {
-+ 	  *slot_num = i;
-+ 	  return (0);
-+         }
-+       }
-+     }
-+     return (-1);
-+   }
-+ }
-+ 
-+ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, 
-+                    const char *wanted_slot_label,
-+                    const char *wanted_token_label,
-+                    unsigned int *slot_num)
-+ {
-+   int rv;
-+ 
-+   rv = -1;
-+   do {
-+     /* see if the card we're looking for is inserted */
-+     rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label,
-+ 	wanted_token_label, slot_num);
-+     if (rv !=  0) {
-+       /* could call C_WaitForSlotEvent, for now just poll */
-+       sleep(10);
-+       refresh_slots(h);
-+       continue;
-+     }
-+   } while (rv != 0);
-+ 
-+   return rv;
-+ }
-+ 
-  int wait_for_token(pkcs11_handle_t *h, 
-                     int wanted_slot_id,
-!                    const char *wanted_token_label,
-                     unsigned int *slot_num)
-  {
-    int rv;
-***************
-*** 995,1001 ****
-    rv = -1;
-    do {
-      /* see if the card we're looking for is inserted */
-!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_slot_label,
-                                          slot_num);
-      if (rv !=  0) {
-        /* could call C_WaitForSlotEvent, for now just poll */
---- 1312,1318 ----
-    rv = -1;
-    do {
-      /* see if the card we're looking for is inserted */
-!     rv = find_slot_by_number_and_label (h, wanted_slot_id,  wanted_token_label,
-                                          slot_num);
-      if (rv !=  0) {
-        /* could call C_WaitForSlotEvent, for now just poll */
-***************
-*** 1306,1312 ****
-    return -1;
-  }
-  
-! const char *get_slot_label(pkcs11_handle_t *h)
-  {
-    return h->slots[h->current_slot].label;
-  }
---- 1623,1629 ----
-    return -1;
-  }
-  
-! const char *get_slot_tokenlabel(pkcs11_handle_t *h)
-  {
-    return h->slots[h->current_slot].label;
-  }
-*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/Makefile.in	Wed Jun  6 02:23:27 2007
---- pam_pkcs11-WS/src/pam_pkcs11/Makefile.in	Mon Sep 28 16:06:48 2009
-***************
-*** 234,241 ****
-  top_builddir = @top_builddir@
-  top_srcdir = @top_srcdir@
-  MAINTAINERCLEANFILES = Makefile.in
-! AM_CFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
-! AM_CPPFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS)
-  lib_LTLIBRARIES = pam_pkcs11.la
-  pam_pkcs11_la_SOURCES = pam_pkcs11.c  \
-  			mapper_mgr.c mapper_mgr.h \
---- 234,241 ----
-  top_builddir = @top_builddir@
-  top_srcdir = @top_srcdir@
-  MAINTAINERCLEANFILES = Makefile.in
-! AM_CFLAGS = $(CRYPTO_CFLAGS)
-! AM_CPPFLAGS = $(CRYPTO_CFLAGS)
-  lib_LTLIBRARIES = pam_pkcs11.la
-  pam_pkcs11_la_SOURCES = pam_pkcs11.c  \
-  			mapper_mgr.c mapper_mgr.h \
-*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.h	Wed Jun  6 02:55:02 2007
---- pam_pkcs11-WS/src/pam_pkcs11/pam_config.h	Mon Sep 28 16:06:48 2009
-***************
-*** 13,19 ****
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   * Lesser General Public License for more details.
-   *
-!  * $Id: pam_config.h 270 2007-05-21 08:13:00Z ludovic.rousseau $
-   */
-  
-  /*
---- 13,19 ----
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   * Lesser General Public License for more details.
-   *
-!  * $Id: pam_config.h 341 2008-10-14 07:36:46Z ludovic.rousseau $
-   */
-  
-  /*
-***************
-*** 38,46 ****
---- 38,48 ----
-  	char *pkcs11_module;
-  	char *pkcs11_modulepath;
-  	char **screen_savers;
-+ 	char *slot_description;
-  	int slot_num;
-  	int support_threads;
-  	cert_policy policy;
-+ 	char *token_type;
-  	char *username; /* provided user name */
-  };
-  
-*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_pkcs11.c	Tue May 22 01:28:33 2007
---- pam_pkcs11-WS/src/pam_pkcs11/pam_pkcs11.c	Mon Nov  2 15:39:57 2009
-***************
-*** 12,18 ****
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   * Lesser General Public License for more details.
-   *
-!  * $Id: pam_pkcs11.c 281 2007-05-22 08:28:40Z ludovic.rousseau $
-   */
-  
-  /* We have to make this definitions before we include the pam header files! */
---- 12,18 ----
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   * Lesser General Public License for more details.
-   *
-!  * $Id: pam_pkcs11.c 341 2008-10-14 07:36:46Z ludovic.rousseau $
-   */
-  
-  /* We have to make this definitions before we include the pam header files! */
-***************
-*** 59,65 ****
-  /*
-  * comodity function that returns 1 on null, empty o spaced string
-  */
-! int is_spaced_str(const char *str) {
-  	char *pt=(char *)str;
-  	if(!str) return 1;
-  	if (!strcmp(str,"")) return 1;
---- 59,65 ----
-  /*
-  * comodity function that returns 1 on null, empty o spaced string
-  */
-! static int is_spaced_str(const char *str) {
-  	char *pt=(char *)str;
-  	if(!str) return 1;
-  	if (!strcmp(str,"")) return 1;
-***************
-*** 91,103 ****
-    rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
-    if (rv != PAM_SUCCESS)
-      return rv;
-!   if ((resp == NULL) || (resp[0].resp == NULL))
-      return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT;
-    if (response) {
-       *response = strdup(resp[0].resp);
-    }
-    /* overwrite memory and release it */
-    memset(resp[0].resp, 0, strlen(resp[0].resp));
-    free(&resp[0]);
-    return PAM_SUCCESS;
-  }
---- 91,106 ----
-    rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
-    if (rv != PAM_SUCCESS)
-      return rv;
-!   if ((resp == NULL) || (resp[0].resp == NULL)) {
-!     free(&resp[0]);
-      return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT;
-+   }
-    if (response) {
-       *response = strdup(resp[0].resp);
-    }
-    /* overwrite memory and release it */
-    memset(resp[0].resp, 0, strlen(resp[0].resp));
-+   free(resp[0].resp);
-    free(&resp[0]);
-    return PAM_SUCCESS;
-  }
-***************
-*** 206,211 ****
---- 209,220 ----
-  	return PAM_AUTHINFO_UNAVAIL;
-    }
-  
-+   /* Either slot_description or slot_num, but not both, needs to be used */
-+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
-+ 	ERR("Error setting configuration parameters");
-+ 	return PAM_AUTHINFO_UNAVAIL;
-+   }
-+ 
-    /* fail if we are using a remote server
-     * local login: DISPLAY=:0
-     * XDMCP login: DISPLAY=host:0 */
-***************
-*** 274,281 ****
-  	    DBG1("explicit username = [%s]", user);
-  	} 
-    } else {
-!         pam_prompt(pamh, PAM_TEXT_INFO, NULL,
-!                    _("Please insert your smart card or enter your username."));
-  	/* get user name */
-  	rv = pam_get_user(pamh, &user, NULL);
-  
---- 283,292 ----
-  	    DBG1("explicit username = [%s]", user);
-  	} 
-    } else {
-! 	sprintf(password_prompt,
-! 		_("Please insert your %s or enter your username."),
-! 		_(configuration->token_type));
-! 	pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
-  	/* get user name */
-  	rv = pam_get_user(pamh, &user, NULL);
-  
-***************
-*** 314,321 ****
-    }
-  
-    /* open pkcs #11 session */
-!   rv = find_slot_by_number_and_label(ph, configuration->slot_num, 
-                                       login_token_name, &slot_num);
-    if (rv != 0) {
-      ERR("no suitable token available");
-      pam_syslog(pamh, LOG_ERR, "no suitable token available");
---- 325,338 ----
-    }
-  
-    /* open pkcs #11 session */
-!   if (configuration->slot_description != NULL) {
-!     rv = find_slot_by_slotlabel_and_tokenlabel(ph,
-!       configuration->slot_description, login_token_name, &slot_num);
-!   } else if (configuration->slot_num != -1) {
-!     rv = find_slot_by_number_and_label(ph, configuration->slot_num,
-                                       login_token_name, &slot_num);
-+   }
-+ 
-    if (rv != 0) {
-      ERR("no suitable token available");
-      pam_syslog(pamh, LOG_ERR, "no suitable token available");
-***************
-*** 337,344 ****
-          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
-                   _("Please insert your smart card."));
-        }
-!       rv = wait_for_token(ph, configuration->slot_num,
-                            login_token_name, &slot_num);
-        if (rv != 0) {
-          release_pkcs11_module(ph);
-          return pkcs11_pam_fail;
---- 354,368 ----
-          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
-                   _("Please insert your smart card."));
-        }
-! 
-!       if (configuration->slot_description != NULL) {
-! 	rv = wait_for_token_by_slotlabel(ph, configuration->slot_description,
-!           login_token_name, &slot_num);
-!       } else if (configuration->slot_num != -1) {
-!         rv = wait_for_token(ph, configuration->slot_num,
-                            login_token_name, &slot_num);
-+       }
-+ 
-        if (rv != 0) {
-          release_pkcs11_module(ph);
-          return pkcs11_pam_fail;
-***************
-*** 350,362 ****
-      } else {
-        /* we haven't prompted for the user yet, get the user and see if
-         * the smart card has been inserted in the mean time */
-!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, 
-!                  _("Please insert your smart card or enter your username."));
-        rv = pam_get_user(pamh, &user, NULL);
-  
-        /* check one last time for the smart card before bouncing to the next
-         * module */
-!       rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
-        if (rv != 0) {
-          /* user gave us a user id and no smart card go to next module */
-          release_pkcs11_module(ph);
---- 374,394 ----
-      } else {
-        /* we haven't prompted for the user yet, get the user and see if
-         * the smart card has been inserted in the mean time */
-!       sprintf(password_prompt,
-! 	  	_("Please insert your %s or enter your username."),
-! 		_(configuration->token_type));
-!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
-        rv = pam_get_user(pamh, &user, NULL);
-  
-        /* check one last time for the smart card before bouncing to the next
-         * module */
-!       if (configuration->slot_description != NULL) {
-! 	rv = find_slot_by_slotlabel(ph, configuration->slot_description,
-! 	  &slot_num);
-!       } else if (configuration->slot_num != -1) {
-!         rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
-!       }
-! 
-        if (rv != 0) {
-          /* user gave us a user id and no smart card go to next module */
-          release_pkcs11_module(ph);
-***************
-*** 364,370 ****
-        }
-      }
-    } else {
-!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Smart card inserted. "));
-    }
-    rv = open_pkcs11_session(ph, slot_num);
-    if (rv != 0) {
---- 396,404 ----
-        }
-      }
-    } else {
-!       sprintf(password_prompt, _("Found the %s."),
-!          _(configuration->token_type));
-!       pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
-    }
-    rv = open_pkcs11_session(ph, slot_num);
-    if (rv != 0) {
-***************
-*** 375,390 ****
-    }
-  
-    /* get password */
-!   sprintf(password_prompt, _("Welcome %.32s!"), get_slot_label(ph));
-    pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
-    if (configuration->use_first_pass) {
-      rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
-    } else if (configuration->try_first_pass) {
-!     rv = pam_get_pwd(pamh, &password, _("Smart card password: "), PAM_AUTHTOK,
-        PAM_AUTHTOK);
-    } else {
-!     rv = pam_get_pwd(pamh, &password, _("Smart card password: "), 0,
-!       PAM_AUTHTOK);
-    }
-    if (rv != PAM_SUCCESS) {
-      release_pkcs11_module(ph);
---- 409,424 ----
-    }
-  
-    /* get password */
-!   sprintf(password_prompt, _("Welcome %.32s!"), get_slot_tokenlabel(ph));
-    pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
-+   sprintf(password_prompt, _("%s PIN: "), _(configuration->token_type));
-    if (configuration->use_first_pass) {
-      rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
-    } else if (configuration->try_first_pass) {
-!     rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK,
-        PAM_AUTHTOK);
-    } else {
-!     rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK);
-    }
-    if (rv != PAM_SUCCESS) {
-      release_pkcs11_module(ph);
-***************
-*** 558,564 ****
-    snprintf(env_temp, sizeof(env_temp) - 1,
-  	   "PKCS11_LOGIN_TOKEN_NAME=%.*s", 
-  	   (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="),
-! 	   get_slot_label(ph));
-    rv = pam_putenv(pamh, env_temp);
-  
-    if (rv != PAM_SUCCESS) {
---- 592,598 ----
-    snprintf(env_temp, sizeof(env_temp) - 1,
-  	   "PKCS11_LOGIN_TOKEN_NAME=%.*s", 
-  	   (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="),
-! 	   get_slot_tokenlabel(ph));
-    rv = pam_putenv(pamh, env_temp);
-  
-    if (rv != PAM_SUCCESS) {
-*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.c	Mon May 21 02:46:19 2007
---- pam_pkcs11-WS/src/pam_pkcs11/pam_config.c	Mon Sep 28 16:06:48 2009
-***************
-*** 20,25 ****
---- 20,26 ----
-  
-  #include <syslog.h>
-  #include <string.h>
-+ #include "config.h"
-  #include "../scconf/scconf.h"
-  #include "../common/debug.h"
-  #include "../common/error.h"
-***************
-*** 27,38 ****
---- 28,45 ----
-  #include "pam_config.h"
-  #include "mapper_mgr.h"
-  
-+ #define N_(string) (string)
-+ 
-  /*
-  * configuration related functions
-  */
-  
-  struct configuration_st configuration = {
-+ #ifndef ORIGINAL /* SUN_SOLARIS */
-+ 	"/etc/security/pam_pkcs11/pam_pkcs11.conf",
-+ #else
-  	"/etc/pam_pkcs11/pam_pkcs11.conf",	/* char * config_file; */
-+ #endif
-  	NULL,				/* scconf_context *ctx; */
-          0,				/* int debug; */
-          0,				/* int nullok; */
-***************
-*** 44,57 ****
-          "default", 			/* const char *pkcs11_module; */
-          "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */
-          NULL,                           /* screen savers */
-!         0,				/* int slot_num; */
-  	0,				/* support threads */
-  	/* cert policy; */
-          { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE },
-  	NULL				/* char *username */
-  };
-  
-- #if 0
-  static void display_config (void) {
-          DBG1("debug %d",configuration.debug);
-          DBG1("nullok %d",configuration.nullok);
---- 51,65 ----
-          "default", 			/* const char *pkcs11_module; */
-          "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */
-          NULL,                           /* screen savers */
-! 	NULL,				/* slot_description */
-!         -1,				/* int slot_num; */
-  	0,				/* support threads */
-  	/* cert policy; */
-          { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE },
-+ 	N_("Smart card"), 		/* token_type */
-  	NULL				/* char *username */
-  };
-  
-  static void display_config (void) {
-          DBG1("debug %d",configuration.debug);
-          DBG1("nullok %d",configuration.nullok);
-***************
-*** 71,77 ****
-          DBG1("signature_policy %d",configuration.policy.signature_policy);
-          DBG1("ocsp_policy %d",configuration.policy.ocsp_policy);
-  }
-- #endif
-  
-  /*
-  parse configuration file
---- 79,84 ----
-***************
-*** 136,143 ****
---- 143,164 ----
-  	        scconf_get_str(pkcs11_mblk,"crl_dir",configuration.policy.crl_dir);
-  	    configuration.policy.nss_dir = (char *)
-  	        scconf_get_str(pkcs11_mblk,"nss_dir",configuration.policy.nss_dir);
-+ 	    configuration.slot_description =  (char *)
-+ 	        scconf_get_str(pkcs11_mblk,"slot_description",configuration.slot_description);
-+ 
-  	    configuration.slot_num = 
-  	        scconf_get_int(pkcs11_mblk,"slot_num",configuration.slot_num);
-+ 
-+ 	    if (configuration.slot_description != NULL && configuration.slot_num != -1) {
-+ 		DBG1("Can not specify both slot_description and slot_num in file %s",configuration.config_file);
-+ 	            return;
-+ 	    }
-+ 
-+ 	    if (configuration.slot_description == NULL && configuration.slot_num == -1) {
-+ 		DBG1("Neither slot_description nor slot_num found in file %s",configuration.config_file);
-+ 	            return;
-+ 	    }
-+ 
-  	    configuration.support_threads = 
-  	        scconf_get_bool(pkcs11_mblk,"support_threads",configuration.support_threads);
-  	    policy_list= scconf_find_list(pkcs11_mblk,"cert_policy");
-***************
-*** 165,170 ****
---- 186,194 ----
-  	        }
-  		policy_list= policy_list->next;
-  	    }
-+ 
-+ 	    configuration.token_type = (char *)
-+ 		scconf_get_str(pkcs11_mblk,"token_type",configuration.token_type);
-  	}
-  	screen_saver_list = scconf_find_list(root,"screen_savers");
-  	if (screen_saver_list) {
-***************
-*** 199,205 ****
-  	int i;
-  	int res;
-  	/* try to find a configuration file entry */
-! 	for (i = 0; i < argc; i++) {
-  	    if (strstr(argv[i],"config_file=") ) {
-  		configuration.config_file=1+strchr(argv[i],'=');
-  		break;
---- 223,229 ----
-  	int i;
-  	int res;
-  	/* try to find a configuration file entry */
-! 	for (i = 1; i < argc; i++) {
-  	    if (strstr(argv[i],"config_file=") ) {
-  		configuration.config_file=1+strchr(argv[i],'=');
-  		break;
-***************
-*** 211,217 ****
-  	/* display_config(); */
-  	/* finally parse provided arguments */
-  	/* dont skip argv[0] */
-! 	for (i = 0; i < argc; i++) {
-  	   if (strcmp("nullok", argv[i]) == 0) {
-  		configuration.nullok = 1;
-  		continue;
---- 235,241 ----
-  	/* display_config(); */
-  	/* finally parse provided arguments */
-  	/* dont skip argv[0] */
-! 	for (i = 1; i < argc; i++) {
-  	   if (strcmp("nullok", argv[i]) == 0) {
-  		configuration.nullok = 1;
-  		continue;
-***************
-*** 246,255 ****
-  		res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module);
-  		continue;
-  	   }
-  	   if (strstr(argv[i],"slot_num=") ) {
-! 		res=sscanf(argv[i],"slot_nume=%d",&configuration.slot_num);
-  		continue;
-  	   }
-  	   if (strstr(argv[i],"ca_dir=") ) {
-  		res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir);
-  		continue;
---- 270,285 ----
-  		res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module);
-  		continue;
-  	   }
-+ 	   if (strstr(argv[i],"slot_description=") ) {
-+ 		res=sscanf(argv[i],"slot_description=%255s",configuration.slot_description);
-+ 		continue;
-+ 	   }
-+ 
-  	   if (strstr(argv[i],"slot_num=") ) {
-! 		res=sscanf(argv[i],"slot_num=%d",&configuration.slot_num);
-  		continue;
-  	   }
-+ 
-  	   if (strstr(argv[i],"ca_dir=") ) {
-  		res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir);
-  		continue;
-***************
-*** 289,294 ****
---- 319,330 ----
-  		}
-  		continue;
-  	   }
-+ 
-+ 	   if (strstr(argv[i],"token_type=") ) {
-+ 		res=sscanf(argv[i],"token_type=%255s",configuration.token_type);
-+ 		continue;
-+ 	   }
-+ 
-  	   if (strstr(argv[i],"config_file=") ) {
-  		/* already parsed, skip */
-  		continue;
-***************
-*** 299,302 ****
-  	}
-  	return &configuration;
-  }
-- 
---- 335,337 ----
-*** pam_pkcs11-0.6.0-ORIG/src/mappers/ldap_mapper.c	Wed Jun  6 02:48:24 2007
---- pam_pkcs11-WS/src/mappers/ldap_mapper.c	Mon Sep 28 16:06:48 2009
-***************
-*** 184,192 ****
-  	}
-  
-  # ifdef HAVE_LDAP_INIT
-! 	*ld = ldap_init (uri, defport);
-  # else
-! 	*ld = ldap_open (uri, defport);
-  # endif
-  	rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS;
-  
---- 184,192 ----
-  	}
-  
-  # ifdef HAVE_LDAP_INIT
-! 	*ld = ldap_init (uri, ldapdefport);
-  # else
-! 	*ld = ldap_open (uri, ldapdefport);
-  # endif
-  	rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS;
-  
-*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_inspect.c	Mon May 21 02:46:19 2007
---- pam_pkcs11-WS/src/tools/pkcs11_inspect.c	Mon Sep 28 16:06:48 2009
-***************
-*** 53,58 ****
---- 53,63 ----
-  	return 1;
-    }
-  
-+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
-+ 	ERR("Error setting configuration parameters");
-+ 	return 1;
-+   }
-+ 
-    /* init openssl */
-    rv = crypto_init(&configuration->policy);
-    if (rv != 0) {
-***************
-*** 79,85 ****
-    }
-  
-    /* open pkcs #11 session */
-!   rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
---- 84,95 ----
-    }
-  
-    /* open pkcs #11 session */
-!   if (configuration->slot_description != NULL) {
-!     rv = find_slot_by_slotlabel(ph, configuration->slot_description, &slot_num);
-!   } else {
-!     rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
-!   }
-! 
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
-*** pam_pkcs11-0.6.0-ORIG/src/tools/pklogin_finder.c	Wed Jun  6 03:00:36 2007
---- pam_pkcs11-WS/src/tools/pklogin_finder.c	Mon Sep 28 16:06:48 2009
-***************
-*** 55,60 ****
---- 55,65 ----
-  	return 1;
-    }
-  
-+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
-+ 	ERR("Error setting configuration parameters");
-+ 	return 1;
-+   }
-+ 
-    /* init openssl */
-    rv = crypto_init(&configuration->policy);
-    if (rv != 0) {
-***************
-*** 80,86 ****
-    }
-  
-    /* open pkcs #11 session */
-!   rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
---- 85,95 ----
-    }
-  
-    /* open pkcs #11 session */
-!   if (configuration->slot_description != NULL) {
-!     rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num);
-!   } else { 
-!     rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
-!   }
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
-*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_eventmgr.c	Wed Jun  6 04:14:27 2007
---- pam_pkcs11-WS/src/tools/pkcs11_eventmgr.c	Mon Sep 28 16:06:48 2009
-***************
-*** 430,435 ****
---- 430,436 ----
-  	}
-      }
-  
-+ #ifdef HAVE_DAEMON
-      if (daemonize) {
-  	DBG("Going to be daemon...");
-  	if ( daemon(0,debug)<0 ) {
-***************
-*** 440,445 ****
---- 441,447 ----
-  		return 1;
-  	}
-      }
-+ #endif 
-  
-      /* 
-       * Wait endlessly for all events in the list of readers
-***************
-*** 512,517 ****
---- 514,520 ----
-      }
-  
-      /* put my self into background if flag is set */
-+ #ifdef HAVE_DAEMON
-      if (daemonize) {
-  	DBG("Going to be daemon...");
-  	if ( daemon(0,debug)<0 ) {
-***************
-*** 521,526 ****
---- 524,530 ----
-  		return 1;
-  	}
-      }
-+ #endif 
-  
-      /* open pkcs11 sesion */
-      DBG("initialising pkcs #11 module...");
-*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_listcerts.c	Mon May 21 02:46:19 2007
---- pam_pkcs11-WS/src/tools/pkcs11_listcerts.c	Mon Sep 28 16:06:48 2009
-***************
-*** 53,58 ****
---- 53,63 ----
-  	return 1;
-    }
-  
-+   if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) {
-+ 	ERR("Error setting configuration parameters");
-+ 	return 1;
-+   }
-+ 
-    /* init openssl */
-    rv = crypto_init(&configuration->policy);
-    if (rv != 0) {
-***************
-*** 78,84 ****
-    }
-  
-    /* open pkcs #11 session */
-!   rv = find_slot_by_number(ph, configuration->slot_num, &slot_num);
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
---- 83,94 ----
-    }
-  
-    /* open pkcs #11 session */
-!   if (configuration->slot_description != NULL) {
-!     rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num);
-!   } else { 
-!     rv = find_slot_by_number(ph,configuration->slot_num, &slot_num);
-!   }
-! 
-    if (rv != 0) {
-      release_pkcs11_module(ph);
-      DBG("no token available");
-*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_setup.c	Wed Jun  6 04:20:09 2007
---- pam_pkcs11-WS/src/tools/pkcs11_setup.c	Mon Sep 28 16:06:48 2009
-***************
-*** 60,65 ****
---- 60,92 ----
-      return value;
-  }
-  
-+ #ifndef ORIGINAL /* SUN_SOLARIS */
-+ /* Written by Niels M\ufffd\ufffdller <[email protected]>
-+  * modified by Ludovic Rousseau <[email protected]>
-+  *
-+  * This file is hereby placed in the public domain.
-+  */
-+ static char * strndup (const char *s, size_t size)
-+ {
-+ 	char *r;
-+ 	char *end = memchr(s, 0, size);
-+ 
-+ 	if (NULL == end)
-+ 		return NULL;
-+ 
-+ 	/* Length */
-+ 	size = end - s;
-+ 
-+ 	r = malloc(size+1);
-+ 	if (r)
-+ 	{
-+ 		memcpy(r, s, size);
-+ 		r[size] = '\0';
-+ 	}
-+ 	return r;
-+ }
-+ #endif
-+ 
-  static int scconf_replace_str_list(scconf_block * block, const char *option, const char *value)
-  {
-      scconf_list *list = NULL;
-*** pam_pkcs11-0.6.0-ORIG/tools/make_hash_link.sh	Mon May 21 02:46:19 2007
---- pam_pkcs11-WS/tools/make_hash_link.sh	Mon Sep 28 16:06:48 2009
-***************
-*** 54,60 ****
-    hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null`
-    if [ ! -z $hash ]; then
-      is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'`
-!     if [ ! -z $is_ca ]; then
-        hash=$hash.
-        mk_link
-      fi
---- 54,60 ----
-    hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null`
-    if [ ! -z $hash ]; then
-      is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'`
-!     if [ ! -z "$is_ca" ]; then
-        hash=$hash.
-        mk_link
-      fi
-***************
-*** 63,69 ****
-    hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null`
-    if [ ! -z $hash ]; then
-      is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'`
-!     if [ ! -z $is_ca ]; then
-        hash=$hash.
-        mk_link
-      fi
---- 63,69 ----
-    hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null`
-    if [ ! -z $hash ]; then
-      is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'`
-!     if [ ! -z "$is_ca" ]; then
-        hash=$hash.
-        mk_link
-      fi