From owner-p4-projects@FreeBSD.ORG Sun Jul 3 23:13:31 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 637DD16A420; Sun, 3 Jul 2005 23:13:31 +0000 (GMT) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 218F916A41C for ; Sun, 3 Jul 2005 23:13:31 +0000 (GMT) (envelope-from samy@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 039D143D46 for ; Sun, 3 Jul 2005 23:13:31 +0000 (GMT) (envelope-from samy@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j63NDUWW027147 for ; Sun, 3 Jul 2005 23:13:30 GMT (envelope-from samy@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j63NDUqm027144 for perforce@freebsd.org; Sun, 3 Jul 2005 23:13:30 GMT (envelope-from samy@FreeBSD.org) Date: Sun, 3 Jul 2005 23:13:30 GMT Message-Id: <200507032313.j63NDUqm027144@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to samy@FreeBSD.org using -f From: Samy Al Bahra To: Perforce Change Reviews Cc: Subject: PERFORCE change 79509 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Jul 2005 23:13:32 -0000 http://perforce.freebsd.org/chv.cgi?CH=79509 Change 79509 by samy@samy_home on 2005/07/03 23:13:09 This patch modifies the default portacl rule API to support defining rules to be attached to a uid/gid inside a prison or exclusively non-prison context. A PID (P for prison) may be prepended to the beginning of a rule "0:uid:5:tcp:50, ...". "all" may be prepended to affect all prisons, "none", for only the system. Approved by: rwatson Affected files ... .. //depot/projects/trustedbsd/mac/sys/security/mac_portacl/mac_portacl.c#7 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/security/mac_portacl/mac_portacl.c#7 (text+ko) ==== @@ -48,7 +48,7 @@ * you will probably want to twiddle the net.inet sysctl listed above. * Then use sysctl(8) to modify the rules string: * - * # sysctl security.mac.portacl.rules="uid:425:tcp:80,uid:425:tcp:79" + * # sysctl security.mac.portacl.rules="all:uid:425:tcp:80,uid:425:tcp:79" * * This ruleset, for example, permits uid 425 to bind TCP ports 80 (http) * and 79 (finger). User names and group names can't be used directly @@ -76,6 +76,7 @@ #include #include #include +#include #include #include @@ -117,11 +118,14 @@ #define MAC_RULE_STRING_LEN 1024 +#define RULE_IGNORE 0 +#define RULE_SYSTEM -1 #define RULE_GID 1 #define RULE_UID 2 #define RULE_PROTO_TCP 1 #define RULE_PROTO_UDP 2 struct rule { + int r_pr_id; id_t r_id; int r_idtype; u_int16_t r_port; @@ -130,6 +134,8 @@ TAILQ_ENTRY(rule) r_entries; }; +#define SYSTEM_STRING "none" +#define IGNORE_STRING "all" #define GID_STRING "gid" #define TCP_STRING "tcp" #define UID_STRING "uid" @@ -138,7 +144,7 @@ /* * Text format for the rule string is that a rule consists of a * comma-seperated list of elements. Each element is in the form - * idtype:id:protocol:portnumber, and constitutes granting of permission + * prison:idtype:id:protocol:portnumber, and constitutes granting of permission * for the specified binding. */ @@ -183,18 +189,46 @@ static int parse_rule_element(char *element, struct rule **rule) { - char *idtype, *id, *protocol, *portnumber, *p; + char *idtype, *id, *rtype, *portnumber, *prison, *p; struct rule *new; int error; error = 0; new = malloc(sizeof(*new), M_PORTACL, M_ZERO | M_WAITOK); - idtype = strsep(&element, ":"); - if (idtype == NULL) { + idtype = NULL; + + prison = strsep(&element, ":"); + if (prison == NULL) { error = EINVAL; goto out; } + + if (strcmp(prison, IGNORE_STRING) == 0) + new->r_pr_id = RULE_IGNORE; + else if (strcmp(prison, SYSTEM_STRING) == 0) + new->r_pr_id = RULE_SYSTEM; + else if (strcmp(prison, UID_STRING) && + strcmp(prison, GID_STRING)) { + new->r_pr_id = strtol(prison, &p, 10); + if (*p != '\0' || new->r_pr_id < 0) { + error = EINVAL; + goto out; + } + } else { + new->r_pr_id = RULE_IGNORE; + idtype = prison; + } + + if (idtype == NULL) { + idtype = strsep(&element, ":"); + + if (idtype == NULL) { + error = EINVAL; + goto out; + } + } + id = strsep(&element, ":"); if (id == NULL) { error = EINVAL; @@ -213,12 +247,15 @@ error = EINVAL; goto out; } + protocol = strsep(&element, ":"); if (protocol == NULL) { error = EINVAL; goto out; } - if (strcmp(protocol, TCP_STRING) == 0) + if (strcmp(protocol, IGNORE_STRING) == 0) + new->r_protocol = RULE_IGNORE; + else if (strcmp(protocol, TCP_STRING) == 0) new->r_protocol = RULE_PROTO_TCP; else if (strcmp(protocol, UDP_STRING) == 0) new->r_protocol = RULE_PROTO_UDP; @@ -292,6 +329,9 @@ } switch (rule->r_protocol) { + case RULE_IGNORE: + protocol = IGNORE_STRING; + break; case RULE_PROTO_TCP: protocol = TCP_STRING; break; @@ -302,8 +342,9 @@ panic("rule_printf: unknown protocol (%d)\n", rule->r_protocol); } - sbuf_printf(sb, "%s:%jd:%s:%d", idtype, (intmax_t)rule->r_id, - protocol, rule->r_port); + + sbuf_printf(sb, "%d:%s:%jd:%s:%d", rule->r_pr_id, idtype, + (intmax_t)rule->r_id, protocol, rule->r_port); } static char * @@ -401,12 +442,24 @@ for (rule = TAILQ_FIRST(&rule_head); rule != NULL; rule = TAILQ_NEXT(rule, r_entries)) { - if (type == SOCK_DGRAM && rule->r_protocol != RULE_PROTO_UDP) + if (rule->r_protocol != RULE_IGNORE) { + if (type == SOCK_DGRAM && rule->r_protocol != RULE_PROTO_UDP) + continue; + if (type == SOCK_STREAM && rule->r_protocol != RULE_PROTO_TCP) + continue; + } + + if (port != rule->r_port) continue; - if (type == SOCK_STREAM && rule->r_protocol != RULE_PROTO_TCP) + + if ((rule->r_pr_id == RULE_SYSTEM) && cred->cr_prison) continue; - if (port != rule->r_port) - continue; + else if (rule->r_pr_id != RULE_IGNORE) { + if (!cred->cr_prison || + (cred->cr_prison->pr_id != rule->r_pr_id)) + continue; + } + if (rule->r_idtype == RULE_UID) { if (cred->cr_uid == rule->r_id) { error = 0;