Date: Sun, 20 Nov 2005 21:43:53 +0100 (CET) From: Oliver Fromme <olli@secnetix.de> To: FreeBSD-gnats-submit@FreeBSD.org Cc: Oliver Fromme <olli@secnetix.de> Subject: bin/89327: [PATCH] Add pattern matching to login.access(5) Message-ID: <200511202043.jAKKhrx7079623@lurza.secnetix.de> Resent-Message-ID: <200511202050.jAKKoPhc059425@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 89327 >Category: bin >Synopsis: [PATCH] Add pattern matching to login.access(5) >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Nov 20 20:50:25 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Oliver Fromme >Release: FreeBSD 6.0-STABLE i386 >Organization: secnetix GmbH & Co. KG, Munich, Germany http://www.secnetix.de/bsd >Environment: System: FreeBSD epia.fromme.com 6.0-STABLE FreeBSD 6.0-STABLE #0: Fri Nov 4 21:35:33 CET 2005 olli@epia.fromme.com:/usr/src/sys/i386/compile/EPIA i386 >Description: The file login.access(5) can be used to restrict access for users coming from certain remote hosts, or on certain local terminals. For example, we have some users who are allowed to log in from virtual terminals only. However, it is tedious and error-prone to list all of the terminal devices in the file. The entry has to look like this: +:foo bar:ttyv0 ttyv1 ttyv2 ttyv3 ttyv4 ttyv5 ttyv6 ttyv7 +:foo bar:ttyv8 ttyv9 ttyva ttyvb ttyvc ttyvd ttyve ttyvf Th patch presented in this PR allows to use patterns like those used by the bourne shell (using wildcards "*", "?" and "["). The above entry is now much easier: +:foo bar:ttyv? Similarly, "ttyd?" can be used to restrict all of the serial dial-in lines. The patch is quite simple. Basically I just replaced the strcasecmp(3) function with fnmatch(3). Normally, the special wildcard characters ("*", "?", "[") don't appear in terminal device names, and they're also forbidden in host names, so there shouldn't be any regression cases. The login.access(5) file is used at three different places in the FreeBSD source tree: in src/usr.bin/login, in src/lib/libpam/modules/pam_login_access, and in src/cryp- to/heimdal/appl/login. The latter is third-party software, so I'm not sure if it's appropriate to patch it in the FreeBSD source tree. However, for consistency, I patched it in the same way and include the patch below for your consideration. The patch set also includes updates to the manual pages which describe the feature, and also a clarification that all matches are performed in a case-insensitive way. (The latter is even true without my patch, but that behaviour was undocumented.) >How-To-Repeat: n/a >Fix: --- src/usr.bin/login/login_access.c.orig Fri Mar 22 02:22:49 2002 +++ src/usr.bin/login/login_access.c Sun Nov 20 21:16:13 2005 @@ -20,6 +20,7 @@ #include <sys/types.h> #include <ctype.h> #include <errno.h> +#include <fnmatch.h> #include <grp.h> #include <stdio.h> #include <stdlib.h> @@ -175,7 +176,7 @@ return (YES); } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */ for (i = 0; group->gr_mem[i]; i++) - if (strcasecmp(string, group->gr_mem[i]) == 0) + if (fnmatch(string, group->gr_mem[i], FNM_CASEFOLD) == 0) return (YES); } return (NO); @@ -205,7 +206,7 @@ return (YES); } else if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(string)) > (tok_len = strlen(tok)) - && strcasecmp(tok, string + str_len - tok_len) == 0) + && fnmatch(tok, string + str_len - tok_len, FNM_CASEFOLD) == 0) return (YES); } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ if (strchr(string, '.') == 0) @@ -231,7 +232,7 @@ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ return (YES); - } else if (strcasecmp(tok, string) == 0) { /* try exact match */ + } else if (fnmatch(tok, string, FNM_CASEFOLD) == 0) { /* try exact match */ return (YES); } return (NO); --- src/usr.bin/login/login.access.5.orig Sat Jul 3 00:22:27 2004 +++ src/usr.bin/login/login.access.5 Sun Nov 20 21:21:17 2005 @@ -45,6 +45,15 @@ logged-in user. Only groups are matched in which users are explicitly listed: the program does not look at a user's primary group id value. +.Pp +In names of users, groups, ttys, hosts and domains, +the special wildcard characters "*", "?" and "[" can be used, +matching patterns according to the rules used by the shell. +This is most useful for tty names: +The pattern "ttyv?" in the third field matches all virtual +terminals, and "ttyd?" matches all serial dial-in lines. +.Pp +All matches are case-insensitive. .Sh FILES .Bl -tag -width /etc/login.access -compact .It Pa /etc/login.access --- src/lib/libpam/modules/pam_login_access/login_access.c.orig Fri Mar 5 09:10:18 2004 +++ src/lib/libpam/modules/pam_login_access/login_access.c Sun Nov 20 21:17:41 2005 @@ -19,6 +19,7 @@ #include <sys/types.h> #include <ctype.h> #include <errno.h> +#include <fnmatch.h> #include <grp.h> #include <stdio.h> #include <stdlib.h> @@ -170,7 +171,7 @@ return (YES); } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */ for (i = 0; group->gr_mem[i]; i++) - if (strcasecmp(string, group->gr_mem[i]) == 0) + if (fnmatch(string, group->gr_mem[i], FNM_CASEFOLD) == 0) return (YES); } return (NO); @@ -199,7 +200,7 @@ return (YES); } else if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(string)) > (tok_len = strlen(tok)) - && strcasecmp(tok, string + str_len - tok_len) == 0) + && fnmatch(tok, string + str_len - tok_len, FNM_CASEFOLD) == 0) return (YES); } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ if (strchr(string, '.') == 0) @@ -224,7 +225,7 @@ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ return (YES); - } else if (strcasecmp(tok, string) == 0) { /* try exact match */ + } else if (fnmatch(tok, string, FNM_CASEFOLD) == 0) { /* try exact match */ return (YES); } return (NO); --- src/lib/libpam/modules/pam_login_access/login.access.5.orig Sat Jul 3 01:52:17 2004 +++ src/lib/libpam/modules/pam_login_access/login.access.5 Sun Nov 20 21:21:18 2005 @@ -46,6 +46,15 @@ logged-in user. Only groups are matched in which users are explicitly listed: the program does not look at a user's primary group id value. +.Pp +In names of users, groups, ttys, hosts and domains, +the special wildcard characters "*", "?" and "[" can be used, +matching patterns according to the rules used by the shell. +This is most useful for tty names: +The pattern "ttyv?" in the third field matches all virtual +terminals, and "ttyd?" matches all serial dial-in lines. +.Pp +All matches are case-insensitive. .Sh FILES .Bl -tag -width /etc/login.access -compact .It Pa /etc/login.access --- src/crypto/heimdal/appl/login/login_access.c.orig Tue Feb 19 16:46:04 2002 +++ src/crypto/heimdal/appl/login/login_access.c Sun Nov 20 21:17:39 2005 @@ -24,6 +24,7 @@ */ #include "login_locl.h" +#include <fnmatch.h> RCSID("$Id: login_access.c,v 1.2 2001/06/04 14:09:45 assar Exp $"); @@ -217,7 +218,7 @@ if (item->user->pw_gid == group->gr_gid) return (YES); for (i = 0; group->gr_mem[i]; i++) - if (strcasecmp(string, group->gr_mem[i]) == 0) + if (fnmatch(string, group->gr_mem[i], FNM_CASEFOLD) == 0) return (YES); } return (NO); @@ -246,7 +247,7 @@ return (YES); } else if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(string)) > (tok_len = strlen(tok)) - && strcasecmp(tok, string + str_len - tok_len) == 0) + && fnmatch(tok, string + str_len - tok_len, FNM_CASEFOLD) == 0) return (YES); } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ if (strchr(string, '.') == 0) @@ -270,7 +271,7 @@ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ return (YES); - } else if (strcasecmp(tok, string) == 0) { /* try exact match */ + } else if (fnmatch(tok, string, FNM_CASEFOLD) == 0) { /* try exact match */ return (YES); } return (NO); --- src/crypto/heimdal/appl/login/login.access.5.orig Thu Oct 9 21:36:19 2003 +++ src/crypto/heimdal/appl/login/login.access.5 Sun Nov 20 21:21:15 2005 @@ -44,6 +44,15 @@ .Pp If the string EXCEPT is found in either the user or from list, the rest of the list are exceptions to the list before EXCEPT. +.Pp +In names of users, groups, ttys, hosts and domains, +the special wildcard characters "*", "?" and "[" can be used, +matching patterns according to the rules used by the shell. +This is most useful for tty names: +The pattern "ttyv?" in the third field matches all virtual +terminals, and "ttyd?" matches all serial dial-in lines. +.Pp +All matches are case-insensitive. .Sh BUGS If there's a user and a group with the same name, there is no way to make the group match if the user also matches. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511202043.jAKKhrx7079623>