From: Mark Wooding Date: Sun, 21 Oct 2012 14:05:20 +0000 (+0100) Subject: policy.h, yaid.h: Allow policy rules to match on the user. X-Git-Tag: 1.0.0~7 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/yaid/commitdiff_plain/c039c9363c583e347cd269f6c741d302d416d1a6?hp=c74afd8acf88d097561546c9cc5a88b1522cb341 policy.h, yaid.h: Allow policy rules to match on the user. So we have a user pattern, and all the associated bits and pieces. This breaks old policy files, but nobody has deployed yet. --- diff --git a/policy.c b/policy.c index 630e1dc..32a4550 100644 --- a/policy.c +++ b/policy.c @@ -80,6 +80,12 @@ static void print_portpat(const struct portpat *pp) static void print_sockpat(const struct addrops *ao, const struct sockpat *sp) { print_addrpat(ao, &sp->addr); putchar(' '); print_portpat(&sp->port); } +static void print_userpat(const struct userpat *up) +{ + if (up->lo == up->hi) printf("%d", up->lo); + else printf("%u-%u", up->lo, up->hi); +} + static const char *const acttab[] = { #define DEFACT(tag, name) name, ACTIONS(DEFACT) @@ -109,6 +115,7 @@ void print_policy(const struct policy *p) { print_sockpat(p->ao, &p->sp[L]); putchar(' '); print_sockpat(p->ao, &p->sp[R]); putchar(' '); + print_userpat(&p->up); putchar(' '); print_action(&p->act); putchar('\n'); } @@ -126,12 +133,17 @@ static int match_sockpat(const struct addrops *ao, match_portpat(&sp->port, s->port)); } +/* Return true if the uid matches the pattern. */ +static int match_userpat(const struct userpat *up, uid_t u) + { unsigned uu = u; return (up->lo <= uu && uu <= up->hi); } + /* Return true if the query matches the patterns in the policy rule. */ int match_policy(const struct policy *p, const struct query *q) { return ((!p->ao || p->ao == q->ao) && match_sockpat(q->ao, &p->sp[L], &q->s[L]) && - match_sockpat(q->ao, &p->sp[R], &q->s[R])); + match_sockpat(q->ao, &p->sp[R], &q->s[R]) && + match_userpat(&p->up, q->u.uid)); } /*----- Parsing -----------------------------------------------------------*/ @@ -385,6 +397,27 @@ static int parse_sockpat(FILE *fp, const struct addrops **aop, return (T_OK); } +/* Parse a user pattern, writing it to UP. */ +static int parse_userpat(FILE *fp, struct userpat *up) +{ + struct passwd *pw; + char buf[32]; + int t; + char *delim; + + if ((t = scan(fp, buf, sizeof(buf))) != 0) return (t); + if (!strcmp(buf, "*")) { up->lo = 0; up->hi = UINT_MAX; } + else if ((pw = getpwnam(buf)) != 0) up->lo = up->hi = pw->pw_uid; + else { + if ((delim = strchr(buf, '-')) != 0) *delim++ = 0; + up->lo = strtoul(buf, 0, 0); + if (!delim) up->hi = up->lo; + else if (!*delim) up->hi = UINT_MAX; + else up->hi = strtoul(delim, 0, 0); + } + return (0); +} + /* Parse a policy rule line, writing it to P. */ static int parse_policy(FILE *fp, struct policy *p) { @@ -395,6 +428,7 @@ static int parse_policy(FILE *fp, struct policy *p) if ((t = parse_sockpat(fp, &p->ao, &p->sp[L])) != 0) goto fail; if ((t = parse_sockpat(fp, &p->ao, &p->sp[R])) != 0) goto err; + if ((t = parse_userpat(fp, &p->up)) != 0) goto err; if ((t = parse_action(fp, &p->act)) != 0) goto err; return (0); diff --git a/yaid.h b/yaid.h index 126c201..387f76e 100644 --- a/yaid.h +++ b/yaid.h @@ -282,12 +282,18 @@ struct action { } u; }; +/* A user pattern matches a user if the uid is within the given bounds. */ +struct userpat { + unsigned lo, hi; +}; + /* A policy rule: if the query matches the pattern, then perform the * action. */ struct policy { const struct addrops *ao; struct sockpat sp[NDIR]; + struct userpat up; struct action act; }; #define POLICY_INIT(a) { .act.act = a }