c2a452
diff -up Linux-PAM-1.1.8/modules/pam_access/access.conf.access-update Linux-PAM-1.1.8/modules/pam_access/access.conf
c2a452
--- Linux-PAM-1.1.8/modules/pam_access/access.conf.access-update	2013-06-18 16:11:21.000000000 +0200
c2a452
+++ Linux-PAM-1.1.8/modules/pam_access/access.conf	2017-09-08 14:06:16.420102221 +0200
c2a452
@@ -18,7 +18,7 @@
c2a452
 # pam_access with X applications that provide PAM_TTY values that are
c2a452
 # the display variable like "host:0".]
c2a452
 #
c2a452
-# 	permission : users : origins
c2a452
+# 	permission:users:origins
c2a452
 #
c2a452
 # The first field should be a "+" (access granted) or "-" (access denied)
c2a452
 # character.
c2a452
@@ -79,44 +79,44 @@
c2a452
 ##############################################################################
c2a452
 #
c2a452
 # User "root" should be allowed to get access via cron .. tty5 tty6.
c2a452
-#+ : root : cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6
c2a452
+#+:root:cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6
c2a452
 #
c2a452
 # User "root" should be allowed to get access from hosts with ip addresses.
c2a452
-#+ : root : 192.168.200.1 192.168.200.4 192.168.200.9
c2a452
-#+ : root : 127.0.0.1
c2a452
+#+:root:192.168.200.1 192.168.200.4 192.168.200.9
c2a452
+#+:root:127.0.0.1
c2a452
 #
c2a452
 # User "root" should get access from network 192.168.201.
c2a452
 # This term will be evaluated by string matching.
c2a452
 # comment: It might be better to use network/netmask instead.
c2a452
 #          The same is 192.168.201.0/24 or 192.168.201.0/255.255.255.0
c2a452
-#+ : root : 192.168.201.
c2a452
+#+:root:192.168.201.
c2a452
 #
c2a452
 # User "root" should be able to have access from domain.
c2a452
 # Uses string matching also.
c2a452
-#+ : root : .foo.bar.org
c2a452
+#+:root:.foo.bar.org
c2a452
 #
c2a452
 # User "root" should be denied to get access from all other sources.
c2a452
-#- : root : ALL
c2a452
+#-:root:ALL
c2a452
 #
c2a452
 # User "foo" and members of netgroup "nis_group" should be
c2a452
 # allowed to get access from all sources.
c2a452
 # This will only work if netgroup service is available.
c2a452
-#+ : @nis_group foo : ALL
c2a452
+#+:@nis_group foo:ALL
c2a452
 #
c2a452
 # User "john" should get access from ipv4 net/mask
c2a452
-#+ : john : 127.0.0.0/24
c2a452
+#+:john:127.0.0.0/24
c2a452
 #
c2a452
 # User "john" should get access from ipv4 as ipv6 net/mask
c2a452
-#+ : john : ::ffff:127.0.0.0/127
c2a452
+#+:john:::ffff:127.0.0.0/127
c2a452
 #
c2a452
 # User "john" should get access from ipv6 host address
c2a452
-#+ : john : 2001:4ca0:0:101::1
c2a452
+#+:john:2001:4ca0:0:101::1
c2a452
 #
c2a452
 # User "john" should get access from ipv6 host address (same as above)
c2a452
-#+ : john : 2001:4ca0:0:101:0:0:0:1
c2a452
+#+:john:2001:4ca0:0:101:0:0:0:1
c2a452
 #
c2a452
 # User "john" should get access from ipv6 net/mask
c2a452
-#+ : john : 2001:4ca0:0:101::/64
c2a452
+#+:john:2001:4ca0:0:101::/64
c2a452
 #
c2a452
 # All other users should be denied to get access from all sources.
c2a452
-#- : ALL : ALL
c2a452
+#-:ALL:ALL
c2a452
diff -up Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml.access-update Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml
c2a452
--- Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml.access-update	2013-06-18 16:11:21.000000000 +0200
c2a452
+++ Linux-PAM-1.1.8/modules/pam_access/access.conf.5.xml	2017-09-08 14:05:41.126320653 +0200
c2a452
@@ -21,8 +21,12 @@
c2a452
     <para>
c2a452
       The <filename>/etc/security/access.conf</filename> file specifies
c2a452
       (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>),
c2a452
-      (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>) or
c2a452
-      (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
c2a452
+      (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>),
c2a452
+      (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>),
c2a452
+      (<replaceable>user/group</replaceable>,
c2a452
+      <replaceable>X-$DISPLAY-value</replaceable>), or
c2a452
+      (<replaceable>user/group</replaceable>,
c2a452
+      <replaceable>pam-service-name</replaceable>)
c2a452
       combinations for which a login will be either accepted or refused.
c2a452
     </para>
c2a452
     <para>
c2a452
@@ -33,7 +37,14 @@
c2a452
       combination, or, in case of non-networked logins, the first entry
c2a452
       that matches the
c2a452
       (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
c2a452
-      combination.  The permissions field of that table entry determines
c2a452
+      combination, or in the case of non-networked logins without a
c2a452
+      tty, the first entry that matches the
c2a452
+      (<replaceable>user/group</replaceable>,
c2a452
+      <replaceable>X-$DISPLAY-value</replaceable>) or
c2a452
+      (<replaceable>user/group</replaceable>,
c2a452
+      <replaceable>pam-service-name/</replaceable>)
c2a452
+      combination.  The permissions field of that table entry
c2a452
+      determines
c2a452
       whether the login will be accepted or refused.
c2a452
    </para>
c2a452
 
c2a452
@@ -65,14 +76,27 @@
c2a452
     <para>
c2a452
       The third field, the <replaceable>origins</replaceable>
c2a452
       field, should be a list of one or more tty names (for non-networked
c2a452
-      logins), host names, domain names (begin with "."), host addresses,
c2a452
+      logins), X <varname>$DISPLAY</varname> values or PAM service
c2a452
+      names (for non-networked logins without a tty), host names,
c2a452
+      domain names (begin with "."), host addresses,
c2a452
       internet network numbers (end with "."), internet network addresses
c2a452
       with network mask (where network mask can be a decimal number or an
c2a452
       internet address also), <emphasis>ALL</emphasis> (which always matches)
c2a452
-      or <emphasis>LOCAL</emphasis>. <emphasis>LOCAL</emphasis>
c2a452
-      keyword matches if and only if the <emphasis>PAM_RHOST</emphasis> is
c2a452
-      not set and <origin> field is thus set from
c2a452
-      <emphasis>PAM_TTY</emphasis> or <emphasis>PAM_SERVICE</emphasis>".
c2a452
+      or <emphasis>LOCAL</emphasis>. The <emphasis>LOCAL</emphasis>
c2a452
+      keyword matches if and only if
c2a452
+      <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
c2a452
+      when called with an <parameter>item_type</parameter> of
c2a452
+      <emphasis>PAM_RHOST</emphasis>, returns NULL or an
c2a452
+      empty string (and therefore the
c2a452
+      <replaceable>origins</replaceable> field is compared against the
c2a452
+      return value of
c2a452
+      <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>
c2a452
+      called with an <parameter>item_type</parameter> of
c2a452
+      <emphasis>PAM_TTY</emphasis> or, absent that,
c2a452
+      <emphasis>PAM_SERVICE</emphasis>).
c2a452
+    </para>
c2a452
+
c2a452
+    <para>
c2a452
       If supported by the system you can use
c2a452
       <emphasis>@netgroupname</emphasis> in host or user patterns. The
c2a452
       <emphasis>@@netgroupname</emphasis> syntax is supported in the user
c2a452
@@ -115,7 +139,7 @@
c2a452
       <emphasis>tty1</emphasis>, ..., <emphasis>tty5</emphasis>,
c2a452
       <emphasis>tty6</emphasis>.
c2a452
     </para>
c2a452
-    <para>+ : root : crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para>
c2a452
+    <para>+:root:crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>root</emphasis> should be allowed to get access from
c2a452
@@ -123,8 +147,8 @@
c2a452
       connection have to be a IPv4 one, a IPv6 connection from a host with
c2a452
       one of this IPv4 addresses does work, too.
c2a452
     </para>
c2a452
-    <para>+ : root : 192.168.200.1 192.168.200.4 192.168.200.9</para>
c2a452
-    <para>+ : root : 127.0.0.1</para>
c2a452
+    <para>+:root:192.168.200.1 192.168.200.4 192.168.200.9</para>
c2a452
+    <para>+:root:127.0.0.1</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>root</emphasis> should get access from network
c2a452
@@ -134,44 +158,44 @@
c2a452
       <emphasis>192.168.201.0/24</emphasis> or
c2a452
       <emphasis>192.168.201.0/255.255.255.0</emphasis>.
c2a452
     </para>
c2a452
-    <para>+ : root : 192.168.201.</para>
c2a452
+    <para>+:root:192.168.201.</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>root</emphasis> should be able to have access from hosts
c2a452
       <emphasis>foo1.bar.org</emphasis> and <emphasis>foo2.bar.org</emphasis>
c2a452
       (uses string matching also).
c2a452
     </para>
c2a452
-    <para>+ : root : foo1.bar.org foo2.bar.org</para>
c2a452
+    <para>+:root:foo1.bar.org foo2.bar.org</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>root</emphasis> should be able to have access from
c2a452
       domain <emphasis>foo.bar.org</emphasis> (uses string matching also).
c2a452
     </para>
c2a452
-    <para>+ : root : .foo.bar.org</para>
c2a452
+    <para>+:root:.foo.bar.org</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>root</emphasis> should be denied to get access
c2a452
       from all other sources.
c2a452
     </para>
c2a452
-    <para>- : root : ALL</para>
c2a452
+    <para>-:root:ALL</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>foo</emphasis> and members of netgroup
c2a452
       <emphasis>admins</emphasis> should be allowed to get access
c2a452
       from all sources. This will only work if netgroup service is available.
c2a452
     </para>
c2a452
-    <para>+ : @admins foo : ALL</para>
c2a452
+    <para>+:@admins foo:ALL</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>john</emphasis> and <emphasis>foo</emphasis>
c2a452
       should get access from IPv6 host address.
c2a452
     </para>
c2a452
-    <para>+ : john foo : 2001:db8:0:101::1</para>
c2a452
+    <para>+:john foo:2001:db8:0:101::1</para>
c2a452
 
c2a452
     <para>
c2a452
       User <emphasis>john</emphasis> should get access from IPv6 net/mask.
c2a452
     </para>
c2a452
-    <para>+ : john : 2001:db8:0:101::/64</para>
c2a452
+    <para>+:john:2001:db8:0:101::/64</para>
c2a452
 
c2a452
     <para>
c2a452
       Disallow console logins to all but the shutdown, sync and all
c2a452
@@ -182,10 +206,22 @@
c2a452
     <para>
c2a452
       All other users should be denied to get access from all sources.
c2a452
     </para>
c2a452
-    <para>- : ALL : ALL</para>
c2a452
+    <para>-:ALL:ALL</para>
c2a452
 
c2a452
   </refsect1>
c2a452
 
c2a452
+  <refsect1 id="access.conf-notes">
c2a452
+    <title>NOTES</title>
c2a452
+    <para>
c2a452
+      The default separators of list items in a field are space, ',', and tabulator
c2a452
+      characters. Thus conveniently if spaces are put at the beginning and the end of
c2a452
+      the fields they are ignored. However if the list separator is changed with the
c2a452
+      <emphasis>listsep</emphasis> option, the spaces will become part of the actual
c2a452
+      item and the line will be most probably ignored. For this reason, it is not
c2a452
+      recommended to put spaces around the ':' characters.
c2a452
+    </para>
c2a452
+  </refsect1>
c2a452
+
c2a452
   <refsect1 id="access.conf-see_also">
c2a452
     <title>SEE ALSO</title>
c2a452
     <para>
c2a452
diff -up Linux-PAM-1.1.8/modules/pam_access/Makefile.am.access-update Linux-PAM-1.1.8/modules/pam_access/Makefile.am
c2a452
--- Linux-PAM-1.1.8/modules/pam_access/Makefile.am.access-update	2013-06-18 16:11:21.000000000 +0200
c2a452
+++ Linux-PAM-1.1.8/modules/pam_access/Makefile.am	2017-09-08 14:10:47.223163175 +0200
c2a452
@@ -15,7 +15,8 @@ securelibdir = $(SECUREDIR)
c2a452
 secureconfdir = $(SCONFIGDIR)
c2a452
 
c2a452
 AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
c2a452
-	-DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" $(NIS_CFLAGS)
c2a452
+	-DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \
c2a452
+	-DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(NIS_CFLAGS)
c2a452
 AM_LDFLAGS =  -no-undefined -avoid-version -module
c2a452
 if HAVE_VERSIONING
c2a452
   AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
c2a452
diff -up Linux-PAM-1.1.8/modules/pam_access/pam_access.c.access-update Linux-PAM-1.1.8/modules/pam_access/pam_access.c
c2a452
--- Linux-PAM-1.1.8/modules/pam_access/pam_access.c.access-update	2013-06-18 16:11:21.000000000 +0200
c2a452
+++ Linux-PAM-1.1.8/modules/pam_access/pam_access.c	2017-09-08 14:03:45.620762824 +0200
c2a452
@@ -44,6 +44,7 @@
c2a452
 #include <arpa/inet.h>
c2a452
 #include <netdb.h>
c2a452
 #include <sys/socket.h>
c2a452
+#include <glob.h>
c2a452
 #ifdef HAVE_RPCSVC_YPCLNT_H
c2a452
 #include <rpcsvc/ypclnt.h>
c2a452
 #endif
c2a452
@@ -90,6 +91,7 @@
c2a452
 #define ALL             2
c2a452
 #define YES             1
c2a452
 #define NO              0
c2a452
+#define NOMATCH        -1
c2a452
 
c2a452
  /*
c2a452
   * A structure to bundle up all login-related information to keep the
c2a452
@@ -412,13 +414,17 @@ login_access (pam_handle_t *pamh, struct
c2a452
 	return NO;
c2a452
     }
c2a452
 #ifdef HAVE_LIBAUDIT
c2a452
-    if (!item->noaudit && line[0] == '-' && (match == YES || (match == ALL &&
c2a452
-	nonall_match == YES))) {
c2a452
+    if (!item->noaudit && (match == YES || (match == ALL &&
c2a452
+	nonall_match == YES)) && line[0] == '-') {
c2a452
 	pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION,
c2a452
 	    "pam_access", 0);
c2a452
     }
c2a452
 #endif
c2a452
-    return (match == NO || (line[0] == '+'));
c2a452
+    if (match == NO)
c2a452
+	return NOMATCH;
c2a452
+    if (line[0] == '+')
c2a452
+	return YES;
c2a452
+    return NO;
c2a452
 }
c2a452
 
c2a452
 
c2a452
@@ -524,7 +530,9 @@ user_match (pam_handle_t *pamh, char *to
c2a452
     /* Try to split on a pattern (@*[^@]+)(@+.*) */
c2a452
     for (at = tok; *at == '@'; ++at);
c2a452
 
c2a452
-    if ((at = strchr(at, '@')) != NULL) {
c2a452
+    if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') {
c2a452
+      return (group_match (pamh, tok, string, item->debug));
c2a452
+    } else if ((at = strchr(at, '@')) != NULL) {
c2a452
         /* split user@host pattern */
c2a452
 	if (item->hostname == NULL)
c2a452
 	    return NO;
c2a452
@@ -549,9 +557,7 @@ user_match (pam_handle_t *pamh, char *to
c2a452
 		hostname = item->hostname;
c2a452
 	}
c2a452
         return (netgroup_match (pamh, tok + 1, hostname, string, item->debug));
c2a452
-    } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
c2a452
-      return (group_match (pamh, tok, string, item->debug));
c2a452
-    else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
c2a452
+    } else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
c2a452
       return rv;
c2a452
     else if (item->only_new_group_syntax == NO &&
c2a452
 	     pam_modutil_user_in_group_nam_nam (pamh,
c2a452
@@ -573,7 +579,7 @@ group_match (pam_handle_t *pamh, const c
c2a452
 
c2a452
     if (debug)
c2a452
         pam_syslog (pamh, LOG_DEBUG,
c2a452
-		    "group_match: grp=%s, user=%s", grptok, usr);
c2a452
+		    "group_match: grp=%s, user=%s", tok, usr);
c2a452
 
c2a452
     if (strlen(tok) < 3)
c2a452
         return NO;
c2a452
@@ -808,6 +814,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
c2a452
     const char *user=NULL;
c2a452
     const void *void_from=NULL;
c2a452
     const char *from;
c2a452
+    const char const *default_config = PAM_ACCESS_CONFIG;
c2a452
     struct passwd *user_pw;
c2a452
     char hostname[MAXHOSTNAMELEN + 1];
c2a452
     int rv;
c2a452
@@ -829,7 +836,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
c2a452
      */
c2a452
     memset(&loginfo, '\0', sizeof(loginfo));
c2a452
     loginfo.user = user_pw;
c2a452
-    loginfo.config_file = PAM_ACCESS_CONFIG;
c2a452
+    loginfo.config_file = default_config;
c2a452
 
c2a452
     /* parse the argument list */
c2a452
 
c2a452
@@ -900,6 +907,26 @@ pam_sm_authenticate (pam_handle_t *pamh,
c2a452
 
c2a452
     rv = login_access(pamh, &loginfo);
c2a452
 
c2a452
+    if (rv == NOMATCH && loginfo.config_file == default_config) {
c2a452
+	glob_t globbuf;
c2a452
+	int i, glob_rv;
c2a452
+
c2a452
+	/* We do not manipulate locale as setlocale() is not
c2a452
+	 * thread safe. We could use uselocale() in future.
c2a452
+	 */
c2a452
+	glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
c2a452
+	if (!glob_rv) {
c2a452
+	    /* Parse the *.conf files. */
c2a452
+	    for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
c2a452
+		loginfo.config_file = globbuf.gl_pathv[i];
c2a452
+		rv = login_access(pamh, &loginfo);
c2a452
+		if (rv != NOMATCH)
c2a452
+		    break;
c2a452
+	    }
c2a452
+	    globfree(&globbuf);
c2a452
+	}
c2a452
+    }
c2a452
+
c2a452
     if (loginfo.gai_rv == 0 && loginfo.res)
c2a452
 	freeaddrinfo(loginfo.res);
c2a452
 
c2a452
diff -up Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml.access-update Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml
c2a452
--- Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml.access-update	2013-06-18 16:11:21.000000000 +0200
c2a452
+++ Linux-PAM-1.1.8/modules/pam_access/pam_access.8.xml	2017-09-08 14:04:25.365642960 +0200
c2a452
@@ -50,16 +50,25 @@
c2a452
       The pam_access PAM module is mainly for access management.
c2a452
       It provides logdaemon style login access control based on login
c2a452
       names, host or domain names, internet addresses or network numbers,
c2a452
-      or on terminal line names in case of non-networked logins.
c2a452
+      or on terminal line names, X <varname>$DISPLAY</varname> values,
c2a452
+      or PAM service names in case of non-networked logins.
c2a452
     </para>
c2a452
     <para>
c2a452
       By default rules for access management are taken from config file
c2a452
       <filename>/etc/security/access.conf</filename> if you don't specify
c2a452
       another file.
c2a452
+      Then individual <filename>*.conf</filename> files from the
c2a452
+      <filename>/etc/security/access.d/</filename> directory are read.
c2a452
+      The files are parsed one after another in the order of the system locale.
c2a452
+      The effect of the individual files is the same as if all the files were
c2a452
+      concatenated together in the order of parsing. This means that once
c2a452
+      a pattern is matched in some file no further files are parsed.
c2a452
+      If a config file is explicitly specified with the <option>accessfile</option>
c2a452
+      option the files in the above directory are not parsed.
c2a452
     </para>
c2a452
     <para>
c2a452
       If Linux PAM is compiled with audit support the module will report
c2a452
-      when it denies access based on origin (host or tty).
c2a452
+      when it denies access based on origin (host, tty, etc.).
c2a452
     </para>
c2a452
   </refsect1>
c2a452