diff --git a/ChangeLog b/ChangeLog index dad3f2a32..56ee5d46e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,9 @@ - otto@cvs.openbsd.org 2008/07/03 21:46:58 [auth2-pubkey.c] avoid nasty double free; ok dtucker@ djm@ + - djm@cvs.openbsd.org 2008/07/04 03:44:59 + [servconf.c groupaccess.h groupaccess.c] + support negation of groups in "Match group" block (bz#1315); ok dtucker@ 20080702 - (dtucker) OpenBSD CVS Sync @@ -4547,4 +4550,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.5051 2008/07/04 02:54:25 dtucker Exp $ +$Id: ChangeLog,v 1.5052 2008/07/04 03:51:12 dtucker Exp $ diff --git a/groupaccess.c b/groupaccess.c index e73f62b22..2381aeb15 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.13 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * @@ -31,6 +31,7 @@ #include #include #include +#include #include "xmalloc.h" #include "groupaccess.h" @@ -87,6 +88,30 @@ ga_match(char * const *groups, int n) return 0; } +/* + * Return 1 if one of user's groups matches group_pattern list. + * Return 0 on negated or no match. + */ +int +ga_match_pattern_list(const char *group_pattern) +{ + int i, found = 0; + size_t len = strlen(group_pattern); + + for (i = 0; i < ngroups; i++) { + switch (match_pattern_list(groups_byname[i], + group_pattern, len, 0)) { + case -1: + return 0; /* Negated match wins */ + case 0: + continue; + case 1: + found = 1; + } + } + return found; +} + /* * Free memory allocated for group access list. */ diff --git a/groupaccess.h b/groupaccess.h index 04b449894..000578e76 100644 --- a/groupaccess.h +++ b/groupaccess.h @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.h,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: groupaccess.h,v 1.8 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. @@ -29,6 +29,7 @@ int ga_init(const char *, gid_t); int ga_match(char * const *, int); +int ga_match_pattern_list(const char *); void ga_free(void); #endif diff --git a/servconf.c b/servconf.c index 9d9c9508e..66e22979f 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.185 2008/07/02 02:24:18 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -525,24 +525,8 @@ static int match_cfg_line_group(const char *grps, int line, const char *user) { int result = 0; - u_int ngrps = 0; - char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS]; struct passwd *pw; - /* - * Even if we do not have a user yet, we still need to check for - * valid syntax. - */ - arg = cp = xstrdup(grps); - while ((p = strsep(&cp, ",")) != NULL && *p != '\0') { - if (ngrps >= MAX_MATCH_GROUPS) { - error("line %d: too many groups in Match Group", line); - result = -1; - goto out; - } - grplist[ngrps++] = p; - } - if (user == NULL) goto out; @@ -552,17 +536,16 @@ match_cfg_line_group(const char *grps, int line, const char *user) } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { debug("Can't Match group because user %.100s not in any group " "at line %d", user, line); - } else if (ga_match(grplist, ngrps) != 1) { - debug("user %.100s does not match group %.100s at line %d", - user, arg, line); + } else if (ga_match_pattern_list(grps) != 1) { + debug("user %.100s does not match group list %.100s at line %d", + user, grps, line); } else { - debug("user %.100s matched group %.100s at line %d", user, - arg, line); + debug("user %.100s matched group list %.100s at line %d", user, + grps, line); result = 1; } out: ga_free(); - xfree(arg); return result; }