summaryrefslogtreecommitdiff
path: root/modules/pam_access
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_access')
-rw-r--r--modules/pam_access/Makefile.am7
-rw-r--r--modules/pam_access/Makefile.in18
-rw-r--r--modules/pam_access/README14
-rw-r--r--modules/pam_access/README.xml32
-rw-r--r--modules/pam_access/access.conf.510
-rw-r--r--modules/pam_access/access.conf.5.xml22
-rw-r--r--modules/pam_access/pam_access.822
-rw-r--r--modules/pam_access/pam_access.8.xml92
-rw-r--r--modules/pam_access/pam_access.c236
9 files changed, 321 insertions, 132 deletions
diff --git a/modules/pam_access/Makefile.am b/modules/pam_access/Makefile.am
index 5723dd59..8af2852a 100644
--- a/modules/pam_access/Makefile.am
+++ b/modules/pam_access/Makefile.am
@@ -15,11 +15,14 @@ dist_check_SCRIPTS = tst-pam_access
TESTS = $(dist_check_SCRIPTS)
securelibdir = $(SECUREDIR)
+if HAVE_VENDORDIR
+secureconfdir = $(VENDOR_SCONFIGDIR)
+else
secureconfdir = $(SCONFIGDIR)
+endif
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/Makefile.in b/modules/pam_access/Makefile.in
index 6f9abf45..9dadd2d3 100644
--- a/modules/pam_access/Makefile.in
+++ b/modules/pam_access/Makefile.in
@@ -431,6 +431,7 @@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
+DOCBOOK_RNG = @DOCBOOK_RNG@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -443,11 +444,13 @@ EXEEXT = @EXEEXT@
EXE_CFLAGS = @EXE_CFLAGS@
EXE_LDFLAGS = @EXE_LDFLAGS@
FGREP = @FGREP@
+FILECMD = @FILECMD@
FO2PDF = @FO2PDF@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
+HTML_STYLESHEET = @HTML_STYLESHEET@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -479,12 +482,14 @@ LIBSELINUX = @LIBSELINUX@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LOGIND_CFLAGS = @LOGIND_CFLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MAN_STYLESHEET = @MAN_STYLESHEET@
MKDIR_P = @MKDIR_P@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
@@ -507,6 +512,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PDF_STYLESHEET = @PDF_STYLESHEET@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
@@ -517,12 +523,16 @@ SECUREDIR = @SECUREDIR@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_PROFILECONDITIONS = @STRINGPARAM_PROFILECONDITIONS@
STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
TIRPC_CFLAGS = @TIRPC_CFLAGS@
TIRPC_LIBS = @TIRPC_LIBS@
+TXT_STYLESHEET = @TXT_STYLESHEET@
USE_NLS = @USE_NLS@
+VENDOR_SCONFIGDIR = @VENDOR_SCONFIGDIR@
VERSION = @VERSION@
WARN_CFLAGS = @WARN_CFLAGS@
XGETTEXT = @XGETTEXT@
@@ -596,10 +606,10 @@ XMLS = README.xml access.conf.5.xml pam_access.8.xml
dist_check_SCRIPTS = tst-pam_access
TESTS = $(dist_check_SCRIPTS)
securelibdir = $(SECUREDIR)
-secureconfdir = $(SCONFIGDIR)
+@HAVE_VENDORDIR_FALSE@secureconfdir = $(SCONFIGDIR)
+@HAVE_VENDORDIR_TRUE@secureconfdir = $(VENDOR_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 $(am__append_1)
securelib_LTLIBRARIES = pam_access.la
diff --git a/modules/pam_access/README b/modules/pam_access/README
index 26aad33e..891e7688 100644
--- a/modules/pam_access/README
+++ b/modules/pam_access/README
@@ -18,6 +18,20 @@ of parsing. This means that once a pattern is matched in some file no further
files are parsed. If a config file is explicitly specified with the accessfile
option the files in the above directory are not parsed.
+By default rules for access management are taken from config file /etc/security
+/access.conf or, if that one is not present, the file %vendordir%/security/
+access.conf. These settings can be overruled by setting in a config file
+explicitly specified with the accessfile option. Then individual *.conf files
+from the /etc/security/access.d/ and %vendordir%/security/access.d directories
+are read. If /etc/security/access.d/@filename@.conf exists, then %vendordir%/
+security/access.d/@filename@.conf will not be used. All access.d/*.conf files
+are sorted by their @filename@.conf in lexicographic order regardless of which
+of the directories they reside in. The effect of the individual files is the
+same as if all the files were concatenated together in the order of parsing.
+This means that once a pattern is matched in some file no further files are
+parsed. If a config file is explicitly specified with the accessfile option the
+files in the above directories are not parsed.
+
If Linux PAM is compiled with audit support the module will report when it
denies access based on origin (host, tty, etc.).
diff --git a/modules/pam_access/README.xml b/modules/pam_access/README.xml
index 8c7d078b..408aed00 100644
--- a/modules/pam_access/README.xml
+++ b/modules/pam_access/README.xml
@@ -1,39 +1,23 @@
-<?xml version="1.0" encoding='UTF-8'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
-"http://www.docbook.org/xml/4.3/docbookx.dtd"
-[
-<!--
-<!ENTITY pamaccess SYSTEM "pam_access.8.xml">
--->
-<!--
-<!ENTITY accessconf SYSTEM "access.conf.5.xml">
--->
-]>
+<article xmlns="http://docbook.org/ns/docbook" version="5.0">
-<article>
-
- <articleinfo>
+ <info>
<title>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_access.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_access-name"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_access.8.xml" xpointer='xpointer(id("pam_access-name")/*)'/>
</title>
- </articleinfo>
+ </info>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-description"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_access.8.xml" xpointer='xpointer(id("pam_access-description")/*)'/>
</section>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-options"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_access.8.xml" xpointer='xpointer(id("pam_access-options")/*)'/>
</section>
<section>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
- href="access.conf.5.xml" xpointer='xpointer(//refsect1[@id = "access.conf-examples"]/*)'/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="access.conf.5.xml" xpointer='xpointer(id("access.conf-examples")/*)'/>
</section>
-</article>
+</article> \ No newline at end of file
diff --git a/modules/pam_access/access.conf.5 b/modules/pam_access/access.conf.5
index 3204aedf..774e5cd9 100644
--- a/modules/pam_access/access.conf.5
+++ b/modules/pam_access/access.conf.5
@@ -1,13 +1,13 @@
'\" t
.\" Title: access.conf
.\" Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 09/03/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/>
+.\" Date: 05/07/2023
.\" Manual: Linux-PAM Manual
-.\" Source: Linux-PAM Manual
+.\" Source: [FIXME: source]
.\" Language: English
.\"
-.TH "ACCESS\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.TH "ACCESS\&.CONF" "5" "05/07/2023" "[FIXME: source]" "Linux\-PAM Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -210,7 +210,7 @@ option, the spaces will become part of the actual item and the line will be most
.PP
\fBpam_access\fR(8),
\fBpam.d\fR(5),
-\fBpam\fR(8)
+\fBpam\fR(7)
.SH "AUTHORS"
.PP
Original
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml
index 8fdbc31d..e1e5531f 100644
--- a/modules/pam_access/access.conf.5.xml
+++ b/modules/pam_access/access.conf.5.xml
@@ -1,8 +1,4 @@
-<?xml version="1.0" encoding='UTF-8'?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
- "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-
-<refentry id="access.conf">
+<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="access.conf">
<refmeta>
<refentrytitle>access.conf</refentrytitle>
@@ -16,7 +12,7 @@
</refnamediv>
- <refsect1 id='access.conf-description'>
+ <refsect1 xml:id="access.conf-description">
<title>DESCRIPTION</title>
<para>
The <filename>/etc/security/access.conf</filename> file specifies
@@ -126,7 +122,7 @@
</refsect1>
- <refsect1 id="access.conf-examples">
+ <refsect1 xml:id="access.conf-examples">
<title>EXAMPLES</title>
<para>
These are some example lines which might be specified in
@@ -135,7 +131,7 @@
<para>
User <emphasis>root</emphasis> should be allowed to get access via
- <emphasis>cron</emphasis>, X11 terminal <emphasis remap='I'>:0</emphasis>,
+ <emphasis>cron</emphasis>, X11 terminal <emphasis remap="I">:0</emphasis>,
<emphasis>tty1</emphasis>, ..., <emphasis>tty5</emphasis>,
<emphasis>tty6</emphasis>.
</para>
@@ -216,7 +212,7 @@
</refsect1>
- <refsect1 id="access.conf-notes">
+ <refsect1 xml:id="access.conf-notes">
<title>NOTES</title>
<para>
The default separators of list items in a field are space, ',', and tabulator
@@ -228,16 +224,16 @@
</para>
</refsect1>
- <refsect1 id="access.conf-see_also">
+ <refsect1 xml:id="access.conf-see_also">
<title>SEE ALSO</title>
<para>
<citerefentry><refentrytitle>pam_access</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
- <refsect1 id="access.conf-author">
+ <refsect1 xml:id="access.conf-author">
<title>AUTHORS</title>
<para>
Original <citerefentry><refentrytitle>login.access</refentrytitle><manvolnum>5</manvolnum></citerefentry>
@@ -250,4 +246,4 @@
introduced by Mike Becher &lt;mike.becher@lrz-muenchen.de&gt;.
</para>
</refsect1>
-</refentry>
+</refentry> \ No newline at end of file
diff --git a/modules/pam_access/pam_access.8 b/modules/pam_access/pam_access.8
index 92de516d..5b0e1a3f 100644
--- a/modules/pam_access/pam_access.8
+++ b/modules/pam_access/pam_access.8
@@ -1,13 +1,13 @@
'\" t
.\" Title: pam_access
.\" Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 09/03/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/>
+.\" Date: 05/07/2023
.\" Manual: Linux-PAM Manual
-.\" Source: Linux-PAM Manual
+.\" Source: Linux-PAM
.\" Language: English
.\"
-.TH "PAM_ACCESS" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.TH "PAM_ACCESS" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -51,25 +51,25 @@ option the files in the above directory are not parsed\&.
If Linux PAM is compiled with audit support the module will report when it denies access based on origin (host, tty, etc\&.)\&.
.SH "OPTIONS"
.PP
-\fBaccessfile=\fR\fB\fI/path/to/access\&.conf\fR\fR
+accessfile=/path/to/access\&.conf
.RS 4
Indicate an alternative
access\&.conf
style configuration file to override the default\&. This can be useful when different services need different access lists\&.
.RE
.PP
-\fBdebug\fR
+debug
.RS 4
A lot of debug information is printed with
\fBsyslog\fR(3)\&.
.RE
.PP
-\fBnoaudit\fR
+noaudit
.RS 4
Do not report logins from disallowed hosts and ttys to the audit subsystem\&.
.RE
.PP
-\fBfieldsep=\fR\fB\fIseparators\fR\fR
+fieldsep=separators
.RS 4
This option modifies the field separator character that pam_access will recognize when parsing the access configuration file\&. For example:
\fBfieldsep=|\fR
@@ -78,14 +78,14 @@ will cause the default `:\*(Aq character to be treated as part of a field value
item is likely to be of the form "hostname:0" which includes a `:\*(Aq character in its value\&. But you should not need this\&.
.RE
.PP
-\fBlistsep=\fR\fB\fIseparators\fR\fR
+listsep=separators
.RS 4
This option modifies the list separator character that pam_access will recognize when parsing the access configuration file\&. For example:
\fBlistsep=,\fR
will cause the default ` \*(Aq (space) and `\et\*(Aq (tab) characters to be treated as part of a list element value and `,\*(Aq becomes the only list element separator\&. Doing this may be useful on a system with group information obtained from a Windows domain, where the default built\-in groups "Domain Users", "Domain Admins" contain a space\&.
.RE
.PP
-\fBnodefgroup\fR
+nodefgroup
.RS 4
User tokens which are not enclosed in parentheses will not be matched against the group database\&. The backwards compatible default is to try the group database match even for tokens not enclosed in parentheses\&.
.RE
@@ -133,7 +133,7 @@ Default configuration file
.PP
\fBaccess.conf\fR(5),
\fBpam.d\fR(5),
-\fBpam\fR(8)\&.
+\fBpam\fR(7)\&.
.SH "AUTHORS"
.PP
The logdaemon style login access control scheme was designed and implemented by Wietse Venema\&. The pam_access PAM module was developed by Alexei Nogin <alexei@nogin\&.dnttm\&.ru>\&. The IPv6 support and the network(address) / netmask feature was developed and provided by Mike Becher <mike\&.becher@lrz\-muenchen\&.de>\&.
diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml
index 9a6556cc..cc01d5ca 100644
--- a/modules/pam_access/pam_access.8.xml
+++ b/modules/pam_access/pam_access.8.xml
@@ -1,16 +1,13 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
-
-<refentry id='pam_access'>
+<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pam_access">
<refmeta>
<refentrytitle>pam_access</refentrytitle>
<manvolnum>8</manvolnum>
- <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ <refmiscinfo class="source">Linux-PAM</refmiscinfo>
+ <refmiscinfo class="manual">Linux-PAM Manual</refmiscinfo>
</refmeta>
- <refnamediv id='pam_access-name'>
+ <refnamediv xml:id="pam_access-name">
<refname>pam_access</refname>
<refpurpose>
PAM module for logdaemon style login access control
@@ -20,31 +17,31 @@
<!-- body begins here -->
<refsynopsisdiv>
- <cmdsynopsis id="pam_access-cmdsynopsis">
+ <cmdsynopsis xml:id="pam_access-cmdsynopsis" sepchar=" ">
<command>pam_access.so</command>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
debug
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
nodefgroup
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
noaudit
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
accessfile=<replaceable>file</replaceable>
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
fieldsep=<replaceable>sep</replaceable>
</arg>
- <arg choice="opt">
+ <arg choice="opt" rep="norepeat">
listsep=<replaceable>sep</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
- <refsect1 id="pam_access-description">
+ <refsect1 xml:id="pam_access-description">
<title>DESCRIPTION</title>
<para>
The pam_access PAM module is mainly for access management.
@@ -53,7 +50,7 @@
or on terminal line names, X <varname>$DISPLAY</varname> values,
or PAM service names in case of non-networked logins.
</para>
- <para>
+ <para condition="without_vendordir">
By default rules for access management are taken from config file
<filename>/etc/security/access.conf</filename> if you don't specify
another file.
@@ -66,19 +63,39 @@
If a config file is explicitly specified with the <option>accessfile</option>
option the files in the above directory are not parsed.
</para>
+ <para condition="with_vendordir">
+ By default rules for access management are taken from config file
+ <filename>/etc/security/access.conf</filename> or, if that one is not
+ present, the file <filename>%vendordir%/security/access.conf</filename>.
+ These settings can be overruled by setting in a config file explicitly
+ specified with the <option>accessfile</option> option.
+ Then individual <filename>*.conf</filename> files from the
+ <filename>/etc/security/access.d/</filename> and
+ <filename>%vendordir%/security/access.d</filename> directories are read.
+ If <filename>/etc/security/access.d/@filename@.conf</filename> exists, then
+ <filename>%vendordir%/security/access.d/@filename@.conf</filename> will not be used.
+ All <filename>access.d/*.conf</filename> files are sorted by their
+ <filename>@filename@.conf</filename> in lexicographic order regardless of which
+ of the directories they reside in.
+ The effect of the individual files is the same as if all the files were
+ concatenated together in the order of parsing. This means that once
+ a pattern is matched in some file no further files are parsed.
+ If a config file is explicitly specified with the <option>accessfile</option>
+ option the files in the above directories are not parsed.
+ </para>
<para>
If Linux PAM is compiled with audit support the module will report
when it denies access based on origin (host, tty, etc.).
</para>
</refsect1>
- <refsect1 id="pam_access-options">
+ <refsect1 xml:id="pam_access-options">
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term>
- <option>accessfile=<replaceable>/path/to/access.conf</replaceable></option>
+ accessfile=/path/to/access.conf
</term>
<listitem>
<para>
@@ -91,7 +108,7 @@
<varlistentry>
<term>
- <option>debug</option>
+ debug
</term>
<listitem>
<para>
@@ -103,7 +120,7 @@
<varlistentry>
<term>
- <option>noaudit</option>
+ noaudit
</term>
<listitem>
<para>
@@ -114,19 +131,19 @@
<varlistentry>
<term>
- <option>fieldsep=<replaceable>separators</replaceable></option>
+ fieldsep=separators
</term>
<listitem>
<para>
This option modifies the field separator character that
pam_access will recognize when parsing the access
configuration file. For example:
- <emphasis remap='B'>fieldsep=|</emphasis> will cause the
+ <emphasis remap="B">fieldsep=|</emphasis> will cause the
default `:' character to be treated as part of a field value
and `|' becomes the field separator. Doing this may be
useful in conjunction with a system that wants to use
pam_access with X based applications, since the
- <emphasis remap='B'>PAM_TTY</emphasis> item is likely to be
+ <emphasis remap="B">PAM_TTY</emphasis> item is likely to be
of the form "hostname:0" which includes a `:' character in
its value. But you should not need this.
</para>
@@ -135,14 +152,14 @@
<varlistentry>
<term>
- <option>listsep=<replaceable>separators</replaceable></option>
+ listsep=separators
</term>
<listitem>
<para>
This option modifies the list separator character that
pam_access will recognize when parsing the access
configuration file. For example:
- <emphasis remap='B'>listsep=,</emphasis> will cause the
+ <emphasis remap="B">listsep=,</emphasis> will cause the
default ` ' (space) and `\t' (tab) characters to be treated
as part of a list element value and `,' becomes the only
list element separator. Doing this may be useful on a system
@@ -155,7 +172,7 @@
<varlistentry>
<term>
- <option>nodefgroup</option>
+ nodefgroup
</term>
<listitem>
<para>
@@ -170,7 +187,7 @@
</variablelist>
</refsect1>
- <refsect1 id="pam_access-types">
+ <refsect1 xml:id="pam_access-types">
<title>MODULE TYPES PROVIDED</title>
<para>
All module types (<option>auth</option>, <option>account</option>,
@@ -178,7 +195,7 @@
</para>
</refsect1>
- <refsect1 id="pam_access-return_values">
+ <refsect1 xml:id="pam_access-return_values">
<title>RETURN VALUES</title>
<variablelist>
<varlistentry>
@@ -224,19 +241,26 @@
</variablelist>
</refsect1>
- <refsect1 id="pam_access-files">
+ <refsect1 xml:id="pam_access-files">
<title>FILES</title>
<variablelist>
<varlistentry>
- <term><filename>/etc/security/access.conf</filename></term>
+ <term>/etc/security/access.conf</term>
<listitem>
<para>Default configuration file</para>
</listitem>
</varlistentry>
+ <varlistentry condition="with_vendordir">
+ <term>%vendordir%/security/access.conf</term>
+ <listitem>
+ <para>Default configuration file if
+ <filename>/etc/security/access.conf</filename> does not exist.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
- <refsect1 id="pam_access-see_also">
+ <refsect1 xml:id="pam_access-see_also">
<title>SEE ALSO</title>
<para>
<citerefentry>
@@ -246,12 +270,12 @@
<refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
- <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ <refentrytitle>pam</refentrytitle><manvolnum>7</manvolnum>
</citerefentry>.
</para>
</refsect1>
- <refsect1 id="pam_access-authors">
+ <refsect1 xml:id="pam_access-authors">
<title>AUTHORS</title>
<para>
The logdaemon style login access control scheme was designed and implemented by
@@ -262,4 +286,4 @@
was developed and provided by Mike Becher &lt;mike.becher@lrz-muenchen.de&gt;.
</para>
</refsect1>
-</refentry>
+</refentry> \ No newline at end of file
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
index 277192b9..f70b7e49 100644
--- a/modules/pam_access/pam_access.c
+++ b/modules/pam_access/pam_access.c
@@ -56,6 +56,13 @@
#include "pam_cc_compat.h"
#include "pam_inline.h"
+#define PAM_ACCESS_CONFIG (SCONFIGDIR "/access.conf")
+#define ACCESS_CONF_GLOB (SCONFIGDIR "/access.d/*.conf")
+#ifdef VENDOR_SCONFIGDIR
+#define VENDOR_PAM_ACCESS_CONFIG (VENDOR_SCONFIGDIR "/access.conf")
+#define VENDOR_ACCESS_CONF_GLOB (VENDOR_SCONFIGDIR "/access.d/*.conf")
+#endif
+
/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
/*
@@ -151,6 +158,95 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo,
return 1; /* OK */
}
+/* --- evaluting all files in VENDORDIR/security/access.d and /etc/security/access.d --- */
+static const char *base_name(const char *path)
+{
+ const char *base = strrchr(path, '/');
+ return base ? base+1 : path;
+}
+
+static int
+compare_filename(const void *a, const void *b)
+{
+ return strcmp(base_name(* (const char * const *) a),
+ base_name(* (const char * const *) b));
+}
+
+/* Evaluating a list of files which have to be parsed in the right order:
+ *
+ * - If etc/security/access.d/@filename@.conf exists, then
+ * %vendordir%/security/access.d/@filename@.conf should not be used.
+ * - All files in both access.d directories are sorted by their @filename@.conf in
+ * lexicographic order regardless of which of the directories they reside in. */
+static char **read_access_dir(pam_handle_t *pamh)
+{
+ glob_t globbuf;
+ size_t i=0;
+ int glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf);
+ char **file_list;
+ size_t file_list_size = glob_rv == 0 ? globbuf.gl_pathc : 0;
+
+#ifdef VENDOR_ACCESS_CONF_GLOB
+ glob_t globbuf_vendor;
+ int glob_rv_vendor = glob(VENDOR_ACCESS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf_vendor);
+ if (glob_rv_vendor == 0)
+ file_list_size += globbuf_vendor.gl_pathc;
+#endif
+ file_list = malloc((file_list_size + 1) * sizeof(char*));
+ if (file_list == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for file list: %m");
+#ifdef VENDOR_ACCESS_CONF_GLOB
+ if (glob_rv_vendor == 0)
+ globfree(&globbuf_vendor);
+#endif
+ if (glob_rv == 0)
+ globfree(&globbuf);
+ return NULL;
+ }
+
+ if (glob_rv == 0) {
+ for (i = 0; i < globbuf.gl_pathc; i++) {
+ file_list[i] = strdup(globbuf.gl_pathv[i]);
+ if (file_list[i] == NULL) {
+ pam_syslog(pamh, LOG_ERR, "strdup failed: %m");
+ break;
+ }
+ }
+ }
+#ifdef VENDOR_ACCESS_CONF_GLOB
+ if (glob_rv_vendor == 0) {
+ for (size_t j = 0; j < globbuf_vendor.gl_pathc; j++) {
+ if (glob_rv == 0 && globbuf.gl_pathc > 0) {
+ int double_found = 0;
+ for (size_t k = 0; k < globbuf.gl_pathc; k++) {
+ if (strcmp(base_name(globbuf.gl_pathv[k]),
+ base_name(globbuf_vendor.gl_pathv[j])) == 0) {
+ double_found = 1;
+ break;
+ }
+ }
+ if (double_found)
+ continue;
+ }
+ file_list[i] = strdup(globbuf_vendor.gl_pathv[j]);
+ if (file_list[i] == NULL) {
+ pam_syslog(pamh, LOG_ERR, "strdup failed: %m");
+ break;
+ }
+ i++;
+ }
+ globfree(&globbuf_vendor);
+ }
+#endif
+ file_list[i] = NULL;
+ qsort(file_list, i, sizeof(char *), compare_filename);
+
+ if (glob_rv == 0)
+ globfree(&globbuf);
+
+ return file_list;
+}
+
/* --- static functions for checking whether the user should be let in --- */
typedef int match_func (pam_handle_t *, char *, struct login_info *);
@@ -567,7 +663,7 @@ static int
group_match (pam_handle_t *pamh, const char *tok, const char* usr,
int debug)
{
- char grptok[BUFSIZ];
+ char grptok[BUFSIZ] = {};
if (debug)
pam_syslog (pamh, LOG_DEBUG,
@@ -577,7 +673,6 @@ group_match (pam_handle_t *pamh, const char *tok, const char* usr,
return NO;
/* token is received under the format '(...)' */
- memset(grptok, 0, BUFSIZ);
strncpy(grptok, tok + 1, strlen(tok) - 2);
if (pam_modutil_user_in_group_nam_nam(pamh, usr, grptok))
@@ -637,7 +732,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));
@@ -678,7 +773,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);
}
@@ -696,7 +791,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 */
@@ -714,7 +809,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,
@@ -723,10 +819,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)
{
@@ -760,54 +858,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;
}
@@ -828,7 +980,6 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
char hostname[MAXHOSTNAMELEN + 1];
int rv;
-
/* set username */
if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
@@ -853,6 +1004,18 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
return PAM_ABORT;
}
+#ifdef VENDOR_PAM_ACCESS_CONFIG
+ if (loginfo.config_file == default_config) {
+ /* Check whether PAM_ACCESS_CONFIG file is available.
+ * If it does not exist, fall back to VENDOR_PAM_ACCESS_CONFIG file. */
+ struct stat buffer;
+ if (stat(loginfo.config_file, &buffer) != 0 && errno == ENOENT) {
+ default_config = VENDOR_PAM_ACCESS_CONFIG;
+ loginfo.config_file = default_config;
+ }
+ }
+#endif
+
/* remote host name */
if (pam_get_item(pamh, PAM_RHOST, &void_from)
@@ -916,23 +1079,18 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
rv = login_access(pamh, &loginfo);
if (rv == NOMATCH && loginfo.config_file == default_config) {
- glob_t globbuf;
- int i, glob_rv;
-
- /* We do not manipulate locale as setlocale() is not
- * thread safe. We could use uselocale() in future.
- */
- glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
- if (!glob_rv) {
- /* Parse the *.conf files. */
- for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
- loginfo.config_file = globbuf.gl_pathv[i];
- rv = login_access(pamh, &loginfo);
- if (rv != NOMATCH)
- break;
- }
- globfree(&globbuf);
- }
+ char **filename_list = read_access_dir(pamh);
+ if (filename_list != NULL) {
+ for (int i = 0; filename_list[i] != NULL; i++) {
+ loginfo.config_file = filename_list[i];
+ rv = login_access(pamh, &loginfo);
+ if (rv != NOMATCH)
+ break;
+ }
+ for (int i = 0; filename_list[i] != NULL; i++)
+ free(filename_list[i]);
+ free(filename_list);
+ }
}
if (loginfo.gai_rv == 0 && loginfo.res)