Accepting request 1041655 from home:kukuk:tiu
- pam_pwhistory-docu.patch, docbook5.patch: convert docu to docbook5 - 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 OBS-URL: https://build.opensuse.org/request/show/1041655 OBS-URL: https://build.opensuse.org/package/show/Linux-PAM/pam?expand=0&rev=267
This commit is contained in:
parent
f8d6ec4fd6
commit
5aa4f5ad81
20423
docbook5.patch
Normal file
20423
docbook5.patch
Normal file
File diff suppressed because it is too large
Load Diff
4632
pam-git.diff
4632
pam-git.diff
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
}
|
|
14
pam.changes
14
pam.changes
@ -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>
|
Tue Nov 22 15:24:12 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>
|
||||||
|
|
||||||
|
15
pam.spec
15
pam.spec
@ -64,14 +64,14 @@ Source12: pam-login_defs-check.sh
|
|||||||
Source13: pam.tmpfiles
|
Source13: pam.tmpfiles
|
||||||
Source14: Linux-PAM-%{version}-docs.tar.xz.asc
|
Source14: Linux-PAM-%{version}-docs.tar.xz.asc
|
||||||
Source15: Linux-PAM-%{version}.tar.xz.asc
|
Source15: Linux-PAM-%{version}.tar.xz.asc
|
||||||
Source16: tst-pam_env-retval.c
|
|
||||||
Patch1: pam-limit-nproc.patch
|
Patch1: pam-limit-nproc.patch
|
||||||
Patch2: pam-hostnames-in-access_conf.patch
|
|
||||||
Patch3: pam-xauth_ownership.patch
|
Patch3: pam-xauth_ownership.patch
|
||||||
Patch4: pam-bsc1177858-dont-free-environment-string.patch
|
Patch4: pam-bsc1177858-dont-free-environment-string.patch
|
||||||
Patch10: pam_xauth_data.3.xml.patch
|
Patch10: pam_xauth_data.3.xml.patch
|
||||||
Patch11: pam-git.diff
|
Patch11: pam-git.diff
|
||||||
Patch12: pam_env_econf.patch
|
Patch12: pam_env_econf.patch
|
||||||
|
Patch13: pam_pwhistory-docu.patch
|
||||||
|
Patch14: docbook5.patch
|
||||||
BuildRequires: audit-devel
|
BuildRequires: audit-devel
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
BuildRequires: flex
|
BuildRequires: flex
|
||||||
@ -147,7 +147,7 @@ Summary: Manualpages for Pluggable Authentication Modules
|
|||||||
Group: Documentation/HTML
|
Group: Documentation/HTML
|
||||||
Provides: pam:/%{_mandir}/man8/PAM.8.gz
|
Provides: pam:/%{_mandir}/man8/PAM.8.gz
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
BuildRequires: docbook-xsl-stylesheets
|
BuildRequires: docbook5-xsl-stylesheets
|
||||||
BuildRequires: elinks
|
BuildRequires: elinks
|
||||||
BuildRequires: xmlgraphics-fop
|
BuildRequires: xmlgraphics-fop
|
||||||
|
|
||||||
@ -177,14 +177,16 @@ building both PAM-aware applications and modules for use with PAM.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q -n Linux-PAM-%{version} -b 1
|
%setup -q -n Linux-PAM-%{version} -b 1
|
||||||
cp -a %{SOURCE12} .
|
cp -a %{SOURCE12} .
|
||||||
cp %{SOURCE16} ./modules/pam_env
|
%patch11 -p1
|
||||||
%patch1 -p1
|
%patch1 -p1
|
||||||
%patch2 -p1
|
|
||||||
%patch3 -p1
|
%patch3 -p1
|
||||||
%patch4 -p1
|
%patch4 -p1
|
||||||
%patch10 -p1
|
%patch10 -p1
|
||||||
%patch11 -p1
|
|
||||||
%patch12 -p1
|
%patch12 -p1
|
||||||
|
%if %{build_doc}
|
||||||
|
%patch13 -p1
|
||||||
|
%patch14 -p1
|
||||||
|
%endif
|
||||||
|
|
||||||
%build
|
%build
|
||||||
bash ./pam-login_defs-check.sh
|
bash ./pam-login_defs-check.sh
|
||||||
@ -343,6 +345,7 @@ done
|
|||||||
%config(noreplace) %{_pam_secconfdir}/time.conf
|
%config(noreplace) %{_pam_secconfdir}/time.conf
|
||||||
%config(noreplace) %{_pam_secconfdir}/namespace.conf
|
%config(noreplace) %{_pam_secconfdir}/namespace.conf
|
||||||
%config(noreplace) %{_pam_secconfdir}/namespace.init
|
%config(noreplace) %{_pam_secconfdir}/namespace.init
|
||||||
|
%config(noreplace) %{_pam_secconfdir}/pwhistory.conf
|
||||||
%dir %{_pam_secconfdir}/namespace.d
|
%dir %{_pam_secconfdir}/namespace.d
|
||||||
%{_libdir}/libpam.so.0
|
%{_libdir}/libpam.so.0
|
||||||
%{_libdir}/libpam.so.%{libpam_so_version}
|
%{_libdir}/libpam.so.%{libpam_so_version}
|
||||||
|
File diff suppressed because it is too large
Load Diff
264
pam_pwhistory-docu.patch
Normal file
264
pam_pwhistory-docu.patch
Normal 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>
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user