]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: 411390
authorThorsten Kukuk <kukuk@thkukuk.de>
Fri, 22 Jun 2007 09:49:03 +0000 (09:49 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Fri, 22 Jun 2007 09:49:03 +0000 (09:49 +0000)
Purpose of commit: new feature

Commit summary:
---------------

2007-06-22  Thorsten Kukuk  <kukuk@thkukuk.de>

        * modules/pam_access/pam_access.c: Add new syntax for groups
        in access.conf to differentiate group names from account names.
        Based on patch from Julien Lecomte <julien@famille-lecomte.net>,
        solves feature request [#411390].
        * modules/pam_access/access.conf: Add example for new group
        syntax.
        * modules/pam_access/access.conf.5.xml: Document new syntax.

ChangeLog
modules/pam_access/README
modules/pam_access/access.conf
modules/pam_access/access.conf.5
modules/pam_access/access.conf.5.xml
modules/pam_access/pam_access.8
modules/pam_access/pam_access.8.xml
modules/pam_access/pam_access.c

index 63f7761c901b6789b51ea421486027517953b237..4a75dd884e21ee50cf89110e35df791bb386f2d0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-06-22  Thorsten Kukuk  <kukuk@thkukuk.de>
+
+       * modules/pam_access/pam_access.c: Add new syntax for groups
+       in access.conf to differentiate group names from account names.
+       Based on patch from Julien Lecomte <julien@famille-lecomte.net>,
+       solves feature request [#411390].
+       * modules/pam_access/access.conf: Add example for new group
+       syntax.
+       * modules/pam_access/access.conf.5.xml: Document new syntax.
+
 2007-06-20  Thorsten Kukuk  <kukuk@thkukuk.de>
 
        * modules/pam_cracklib/pam_cracklib.8.xml: Document new minclass
index c3561da0fbc66f78a0af18e1bbffc601f74a1b85..a3adcc8f16dcd8d9992ca6168927e58d691697d6 100644 (file)
@@ -45,6 +45,11 @@ listsep=separators
     information obtained from a Windows domain, where the default built-in
     groups "Domain Users", "Domain Admins" contain a space.
 
+nodefgroup
+
+    The group database will not be used for tokens not identified as account
+    name.
+
 EXAMPLES
 
 These are some example lines which might be specified in /etc/security/
@@ -97,6 +102,11 @@ User john should get access from IPv6 net/mask.
 
 + : john : 2001:4ca0:0:101::/64
 
+Disallow console logins to all but the shutdown, sync and all other accounts,
+which are a member of the wheel group.
+
+-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+
 All other users should be denied to get access from all sources.
 
 - : ALL : ALL
index b22f1d43f44377a4984d82698431c85775de8599..74c5fbe84b8e3ee8a9790809d821a447e2ac4684 100644 (file)
@@ -1,14 +1,14 @@
 # Login access control table.
-# 
+#
 # Comment line must start with "#", no space at front.
 # Order of lines is important.
 #
 # When someone logs in, the table is scanned for the first entry that
 # matches the (user, host) combination, or, in case of non-networked
 # logins, the first entry that matches the (user, tty) combination.  The
-# permissions field of that table entry determines whether the login will 
+# permissions field of that table entry determines whether the login will
 # be accepted or refused.
-# 
+#
 # Format of the login access control table is three fields separated by a
 # ":" character:
 #
 # '|'. This is useful for configurations where you are trying to use
 # pam_access with X applications that provide PAM_TTY values that are
 # the display variable like "host:0".]
-# 
+#
 #      permission : users : origins
-# 
+#
 # The first field should be a "+" (access granted) or "-" (access denied)
-# character. 
+# character.
 #
 # The second field should be a list of one or more login names, group
 # names, or ALL (always matches). A pattern of the form user@host is
 # The group file is searched only when a name does not match that of the
 # logged-in user. Both the user's primary group is matched, as well as
 # groups in which users are explicitly listed.
+# To avoid problems with accounts, which have the same name as a group,
+# you can use brackets around group names '(group)' to differentiate.
+# In this case, you should also set the "nodefgroup" option.
 #
 # TTY NAMES: Must be in the form returned by ttyname(3) less the initial
 # "/dev" (e.g. tty1 or vc/1)
 #
 ##############################################################################
-# 
+#
 # Disallow non-root logins on tty1
 #
 #-:ALL EXCEPT root:tty1
-# 
+#
 # Disallow console logins to all but a few accounts.
 #
 #-:ALL EXCEPT wheel shutdown sync:LOCAL
 #
+# Same, but make sure that really the group wheel and not the user
+# wheel is used (use nodefgroup argument, too):
+#
+#-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+#
 # Disallow non-local logins to privileged accounts (group wheel).
 #
 #-:wheel:ALL EXCEPT LOCAL .win.tue.nl
@@ -87,7 +95,7 @@
 # Uses string matching also.
 #+ : root : .foo.bar.org
 #
-# User "root" should be denied to get access from all other sources. 
+# User "root" should be denied to get access from all other sources.
 #- : root : ALL
 #
 # User "foo" and members of netgroup "nis_group" should be
 #+ : john : 2001:4ca0:0:101::/64
 #
 # All other users should be denied to get access from all sources.
-#- : ALL : ALL 
+#- : ALL : ALL
index 43cc4fce53200369fbfc22eff00b9aa7f75d6948..fcd33bb4e7697bba662ea1d7c993a4238fb0928d 100644 (file)
@@ -1,11 +1,11 @@
 .\"     Title: access.conf
 .\"    Author: 
-.\" Generator: DocBook XSL Stylesheets v1.70.1 <http://docbook.sf.net/>
-.\"      Date: 06/21/2006
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\"      Date: 06/22/2007
 .\"    Manual: Linux\-PAM Manual
 .\"    Source: Linux\-PAM Manual
 .\"
-.TH "ACCESS.CONF" "5" "06/21/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.TH "ACCESS.CONF" "5" "06/22/2007" "Linux\-PAM Manual" "Linux\-PAM Manual"
 .\" disable hyphenation
 .nh
 .\" disable justification (adjust text to left margin only)
@@ -16,32 +16,33 @@ access.conf \- the login access control table file
 .PP
 The
 \fI/etc/security/access.conf\fR
-file specifies (\fIuser\fR,
-\fIhost\fR), (\fIuser\fR,
-\fInetwork/netmask\fR) or (\fIuser\fR,
+file specifies (\fIuser/group\fR,
+\fIhost\fR), (\fIuser/group\fR,
+\fInetwork/netmask\fR) or (\fIuser/group\fR,
 \fItty\fR) combinations for which a login will be either accepted or refused.
 .PP
 When someone logs in, the file
 \fIaccess.conf\fR
-is scanned for the first entry that matches the (\fIuser\fR,
-\fIhost\fR) or (\fIuser\fR,
-\fInetwork/netmask\fR) combination, or, in case of non\-networked logins, the first entry that matches the (\fIuser\fR,
+is scanned for the first entry that matches the (\fIuser/group\fR,
+\fIhost\fR) or (\fIuser/group\fR,
+\fInetwork/netmask\fR) combination, or, in case of non\-networked logins, the first entry that matches the (\fIuser/group\fR,
 \fItty\fR) combination. The permissions field of that table entry determines whether the login will be accepted or refused.
 .PP
 Each line of the login access control table has three fields separated by a ":" character (colon):
 .PP
 
-\fIpermission\fR:\fIusers\fR:\fIorigins\fR
+\fIpermission\fR:\fIusers/groups\fR:\fIorigins\fR
 .PP
 The first field, the
 \fIpermission\fR
 field, can be either a "\fI+\fR" character (plus) for access granted or a "\fI\-\fR" character (minus) for access denied.
 .PP
 The second field, the
-\fIusers\fR
+\fIusers\fR/\fIgroup\fR
 field, should be a list of one or more login names, group names, or
 \fIALL\fR
-(which always matches).
+(which always matches). To differentiate user entries from group entries, group entries should be written with brackets, e.g.
+\fI(group)\fR.
 .PP
 The third field, the
 \fIorigins\fR
@@ -54,10 +55,12 @@ field, should be a list of one or more tty names (for non\-networked logins), ho
 in host or user patterns.
 .PP
 The
-\fIexcept\fR
+\fIEXCEPT\fR
 operator makes it possible to write very compact rules.
 .PP
-The group file is searched only when a name does not match that of the logged\-in user. Only groups are matched in which users are explicitly listed. However the PAM module does not look at the primary group id of a user.
+If the
+\fBnodefgroup\fR
+is not set, the group file is searched when a name does not match that of the logged\-in user. Only groups are matched in which users are explicitly listed. However the PAM module does not look at the primary group id of a user.
 .PP
 The "\fI#\fR" character at start of line (no space at front) can be used to mark this line as a comment line.
 .SH "EXAMPLES"
@@ -143,6 +146,10 @@ should get access from IPv6 net/mask.
 .PP
 + : john : 2001:4ca0:0:101::/64
 .PP
+Disallow console logins to all but the shutdown, sync and all other accounts, which are a member of the wheel group.
+.PP
+\-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+.PP
 All other users should be denied to get access from all sources.
 .PP
 \- : ALL : ALL
index 492f995d8512c2dd544332b839535377540af72c..f8eb7a4e09a3e019aa4920c5e45617720a16bf74 100644 (file)
     <title>DESCRIPTION</title>
     <para>
       The <filename>/etc/security/access.conf</filename> file specifies
-      (<replaceable>user</replaceable>, <replaceable>host</replaceable>),
-      (<replaceable>user</replaceable>, <replaceable>network/netmask</replaceable>) or
-      (<replaceable>user</replaceable>, <replaceable>tty</replaceable>)
+      (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>),
+      (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>) or
+      (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
       combinations for which a login will be either accepted or refused.
     </para>
     <para>
       When someone logs in, the file <filename>access.conf</filename> is
       scanned for the first entry that matches the
-      (<replaceable>user</replaceable>, <replaceable>host</replaceable>) or
-      (<replaceable>user</replaceable>, <replaceable>network/netmask</replaceable>)
+      (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>) or
+      (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>)
       combination, or, in case of non-networked logins, the first entry
       that matches the
-      (<replaceable>user</replaceable>, <replaceable>tty</replaceable>)
+      (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
       combination.  The permissions field of that table entry determines
       whether the login will be accepted or refused.
    </para>
@@ -43,7 +43,7 @@
     </para>
 
     <para>
-      <replaceable>permission</replaceable>:<replaceable>users</replaceable>:<replaceable>origins</replaceable>
+      <replaceable>permission</replaceable>:<replaceable>users/groups</replaceable>:<replaceable>origins</replaceable>
     </para>
 
 
     </para>
 
     <para>
-      The second field, the <replaceable>users</replaceable>
+      The second field, the
+      <replaceable>users</replaceable>/<replaceable>group</replaceable>
       field, should be a list of one or more login names, group names, or
-      <emphasis>ALL</emphasis> (which always matches).
+      <emphasis>ALL</emphasis> (which always matches). To differentiate
+      user entries from group entries, group entries should be written
+      with brackets, e.g. <emphasis>(group)</emphasis>.
     </para>
 
     <para>
     </para>
 
     <para>
-      The <replaceable>except</replaceable> operator makes it possible to
+      The <replaceable>EXCEPT</replaceable> operator makes it possible to
       write very compact rules.
     </para>
 
     <para>
-       The group file is searched only when a name does not match that of
-       the logged-in user. Only groups are matched in which users are
-       explicitly listed. However the PAM module does not look at the
-       primary group id of a user.
+       If the <option>nodefgroup</option> is not set, the group file
+       is searched when a name does not match that of the logged-in
+       user. Only groups are matched in which users are explicitly listed.
+       However the PAM module does not look at the primary group id of a user.
     </para>
 
 
     </para>
     <para>+ : john : 2001:4ca0:0:101::/64</para>
 
+    <para>
+      Disallow console logins to all but the shutdown, sync and all
+      other accounts, which are a member of the wheel group.
+    </para>
+    <para>-:ALL EXCEPT (wheel) shutdown sync:LOCAL</para>
+
     <para>
       All other users should be denied to get access from all sources.
     </para>
index b613e323745e7b0aeb66a3a2143497cb97af63f8..ca8cc5b0b1f7a8d234c38858f0a8992326561a8a 100644 (file)
@@ -1,11 +1,11 @@
 .\"     Title: pam_access
 .\"    Author: 
-.\" Generator: DocBook XSL Stylesheets vsnapshot_2006\-08\-24_0226 <http://docbook.sf.net/>
-.\"      Date: 08/31/2006
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\"      Date: 06/22/2007
 .\"    Manual: Linux\-PAM Manual
 .\"    Source: Linux\-PAM Manual
 .\"
-.TH "PAM_ACCESS" "8" "08/31/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.TH "PAM_ACCESS" "8" "06/22/2007" "Linux\-PAM Manual" "Linux\-PAM Manual"
 .\" disable hyphenation
 .nh
 .\" disable justification (adjust text to left margin only)
@@ -14,7 +14,7 @@
 pam_access \- PAM module for logdaemon style login access control
 .SH "SYNOPSIS"
 .HP 14
-\fBpam_access.so\fR [debug] [accessfile=\fIfile\fR] [fieldsep=\fIsep\fR] [listsep=\fIsep\fR]
+\fBpam_access.so\fR [debug] [nodefgroup] [accessfile=\fIfile\fR] [fieldsep=\fIsep\fR] [listsep=\fIsep\fR]
 .SH "DESCRIPTION"
 .PP
 The pam_access PAM module is mainly for access management. It provides logdaemon style login access control based on login names, host or domain names, internet addresses or network numbers, or on terminal line names in case of non\-networked logins.
@@ -23,52 +23,77 @@ By default rules for access management are taken from config file
 \fI/etc/security/access.conf\fR
 if you don't specify another file.
 .SH "OPTIONS"
-.TP 3n
+.PP
 \fBaccessfile=\fR\fB\fI/path/to/access.conf\fR\fR
+.RS 4
 Indicate an alternative
 \fIaccess.conf\fR
 style configuration file to override the default. This can be useful when different services need different access lists.
-.TP 3n
+.RE
+.PP
 \fBdebug\fR
+.RS 4
 A lot of debug informations are printed with
 \fBsyslog\fR(3).
-.TP 3n
+.RE
+.PP
 \fBfieldsep=\fR\fB\fIseparators\fR\fR
+.RS 4
 This option modifies the field separator character that pam_access will recognize when parsing the access configuration file. For example:
 \fBfieldsep=|\fR
 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 conjuction with a system that wants to use pam_access with X based applications, since the
 \fBPAM_TTY\fR
 item is likely to be of the form "hostname:0" which includes a `:' character in its value. But you should not need this.
-.TP 3n
+.RE
+.PP
 \fBlistsep=\fR\fB\fIseparators\fR\fR
+.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 ` ' (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 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
+.RS 4
+The group database will not be used for tokens not identified as account name.
+.RE
 .SH "MODULE SERVICES PROVIDED"
 .PP
 All services are supported.
 .SH "RETURN VALUES"
-.TP 3n
+.PP
 PAM_SUCCESS
+.RS 4
 Access was granted.
-.TP 3n
+.RE
+.PP
 PAM_PERM_DENIED
+.RS 4
 Access was not granted.
-.TP 3n
+.RE
+.PP
 PAM_IGNORE
+.RS 4
 
 \fBpam_setcred\fR
 was called which does nothing.
-.TP 3n
+.RE
+.PP
 PAM_ABORT
+.RS 4
 Not all relevant data or options could be gotten.
-.TP 3n
+.RE
+.PP
 PAM_USER_UNKNOWN
+.RS 4
 The user is not known to the system.
+.RE
 .SH "FILES"
-.TP 3n
+.PP
 \fI/etc/security/access.conf\fR
+.RS 4
 Default configuration file
+.RE
 .SH "SEE ALSO"
 .PP
 
index 74e399930a36e57db0504cbfc4bb7aba5aa18f56..1d814e880f3cc15ad058766561f2a89d3fa9293e 100644 (file)
@@ -25,6 +25,9 @@
       <arg choice="opt">
         debug
       </arg>
+      <arg choice="opt">
+        nodefgroup
+      </arg>
       <arg choice="opt">
         accessfile=<replaceable>file</replaceable>
       </arg>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>
+          <option>nodefgroup</option>
+        </term>
+        <listitem>
+          <para>
+            The group database will not be used for tokens not
+            identified as account name.
+          </para>
+        </listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 34ee56bd5d7b1a11365f01300281dc2c49ad233a..82fdfcc77ec1c45575f6b23d4887d81304dd0096 100644 (file)
@@ -89,6 +89,9 @@ static const char *sep = ", \t";              /* list-element separator */
 #define YES             1
 #define NO              0
 
+/* Only allow group entries of the form "(xyz)" */
+static int only_new_group_syntax = NO;
+
  /*
   * A structure to bundle up all login-related information to keep the
   * functional interfaces as generic as possible.
@@ -136,6 +139,8 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo,
 
        } else if (strcmp (argv[i], "debug") == 0) {
            pam_access_debug = YES;
+       } else if (strcmp (argv[i], "nodefgroup") == 0) {
+           only_new_group_syntax = YES;
        } else {
            pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]);
        }
@@ -151,6 +156,7 @@ typedef int match_func (pam_handle_t *, char *, struct login_info *);
 static int list_match (pam_handle_t *, char *, struct login_info *,
                       match_func *);
 static int user_match (pam_handle_t *, char *, struct login_info *);
+static int group_match (pam_handle_t *, const char *, const char *);
 static int from_match (pam_handle_t *, char *, struct login_info *);
 static int string_match (pam_handle_t *, const char *, const char *);
 static int network_netmask_match (pam_handle_t *, const char *, const char *);
@@ -442,7 +448,7 @@ static char * myhostname(void)
 /* netgroup_match - match group against machine or user */
 
 static int
-netgroup_match (pam_handle_t *pamh, const char *group,
+netgroup_match (pam_handle_t *pamh, const char *netgroup,
                const char *machine, const char *user)
 {
   char *mydomain = NULL;
@@ -451,11 +457,12 @@ netgroup_match (pam_handle_t *pamh, const char *group,
   yp_get_default_domain(&mydomain);
 
 
-  retval = innetgr (group, machine, user, mydomain);
+  retval = innetgr (netgroup, machine, user, mydomain);
   if (pam_access_debug == YES)
     pam_syslog (pamh, LOG_DEBUG,
-               "netgroup_match: %d (group=%s, machine=%s, user=%s, domain=%s)",
-               retval, group ? group : "NULL",  machine ? machine : "NULL",
+               "netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)",
+               retval, netgroup ? netgroup : "NULL",
+               machine ? machine : "NULL",
                user ? user : "NULL", mydomain ? mydomain : "NULL");
   return retval;
 
@@ -490,15 +497,45 @@ user_match (pam_handle_t *pamh, char *tok, struct login_info *item)
                from_match (pamh, at + 1, &fake_item));
     } else if (tok[0] == '@') /* netgroup */
       return (netgroup_match (pamh, tok + 1, (char *) 0, string));
+    else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
+      return (group_match (pamh, tok, string));
     else if (string_match (pamh, tok, string)) /* ALL or exact match */
-       return YES;
-    else if (pam_modutil_user_in_group_nam_nam (pamh, item->user->pw_name, tok))
+      return YES;
+    else if (only_new_group_syntax == NO &&
+            pam_modutil_user_in_group_nam_nam (pamh,
+                                               item->user->pw_name, tok))
       /* try group membership */
       return YES;
 
     return NO;
 }
 
+
+/* group_match - match a username against token named group */
+
+static int
+group_match (pam_handle_t *pamh, const char *tok, const char* usr)
+{
+    char grptok[BUFSIZ];
+
+    if (pam_access_debug)
+        pam_syslog (pamh, LOG_DEBUG,
+                   "group_match: grp=%s, user=%s", grptok, usr);
+
+    if (strlen(tok) < 3)
+        return NO;
+
+    /* token is recieved 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))
+        return YES;
+
+  return NO;
+}
+
+
 /* from_match - match a host or tty against a list of tokens */
 
 static int