Accepting request 1041656 from Linux-PAM

OBS-URL: https://build.opensuse.org/request/show/1041656
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/pam?expand=0&rev=125
This commit is contained in:
Dominique Leuenberger 2022-12-10 20:17:22 +00:00 committed by Git OBS Bridge
commit dbcb16eb1c
8 changed files with 25579 additions and 1429 deletions

20423
docbook5.patch Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,194 +0,0 @@
From d275f22cf28da287e93b5e5a1fdb8a68b2815982 Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Thu, 24 Feb 2022 10:37:32 +0100
Subject: [PATCH] pam_access: handle hostnames in access.conf
According to the manual page, the following entry is valid but does not
work:
-:root:ALL EXCEPT localhost
See https://bugzilla.suse.com/show_bug.cgi?id=1019866
Patched is based on PR#226 from Josef Moellers
---
modules/pam_access/pam_access.c | 95 ++++++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 19 deletions(-)
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 0d033aa20..3cec542be 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -640,7 +640,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
if ((str_len = strlen(string)) > tok_len
&& strcasecmp(tok, string + str_len - tok_len) == 0)
return YES;
- } else if (tok[tok_len - 1] == '.') {
+ } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */
struct addrinfo hint;
memset (&hint, '\0', sizeof (hint));
@@ -681,7 +681,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
return NO;
}
- /* Assume network/netmask with an IP of a host. */
+ /* Assume network/netmask, IP address or hostname. */
return network_netmask_match(pamh, tok, string, item);
}
@@ -699,7 +699,7 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
/*
* If the token has the magic value "ALL" the match always succeeds.
* Otherwise, return YES if the token fully matches the string.
- * "NONE" token matches NULL string.
+ * "NONE" token matches NULL string.
*/
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
@@ -717,7 +717,8 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
/* network_netmask_match - match a string against one token
* where string is a hostname or ip (v4,v6) address and tok
- * represents either a single ip (v4,v6) address or a network/netmask
+ * represents either a hostname, a single ip (v4,v6) address
+ * or a network/netmask
*/
static int
network_netmask_match (pam_handle_t *pamh,
@@ -726,10 +727,12 @@ network_netmask_match (pam_handle_t *pamh,
char *netmask_ptr;
char netmask_string[MAXHOSTNAMELEN + 1];
int addr_type;
+ struct addrinfo *ai = NULL;
if (item->debug)
- pam_syslog (pamh, LOG_DEBUG,
+ pam_syslog (pamh, LOG_DEBUG,
"network_netmask_match: tok=%s, item=%s", tok, string);
+
/* OK, check if tok is of type addr/mask */
if ((netmask_ptr = strchr(tok, '/')) != NULL)
{
@@ -763,54 +766,108 @@ network_netmask_match (pam_handle_t *pamh,
netmask_ptr = number_to_netmask(netmask, addr_type,
netmask_string, MAXHOSTNAMELEN);
}
- }
+
+ /*
+ * Construct an addrinfo list from the IP address.
+ * This should not fail as the input is a correct IP address...
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
+ {
+ return NO;
+ }
+ }
else
- /* NO, then check if it is only an addr */
- if (isipaddr(tok, NULL, NULL) != YES)
+ {
+ /*
+ * It is either an IP address or a hostname.
+ * Let getaddrinfo sort everything out
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
{
+ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok);
+
return NO;
}
+ netmask_ptr = NULL;
+ }
if (isipaddr(string, NULL, NULL) != YES)
{
- /* Assume network/netmask with a name of a host. */
struct addrinfo hint;
+ /* Assume network/netmask with a name of a host. */
memset (&hint, '\0', sizeof (hint));
hint.ai_flags = AI_CANONNAME;
hint.ai_family = AF_UNSPEC;
if (item->gai_rv != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else if (!item->res &&
(item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else
{
struct addrinfo *runp = item->res;
+ struct addrinfo *runp1;
while (runp != NULL)
{
char buf[INET6_ADDRSTRLEN];
- DIAG_PUSH_IGNORE_CAST_ALIGN;
- inet_ntop (runp->ai_family,
- runp->ai_family == AF_INET
- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
- buf, sizeof (buf));
- DIAG_POP_IGNORE_CAST_ALIGN;
+ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
- if (are_addresses_equal(buf, tok, netmask_ptr))
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
{
- return YES;
+ char buf1[INET6_ADDRSTRLEN];
+
+ if (runp->ai_family != runp1->ai_family)
+ continue;
+
+ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
+
+ if (are_addresses_equal (buf, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
}
runp = runp->ai_next;
}
}
}
else
- return (are_addresses_equal(string, tok, netmask_ptr));
+ {
+ struct addrinfo *runp1;
+
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
+ {
+ char buf1[INET6_ADDRSTRLEN];
+
+ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST);
+
+ if (are_addresses_equal(string, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
+ }
+ }
+
+ freeaddrinfo(ai);
return NO;
}

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Tue Dec 6 16:43:49 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>
- pam_pwhistory-docu.patch, docbook5.patch: convert docu to
docbook5
-------------------------------------------------------------------
Thu Dec 1 13:51:35 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>
- pam-git.diff: update to current git
- obsoletes pam-hostnames-in-access_conf.patch
- obsoletes tst-pam_env-retval.c
- pam_env_econf.patch refresh
-------------------------------------------------------------------
Tue Nov 22 15:24:12 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>

View File

@ -64,14 +64,14 @@ Source12: pam-login_defs-check.sh
Source13: pam.tmpfiles
Source14: Linux-PAM-%{version}-docs.tar.xz.asc
Source15: Linux-PAM-%{version}.tar.xz.asc
Source16: tst-pam_env-retval.c
Patch1: pam-limit-nproc.patch
Patch2: pam-hostnames-in-access_conf.patch
Patch3: pam-xauth_ownership.patch
Patch4: pam-bsc1177858-dont-free-environment-string.patch
Patch10: pam_xauth_data.3.xml.patch
Patch11: pam-git.diff
Patch12: pam_env_econf.patch
Patch13: pam_pwhistory-docu.patch
Patch14: docbook5.patch
BuildRequires: audit-devel
BuildRequires: bison
BuildRequires: flex
@ -147,7 +147,7 @@ Summary: Manualpages for Pluggable Authentication Modules
Group: Documentation/HTML
Provides: pam:/%{_mandir}/man8/PAM.8.gz
BuildArch: noarch
BuildRequires: docbook-xsl-stylesheets
BuildRequires: docbook5-xsl-stylesheets
BuildRequires: elinks
BuildRequires: xmlgraphics-fop
@ -177,14 +177,16 @@ building both PAM-aware applications and modules for use with PAM.
%prep
%setup -q -n Linux-PAM-%{version} -b 1
cp -a %{SOURCE12} .
cp %{SOURCE16} ./modules/pam_env
%patch11 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%if %{build_doc}
%patch13 -p1
%patch14 -p1
%endif
%build
bash ./pam-login_defs-check.sh
@ -343,6 +345,7 @@ done
%config(noreplace) %{_pam_secconfdir}/time.conf
%config(noreplace) %{_pam_secconfdir}/namespace.conf
%config(noreplace) %{_pam_secconfdir}/namespace.init
%config(noreplace) %{_pam_secconfdir}/pwhistory.conf
%dir %{_pam_secconfdir}/namespace.d
%{_libdir}/libpam.so.0
%{_libdir}/libpam.so.%{libpam_so_version}

File diff suppressed because it is too large Load Diff

264
pam_pwhistory-docu.patch Normal file
View File

@ -0,0 +1,264 @@
diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am
index 8a4dbcb2..c29a8e11 100644
--- a/modules/pam_pwhistory/Makefile.am
+++ b/modules/pam_pwhistory/Makefile.am
@@ -9,9 +9,10 @@ MAINTAINERCLEANFILES = $(MANS) README
EXTRA_DIST = $(XMLS)
if HAVE_DOC
-dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
+dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5
endif
-XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml \
+ pwhistory.conf.5.xml
dist_check_SCRIPTS = tst-pam_pwhistory
TESTS = $(dist_check_SCRIPTS)
diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml
index d88115c2..2a8fa7f6 100644
--- a/modules/pam_pwhistory/pam_pwhistory.8.xml
+++ b/modules/pam_pwhistory/pam_pwhistory.8.xml
@@ -36,6 +36,12 @@
<arg choice="opt">
authtok_type=<replaceable>STRING</replaceable>
</arg>
+ <arg choice="opt">
+ file=<replaceable>/path/filename</replaceable>
+ </arg>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/config-file</replaceable>
+ </arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -104,7 +110,7 @@
<listitem>
<para>
The last <replaceable>N</replaceable> passwords for each
- user are saved in <filename>/etc/security/opasswd</filename>.
+ user are saved.
The default is <emphasis>10</emphasis>. Value of
<emphasis>0</emphasis> makes the module to keep the existing
contents of the <filename>opasswd</filename> file unchanged.
@@ -137,7 +143,39 @@
</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>
+
+ <varlistentry>
+ <term>
+ <option>conf=<replaceable>/path/to/config-file</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Use another configuration file instead of the default
+ <filename>/etc/security/pwhistory.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
+ <para>
+ The options for configuring the module behavior are described in the
+ <citerefentry><refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> manual page. The options
+ specified on the module command line override the values from the
+ configuration file.
+ </para>
</refsect1>
<refsect1 id="pam_pwhistory-types">
@@ -213,7 +251,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>
@@ -222,6 +260,9 @@ password required pam_unix.so use_authtok
<refsect1 id='pam_pwhistory-see_also'>
<title>SEE ALSO</title>
<para>
+ <citerefentry>
+ <refentrytitle>pwhistory.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
<citerefentry>
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
diff --git a/modules/pam_pwhistory/pwhistory.conf.5.xml b/modules/pam_pwhistory/pwhistory.conf.5.xml
new file mode 100644
index 00000000..bac5ffed
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory.conf.5.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pwhistory.conf">
+
+ <refmeta>
+ <refentrytitle>pwhistory.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pwhistory.conf-name">
+ <refname>pwhistory.conf</refname>
+ <refpurpose>pam_pwhistory configuration file</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="pwhistory.conf-description">
+
+ <title>DESCRIPTION</title>
+ <para>
+ <emphasis remap='B'>pwhistory.conf</emphasis> provides a way to configure the
+ default settings for saving the last passwords for each user.
+ This file is read by the <emphasis>pam_pwhistory</emphasis> module and is the
+ preferred method over configuring <emphasis>pam_pwhistory</emphasis> directly.
+ </para>
+ <para>
+ The file has a very simple <emphasis>name = value</emphasis> format with possible comments
+ starting with <emphasis>#</emphasis> character. The whitespace at the beginning of line, end
+ of line, and around the <emphasis>=</emphasis> sign is ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pwhistory.conf-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>enforce_for_root</option>
+ </term>
+ <listitem>
+ <para>
+ If this option is set, the check is enforced for root, too.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>remember=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>N</replaceable> passwords for each
+ user are saved.
+ The default is <emphasis>10</emphasis>. Value of
+ <emphasis>0</emphasis> makes the module to keep the existing
+ contents of the <filename>opasswd</filename> file unchanged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>retry=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Prompt user at most <replaceable>N</replaceable> times
+ before returning with error. The default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/filename</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Store password history in file
+ <replaceable>/path/filename</replaceable> rather than the default
+ location. The default location is
+ <filename>/etc/security/opasswd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ /etc/security/pwhistory.conf file example:
+ </para>
+ <programlisting>
+debug
+remember=5
+file=/tmp/opasswd
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pwhistory.conf-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/pwhistory.conf</filename></term>
+ <listitem>
+ <para>the config file for custom options</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory.conf-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_pwhistory was written by Thorsten Kukuk. The support for
+ pwhistory.conf was written by Iker Pedrosa.
+ </para>
+ </refsect1>
+
+</refentry>

View File

@ -1,259 +0,0 @@
/*
* Check pam_env return values.
*
* Copyright (c) 2020-2022 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2022 Stefan Schubert <schubi@suse.de>
*/
#include "test_assert.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <security/pam_appl.h>
#define MODULE_NAME "pam_env"
#define TEST_NAME "tst-" MODULE_NAME "-retval"
#define TEST_NAME_DIR TEST_NAME ".dir"
static const char service_file[] = TEST_NAME ".service";
static const char missing_file[] = TEST_NAME ".missing";
static const char dir[] = TEST_NAME_DIR;
static const char dir_usr[] = TEST_NAME_DIR "/usr";
static const char dir_usr_etc[] = TEST_NAME_DIR "/usr/etc";
static const char dir_usr_etc_security[] = TEST_NAME_DIR "/usr/etc/security";
static const char my_conf[] = TEST_NAME ".conf";
static const char my_env[] = TEST_NAME ".env";
static const char usr_env[] = TEST_NAME_DIR "/usr/etc/environment";
static const char usr_conf[] = TEST_NAME_DIR "/usr/etc/security/pam_env.conf";
static struct pam_conv conv;
static void
setup(void)
{
FILE *fp;
ASSERT_EQ(0, mkdir(dir, 0755));
ASSERT_EQ(0, mkdir(dir_usr, 0755));
ASSERT_EQ(0, mkdir(dir_usr_etc, 0755));
ASSERT_EQ(0, mkdir(dir_usr_etc_security, 0755));
ASSERT_NE(NULL, fp = fopen(my_conf, "w"));
ASSERT_LT(0, fprintf(fp,
"EDITOR\tDEFAULT=vim\n"
"PAGER\tDEFAULT=more\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(my_env, "w"));
ASSERT_LT(0, fprintf(fp,
"test_value=foo\n"
"test2_value=bar\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(usr_env, "w"));
ASSERT_LT(0, fprintf(fp,
"usr_etc_test=foo\n"
"usr_etc_test2=bar\n"));
ASSERT_EQ(0, fclose(fp));
ASSERT_NE(NULL, fp = fopen(usr_conf, "w"));
ASSERT_LT(0, fprintf(fp,
"PAGER DEFAULT=emacs\n"
"MANPAGER DEFAULT=less\n"));
ASSERT_EQ(0, fclose(fp));
}
static void
cleanup(void)
{
ASSERT_EQ(0, unlink(my_conf));
ASSERT_EQ(0, unlink(my_env));
ASSERT_EQ(0, unlink(usr_env));
ASSERT_EQ(0, unlink(usr_conf));
ASSERT_EQ(0, rmdir(dir_usr_etc_security));
ASSERT_EQ(0, rmdir(dir_usr_etc));
ASSERT_EQ(0, rmdir(dir_usr));
ASSERT_EQ(0, rmdir(dir));
}
static void
check_array(const char **array1, char **array2)
{
for (const char **a1 = array1; *a1 != NULL; ++a1) {
char **a2;
for (a2 = array2; *a2 != NULL; ++a2) {
if (strcmp(*a1, *a2) == 0)
break;
}
ASSERT_NE(NULL, *a2);
}
}
static void
check_env(const char **list)
{
pam_handle_t *pamh = NULL;
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &conv, ".", &pamh));
ASSERT_NE(NULL, pamh);
ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
char **env_list = pam_getenvlist(pamh);
ASSERT_NE(NULL, env_list);
check_array(list, env_list);
for (char **e = env_list; *e != NULL; ++e)
free(*e);
free(env_list);
ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
}
int
main(void)
{
pam_handle_t *pamh = NULL;
FILE *fp;
char cwd[PATH_MAX];
ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
setup();
/*
* When conffile= specifies a missing file, all methods except
* pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE.
* The return code of the stack where every module returns PAM_IGNORE
* is 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 conffile=%s/%s\n"
"account required %s/.libs/%s.so conffile=%s/%s\n"
"password required %s/.libs/%s.so conffile=%s/%s\n"
"session required %s/.libs/%s.so conffile=%s/%s\n",
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file,
cwd, MODULE_NAME, cwd, missing_file));
ASSERT_EQ(0, fclose(fp));
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &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_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0));
ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, 0));
ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
pamh = NULL;
/*
* When conffile= specifies a missing file, all methods except
* pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE.
* pam_permit is added after pam_env to convert PAM_IGNORE to 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 conffile=%s/%s\n"
"auth required %s/../pam_permit/.libs/pam_permit.so\n"
"account required %s/.libs/%s.so conffile=%s/%s\n"
"account required %s/../pam_permit/.libs/pam_permit.so\n"
"password required %s/.libs/%s.so conffile=%s/%s\n"
"password required %s/../pam_permit/.libs/pam_permit.so\n"
"session required %s/.libs/%s.so conffile=%s/%s\n"
"session required %s/../pam_permit/.libs/pam_permit.so\n",
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd,
cwd, MODULE_NAME, cwd, missing_file, cwd));
ASSERT_EQ(0, fclose(fp));
ASSERT_EQ(PAM_SUCCESS,
pam_start_confdir(service_file, "", &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_SERVICE_ERR, pam_acct_mgmt(pamh, 0));
ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
pamh = NULL;
/*
* conffile= specifies an existing file,
* envfile= specifies an empty file.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s/%s envfile=%s\n",
cwd, MODULE_NAME,
cwd, my_conf, "/dev/null"));
ASSERT_EQ(0, fclose(fp));
const char *env1[] = { "EDITOR=vim", "PAGER=more", NULL };
check_env(env1);
/*
* conffile= specifies an empty file,
* envfile= specifies an existing file.
*/
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s envfile=%s/%s\n",
cwd, MODULE_NAME,
"/dev/null", cwd, my_env));
ASSERT_EQ(0, fclose(fp));
const char *env2[] = { "test_value=foo", "test2_value=bar", NULL };
check_env(env2);
#if defined (USE_ECONF) && defined (VENDORDIR)
/* envfile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s envfile=%s/%s/\n",
cwd, MODULE_NAME,
"/dev/null",
cwd, dir));
ASSERT_EQ(0, fclose(fp));
const char *env3[] = {"usr_etc_test=foo", "usr_etc_test2=bar", NULL};
check_env(env3);
/* conffile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */
ASSERT_NE(NULL, fp = fopen(service_file, "w"));
ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
"session required %s/.libs/%s.so"
" conffile=%s/%s/ envfile=%s\n",
cwd, MODULE_NAME,
cwd, dir,
"/dev/null"));
ASSERT_EQ(0, fclose(fp));
const char *env4[] = {"PAGER=emacs", "MANPAGER=less", NULL};
check_env(env4);
#endif
/* cleanup */
cleanup();
ASSERT_EQ(0, unlink(service_file));
return 0;
}