diff options
-rw-r--r-- | bin/systrace/policy.c | 95 | ||||
-rw-r--r-- | bin/systrace/systrace.1 | 31 | ||||
-rw-r--r-- | bin/systrace/systrace.c | 6 |
3 files changed, 125 insertions, 7 deletions
diff --git a/bin/systrace/policy.c b/bin/systrace/policy.c index c75fb4d6c4d..187be64a906 100644 --- a/bin/systrace/policy.c +++ b/bin/systrace/policy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: policy.c,v 1.5 2002/06/04 23:05:26 provos Exp $ */ +/* $OpenBSD: policy.c,v 1.6 2002/06/05 20:52:47 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -37,6 +37,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <grp.h> #include <stdio.h> #include <fcntl.h> #include <ctype.h> @@ -87,7 +88,9 @@ SPLAY_GENERATE(polnrtree, policy, nrnode, polnrcompare); extern int userpolicy; -char policydir[MAXPATHLEN]; +static char policydir[MAXPATHLEN]; +static char *groupnames[NGROUPS_MAX]; +static int ngroups; void systrace_setupdir(void) @@ -116,9 +119,25 @@ systrace_setupdir(void) int systrace_initpolicy(char *file) { + gid_t groups[NGROUPS_MAX]; + int i; + SPLAY_INIT(&policyroot); SPLAY_INIT(&polnrroot); + /* Find out group names for current user */ + if ((ngroups = getgroups(NGROUPS_MAX, groups)) == -1) + err(1, "getgroups"); + + for (i = 0; i < ngroups; i++) { + struct group *gr; + + if ((gr = getgrgid(groups[i])) == NULL) + err(1, "getgrgid(%d)", groups[i]); + if ((groupnames[i] = strdup(gr->gr_name)) == NULL) + err(1, "strdup(%s)", gr->gr_name); + } + if (userpolicy) systrace_setupdir(); @@ -283,6 +302,59 @@ systrace_addpolicy(char *name) } int +systrace_predicatematch(char *p) +{ + extern char *username; + int i, res, neg; + + res = 0; + neg = 0; + + if (!strncasecmp(p, "user", 4)) { + /* Match against user name */ + p += 4; + p += strspn(p, " \t"); + if (!strncmp(p, "=", 1)) { + p += 1; + neg = 0; + } else if (!strncmp(p, "!=", 2)) { + p += 2; + neg = 1; + } else + return (-1); + p += strspn(p, " \t"); + + res = (!strcmp(p, username)); + } else if (!strncasecmp(p, "group", 5)) { + /* Match against group list */ + p += 5; + p += strspn(p, " \t"); + if (!strncmp(p, "=", 1)) { + p += 1; + neg = 0; + } else if (!strncmp(p, "!=", 2)) { + p += 2; + neg = 1; + } else + return (-1); + p += strspn(p, " \t"); + + for (i = 0; i < ngroups; i++) { + if (!strcmp(p, groupnames[i])) { + res = 1; + break; + } + } + } else + return (-1); + + if (neg) + res = !res; + + return (res); +} + +int systrace_readpolicy(char *filename) { FILE *fp; @@ -338,6 +410,25 @@ systrace_readpolicy(char *filename) policy->flags |= POLICY_DETACHED; policy = NULL; continue; + } else if (!strncasecmp(p, "if", 2)) { + int match; + char *predicate; + + /* Process predicates */ + p += 2; + p += strspn(p, " \t"); + predicate = strsep(&p, ","); + if (p == NULL) + goto error; + + match = systrace_predicatematch(predicate); + if (match == -1) + goto error; + /* If the predicate does not match skip rule */ + if (!match) + continue; + + p += strspn(p, " \t"); } emulation = strsep(&p, "-"); diff --git a/bin/systrace/systrace.1 b/bin/systrace/systrace.1 index 379e29dfaae..2148effc982 100644 --- a/bin/systrace/systrace.1 +++ b/bin/systrace/systrace.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: systrace.1,v 1.10 2002/06/05 18:58:07 provos Exp $ +.\" $OpenBSD: systrace.1,v 1.11 2002/06/05 20:52:47 provos Exp $ .\" .\" Copyright 2002 Niels Provos <provos@citi.umich.edu> .\" All rights reserved. @@ -79,7 +79,7 @@ knows about. .Pp .Sh POLICY The policy is specified via the following grammar: -.Bd -literal +.Bd -literal -offset AAA filter = expression "then" action errorcode expression = symbol | "not" expression | "(" expression ")" | expression "and" expression | expression "or" expression @@ -95,7 +95,32 @@ errorcode = /* empty */ | "[" string "]" The .Va cmd-string is an arbitrary string enclosed with quotation marks. - +.Pp +Policy entries can be prefixed with a predicate. +Predicates have the following format: +.Bd -literal -offset AAA +"if" {"user", "group"} {"=", "!="} string "," +.Ed +.Pp +A rule is added to the configured policy only if its predicate +evaluates to true. +.Sh EXAMPLES +An excerpt from a sample +.Xr ls 1 +policy might look as follows: +.Bd -literal -offset AAA +Policy: /bin/ls, Emulation: native +[...] + native-open: filename eq "$HOME" and oflags sub "ro" then permit + native-fchdir: permit +[...] + native-open: filename eq "/tmp" and oflags sub "ro" then permit + native-stat: permit + native-open: filename match "$HOME/*" and oflags sub "ro" then permit + native-open: filename eq "/etc/pwd.db" and oflags sub "ro" then permit +[...] + if group != wheel, native-open: filename eq "/etc" then deny[eperm] +.Ed .Sh FILES .Bl -tag -width xHOME/xsystrace -compact .It Pa /dev/systrace diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c index a266ada97e8..1528d336005 100644 --- a/bin/systrace/systrace.c +++ b/bin/systrace/systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.c,v 1.12 2002/06/05 20:01:22 provos Exp $ */ +/* $OpenBSD: systrace.c,v 1.13 2002/06/05 20:52:47 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -398,7 +398,6 @@ main(int argc, char **argv) switch (c) { case 'a': automatic = 1; - username = uid_to_name(getuid()); break; case 'A': allow = 1; @@ -429,6 +428,9 @@ main(int argc, char **argv) if (argc == 0) usage(); + /* Username for automatic mode, and policy predicates */ + username = uid_to_name(getuid()); + /* Determine current working directory for filtering */ if (getcwd(cwd, sizeof(cwd)) == NULL) err(1, "getcwd"); |