summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2008-07-04 03:45:00 +0000
committerDamien Miller <djm@cvs.openbsd.org>2008-07-04 03:45:00 +0000
commitc10ef3f8103182ee37068815a7c18848c10b4e6c (patch)
treec7e61875eb6420d9dfe26970b39af08dba7ecf36
parent4a3279308d365a0c004fecee6d7375c53e8b66ba (diff)
support negation of groups in "Match group" block (bz#1315); ok dtucker@
-rw-r--r--usr.bin/ssh/groupaccess.c27
-rw-r--r--usr.bin/ssh/groupaccess.h3
-rw-r--r--usr.bin/ssh/servconf.c29
3 files changed, 34 insertions, 25 deletions
diff --git a/usr.bin/ssh/groupaccess.c b/usr.bin/ssh/groupaccess.c
index 976cdb01f52..a2cdb04c676 100644
--- a/usr.bin/ssh/groupaccess.c
+++ b/usr.bin/ssh/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.
*
@@ -29,6 +29,7 @@
#include <grp.h>
#include <unistd.h>
#include <stdarg.h>
+#include <string.h>
#include "xmalloc.h"
#include "groupaccess.h"
@@ -78,6 +79,30 @@ ga_match(char * const *groups, int n)
}
/*
+ * 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.
*/
void
diff --git a/usr.bin/ssh/groupaccess.h b/usr.bin/ssh/groupaccess.h
index 04b44989401..000578e7646 100644
--- a/usr.bin/ssh/groupaccess.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 42c09e3c314..f524c03876f 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/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 <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -488,24 +488,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;
@@ -515,17 +499,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;
}