File pam-git.diff of Package pam

diff --git a/README b/README
index 21af8c4c..aa99927e 100644
--- a/README
+++ b/README
@@ -6,7 +6,7 @@ NOTES:
 
 How to use it is as follows:
 
-Please look at the ci/install_dependencies.sh for the necessary
+Please look at the ci/install-dependencies.sh for the necessary
 prerequisite packages to be able to build the Linux-PAM. The script
 is targeted at Debian based Linux distributions so the package
 names and availability might differ on other distributions.
diff --git a/configure.ac b/configure.ac
index c06bc7dd..639fc1ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -259,6 +259,8 @@ AC_MSG_RESULT([Defining \$ISA to "$ISA"])
 AC_ARG_ENABLE(sconfigdir,
 	AS_HELP_STRING([--enable-sconfigdir=DIR],[path to module conf files @<:@default=$sysconfdir/security@:>@]),
 	SCONFIGDIR=$enableval, SCONFIGDIR=$sysconfdir/security)
+AC_DEFINE_UNQUOTED([SCONFIGDIR], ["$SCONFIGDIR"],
+		   [Directory for PAM modules system configuration files])
 AC_SUBST(SCONFIGDIR)
 
 AC_ARG_ENABLE(pamlocking,
@@ -507,9 +509,11 @@ AC_ARG_ENABLE([vendordir],
 if test -n "$enable_vendordir"; then
   AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
 		     [Directory for distribution provided configuration files])
-  STRINGPARAM_VENDORDIR="--stringparam vendordir '$enable_vendordir'"
+  AC_DEFINE_UNQUOTED([VENDOR_SCONFIGDIR], ["$enable_vendordir/security"],
+		     [Directory for PAM modules distribution provided configuration files])
+  STRINGPARAM_VENDORDIR="--stringparam vendordir '$enable_vendordir' --stringparam profile.condition 'with_vendordir'"
 else
-  STRINGPARAM_VENDORDIR="--stringparam vendordir '<vendordir>'"
+  STRINGPARAM_VENDORDIR="--stringparam profile.condition 'without_vendordir'"
 fi
 AC_SUBST([STRINGPARAM_VENDORDIR])
 
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 78c891df..c6fd73db 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -43,7 +43,7 @@ XMLS = pam.3.xml pam.8.xml \
 	pam_item_types_std.inc.xml pam_item_types_ext.inc.xml \
 	pam.conf-desc.xml pam.conf-dir.xml pam.conf-syntax.xml \
 	misc_conv.3.xml pam_misc_paste_env.3.xml pam_misc_drop_env.3.xml \
-	pam_misc_setenv.3.xml
+	pam_misc_setenv.3.xml pam_xauth_data.3.xml
 
 if ENABLE_REGENERATE_MAN
 PAM.8: pam.8
diff --git a/doc/man/pam.8.xml b/doc/man/pam.8.xml
index 464af0e5..8eef665a 100644
--- a/doc/man/pam.8.xml
+++ b/doc/man/pam.8.xml
@@ -158,15 +158,14 @@ closing hook for modules to affect the services available to a user.</para>
           </para>
         </listitem>
       </varlistentry>
-      <varlistentry>
+      <varlistentry condition="with_vendordir">
         <term><filename>%vendordir%/pam.d</filename></term>
         <listitem>
           <para>
             the <emphasis remap='B'>Linux-PAM</emphasis> vendor configuration
 	    directory. Files in <filename>/etc/pam.d</filename> and
 	    <filename>/usr/lib/pam.d</filename> override files with the same
-	    name in this directory. Only available if Linux-PAM was compiled
-	    with vendordir enabled.
+	    name in this directory.
           </para>
         </listitem>
       </varlistentry>
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 722ec686..c4c3c261 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -11,4 +11,4 @@ AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
 LDADD = $(top_builddir)/libpam/libpam.la \
 	$(top_builddir)/libpam_misc/libpam_misc.la
 
-noinst_PROGRAMS = xsh vpass blank check_user
+noinst_PROGRAMS = xsh vpass blank check_user tty_conv
diff --git a/examples/tty_conv.c b/examples/tty_conv.c
new file mode 100644
index 00000000..23f0684c
--- /dev/null
+++ b/examples/tty_conv.c
@@ -0,0 +1,177 @@
+/* PlanC (hubenchang0515@outlook.com) -- an example application
+ * that implements a custom conversation */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <termio.h>
+#include <security/pam_appl.h>
+
+/***************************************
+ * @brief echo off/on
+ * @param[in] fd file descriptor
+ * @param[in] off 1 - echo off,0 - echo on
+ ***************************************/
+static void echoOff(int fd, int off)
+{
+    struct termio tty;
+    if (ioctl(fd, TCGETA, &tty) < 0)
+    {
+        fprintf(stderr, "TCGETA failed: %s\n", strerror(errno));
+        return;
+    }
+
+    if (off)
+    {
+        tty.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+        if (ioctl(fd, TCSETAF, &tty) < 0)
+        {
+            fprintf(stderr, "TCSETAF failed: %s\n", strerror(errno));
+        }
+    }
+    else
+    {
+        tty.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
+        if (ioctl(fd, TCSETAW, &tty) < 0)
+        {
+            fprintf(stderr, "TCSETAW failed: %s\n", strerror(errno));
+        }
+    }
+}
+
+/***************************************
+ * @brief echo off stdin
+ ***************************************/
+static void echoOffStdin(void)
+{
+    echoOff(fileno(stdin), 1);
+}
+
+/***************************************
+ * @brief echo on stdin
+ ***************************************/
+static void echoOnStdin(void)
+{
+    echoOff(fileno(stdin), 0);
+}
+
+/***************************************
+ * @brief read a line input
+ * @return the input string
+ ***************************************/
+static char *readline(void)
+{
+    char input[PAM_MAX_RESP_SIZE];
+    int i;
+
+    flockfile(stdin);
+    for (i = 0; i < PAM_MAX_RESP_SIZE; i++)
+    {
+        int ch = getchar_unlocked();
+        if (ch == '\n' || ch == '\r' ||ch == EOF)
+            break;
+        input[i] = ch;
+    }
+    funlockfile(stdin);
+    input[i] = '\0';
+
+    return (strdup(input));
+}
+
+/**************************************************
+ * @brief callback of PAM conversation
+ * @param[in] num_msg the count of message
+ * @param[in] msg PAM message
+ * @param[out] resp our response
+ * @param[in] appdata_ptr custom data passed by struct pam_conv.appdata_ptr
+ * @return state
+ **************************************************/
+static int conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
+{
+    (void)(appdata_ptr);
+    int i;
+
+    /* check the count of message */
+    if (num_msg <= 0 || num_msg >= PAM_MAX_MSG_SIZE)
+    {
+        fprintf(stderr, "invalid num_msg(%d)\n", num_msg);
+        return PAM_CONV_ERR;
+    }
+
+    /* alloc memory for response */
+    if ((resp[0] = malloc(num_msg * sizeof(struct pam_response))) == NULL)
+    {
+        fprintf(stderr, "bad alloc\n");
+        return PAM_BUF_ERR;
+    }
+
+    /* response for message */
+    for (i = 0; i < num_msg; i++)
+    {
+        const struct pam_message *m = *msg + i;
+        struct pam_response *r = *resp + i;
+        r->resp_retcode = 0;    /* currently un-used, zero expected */
+        switch (m->msg_style)
+        {
+        case PAM_PROMPT_ECHO_OFF:   /* get the input with echo off, like the password */
+            printf("%s", m->msg);
+            echoOffStdin();
+            r->resp = readline();
+            echoOnStdin();
+            printf("\n");
+            break;
+
+        case PAM_PROMPT_ECHO_ON:    /* get the input with echo on, like the username */
+            printf("%s", m->msg);
+            r->resp = readline();
+            break;
+
+        case PAM_TEXT_INFO:         /* normal info */
+            printf("%s\n", m->msg);
+            break;
+
+        case PAM_ERROR_MSG:         /* error info */
+            fprintf(stderr, "%s\n", m->msg);
+            break;
+
+        default:
+            fprintf(stderr, "unexpected msg_style: %d\n", m->msg_style);
+            break;
+        }
+    }
+    return PAM_SUCCESS;
+}
+
+int main(void)
+{
+    struct pam_conv pam_conv = {conversation, NULL};
+    pam_handle_t *pamh;
+
+    /* echo on while exist, like Ctrl+C on input password */
+    atexit(echoOnStdin);
+
+    if (PAM_SUCCESS != pam_start("login", NULL, &pam_conv, &pamh))
+    {
+        fprintf(stderr, "pam_start failed\n");
+        return EXIT_FAILURE;
+    }
+
+    if (PAM_SUCCESS != pam_authenticate(pamh, 0))
+    {
+        fprintf(stderr, "pam_authenticate failed\n");
+        pam_end(pamh, 0);
+        return EXIT_FAILURE;
+    }
+
+    if (PAM_SUCCESS != pam_acct_mgmt(pamh, 0))
+    {
+        fprintf(stderr, "pam_acct_mgmt failed\n");
+        pam_end(pamh, 0);
+        return EXIT_FAILURE;
+    }
+
+    pam_end(pamh, 0);
+    return EXIT_SUCCESS;
+}
diff --git a/examples/xsh.c b/examples/xsh.c
index ef4dca0c..5b34fc17 100644
--- a/examples/xsh.c
+++ b/examples/xsh.c
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
 	 tty = ttyname(fileno(stdin));
 	 if (tty) {
 	     retcode = pam_set_item(pamh, PAM_TTY, tty);
-	     bail_out(pamh,1,retcode,"pam_set_item(PAM_RHOST)");
+	     bail_out(pamh,1,retcode,"pam_set_item(PAM_TTY)");
 	 }
      }
 
diff --git a/libpam/Makefile.am b/libpam/Makefile.am
index 55222afc..389d5d02 100644
--- a/libpam/Makefile.am
+++ b/libpam/Makefile.am
@@ -21,7 +21,7 @@ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
 		include/pam_inline.h include/test_assert.h
 
 libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85
-libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@
+libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ @LTLIBINTL@
 
 if HAVE_VERSIONING
   libpam_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libpam.map
diff --git a/modules/pam_access/Makefile.am b/modules/pam_access/Makefile.am
index 5723dd59..b9fbefdb 100644
--- a/modules/pam_access/Makefile.am
+++ b/modules/pam_access/Makefile.am
@@ -18,8 +18,7 @@ securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-	-DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \
-	-DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(WARN_CFLAGS)
+	    $(WARN_CFLAGS)
 AM_LDFLAGS =  -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 277192b9..0d033aa2 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -56,6 +56,9 @@
 #include "pam_cc_compat.h"
 #include "pam_inline.h"
 
+#define PAM_ACCESS_CONFIG	(SCONFIGDIR "/access.conf")
+#define ACCESS_CONF_GLOB	(SCONFIGDIR "/access.d/*.conf")
+
 /* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
 
  /*
diff --git a/modules/pam_env/Makefile.am b/modules/pam_env/Makefile.am
index c66112d6..beca8e1a 100644
--- a/modules/pam_env/Makefile.am
+++ b/modules/pam_env/Makefile.am
@@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-	-DDEFAULT_CONF_FILE=\"$(SCONFIGDIR)/pam_env.conf\" $(WARN_CFLAGS)
+	    $(WARN_CFLAGS)
 AM_LDFLAGS = -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
index f5f8cead..c03ec3a3 100644
--- a/modules/pam_env/pam_env.c
+++ b/modules/pam_env/pam_env.c
@@ -41,6 +41,8 @@ typedef struct var {
   char *override;
 } VAR;
 
+#define DEFAULT_CONF_FILE	(SCONFIGDIR "/pam_env.conf")
+
 #define BUF_SIZE 8192
 #define MAX_ENV  8192
 
diff --git a/modules/pam_faillock/Makefile.am b/modules/pam_faillock/Makefile.am
index 44a49660..16d9f8bc 100644
--- a/modules/pam_faillock/Makefile.am
+++ b/modules/pam_faillock/Makefile.am
@@ -15,7 +15,7 @@ endif
 XMLS = README.xml pam_faillock.8.xml faillock.8.xml faillock.conf.5.xml
 
 dist_check_SCRIPTS = tst-pam_faillock
-TESTS = $(dist_check_SCRIPTS)
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
 
 securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
@@ -33,6 +33,9 @@ if HAVE_VERSIONING
   pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
 endif
 
+check_PROGRAMS = tst-pam_faillock-retval
+tst_pam_faillock_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
 faillock_LDFLAGS = @EXE_LDFLAGS@
 faillock_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
 
diff --git a/modules/pam_faillock/faillock.h b/modules/pam_faillock/faillock.h
index b22a9dfb..c3f157ef 100644
--- a/modules/pam_faillock/faillock.h
+++ b/modules/pam_faillock/faillock.h
@@ -67,7 +67,10 @@ struct tally_data {
 };
 
 #define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock"
-#define FAILLOCK_DEFAULT_CONF "/etc/security/faillock.conf"
+#define FAILLOCK_DEFAULT_CONF SCONFIGDIR "/faillock.conf"
+#ifdef VENDOR_SCONFIGDIR
+#define VENDOR_FAILLOCK_DEFAULT_CONF VENDOR_SCONFIGDIR "/faillock.conf"
+#endif
 
 int open_tally(const char *dir, const char *user, uid_t uid, int create);
 int read_tally(int fd, struct tally_data *tallies);
diff --git a/modules/pam_faillock/main.c b/modules/pam_faillock/main.c
index f62e1bb2..ea6329ca 100644
--- a/modules/pam_faillock/main.c
+++ b/modules/pam_faillock/main.c
@@ -174,6 +174,11 @@ do_user(struct options *opts, const char *user)
 			time_t when = tallies.records[i].time;
 
 			tm = localtime(&when);
+			if(tm == NULL) {
+				fprintf(stderr, "%s: Invalid timestamp in the tally record\n",
+					opts->progname);
+				continue;
+			}
 			strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
 			printf("%-19s %-5s %-52.52s %s\n", timebuf,
 				status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"),
diff --git a/modules/pam_faillock/pam_faillock.8.xml b/modules/pam_faillock/pam_faillock.8.xml
index 58c16442..79bcbbd0 100644
--- a/modules/pam_faillock/pam_faillock.8.xml
+++ b/modules/pam_faillock/pam_faillock.8.xml
@@ -134,10 +134,17 @@
                  <option>conf=/path/to/config-file</option>
                </term>
                <listitem>
-                 <para>
+                 <para condition="without_vendordir">
                    Use another configuration file instead of the default
                    <filename>/etc/security/faillock.conf</filename>.
                  </para>
+                 <para condition="with_vendordir">
+                   Use another configuration file instead of the default
+                   which is to use the file
+                   <filename>/etc/security/faillock.conf</filename> or,
+                   if that one is not present, the file
+                   <filename>%vendordir%/security/faillock.conf</filename>.
+                 </para>
                </listitem>
             </varlistentry>
         </variablelist>
@@ -328,6 +335,15 @@ session  required       pam_selinux.so open
           <para>the config file for pam_faillock options</para>
         </listitem>
       </varlistentry>
+      <varlistentry condition="with_vendordir">
+        <term><filename>%vendordir%/security/faillock.conf</filename></term>
+        <listitem>
+          <para>
+            the config file for pam_faillock options. It will be used if
+            <filename>/etc/security/faillock.conf</filename> does not exist.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
index 8328fbae..932d4281 100644
--- a/modules/pam_faillock/pam_faillock.c
+++ b/modules/pam_faillock/pam_faillock.c
@@ -192,6 +192,15 @@ read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile)
 	char linebuf[FAILLOCK_CONF_MAX_LINELEN+1];
 
 	f = fopen(cfgfile, "r");
+#ifdef VENDOR_FAILLOCK_DEFAULT_CONF
+	if (f == NULL && errno == ENOENT && cfgfile == default_faillock_conf) {
+	  /*
+	   * If the default configuration file in /etc does not exist,
+	   * try the vendor configuration file as fallback.
+	   */
+	  f = fopen(VENDOR_FAILLOCK_DEFAULT_CONF, "r");
+	}
+#endif
 	if (f == NULL) {
 		/* ignore non-existent default config file */
 		if (errno == ENOENT && cfgfile == default_faillock_conf)
diff --git a/modules/pam_faillock/tst-pam_faillock-retval.c b/modules/pam_faillock/tst-pam_faillock-retval.c
new file mode 100644
index 00000000..133026cb
--- /dev/null
+++ b/modules/pam_faillock/tst-pam_faillock-retval.c
@@ -0,0 +1,119 @@
+/*
+ * Check pam_faillock return values.
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_faillock"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char config_filename[] = TEST_NAME ".conf";
+static const char user_name[] = "root";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+	pam_handle_t *pamh = NULL;
+	FILE *fp;
+	char cwd[PATH_MAX];
+
+	ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+	ASSERT_NE(NULL, fp = fopen(config_filename, "w"));
+	ASSERT_LT(0, fprintf(fp,
+		"deny = 2\n"
+		"unlock_time = 5\n"
+		"root_unlock_time = 5\n"));
+	ASSERT_EQ(0, fclose(fp));
+
+	/* root has access */
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+			"auth required %s/../pam_permit/.libs/pam_permit.so\n"
+			"auth required %s/.libs/%s.so authsucc even_deny_root dir=%s conf=%s\n"
+			"account required %s/.libs/%s.so dir=%s\n"
+			"password required %s/.libs/%s.so dir=%s\n"
+			"session required %s/.libs/%s.so dir=%s\n",
+			cwd,
+			cwd, MODULE_NAME, cwd, config_filename,
+			cwd, MODULE_NAME, cwd,
+			cwd, MODULE_NAME, cwd,
+			cwd, MODULE_NAME, cwd));
+
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	ASSERT_EQ(0, unlink(service_file));
+	pamh = NULL;
+
+	/* root tries to login 2 times without success*/
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+			"auth requisite %s/.libs/%s.so dir=%s preauth even_deny_root conf=%s\n"
+			"auth [success=1 default=bad] %s/../pam_debug/.libs/pam_debug.so auth=perm_denied cred=success\n"
+			"auth [default=die] %s/.libs/%s.so dir=%s authfail even_deny_root conf=%s\n"
+			"auth sufficient %s/.libs/%s.so dir=%s authsucc even_deny_root conf=%s\n",
+			cwd, MODULE_NAME, cwd, config_filename,
+			cwd,
+			cwd, MODULE_NAME, cwd, config_filename,
+			cwd, MODULE_NAME, cwd, config_filename));
+
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+	pamh = NULL;
+	ASSERT_EQ(0, unlink(service_file));
+
+	/* root is locked for 5 sec*/
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+			"auth requisite %s/.libs/%s.so dir=%s preauth even_deny_root conf=%s\n"
+			"auth [success=1 default=bad] %s/../pam_debug/.libs/pam_debug.so auth=success cred=success\n"
+			"auth [default=die] %s/.libs/%s.so dir=%s authfail even_deny_root conf=%s\n"
+			"auth sufficient %s/.libs/%s.so dir=%s authsucc even_deny_root conf=%s\n",
+			cwd, MODULE_NAME, cwd, config_filename,
+			cwd,
+			cwd, MODULE_NAME, cwd, config_filename,
+			cwd, MODULE_NAME, cwd, config_filename));
+
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_AUTH_ERR, pam_authenticate(pamh, 0));
+
+	/* waiting at least 5 sec --> login is working again*/
+	sleep(6);
+	ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	ASSERT_EQ(0, unlink(service_file));
+	pamh = NULL;
+
+	ASSERT_EQ(0,unlink(user_name));
+	ASSERT_EQ(0,unlink(config_filename));
+
+	return 0;
+}
diff --git a/modules/pam_group/Makefile.am b/modules/pam_group/Makefile.am
index a9a0a1ef..fd88b952 100644
--- a/modules/pam_group/Makefile.am
+++ b/modules/pam_group/Makefile.am
@@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-	-DPAM_GROUP_CONF=\"$(SCONFIGDIR)/group.conf\" $(WARN_CFLAGS)
+	    $(WARN_CFLAGS)
 AM_LDFLAGS = -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_group/pam_group.8.xml b/modules/pam_group/pam_group.8.xml
index 2c1c9058..e4a59dfd 100644
--- a/modules/pam_group/pam_group.8.xml
+++ b/modules/pam_group/pam_group.8.xml
@@ -38,6 +38,10 @@
       By default rules for group memberships are taken from config file
       <filename>/etc/security/group.conf</filename>.
     </para>
+    <para condition="with_vendordir">
+      If <filename>/etc/security/group.conf</filename> does not exist,
+      <filename>%vendordir%/security/group.conf</filename> is used.
+    </para>
     <para>
       This module's usefulness relies on the file-systems
       accessible to the user. The point being that once granted the
diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c
index d9a35ea6..c49358a1 100644
--- a/modules/pam_group/pam_group.c
+++ b/modules/pam_group/pam_group.c
@@ -16,6 +16,7 @@
 #include <time.h>
 #include <syslog.h>
 #include <string.h>
+#include <errno.h>
 
 #include <grp.h>
 #include <sys/types.h>
@@ -23,6 +24,10 @@
 #include <fcntl.h>
 #include <netdb.h>
 
+#define PAM_GROUP_CONF		SCONFIGDIR "/group.conf"
+#ifdef VENDOR_SCONFIGDIR
+# define VENDOR_PAM_GROUP_CONF	VENDOR_SCONFIGDIR "/group.conf"
+#endif
 #define PAM_GROUP_BUFLEN        1000
 #define FIELD_SEPARATOR         ';'   /* this is new as of .02 */
 
@@ -70,7 +75,8 @@ trim_spaces(char *buf, char *from)
 #define STATE_EOF      3 /* end of file or error */
 
 static int
-read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state)
+read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state,
+	   const char *conf_filename)
 {
     char *to;
     char *src;
@@ -89,9 +95,9 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state)
 	}
 	*from = 0;
         *state = STATE_NL;
-	fd = open(PAM_GROUP_CONF, O_RDONLY);
+	fd = open(conf_filename, O_RDONLY);
 	if (fd < 0) {
-	    pam_syslog(pamh, LOG_ERR, "error opening %s: %m", PAM_GROUP_CONF);
+	    pam_syslog(pamh, LOG_ERR, "error opening %s: %m", conf_filename);
 	    _pam_drop(*buf);
 	    *state = STATE_EOF;
 	    return -1;
@@ -106,7 +112,7 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state)
     while (fd != -1 && to - *buf < PAM_GROUP_BUFLEN) {
 	i = pam_modutil_read(fd, to, PAM_GROUP_BUFLEN - (to - *buf));
 	if (i < 0) {
-	    pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_GROUP_CONF);
+	    pam_syslog(pamh, LOG_ERR, "error reading %s: %m", conf_filename);
 	    close(fd);
 	    memset(*buf, 0, PAM_GROUP_BUFLEN);
 	    _pam_drop(*buf);
@@ -573,6 +579,18 @@ static int check_account(pam_handle_t *pamh, const char *service,
     int retval=PAM_SUCCESS;
     gid_t *grps;
     int no_grps;
+    const char *conf_filename = PAM_GROUP_CONF;
+
+#ifdef VENDOR_PAM_GROUP_CONF
+    /*
+     * Check whether PAM_GROUP_CONF file is available.
+     * If it does not exist, fall back to VENDOR_PAM_GROUP_CONF file.
+     */
+    struct stat stat_buffer;
+    if (stat(conf_filename, &stat_buffer) != 0 && errno == ENOENT) {
+	conf_filename = VENDOR_PAM_GROUP_CONF;
+    }
+#endif
 
     /*
      * first we get the current list of groups - the application
@@ -611,7 +629,7 @@ static int check_account(pam_handle_t *pamh, const char *service,
 
 	/* here we get the service name field */
 
-	fd = read_field(pamh, fd, &buffer, &from, &state);
+	fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename);
 	if (!buffer || !buffer[0]) {
 	    /* empty line .. ? */
 	    continue;
@@ -621,7 +639,7 @@ static int check_account(pam_handle_t *pamh, const char *service,
 
 	if (state != STATE_FIELD) {
 	    pam_syslog(pamh, LOG_ERR,
-		       "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+		       "%s: malformed rule #%d", conf_filename, count);
 	    continue;
 	}
 
@@ -630,10 +648,10 @@ static int check_account(pam_handle_t *pamh, const char *service,
 
 	/* here we get the terminal name field */
 
-	fd = read_field(pamh, fd, &buffer, &from, &state);
+	fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename);
 	if (state != STATE_FIELD) {
 	    pam_syslog(pamh, LOG_ERR,
-		       "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+		       "%s: malformed rule #%d", conf_filename, count);
 	    continue;
 	}
 	good &= logic_field(pamh,tty, buffer, count, is_same);
@@ -641,10 +659,10 @@ static int check_account(pam_handle_t *pamh, const char *service,
 
 	/* here we get the username field */
 
-	fd = read_field(pamh, fd, &buffer, &from, &state);
+	fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename);
 	if (state != STATE_FIELD) {
 	    pam_syslog(pamh, LOG_ERR,
-		       "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+		       "%s: malformed rule #%d", conf_filename, count);
 	    continue;
 	}
 	/* If buffer starts with @, we are using netgroups */
@@ -663,20 +681,20 @@ static int check_account(pam_handle_t *pamh, const char *service,
 
 	/* here we get the time field */
 
-	fd = read_field(pamh, fd, &buffer, &from, &state);
+	fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename);
 	if (state != STATE_FIELD) {
 	    pam_syslog(pamh, LOG_ERR,
-		       "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+		       "%s: malformed rule #%d", conf_filename, count);
 	    continue;
 	}
 
 	good &= logic_field(pamh,&here_and_now, buffer, count, check_time);
 	D(("with time: %s", good ? "passes":"fails" ));
 
-	fd = read_field(pamh, fd, &buffer, &from, &state);
+	fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename);
 	if (state == STATE_FIELD) {
 	    pam_syslog(pamh, LOG_ERR,
-		       "%s: poorly terminated rule #%d", PAM_GROUP_CONF, count);
+		       "%s: poorly terminated rule #%d", conf_filename, count);
 	    continue;
 	}
 
diff --git a/modules/pam_limits/Makefile.am b/modules/pam_limits/Makefile.am
index 911b07b3..9ae1794d 100644
--- a/modules/pam_limits/Makefile.am
+++ b/modules/pam_limits/Makefile.am
@@ -19,8 +19,8 @@ secureconfdir = $(SCONFIGDIR)
 limits_conf_dir = $(SCONFIGDIR)/limits.d
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-	-DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \
-	-DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\" $(WARN_CFLAGS)
+	    -DLIMITS_FILE_DIR=\"$(limits_conf_dir)\" \
+	    $(WARN_CFLAGS)
 AM_LDFLAGS = -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml
index bc46cbf4..08c6fc4d 100644
--- a/modules/pam_limits/pam_limits.8.xml
+++ b/modules/pam_limits/pam_limits.8.xml
@@ -57,6 +57,11 @@
       If a config file is explicitly specified with a module option then the
       files in the above directory are not parsed.
     </para>
+    <para condition="with_vendordir">
+      If there is no explicitly specified configuration file and
+      <filename>/etc/security/limits.conf</filename> does not exist,
+      <filename>%vendordir%/security/limits.conf</filename> is used.
+    </para>
     <para>
       The module must not be called by a multithreaded application.
     </para>
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
index 7cc45d77..6fbe95fc 100644
--- a/modules/pam_limits/pam_limits.c
+++ b/modules/pam_limits/pam_limits.c
@@ -47,6 +47,10 @@
 #include <libaudit.h>
 #endif
 
+#ifndef PR_SET_NO_NEW_PRIVS
+# define PR_SET_NO_NEW_PRIVS 38 /* from <linux/prctl.h> */
+#endif
+
 /* Module defines */
 #define LINE_LENGTH 1024
 
@@ -119,9 +123,10 @@ struct pam_limit_s {
 #define PAM_SET_ALL         0x0010
 
 /* Limits from globbed files. */
-#define LIMITS_CONF_GLOB LIMITS_FILE_DIR
+#define LIMITS_CONF_GLOB	(LIMITS_FILE_DIR "/*.conf")
 
-#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE
+#define LIMITS_FILE	(SCONFIGDIR "/limits.conf")
+#define CONF_FILE	((pl->conf_file != NULL) ? pl->conf_file : LIMITS_FILE)
 
 static int
 _pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
@@ -811,14 +816,30 @@ parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid,
     FILE *fil;
     char buf[LINE_LENGTH];
 
-    /* check for the LIMITS_FILE */
+    /* check for the CONF_FILE */
     if (ctrl & PAM_DEBUG_ARG)
         pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE);
     fil = fopen(CONF_FILE, "r");
     if (fil == NULL) {
-        pam_syslog (pamh, LOG_WARNING,
-		    "cannot read settings from %s: %m", CONF_FILE);
-        return PAM_SERVICE_ERR;
+      int err = errno;
+
+#ifdef VENDOR_SCONFIGDIR
+      /* if the specified file does not exist, and it is not provided by
+         the user, try the vendor file as fallback. */
+      if (pl->conf_file == NULL && err == ENOENT)
+        fil = fopen(VENDOR_SCONFIGDIR "/limits.conf", "r");
+
+      if (fil == NULL)
+#endif
+        {
+          if (err == ENOENT)
+            return PAM_SUCCESS;
+
+          pam_syslog (pamh, LOG_WARNING,
+                      "cannot read settings from %s: %s", CONF_FILE,
+                      strerror(err));
+          return PAM_SERVICE_ERR;
+        }
     }
 
     /* start the show */
diff --git a/modules/pam_namespace/Makefile.am b/modules/pam_namespace/Makefile.am
index 47cc38e1..33375857 100644
--- a/modules/pam_namespace/Makefile.am
+++ b/modules/pam_namespace/Makefile.am
@@ -21,7 +21,7 @@ namespaceddir = $(SCONFIGDIR)/namespace.d
 servicedir = $(systemdunitdir)
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-        -DSECURECONF_DIR=\"$(SCONFIGDIR)/\" $(WARN_CFLAGS)
+	    $(WARN_CFLAGS)
 AM_LDFLAGS =  -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
index b51f2841..169bd59f 100644
--- a/modules/pam_namespace/pam_namespace.h
+++ b/modules/pam_namespace/pam_namespace.h
@@ -90,14 +90,10 @@
 /*
  * Module defines
  */
-#ifndef SECURECONF_DIR
-#define SECURECONF_DIR "/etc/security/"
-#endif
-
-#define PAM_NAMESPACE_CONFIG (SECURECONF_DIR "namespace.conf")
-#define NAMESPACE_INIT_SCRIPT (SECURECONF_DIR "namespace.init")
-#define NAMESPACE_D_DIR (SECURECONF_DIR "namespace.d/")
-#define NAMESPACE_D_GLOB (SECURECONF_DIR "namespace.d/*.conf")
+#define PAM_NAMESPACE_CONFIG (SCONFIGDIR "/namespace.conf")
+#define NAMESPACE_INIT_SCRIPT (SCONFIGDIR "/namespace.init")
+#define NAMESPACE_D_DIR (SCONFIGDIR "/namespace.d/")
+#define NAMESPACE_D_GLOB (SCONFIGDIR "/namespace.d/*.conf")
 
 /* module flags */
 #define PAMNS_DEBUG           0x00000100 /* Running in debug mode */
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index a6cd3d2a..1d3242ca 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -44,6 +44,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -74,8 +75,7 @@
 #define RANDOM_DEVICE "/dev/urandom"
 #endif
 
-#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
-#define TMP_PASSWORDS_FILE OLD_PASSWORDS_FILE".tmpXXXXXX"
+#define DEFAULT_OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd"
 
 #define DEFAULT_BUFLEN 4096
 
@@ -142,7 +142,7 @@ compare_password(const char *newpass, const char *oldpass)
 
 /* Check, if the new password is already in the opasswd file.  */
 PAMH_ARG_DECL(int
-check_old_pass, const char *user, const char *newpass, int debug)
+check_old_pass, const char *user, const char *newpass, const char *filename, int debug)
 {
   int retval = PAM_SUCCESS;
   FILE *oldpf;
@@ -156,10 +156,13 @@ check_old_pass, const char *user, const char *newpass, int debug)
     return PAM_PWHISTORY_RUN_HELPER;
 #endif
 
-  if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+  const char *opasswd_file =
+	  (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+
+  if ((oldpf = fopen (opasswd_file, "r")) == NULL)
     {
       if (errno != ENOENT)
-	pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", OLD_PASSWORDS_FILE);
+	pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
       return PAM_SUCCESS;
     }
 
@@ -242,9 +245,8 @@ check_old_pass, const char *user, const char *newpass, int debug)
 }
 
 PAMH_ARG_DECL(int
-save_old_pass, const char *user, int howmany, int debug UNUSED)
+save_old_pass, const char *user, int howmany, const char *filename, int debug UNUSED)
 {
-  char opasswd_tmp[] = TMP_PASSWORDS_FILE;
   struct stat opasswd_stat;
   FILE *oldpf, *newpf;
   int newpf_fd;
@@ -256,6 +258,15 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
   struct passwd *pwd;
   const char *oldpass;
 
+  /* Define opasswd file and temp file for opasswd */
+  const char *opasswd_file =
+	  (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+  char opasswd_tmp[PATH_MAX];
+
+  if ((size_t) snprintf (opasswd_tmp, sizeof (opasswd_tmp), "%s.tmpXXXXXX",
+			 opasswd_file) >= sizeof (opasswd_tmp))
+    return PAM_BUF_ERR;
+
   pwd = pam_modutil_getpwnam (pamh, user);
   if (pwd == NULL)
     return PAM_USER_UNKNOWN;
@@ -285,24 +296,22 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
   if (oldpass == NULL || *oldpass == '\0')
     return PAM_SUCCESS;
 
-  if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+  if ((oldpf = fopen (opasswd_file, "r")) == NULL)
     {
       if (errno == ENOENT)
 	{
-	  pam_syslog (pamh, LOG_NOTICE, "Creating %s",
-		      OLD_PASSWORDS_FILE);
+	  pam_syslog (pamh, LOG_NOTICE, "Creating %s", opasswd_file);
 	  do_create = 1;
 	}
       else
 	{
-	  pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m",
-		      OLD_PASSWORDS_FILE);
+	  pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
 	  return PAM_AUTHTOK_ERR;
 	}
     }
   else if (fstat (fileno (oldpf), &opasswd_stat) < 0)
     {
-      pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", OLD_PASSWORDS_FILE);
+      pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", opasswd_file);
       fclose (oldpf);
       return PAM_AUTHTOK_ERR;
     }
@@ -312,7 +321,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
   if (newpf_fd == -1)
     {
       pam_syslog (pamh, LOG_ERR, "Cannot create %s temp file: %m",
-		  OLD_PASSWORDS_FILE);
+		  opasswd_file);
       if (oldpf)
 	fclose (oldpf);
       return PAM_AUTHTOK_ERR;
@@ -321,23 +330,19 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
     {
       if (fchmod (newpf_fd, S_IRUSR|S_IWUSR) != 0)
 	pam_syslog (pamh, LOG_ERR,
-		    "Cannot set permissions of %s temp file: %m",
-		    OLD_PASSWORDS_FILE);
+		    "Cannot set permissions of %s temp file: %m", opasswd_file);
       if (fchown (newpf_fd, 0, 0) != 0)
 	pam_syslog (pamh, LOG_ERR,
-		    "Cannot set owner/group of %s temp file: %m",
-		    OLD_PASSWORDS_FILE);
+		    "Cannot set owner/group of %s temp file: %m", opasswd_file);
     }
   else
     {
       if (fchmod (newpf_fd, opasswd_stat.st_mode) != 0)
 	pam_syslog (pamh, LOG_ERR,
-		    "Cannot set permissions of %s temp file: %m",
-		    OLD_PASSWORDS_FILE);
+		    "Cannot set permissions of %s temp file: %m", opasswd_file);
       if (fchown (newpf_fd, opasswd_stat.st_uid, opasswd_stat.st_gid) != 0)
 	pam_syslog (pamh, LOG_ERR,
-		    "Cannot set owner/group of %s temp file: %m",
-		    OLD_PASSWORDS_FILE);
+		    "Cannot set owner/group of %s temp file: %m", opasswd_file);
     }
   newpf = fdopen (newpf_fd, "w+");
   if (newpf == NULL)
@@ -550,12 +555,20 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
       goto error_opasswd;
     }
 
-  unlink (OLD_PASSWORDS_FILE".old");
-  if (link (OLD_PASSWORDS_FILE, OLD_PASSWORDS_FILE".old") != 0 &&
+  char opasswd_backup[PATH_MAX];
+  if ((size_t) snprintf (opasswd_backup, sizeof (opasswd_backup), "%s.old",
+			 opasswd_file) >= sizeof (opasswd_backup))
+    {
+      retval = PAM_BUF_ERR;
+      goto error_opasswd;
+    }
+
+  unlink (opasswd_backup);
+  if (link (opasswd_file, opasswd_backup) != 0 &&
       errno != ENOENT)
     pam_syslog (pamh, LOG_ERR, "Cannot create backup file of %s: %m",
-		OLD_PASSWORDS_FILE);
-  rename (opasswd_tmp, OLD_PASSWORDS_FILE);
+		opasswd_file);
+  rename (opasswd_tmp, opasswd_file);
  error_opasswd:
   unlink (opasswd_tmp);
   free (buf);
diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h
index 3f257288..19a4062c 100644
--- a/modules/pam_pwhistory/opasswd.h
+++ b/modules/pam_pwhistory/opasswd.h
@@ -57,10 +57,10 @@ void
 helper_log_err(int err, const char *format, ...);
 #endif
 
-PAMH_ARG_DECL(int
-check_old_pass, const char *user, const char *newpass, int debug);
+PAMH_ARG_DECL(int check_old_pass, const char *user, const char *newpass,
+              const char *filename, int debug);
 
-PAMH_ARG_DECL(int
-save_old_pass, const char *user, int howmany, int debug);
+PAMH_ARG_DECL(int save_old_pass, const char *user, int howmany,
+              const char *filename, int debug);
 
 #endif /* __OPASSWD_H__ */
diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml
index d88115c2..df16a776 100644
--- a/modules/pam_pwhistory/pam_pwhistory.8.xml
+++ b/modules/pam_pwhistory/pam_pwhistory.8.xml
@@ -36,6 +36,9 @@
       <arg choice="opt">
         authtok_type=<replaceable>STRING</replaceable>
       </arg>
+      <arg choice="opt">
+	      file=<replaceable>/path/filename</replaceable>
+      </arg>
 
     </cmdsynopsis>
   </refsynopsisdiv>
@@ -137,6 +140,19 @@
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>
+            <option>file=<replaceable>/path/filename</replaceable></option>
+          </term>
+          <listitem>
+            <para>
+              Store password history in file <filename>/path/filename</filename>
+              rather than the default location. The default location is
+	      <filename>/etc/security/opasswd</filename>.
+            </para>
+          </listitem>
+        </varlistentry>
+
     </variablelist>
   </refsect1>
 
@@ -213,7 +229,7 @@ password     required       pam_unix.so        use_authtok
       <varlistentry>
         <term><filename>/etc/security/opasswd</filename></term>
         <listitem>
-          <para>File with password history</para>
+          <para>Default file with password history</para>
         </listitem>
       </varlistentry>
     </variablelist>
diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c
index ce2c21f5..9c1bdd87 100644
--- a/modules/pam_pwhistory/pam_pwhistory.c
+++ b/modules/pam_pwhistory/pam_pwhistory.c
@@ -69,6 +69,7 @@ struct options_t {
   int enforce_for_root;
   int remember;
   int tries;
+  const char *filename;
 };
 typedef struct options_t options_t;
 
@@ -104,13 +105,23 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
     options->enforce_for_root = 1;
   else if (pam_str_skip_icase_prefix(argv, "authtok_type=") != NULL)
     { /* ignore, for pam_get_authtok */; }
+  else if ((str = pam_str_skip_icase_prefix(argv, "file=")) != NULL)
+    {
+      if (*str != '/')
+        {
+          pam_syslog (pamh, LOG_ERR,
+                      "pam_pwhistory: file path should be absolute: %s", argv);
+        }
+      else
+        options->filename = str;
+    }
   else
     pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
 }
 
 static int
 run_save_helper(pam_handle_t *pamh, const char *user,
-		int howmany, int debug)
+		int howmany, const char *filename, int debug)
 {
   int retval, child;
   struct sigaction newsa, oldsa;
@@ -123,7 +134,7 @@ run_save_helper(pam_handle_t *pamh, const char *user,
   if (child == 0)
     {
       static char *envp[] = { NULL };
-      char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+      char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
       if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
           PAM_MODUTIL_PIPE_FD,
@@ -137,9 +148,10 @@ run_save_helper(pam_handle_t *pamh, const char *user,
       args[0] = (char *)PWHISTORY_HELPER;
       args[1] = (char *)"save";
       args[2] = (char *)user;
+      args[3] = (char *)filename;
       DIAG_POP_IGNORE_CAST_QUAL;
-      if (asprintf(&args[3], "%d", howmany) < 0 ||
-          asprintf(&args[4], "%d", debug) < 0)
+      if (asprintf(&args[4], "%d", howmany) < 0 ||
+          asprintf(&args[5], "%d", debug) < 0)
         {
           pam_syslog(pamh, LOG_ERR, "asprintf: %m");
           _exit(PAM_SYSTEM_ERR);
@@ -185,7 +197,7 @@ run_save_helper(pam_handle_t *pamh, const char *user,
 
 static int
 run_check_helper(pam_handle_t *pamh, const char *user,
-		 const char *newpass, int debug)
+		 const char *newpass, const char *filename, int debug)
 {
   int retval, child, fds[2];
   struct sigaction newsa, oldsa;
@@ -202,7 +214,7 @@ run_check_helper(pam_handle_t *pamh, const char *user,
   if (child == 0)
     {
       static char *envp[] = { NULL };
-      char *args[] = { NULL, NULL, NULL, NULL, NULL };
+      char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
 
       /* reopen stdin as pipe */
       if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO)
@@ -223,8 +235,9 @@ run_check_helper(pam_handle_t *pamh, const char *user,
       args[0] = (char *)PWHISTORY_HELPER;
       args[1] = (char *)"check";
       args[2] = (char *)user;
+      args[3] = (char *)filename;
       DIAG_POP_IGNORE_CAST_QUAL;
-      if (asprintf(&args[3], "%d", debug) < 0)
+      if (asprintf(&args[4], "%d", debug) < 0)
         {
           pam_syslog(pamh, LOG_ERR, "asprintf: %m");
           _exit(PAM_SYSTEM_ERR);
@@ -323,10 +336,10 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
       return PAM_SUCCESS;
     }
 
-  retval = save_old_pass (pamh, user, options.remember, options.debug);
+  retval = save_old_pass (pamh, user, options.remember, options.filename, options.debug);
 
   if (retval == PAM_PWHISTORY_RUN_HELPER)
-      retval = run_save_helper(pamh, user, options.remember, options.debug);
+      retval = run_save_helper(pamh, user, options.remember, options.filename, options.debug);
 
   if (retval != PAM_SUCCESS)
     return retval;
@@ -358,9 +371,9 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
       if (options.debug)
 	pam_syslog (pamh, LOG_DEBUG, "check against old password file");
 
-      retval = check_old_pass (pamh, user, newpass, options.debug);
+      retval = check_old_pass (pamh, user, newpass, options.filename, options.debug);
       if (retval == PAM_PWHISTORY_RUN_HELPER)
-	  retval = run_check_helper(pamh, user, newpass, options.debug);
+	  retval = run_check_helper(pamh, user, newpass, options.filename, options.debug);
 
       if (retval != PAM_SUCCESS)
 	{
diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c
index b08a14a7..7a61ae53 100644
--- a/modules/pam_pwhistory/pwhistory_helper.c
+++ b/modules/pam_pwhistory/pwhistory_helper.c
@@ -51,7 +51,7 @@
 
 
 static int
-check_history(const char *user, const char *debug)
+check_history(const char *user, const char *filename, const char *debug)
 {
   char pass[PAM_MAX_RESP_SIZE + 1];
   char *passwords[] = { pass };
@@ -68,7 +68,7 @@ check_history(const char *user, const char *debug)
       return PAM_AUTHTOK_ERR;
     }
 
-  retval = check_old_pass(user, pass, dbg);
+  retval = check_old_pass(user, pass, filename, dbg);
 
   memset(pass, '\0', PAM_MAX_RESP_SIZE);	/* clear memory of the password */
 
@@ -76,13 +76,13 @@ check_history(const char *user, const char *debug)
 }
 
 static int
-save_history(const char *user, const char *howmany, const char *debug)
+save_history(const char *user, const char *filename, const char *howmany, const char *debug)
 {
   int num = atoi(howmany);
   int dbg = atoi(debug); /* no need to be too fancy here */
   int retval;
 
-  retval = save_old_pass(user, num, dbg);
+  retval = save_old_pass(user, num, filename, dbg);
 
   return retval;
 }
@@ -92,13 +92,14 @@ main(int argc, char *argv[])
 {
   const char *option;
   const char *user;
+  const char *filename;
 
   /*
    * we establish that this program is running with non-tty stdin.
    * this is to discourage casual use.
    */
 
-  if (isatty(STDIN_FILENO) || argc < 4)
+  if (isatty(STDIN_FILENO) || argc < 5)
     {
       fprintf(stderr,
             "This binary is not designed for running in this way.\n");
@@ -107,11 +108,12 @@ main(int argc, char *argv[])
 
   option = argv[1];
   user = argv[2];
+  filename = argv[3];
 
-  if (strcmp(option, "check") == 0 && argc == 4)
-    return check_history(user, argv[3]);
-  else if (strcmp(option, "save") == 0 && argc == 5)
-    return save_history(user, argv[3], argv[4]);
+  if (strcmp(option, "check") == 0 && argc == 5)
+    return check_history(user, filename, argv[4]);
+  else if (strcmp(option, "save") == 0 && argc == 6)
+    return save_history(user, filename, argv[4], argv[5]);
 
   fprintf(stderr, "This binary is not designed for running in this way.\n");
 
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
index dd374c53..9bc15abf 100644
--- a/modules/pam_rootok/pam_rootok.c
+++ b/modules/pam_rootok/pam_rootok.c
@@ -53,11 +53,10 @@ static int
 PAM_FORMAT((printf, 2, 3))
 log_callback (int type UNUSED, const char *fmt, ...)
 {
-    int audit_fd;
     va_list ap;
 
 #ifdef HAVE_LIBAUDIT
-    audit_fd = audit_open();
+    int audit_fd = audit_open();
 
     if (audit_fd >= 0) {
 	char *buf;
diff --git a/modules/pam_sepermit/Makefile.am b/modules/pam_sepermit/Makefile.am
index 18a89b60..bed3b149 100644
--- a/modules/pam_sepermit/Makefile.am
+++ b/modules/pam_sepermit/Makefile.am
@@ -13,7 +13,7 @@ dist_man_MANS = pam_sepermit.8 sepermit.conf.5
 endif
 XMLS = README.xml pam_sepermit.8.xml sepermit.conf.5.xml
 dist_check_SCRIPTS = tst-pam_sepermit
-TESTS = $(dist_check_SCRIPTS)
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
 
 securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
@@ -21,7 +21,6 @@ sepermitlockdir = ${localstatedir}/run/sepermit
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
 	-I$(top_srcdir)/libpam_misc/include \
-	-D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\" \
 	-D SEPERMIT_LOCKDIR=\"$(sepermitlockdir)\" $(WARN_CFLAGS)
 
 pam_sepermit_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
@@ -33,6 +32,9 @@ endif
 dist_secureconf_DATA = sepermit.conf
 securelib_LTLIBRARIES = pam_sepermit.la
 
+check_PROGRAMS = tst-pam_sepermit-retval
+tst_pam_sepermit_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
 install-data-local:
 	mkdir -p $(DESTDIR)$(sepermitlockdir)
 
diff --git a/modules/pam_sepermit/pam_sepermit.8.xml b/modules/pam_sepermit/pam_sepermit.8.xml
index 30d9cc54..5763c346 100644
--- a/modules/pam_sepermit/pam_sepermit.8.xml
+++ b/modules/pam_sepermit/pam_sepermit.8.xml
@@ -54,7 +54,11 @@
       <refentrytitle>sepermit.conf</refentrytitle><manvolnum>5</manvolnum>
       </citerefentry> for details.
     </para>
-
+      <para condition="with_vendordir">
+      If there is no explicitly specified configuration file and
+      <filename>/etc/security/sepermit.conf</filename> does not exist,
+      <filename>%vendordir%/security/sepermit.conf</filename> is used.
+    </para>
   </refsect1>
 
   <refsect1 id="pam_sepermit-options">
diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c
index f7d98d5b..5fbc8fdd 100644
--- a/modules/pam_sepermit/pam_sepermit.c
+++ b/modules/pam_sepermit/pam_sepermit.c
@@ -61,6 +61,12 @@
 
 #include <selinux/selinux.h>
 
+#include "pam_inline.h"
+
+#define SEPERMIT_CONF_FILE	(SCONFIGDIR "/sepermit.conf")
+#ifdef VENDOR_SCONFIGDIR
+# define SEPERMIT_VENDOR_CONF_FILE	(VENDOR_SCONFIGDIR "/sepermit.conf");
+#endif
 #define MODULE "pam_sepermit"
 #define OPT_DELIM ":"
 
@@ -370,16 +376,31 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
 	const char *user = NULL;
 	char *seuser = NULL;
 	char *level = NULL;
-	const char *cfgfile = SEPERMIT_CONF_FILE;
+	const char *cfgfile = NULL;
 
 	/* Parse arguments. */
 	for (i = 0; i < argc; i++) {
+		const char *str;
+
 		if (strcmp(argv[i], "debug") == 0) {
 			debug = 1;
+		} else if ((str = pam_str_skip_prefix(argv[i], "conf=")) != NULL) {
+			cfgfile = str;
+		} else {
+			pam_syslog(pamh, LOG_ERR, "unknown option: %s", argv[i]);
 		}
-		if (strcmp(argv[i], "conf=") == 0) {
-			cfgfile = argv[i] + 5;
-		}
+	}
+
+	if (cfgfile == NULL) {
+#ifdef SEPERMIT_VENDOR_CONF_FILE
+		struct stat buffer;
+
+		cfgfile = SEPERMIT_CONF_FILE;
+		if (stat(cfgfile, &buffer) != 0 && errno == ENOENT)
+			cfgfile = SEPERMIT_VENDOR_CONF_FILE;
+#else
+		cfgfile = SEPERMIT_CONF_FILE;
+#endif
 	}
 
 	if (debug)
diff --git a/modules/pam_sepermit/tst-pam_sepermit-retval.c b/modules/pam_sepermit/tst-pam_sepermit-retval.c
new file mode 100644
index 00000000..321bd6d1
--- /dev/null
+++ b/modules/pam_sepermit/tst-pam_sepermit-retval.c
@@ -0,0 +1,158 @@
+/*
+ * Check pam_sepermit return values and conf= option.
+ *
+ * Copyright (c) 2020-2022 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_sepermit"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char missing_file[] = TEST_NAME ".missing";
+static const char config_file[] = TEST_NAME ".conf";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+	pam_handle_t *pamh = NULL;
+	FILE *fp;
+	char cwd[PATH_MAX];
+
+	ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+	/* PAM_USER_UNKNOWN */
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0,
+		  fprintf(fp, "#%%PAM-1.0\n"
+			      "auth required %s/.libs/%s.so\n"
+			      "account required %s/.libs/%s.so\n"
+			      "password required %s/.libs/%s.so\n"
+			      "session required %s/.libs/%s.so\n",
+			  cwd, MODULE_NAME,
+			  cwd, MODULE_NAME,
+			  cwd, MODULE_NAME,
+			  cwd, MODULE_NAME));
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		  pam_start_confdir(service_file, "", &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_USER_UNKNOWN, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+	ASSERT_EQ(PAM_USER_UNKNOWN, pam_acct_mgmt(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	pamh = NULL;
+
+	ASSERT_NE(NULL, fp = fopen(config_file, "w"));
+	ASSERT_LT(0, fprintf(fp, "nosuchuser:ignore\n"));
+	ASSERT_EQ(0, fclose(fp));
+
+	/*
+	 * conf= specifies an existing file,
+	 * PAM_IGNORE -> PAM_PERM_DENIED
+	 */
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0,
+		  fprintf(fp, "#%%PAM-1.0\n"
+			      "auth required %s/.libs/%s.so conf=%s\n"
+			      "account required %s/.libs/%s.so conf=%s\n"
+			      "password required %s/.libs/%s.so conf=%s\n"
+			      "session required %s/.libs/%s.so conf=%s\n",
+			  cwd, MODULE_NAME, config_file,
+			  cwd, MODULE_NAME, config_file,
+			  cwd, MODULE_NAME, config_file,
+			  cwd, MODULE_NAME, config_file));
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		  pam_start_confdir(service_file, "root", &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+	ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	pamh = NULL;
+
+	/*
+	 * conf= specifies an existing file,
+	 * PAM_IGNORE -> PAM_SUCCESS
+	 */
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0,
+		  fprintf(fp, "#%%PAM-1.0\n"
+			      "auth required %s/.libs/%s.so conf=%s\n"
+			      "auth required %s/../pam_permit/.libs/pam_permit.so\n"
+			      "account required %s/.libs/%s.so conf=%s\n"
+			      "account required %s/../pam_permit/.libs/pam_permit.so\n"
+			      "password required %s/.libs/%s.so conf=%s\n"
+			      "password required %s/../pam_permit/.libs/pam_permit.so\n"
+			      "session required %s/.libs/%s.so conf=%s\n"
+			      "session required %s/../pam_permit/.libs/pam_permit.so\n",
+			  cwd, MODULE_NAME, config_file, cwd,
+			  cwd, MODULE_NAME, config_file, cwd,
+			  cwd, MODULE_NAME, config_file, cwd,
+			  cwd, MODULE_NAME, config_file, cwd));
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		  pam_start_confdir(service_file, "root", &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	pamh = NULL;
+
+	/*
+	 * conf= specifies a missing file,
+	 * PAM_IGNORE -> PAM_PERM_DENIED
+	 */
+	ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+	ASSERT_LT(0,
+		  fprintf(fp, "#%%PAM-1.0\n"
+			      "auth required %s/.libs/%s.so conf=%s\n"
+			      "account required %s/.libs/%s.so conf=%s\n"
+			      "password required %s/.libs/%s.so conf=%s\n"
+			      "session required %s/.libs/%s.so conf=%s\n",
+			  cwd, MODULE_NAME, missing_file,
+			  cwd, MODULE_NAME, missing_file,
+			  cwd, MODULE_NAME, missing_file,
+			  cwd, MODULE_NAME, missing_file));
+	ASSERT_EQ(0, fclose(fp));
+
+	ASSERT_EQ(PAM_SUCCESS,
+		  pam_start_confdir(service_file, "root", &conv, ".", &pamh));
+	ASSERT_NE(NULL, pamh);
+	ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+	ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+	ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+	ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+	ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+	pamh = NULL;
+
+	/* cleanup */
+	ASSERT_EQ(0, unlink(config_file));
+	ASSERT_EQ(0, unlink(service_file));
+
+	return 0;
+}
diff --git a/modules/pam_time/Makefile.am b/modules/pam_time/Makefile.am
index 833d51a6..f34f8dce 100644
--- a/modules/pam_time/Makefile.am
+++ b/modules/pam_time/Makefile.am
@@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR)
 secureconfdir = $(SCONFIGDIR)
 
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
-	-DPAM_TIME_CONF=\"$(SCONFIGDIR)/time.conf\" $(WARN_CFLAGS)
+	    $(WARN_CFLAGS)
 AM_LDFLAGS = -no-undefined -avoid-version -module
 if HAVE_VERSIONING
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c
index 089ae22d..8eebc914 100644
--- a/modules/pam_time/pam_time.c
+++ b/modules/pam_time/pam_time.c
@@ -33,6 +33,8 @@
 #include <libaudit.h>
 #endif
 
+#define PAM_TIME_CONF	(SCONFIGDIR "/time.conf")
+
 #define PAM_TIME_BUFLEN        1000
 #define FIELD_SEPARATOR        ';'   /* this is new as of .02 */
 
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index f2474a5b..c8ab49f3 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -334,7 +334,7 @@ PAMH_ARG_DECL(int check_shadow_expiry,
 
 #define PW_TMPFILE              "/etc/npasswd"
 #define SH_TMPFILE              "/etc/nshadow"
-#define OPW_TMPFILE             "/etc/security/nopasswd"
+#define OPW_TMPFILE             SCONFIGDIR "/nopasswd"
 
 /*
  * i64c - convert an integer to a radix 64 character
diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h
index c07037d2..463ef185 100644
--- a/modules/pam_unix/passverify.h
+++ b/modules/pam_unix/passverify.h
@@ -8,7 +8,7 @@
 
 #define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT
 
-#define OLD_PASSWORDS_FILE      "/etc/security/opasswd"
+#define OLD_PASSWORDS_FILE      SCONFIGDIR "/opasswd"
 
 int
 is_pwd_shadowed(const struct passwd *pwd);
diff --git a/xtests/run-xtests.sh b/xtests/run-xtests.sh
index 14f585d9..ff9a4dc1 100755
--- a/xtests/run-xtests.sh
+++ b/xtests/run-xtests.sh
@@ -18,10 +18,12 @@ all=0
 
 mkdir -p /etc/security
 for config in access.conf group.conf time.conf limits.conf ; do
-	cp /etc/security/$config /etc/security/$config-pam-xtests
+	[ -f "/etc/security/$config" ] &&
+		mv /etc/security/$config /etc/security/$config-pam-xtests
 	install -m 644 "${SRCDIR}"/$config /etc/security/$config
 done
-mv /etc/security/opasswd /etc/security/opasswd-pam-xtests
+[ -f /etc/security/opasswd ] &&
+	mv /etc/security/opasswd /etc/security/opasswd-pam-xtests
 
 for testname in $XTESTS ; do
 	  for cfg in "${SRCDIR}"/$testname*.pamd ; do
@@ -47,11 +49,15 @@ for testname in $XTESTS ; do
 	  all=`expr $all + 1`
 	  rm -f /etc/pam.d/$testname*
 done
-mv /etc/security/access.conf-pam-xtests /etc/security/access.conf
-mv /etc/security/group.conf-pam-xtests /etc/security/group.conf
-mv /etc/security/time.conf-pam-xtests /etc/security/time.conf
-mv /etc/security/limits.conf-pam-xtests /etc/security/limits.conf
-mv /etc/security/opasswd-pam-xtests /etc/security/opasswd
+
+for config in access.conf group.conf time.conf limits.conf opasswd ; do
+	if [ -f "/etc/security/$config-pam-xtests" ]; then
+		mv /etc/security/$config-pam-xtests /etc/security/$config
+	else
+		rm -f /etc/security/$config
+	fi
+done
+
 if test "$failed" -ne 0; then
 	  echo "==================="
 	  echo "$failed of $all tests failed"
openSUSE Build Service is sponsored by