summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Kukuk <kukuk@thkukuk.de>2007-06-25 11:09:32 +0000
committerThorsten Kukuk <kukuk@thkukuk.de>2007-06-25 11:09:32 +0000
commitdd80f758c4772b8bebb2fc3335bf3457ab1eb7ca (patch)
tree0fe639587103fc1b4a961bddff260ae508f5d73c
parentcc4a814d318d7926bb73dec21c99f46f6ef31d3a (diff)
Relevant BUGIDs:
Purpose of commit: bugfix Commit summary: --------------- 2007-06-25 Thorsten Kukuk <kukuk@thkukuk.de> * modules/pam_access/pam_access.c (list_match): Use saveptr of strtok_r result for recursive calls. * xtests/Makefile.am: Add new pam_access test cases. * xtests/pam_access1.c: New test case. * xtests/pam_access2.c: Likewise. * xtests/pam_access3.c: Likewise. * xtests/pam_access4.c: Likewise. * xtests/pam_access1.sh: Wrapper to create user accounts. * xtests/pam_access2.sh: Likewise. * xtests/pam_access3.sh: Likewise. * xtests/pam_access4.sh: Likewise. * xtests/pam_access1.pamd: PAM config file for pam_access tests. * xtests/pam_access2.pamd: Likewise. * xtests/pam_access3.pamd: Likewise. * xtests/pam_access4.pamd: Likewise. * xtests/access.conf: Config file for pam_access tests. * xtests/run-tests.sh: Install access.conf into system.
-rw-r--r--ChangeLog20
-rw-r--r--README4
-rw-r--r--modules/pam_access/pam_access.c8
-rw-r--r--xtests/.cvsignore4
-rw-r--r--xtests/Makefile.am10
-rw-r--r--xtests/access.conf2
-rwxr-xr-xxtests/run-xtests.sh12
-rw-r--r--xtests/tst-pam_access1.c131
-rw-r--r--xtests/tst-pam_access1.pamd6
-rwxr-xr-xxtests/tst-pam_access1.sh9
-rw-r--r--xtests/tst-pam_access2.c131
-rw-r--r--xtests/tst-pam_access2.pamd6
-rwxr-xr-xxtests/tst-pam_access2.sh9
-rw-r--r--xtests/tst-pam_access3.c131
-rw-r--r--xtests/tst-pam_access3.pamd6
-rwxr-xr-xxtests/tst-pam_access3.sh7
-rw-r--r--xtests/tst-pam_access4.c149
-rw-r--r--xtests/tst-pam_access4.pamd6
-rwxr-xr-xxtests/tst-pam_access4.sh7
19 files changed, 650 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c9374a3..3e18b430 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-06-25 Thorsten Kukuk <kukuk@thkukuk.de>
+
+ * modules/pam_access/pam_access.c (list_match): Use saveptr of strtok_r
+ result for recursive calls.
+ * xtests/Makefile.am: Add new pam_access test cases.
+ * xtests/pam_access1.c: New test case.
+ * xtests/pam_access2.c: Likewise.
+ * xtests/pam_access3.c: Likewise.
+ * xtests/pam_access4.c: Likewise.
+ * xtests/pam_access1.sh: Wrapper to create user accounts.
+ * xtests/pam_access2.sh: Likewise.
+ * xtests/pam_access3.sh: Likewise.
+ * xtests/pam_access4.sh: Likewise.
+ * xtests/pam_access1.pamd: PAM config file for pam_access tests.
+ * xtests/pam_access2.pamd: Likewise.
+ * xtests/pam_access3.pamd: Likewise.
+ * xtests/pam_access4.pamd: Likewise.
+ * xtests/access.conf: Config file for pam_access tests.
+ * xtests/run-tests.sh: Install access.conf into system.
+
2007-06-22 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_loginuid/pam_loginuid.c (set_loginuid): Print
diff --git a/README b/README
index bd804b17..364890db 100644
--- a/README
+++ b/README
@@ -33,6 +33,10 @@ You can run additional checks after installing by executing
as root.
+WARNING: Running "make xtests" can overwrite configuration data
+or make the system insecure/unfunctional for a short time!
+Backup all important data before!
+
If you do not wish to make the modules dynamically loadable, but
build a static libpam including all PAM modules, you have to call:
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 82fdfcc7..29a1606c 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -407,6 +407,10 @@ static int list_match(pam_handle_t *pamh,
int match = NO;
char *sptr;
+ if (pam_access_debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "list_match: list=%s, item=%s", list, item->user->pw_name);
+
/*
* Process tokens one at a time. We have exhausted all possible matches
* when we reach an "EXCEPT" token or the end of the list. If we do find
@@ -426,7 +430,7 @@ static int list_match(pam_handle_t *pamh,
if (match != NO) {
while ((tok = strtok_r(NULL, sep, &sptr)) && strcasecmp(tok, "EXCEPT"))
/* VOID */ ;
- if (tok == 0 || list_match(pamh, (char *) 0, item, match_fn) == NO)
+ if (tok == 0 || list_match(pamh, sptr, item, match_fn) == NO)
return (match);
}
return (NO);
@@ -434,7 +438,7 @@ static int list_match(pam_handle_t *pamh,
/* myhostname - figure out local machine name */
-static char * myhostname(void)
+static char *myhostname(void)
{
static char name[MAXHOSTNAMELEN + 1];
diff --git a/xtests/.cvsignore b/xtests/.cvsignore
index 074250ca..031eae99 100644
--- a/xtests/.cvsignore
+++ b/xtests/.cvsignore
@@ -2,6 +2,10 @@ Makefile
Makefile.in
.deps
.libs
+tst-pam_access1
+tst-pam_access2
+tst-pam_access3
+tst-pam_access4
tst-pam_dispatch1
tst-pam_dispatch2
tst-pam_dispatch3
diff --git a/xtests/Makefile.am b/xtests/Makefile.am
index 2629a13f..0fc76b01 100644
--- a/xtests/Makefile.am
+++ b/xtests/Makefile.am
@@ -13,11 +13,17 @@ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \
tst-pam_dispatch3.pamd tst-pam_dispatch4.pamd \
tst-pam_cracklib1.pamd tst-pam_cracklib2.pamd \
tst-pam_unix1.pamd tst-pam_unix2.pamd tst-pam_unix3.pamd \
- tst-pam_unix1.sh tst-pam_unix2.sh tst-pam_unix3.sh
+ tst-pam_unix1.sh tst-pam_unix2.sh tst-pam_unix3.sh \
+ access.conf tst-pam_access1.pamd tst-pam_access1.sh \
+ tst-pam_access2.pamd tst-pam_access2.sh \
+ tst-pam_access3.pamd tst-pam_access3.sh \
+ tst-pam_access4.pamd tst-pam_access4.sh
XTESTS = tst-pam_dispatch1 tst-pam_dispatch2 tst-pam_dispatch3 \
tst-pam_dispatch4 tst-pam_cracklib1 tst-pam_cracklib2 \
- tst-pam_unix1 tst-pam_unix2 tst-pam_unix3
+ tst-pam_unix1 tst-pam_unix2 tst-pam_unix3 \
+ tst-pam_access1 tst-pam_access2 tst-pam_access3 \
+ tst-pam_access4
noinst_PROGRAMS = $(XTESTS)
diff --git a/xtests/access.conf b/xtests/access.conf
new file mode 100644
index 00000000..8088ec61
--- /dev/null
+++ b/xtests/access.conf
@@ -0,0 +1,2 @@
+
+-:ALL EXCEPT (tstpamaccess) tstpamaccess3 :LOCAL
diff --git a/xtests/run-xtests.sh b/xtests/run-xtests.sh
index e05e45e2..9670bd7a 100755
--- a/xtests/run-xtests.sh
+++ b/xtests/run-xtests.sh
@@ -15,6 +15,9 @@ failed=0
pass=0
all=0
+mkdir -p /etc/security
+cp /etc/security/access.conf /etc/security/access.conf-pam-xtests
+install -m 644 "${SRCDIR}"/access.conf /etc/security/access.conf
for testname in $XTESTS ; do
install -m 644 "${SRCDIR}"/$testname.pamd /etc/pam.d/$testname
if test -x "${SRCDIR}"/$testname.sh ; then
@@ -31,15 +34,16 @@ for testname in $XTESTS ; do
fi
all=`expr $all + 1`
rm -f /etc/pam.d/$testname
- done
- if test "$failed" -ne 0; then
+done
+mv /etc/security/access.conf-pam-xtests /etc/security/access.conf
+if test "$failed" -ne 0; then
echo "==================="
echo "$failed of $all tests failed"
echo "==================="
exit 1
- else
+else
echo "=================="
echo "All $all tests passed"
echo "=================="
- fi
+fi
exit 0
diff --git a/xtests/tst-pam_access1.c b/xtests/tst-pam_access1.c
new file mode 100644
index 00000000..06b65f0c
--- /dev/null
+++ b/xtests/tst-pam_access1.c
@@ -0,0 +1,131 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ test case:
+
+ Check the following line in access.conf:
+ -:ALL EXCEPT (tstpamaccess):LOCAL
+
+ User is member of group tstpamaccess, pam_authenticate should pass.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <security/pam_appl.h>
+
+/* A conversation function which uses an internally-stored value for
+ the responses. */
+static int
+fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
+ struct pam_response **response, void *appdata_ptr UNUSED)
+{
+ struct pam_response *reply;
+ int count;
+
+ /* Sanity test. */
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ /* Allocate memory for the responses. */
+ reply = calloc (num_msg, sizeof (struct pam_response));
+ if (reply == NULL)
+ return PAM_CONV_ERR;
+
+ /* Each prompt elicits the same response. */
+ for (count = 0; count < num_msg; ++count)
+ {
+ reply[count].resp_retcode = 0;
+ reply[count].resp = strdup ("!!");
+ }
+
+ /* Set the pointers in the response structure and return. */
+ *response = reply;
+ return PAM_SUCCESS;
+}
+
+static struct pam_conv conv = {
+ fake_conv,
+ NULL
+};
+
+int
+main(int argc, char *argv[])
+{
+ pam_handle_t *pamh = NULL;
+ const char *user="tstpamaccess";
+ int retval;
+ int debug = 0;
+
+ if (argc > 1 && strcmp (argv[1], "-d") == 0)
+ debug = 1;
+
+ retval = pam_start("tst-pam_access1", user, &conv, &pamh);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access1: pam_start returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_set_item (pamh, PAM_TTY, "/dev/tty1");
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr,
+ "pam_access1: pam_set_item(PAM_TTY) returned %d\n",
+ retval);
+ return 1;
+ }
+
+ retval = pam_authenticate (pamh, 0);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access1: pam_authenticate returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_end (pamh,retval);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access1: pam_end returned %d\n", retval);
+ return 1;
+ }
+ return 0;
+}
diff --git a/xtests/tst-pam_access1.pamd b/xtests/tst-pam_access1.pamd
new file mode 100644
index 00000000..f47ec34f
--- /dev/null
+++ b/xtests/tst-pam_access1.pamd
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth required pam_access.so nodefgroup
+account required pam_permit.so
+password required pam_permit.so
+session required pam_permit.so
+
diff --git a/xtests/tst-pam_access1.sh b/xtests/tst-pam_access1.sh
new file mode 100755
index 00000000..48d8cb3e
--- /dev/null
+++ b/xtests/tst-pam_access1.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+/usr/sbin/groupadd -p '!!' tstpamaccess
+/usr/sbin/useradd -G tstpamaccess -p '!!' tstpamaccess
+./tst-pam_access1
+RET=$?
+/usr/sbin/userdel -r tstpamaccess 2> /dev/null
+/usr/sbin/groupdel tstpamaccess 2> /dev/null
+exit $RET
diff --git a/xtests/tst-pam_access2.c b/xtests/tst-pam_access2.c
new file mode 100644
index 00000000..194d07d7
--- /dev/null
+++ b/xtests/tst-pam_access2.c
@@ -0,0 +1,131 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ test case:
+
+ Check the following line in access.conf:
+ -:ALL EXCEPT (tstpamaccess):LOCAL
+
+ User is not member of group tstpamaccess, pam_authenticate should fail.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <security/pam_appl.h>
+
+/* A conversation function which uses an internally-stored value for
+ the responses. */
+static int
+fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
+ struct pam_response **response, void *appdata_ptr UNUSED)
+{
+ struct pam_response *reply;
+ int count;
+
+ /* Sanity test. */
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ /* Allocate memory for the responses. */
+ reply = calloc (num_msg, sizeof (struct pam_response));
+ if (reply == NULL)
+ return PAM_CONV_ERR;
+
+ /* Each prompt elicits the same response. */
+ for (count = 0; count < num_msg; ++count)
+ {
+ reply[count].resp_retcode = 0;
+ reply[count].resp = strdup ("!!");
+ }
+
+ /* Set the pointers in the response structure and return. */
+ *response = reply;
+ return PAM_SUCCESS;
+}
+
+static struct pam_conv conv = {
+ fake_conv,
+ NULL
+};
+
+int
+main(int argc, char *argv[])
+{
+ pam_handle_t *pamh = NULL;
+ const char *user="tstpamaccess";
+ int retval;
+ int debug = 0;
+
+ if (argc > 1 && strcmp (argv[1], "-d") == 0)
+ debug = 1;
+
+ retval = pam_start("tst-pam_access2", user, &conv, &pamh);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access2: pam_start returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_set_item (pamh, PAM_TTY, "/dev/tty1");
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr,
+ "pam_access2: pam_set_item(PAM_TTY) returned %d\n",
+ retval);
+ return 1;
+ }
+
+ retval = pam_authenticate (pamh, 0);
+ if (retval != PAM_PERM_DENIED)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access2: pam_authenticate returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_end (pamh,retval);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access2: pam_end returned %d\n", retval);
+ return 1;
+ }
+ return 0;
+}
diff --git a/xtests/tst-pam_access2.pamd b/xtests/tst-pam_access2.pamd
new file mode 100644
index 00000000..f47ec34f
--- /dev/null
+++ b/xtests/tst-pam_access2.pamd
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth required pam_access.so nodefgroup
+account required pam_permit.so
+password required pam_permit.so
+session required pam_permit.so
+
diff --git a/xtests/tst-pam_access2.sh b/xtests/tst-pam_access2.sh
new file mode 100755
index 00000000..c1b3c992
--- /dev/null
+++ b/xtests/tst-pam_access2.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+/usr/sbin/groupadd -p '!!' tstpamaccess
+/usr/sbin/useradd -p '!!' tstpamaccess
+./tst-pam_access2
+RET=$?
+/usr/sbin/userdel -r tstpamaccess 2> /dev/null
+/usr/sbin/groupdel tstpamaccess 2> /dev/null
+exit $RET
diff --git a/xtests/tst-pam_access3.c b/xtests/tst-pam_access3.c
new file mode 100644
index 00000000..cd989bb3
--- /dev/null
+++ b/xtests/tst-pam_access3.c
@@ -0,0 +1,131 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ test case:
+
+ Check the following line in access.conf:
+ -:ALL EXCEPT tstpamaccess3 :LOCAL
+
+ pam_authenticate should pass for user tstpamaccess3
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <security/pam_appl.h>
+
+/* A conversation function which uses an internally-stored value for
+ the responses. */
+static int
+fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
+ struct pam_response **response, void *appdata_ptr UNUSED)
+{
+ struct pam_response *reply;
+ int count;
+
+ /* Sanity test. */
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ /* Allocate memory for the responses. */
+ reply = calloc (num_msg, sizeof (struct pam_response));
+ if (reply == NULL)
+ return PAM_CONV_ERR;
+
+ /* Each prompt elicits the same response. */
+ for (count = 0; count < num_msg; ++count)
+ {
+ reply[count].resp_retcode = 0;
+ reply[count].resp = strdup ("!!");
+ }
+
+ /* Set the pointers in the response structure and return. */
+ *response = reply;
+ return PAM_SUCCESS;
+}
+
+static struct pam_conv conv = {
+ fake_conv,
+ NULL
+};
+
+int
+main(int argc, char *argv[])
+{
+ pam_handle_t *pamh = NULL;
+ const char *user="tstpamaccess3";
+ int retval;
+ int debug = 0;
+
+ if (argc > 1 && strcmp (argv[1], "-d") == 0)
+ debug = 1;
+
+ retval = pam_start("tst-pam_access3", user, &conv, &pamh);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access3: pam_start returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_set_item (pamh, PAM_TTY, "/dev/tty1");
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr,
+ "pam_access3: pam_set_item(PAM_TTY) returned %d\n",
+ retval);
+ return 1;
+ }
+
+ retval = pam_authenticate (pamh, 0);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access3: pam_authenticate returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_end (pamh,retval);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access3: pam_end returned %d\n", retval);
+ return 1;
+ }
+ return 0;
+}
diff --git a/xtests/tst-pam_access3.pamd b/xtests/tst-pam_access3.pamd
new file mode 100644
index 00000000..f47ec34f
--- /dev/null
+++ b/xtests/tst-pam_access3.pamd
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth required pam_access.so nodefgroup
+account required pam_permit.so
+password required pam_permit.so
+session required pam_permit.so
+
diff --git a/xtests/tst-pam_access3.sh b/xtests/tst-pam_access3.sh
new file mode 100755
index 00000000..348e0c3c
--- /dev/null
+++ b/xtests/tst-pam_access3.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+/usr/sbin/useradd -p '!!' tstpamaccess3
+./tst-pam_access3
+RET=$?
+/usr/sbin/userdel -r tstpamaccess3 2> /dev/null
+exit $RET
diff --git a/xtests/tst-pam_access4.c b/xtests/tst-pam_access4.c
new file mode 100644
index 00000000..1e53a364
--- /dev/null
+++ b/xtests/tst-pam_access4.c
@@ -0,0 +1,149 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ test case:
+
+ Check the following line in access.conf:
+ -:ALL EXCEPT tstpamaccess3 :LOCAL
+
+ pam_authenticate should fail for /dev/tty1 and pass for www.example.com
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <security/pam_appl.h>
+
+/* A conversation function which uses an internally-stored value for
+ the responses. */
+static int
+fake_conv (int num_msg, const struct pam_message **msgm UNUSED,
+ struct pam_response **response, void *appdata_ptr UNUSED)
+{
+ struct pam_response *reply;
+ int count;
+
+ /* Sanity test. */
+ if (num_msg <= 0)
+ return PAM_CONV_ERR;
+
+ /* Allocate memory for the responses. */
+ reply = calloc (num_msg, sizeof (struct pam_response));
+ if (reply == NULL)
+ return PAM_CONV_ERR;
+
+ /* Each prompt elicits the same response. */
+ for (count = 0; count < num_msg; ++count)
+ {
+ reply[count].resp_retcode = 0;
+ reply[count].resp = strdup ("!!");
+ }
+
+ /* Set the pointers in the response structure and return. */
+ *response = reply;
+ return PAM_SUCCESS;
+}
+
+static struct pam_conv conv = {
+ fake_conv,
+ NULL
+};
+
+int
+main(int argc, char *argv[])
+{
+ pam_handle_t *pamh = NULL;
+ const char *user="tstpamaccess";
+ int retval;
+ int debug = 0;
+
+ if (argc > 1 && strcmp (argv[1], "-d") == 0)
+ debug = 1;
+
+ retval = pam_start("tst-pam_access4", user, &conv, &pamh);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access4: pam_start returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_set_item (pamh, PAM_TTY, "/dev/tty1");
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr,
+ "pam_access4-1: pam_set_item(PAM_TTY) returned %d\n",
+ retval);
+ return 1;
+ }
+
+ retval = pam_authenticate (pamh, 0);
+ if (retval != PAM_PERM_DENIED)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access4-1: pam_authenticate returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_set_item (pamh, PAM_TTY, "www.example.com");
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr,
+ "pam_access4-2: pam_set_item(PAM_TTY) returned %d\n",
+ retval);
+ return 1;
+ }
+
+ retval = pam_authenticate (pamh, 0);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access4-2: pam_authenticate returned %d\n", retval);
+ return 1;
+ }
+
+ retval = pam_end (pamh,retval);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ fprintf (stderr, "pam_access4: pam_end returned %d\n", retval);
+ return 1;
+ }
+ return 0;
+}
diff --git a/xtests/tst-pam_access4.pamd b/xtests/tst-pam_access4.pamd
new file mode 100644
index 00000000..f47ec34f
--- /dev/null
+++ b/xtests/tst-pam_access4.pamd
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth required pam_access.so nodefgroup
+account required pam_permit.so
+password required pam_permit.so
+session required pam_permit.so
+
diff --git a/xtests/tst-pam_access4.sh b/xtests/tst-pam_access4.sh
new file mode 100755
index 00000000..58bf260d
--- /dev/null
+++ b/xtests/tst-pam_access4.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+/usr/sbin/useradd -p '!!' tstpamaccess
+./tst-pam_access4
+RET=$?
+/usr/sbin/userdel -r tstpamaccess 2> /dev/null
+exit $RET