+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
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/
+ : 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
# 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
# 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
.\" 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)
.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
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"
.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
<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>
</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>
.\" 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)
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.
\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
<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>
#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.
} 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]);
}
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 *);
/* 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;
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;
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