diff options
Diffstat (limited to 'lib/libugidfw')
-rw-r--r-- | lib/libugidfw/Makefile | 17 | ||||
-rw-r--r-- | lib/libugidfw/bsde_get_rule.3 | 159 | ||||
-rw-r--r-- | lib/libugidfw/bsde_get_rule_count.3 | 93 | ||||
-rw-r--r-- | lib/libugidfw/bsde_parse_rule.3 | 105 | ||||
-rw-r--r-- | lib/libugidfw/bsde_rule_to_string.3 | 82 | ||||
-rw-r--r-- | lib/libugidfw/libugidfw.3 | 115 | ||||
-rw-r--r-- | lib/libugidfw/ugidfw.c | 1323 | ||||
-rw-r--r-- | lib/libugidfw/ugidfw.h | 58 |
8 files changed, 1952 insertions, 0 deletions
diff --git a/lib/libugidfw/Makefile b/lib/libugidfw/Makefile new file mode 100644 index 0000000..bdcb5ca --- /dev/null +++ b/lib/libugidfw/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +LIB= ugidfw +SHLIB_MAJOR= 2 +SRCS= ugidfw.c +INCS= ugidfw.h + +MAN+= bsde_get_rule.3 bsde_get_rule_count.3 bsde_parse_rule.3 \ + bsde_rule_to_string.3 libugidfw.3 + +MLINKS= bsde_get_rule.3 bsde_add_rule.3 +MLINKS+= bsde_get_rule.3 bsde_delete_rule.3 +MLINKS+= bsde_get_rule.3 bsde_set_rule.3 +MLINKS+= bsde_get_rule_count.3 bsde_get_rule_slots.3 +MLINKS+= bsde_parse_rule.3 bsde_parse_rule_string.3 + +.include <bsd.lib.mk> diff --git a/lib/libugidfw/bsde_get_rule.3 b/lib/libugidfw/bsde_get_rule.3 new file mode 100644 index 0000000..a3b6691 --- /dev/null +++ b/lib/libugidfw/bsde_get_rule.3 @@ -0,0 +1,159 @@ +.\" Copyright (c) 2003-2004 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris +.\" Costello at Safeport Network Services and Network Associates +.\" Laboratories, the Security Research Division of Network Associates, +.\" Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part +.\" of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd February 24, 2004 +.Os +.Dt BSDE_GET_RULE 3 +.Sh NAME +.Nm bsde_add_rule , +.Nm bsde_get_rule , +.Nm bsde_set_rule , +.Nm bsde_delete_rule +.Nd "file system firewall rules list management" +.Sh LIBRARY +.Lb libugidfw +.Sh SYNOPSIS +.In ugidfw.h +.Ft int +.Fo bsde_add_rule +.Fa "int *rulenum" "struct mac_bsdextended_rule *rule" +.Fa "size_t buflen" "char *errstr" +.Fc +.Ft int +.Fo bsde_get_rule +.Fa "int rulenum" "struct mac_bsdextended_rule *rule" +.Fa "size_t errlen" "char *errstr" +.Fc +.Ft int +.Fo bsde_set_rule +.Fa "int rulenum" "struct mac_bsdextended_rule *rule" +.Fa "size_t errlen" "char *errstr" +.Fc +.Ft int +.Fn bsde_delete_rule "int rulenum" "size_t errlen" "char *errstr" +.Sh DESCRIPTION +The +.Fn bsde_add_rule +function fills the next available +rule (in +.Vt "struct mac_bsdextended_rule" +form, either from +.Fn bsde_get_rule +or +.Xr bsde_parse_rule 3 ) . +If an error occurs, +.Fa *errstr +is filled with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +If successful and +.Fa rulenum +is +.No non- Ns Dv NULL , +the rule number used will be returned in +.Fa *rulenum . +.Pp +The +.Fn bsde_get_rule +function fills in +.Fa *rule +with the rule numbered +.Fa rulenum . +If an error occurs, +.Fa *errstr +is filled in with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +.Pp +The +.Fn bsde_set_rule +function fills the slot numbered +.Fa rulenum +with the specified rule +(in +.Vt "struct mac_bsdextended_rule" +form, either from +.Fn bsde_get_rule +or +.Xr bsde_parse_rule 3 ) . +If an error occurs, +.Fa *errstr +is filled with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +.Pp +The +.Fn bsde_delete_rule +function deletes the rule numbered +.Fa rulenum . +If an error occurs, +.Fa *errstr +is filled with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +.Sh RETURN VALUES +The +.Fn bsde_get_rule , +.Fn bsde_set_rule , +and +.Fn bsde_delete_rule +functions return 0 if successful; +otherwise the value \-1 is returned and the value of +.Fa *errstr +is filled in as documented in +.Sx DESCRIPTION . +.Sh SEE ALSO +.Xr bsde_get_rule_count 3 , +.Xr bsde_get_rule_slots 3 , +.Xr bsde_parse_rule 3 , +.Xr bsde_parse_rule_string 3 , +.Xr bsde_rule_to_string 3 , +.Xr libugidfw 3 , +.Xr mac_bsdextended 4 , +.Xr ugidfw 8 +.Sh AUTHORS +This software was contributed to the +.Fx +Project by Network Associates Labs, +the Security Research Division of Network Associates +Inc. +under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libugidfw/bsde_get_rule_count.3 b/lib/libugidfw/bsde_get_rule_count.3 new file mode 100644 index 0000000..bf441e1 --- /dev/null +++ b/lib/libugidfw/bsde_get_rule_count.3 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2003 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris +.\" Costello at Safeport Network Services and Network Associates +.\" Laboratories, the Security Research Division of Network Associates, +.\" Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part +.\" of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd January 7, 2003 +.Os +.Dt BSDE_GET_RULE_COUNT 3 +.Sh NAME +.Nm bsde_get_rule_count , +.Nm bsde_get_rule_slots +.Nd "file system firewall statistics" +.Sh LIBRARY +.Lb libugidfw +.Sh SYNOPSIS +.In ugidfw.h +.Ft int +.Fn bsde_get_rule_count "size_t errlen" "char *errstr" +.Ft int +.Fn bsde_get_rule_slots "size_t errlen" "char *errstr" +.Sh DESCRIPTION +The +.Fn bsde_get_rule_count +and +.Fn bsde_get_rule_slots +functions +return the total number of enforced rules +and the total number of used rule slots, respectively. +If an error occurs, +.Fa *errstr +is filled in with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +.Sh RETURN VALUES +The +.Fn bsde_get_rule_count +and +.Fn bsde_get_rule_slots +functions return +the number of enforced rules and rule slots (respectively) +if successful; +otherwise the value \-1 is returned and the value of +.Fa *errstr +is filled in as documented in +.Sx DESCRIPTION . +.Sh SEE ALSO +.Xr bsde_delete_rule 3 , +.Xr bsde_get_rule 3 , +.Xr bsde_parse_rule 3 , +.Xr bsde_parse_rule_string 3 , +.Xr bsde_rule_to_string 3 , +.Xr bsde_set_rule 3 , +.Xr libugidfw 3 , +.Xr mac_bsdextended 4 , +.Xr ugidfw 8 +.Sh AUTHORS +This software was contributed to the +.Fx +Project by Network Associates Labs, +the Security Research Division of Network Associates +Inc. +under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libugidfw/bsde_parse_rule.3 b/lib/libugidfw/bsde_parse_rule.3 new file mode 100644 index 0000000..d510cab --- /dev/null +++ b/lib/libugidfw/bsde_parse_rule.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2003 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris +.\" Costello at Safeport Network Services and Network Associates +.\" Laboratories, the Security Research Division of Network Associates, +.\" Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part +.\" of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd January 7, 2003 +.Os +.Dt BSDE_PARSE_RULE 3 +.Sh NAME +.Nm bsde_parse_rule , +.Nm bsde_parse_rule_string +.Nd "parse file system firewall rules" +.Sh LIBRARY +.Lb libugidfw +.Sh SYNOPSIS +.In ugidfw.h +.Ft int +.Fo bsde_parse_rule +.Fa "int argc" "char *argv[]" "struct mac_bsdextended_rule *rule" +.Fa "size_t buflen" "char *errstr" +.Fc +.Ft int +.Fo bsde_parse_rule_string +.Fa "const char *string" "struct mac_bsdextended_rule *rule" +.Fa "size_t buflen" "char *errstr" +.Fc +.Sh DESCRIPTION +The +.Fn bsde_parse_rule +function parses an argument vector +(e.g.\& +.Fa argv +as passed to +.Fn main ) +into +.Fa rule . +If an error occurs, +.Fa *errstr +is filled in with the error string +(up to +.Fa errlen +characters, including the terminating +.Dv NUL ) . +.Pp +The +.Fn bsde_parse_rule_string +function is identical to +.Fn bsde_parse_rule , +except that it parses a single string rather than an array of arguments. +.Sh RETURN VALUES +The +.Fn bsde_parse_rule_string +and +.Fn bsde_parse_rule +functions return 0 if successful; +otherwise the value \-1 is returned and the value of +.Fa *errstr +is filled in as documented in +.Sx DESCRIPTION . +.Sh SEE ALSO +.Xr bsde_delete_rule 3 , +.Xr bsde_get_rule 3 , +.Xr bsde_get_rule_count 3 , +.Xr bsde_get_rule_slots 3 , +.Xr bsde_rule_to_string 3 , +.Xr bsde_set_rule 3 , +.Xr libugidfw 3 , +.Xr mac_bsdextended 4 , +.Xr ugidfw 8 +.Sh AUTHORS +This software was contributed to the +.Fx +Project by Network Associates Labs, +the Security Research Division of Network Associates +Inc. +under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libugidfw/bsde_rule_to_string.3 b/lib/libugidfw/bsde_rule_to_string.3 new file mode 100644 index 0000000..4414406 --- /dev/null +++ b/lib/libugidfw/bsde_rule_to_string.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 2003 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris +.\" Costello at Safeport Network Services and Network Associates +.\" Laboratories, the Security Research Division of Network Associates, +.\" Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part +.\" of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd January 7, 2003 +.Os +.Dt BSDE_RULE_TO_STRING 3 +.Sh NAME +.Nm bsde_rule_to_string +.Nd "convert a ugidfw rule into its text representation" +.Sh LIBRARY +.Lb libugidfw +.Sh SYNOPSIS +.In ugidfw.h +.Ft int +.Fo bsde_rule_to_string +.Fa "struct mac_bsdextended_rule *rule" "char *buf" "size_t buflen" +.Fc +.Sh DESCRIPTION +The +.Fn bsde_rule_to_string +function converts a rule in its internal representation +.Pq Vt "struct mac_bsdextended_rule" +into its text representation, and writes up to +.Fa buflen +bytes of it to +.Fa buf +(including the terminating +.Dv NUL ) . +.Sh RETURN VALUES +The +.Fn bsde_rule_to_string +function returns \-1 if the conversion was truncated; +otherwise the value 0 is returned. +.Sh SEE ALSO +.Xr bsde_delete_rule 3 , +.Xr bsde_get_rule 3 , +.Xr bsde_get_rule_count 3 , +.Xr bsde_get_rule_slots 3 , +.Xr bsde_parse_rule 3 , +.Xr bsde_parse_rule_string 3 , +.Xr bsde_set_rule 3 , +.Xr libugidfw 3 , +.Xr mac_bsdextended 4 , +.Xr ugidfw 8 +.Sh AUTHORS +This software was contributed to the +.Fx +Project by Network Associates Labs, +the Security Research Division of Network Associates +Inc. +under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libugidfw/libugidfw.3 b/lib/libugidfw/libugidfw.3 new file mode 100644 index 0000000..3ff407c --- /dev/null +++ b/lib/libugidfw/libugidfw.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2003 Networks Associates Technology, Inc. +.\" All rights reserved. +.\" +.\" This software was developed for the FreeBSD Project by Chris +.\" Costello at Safeport Network Services and Network Associates +.\" Laboratories, the Security Research Division of Network Associates, +.\" Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part +.\" of the DARPA CHATS research program. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd February 25, 2004 +.Os +.Dt LIBUGIDFW 3 +.Sh NAME +.Nm libugidfw +.Nd "library interface to the file system firewall MAC policy" +.Sh LIBRARY +.Lb libugidfw +.Sh SYNOPSIS +.In sys/types.h +.In security/mac_bsdextended/mac_bsdextended.h +.In ugidfw.h +.Sh DESCRIPTION +The +.Nm +library routines provide an interface to the +.Xr mac_bsdextended 4 +file system firewall MAC policy. +.Pp +The +.Nm +library defines the following functions: +.Bl -tag -width ".Fn bsde_parse_rule_string" +.It Fn bsde_rule_to_string +Converts the internal representation of a rule +.Pq Vt "struct mac_bsdextended_rule" +into its text representation; +see +.Xr bsde_rule_to_string 3 . +.It Fn bsde_parse_rule +Parses an entire rule +(in argument array form); +see +.Xr bsde_parse_rule 3 . +.It Fn bsde_parse_rule_string +Parses an entire rule string; +see +.Xr bsde_parse_rule_string 3 . +.It Fn bsde_get_rule_count +Returns the total number of ugidfw rules being enforced in the system; +see +.Xr bsde_get_rule_count 3 . +.It Fn bsde_get_rule_slots +Returns the total number of used rule slots; +see +.Xr bsde_get_rule_slots 3 . +.It Fn bsde_get_rule +Returns a rule by its rule number; +see +.Xr bsde_get_rule 3 . +.It Fn bsde_delete_rule +Deletes a rule by its rule number; +see +.Xr bsde_delete_rule 3 . +.It Fn bsde_set_rule +Uploads the rule to the +.Xr mac_bsdextended 4 +module and applies it; +see +.Xr bsde_set_rule 3 . +.It Fn bsde_add_rule +Upload the rule to the module, automatically selecting the next available +rule number; see +.Xr bsde_add_rule 3 . +.El +.Sh SEE ALSO +.Xr bsde_delete_rule 3 , +.Xr bsde_get_rule 3 , +.Xr bsde_get_rule_count 3 , +.Xr bsde_get_rule_slots 3 , +.Xr bsde_parse_rule 3 , +.Xr bsde_parse_rule_string 3 , +.Xr bsde_rule_to_string 3 , +.Xr bsde_set_rule 3 +.Sh AUTHORS +This software was contributed to the +.Fx +Project by Network Associates Labs, +the Security Research Division of Network Associates +Inc. +under DARPA/SPAWAR contract N66001-01-C-8035 +.Pq Dq CBOSS , +as part of the DARPA CHATS research program. diff --git a/lib/libugidfw/ugidfw.c b/lib/libugidfw/ugidfw.c new file mode 100644 index 0000000..341ac25 --- /dev/null +++ b/lib/libugidfw/ugidfw.c @@ -0,0 +1,1323 @@ +/*- + * Copyright (c) 2002-2005 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Network Associates + * Laboratories, the Security Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include <sys/param.h> +#include <sys/errno.h> +#include <sys/time.h> +#include <sys/sysctl.h> +#include <sys/ucred.h> +#include <sys/mount.h> + +#include <security/mac_bsdextended/mac_bsdextended.h> + +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ugidfw.h" + +/* + * Text format for rules: rules contain subject and object elements, mode. + * The total form is "subject [s_element] object [o_element] mode [mode]". + * At least * one of a uid or gid entry must be present; both may also be + * present. + */ + +#define MIB "security.mac.bsdextended" + +int +bsde_rule_to_string(struct mac_bsdextended_rule *rule, char *buf, size_t buflen) +{ + struct group *grp; + struct passwd *pwd; + struct statfs *mntbuf; + char *cur, type[sizeof(rule->mbr_object.mbo_type) * CHAR_BIT + 1]; + size_t left, len; + int anymode, unknownmode, truncated, numfs, i, notdone; + + cur = buf; + left = buflen; + truncated = 0; + + len = snprintf(cur, left, "subject "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + if (rule->mbr_subject.mbs_flags) { + if (rule->mbr_subject.mbs_neg == MBS_ALL_FLAGS) { + len = snprintf(cur, left, "not "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + notdone = 1; + } else { + notdone = 0; + } + + if (!notdone && (rule->mbr_subject.mbs_neg & MBO_UID_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_subject.mbs_flags & MBO_UID_DEFINED) { + pwd = getpwuid(rule->mbr_subject.mbs_uid_min); + if (pwd != NULL) { + len = snprintf(cur, left, "uid %s", + pwd->pw_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, "uid %u", + rule->mbr_subject.mbs_uid_min); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_subject.mbs_uid_min != + rule->mbr_subject.mbs_uid_max) { + pwd = getpwuid(rule->mbr_subject.mbs_uid_max); + if (pwd != NULL) { + len = snprintf(cur, left, ":%s ", + pwd->pw_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, ":%u ", + rule->mbr_subject.mbs_uid_max); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } else { + len = snprintf(cur, left, " "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + if (!notdone && (rule->mbr_subject.mbs_neg & MBO_GID_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_subject.mbs_flags & MBO_GID_DEFINED) { + grp = getgrgid(rule->mbr_subject.mbs_gid_min); + if (grp != NULL) { + len = snprintf(cur, left, "gid %s", + grp->gr_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, "gid %u", + rule->mbr_subject.mbs_gid_min); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_subject.mbs_gid_min != + rule->mbr_subject.mbs_gid_max) { + grp = getgrgid(rule->mbr_subject.mbs_gid_max); + if (grp != NULL) { + len = snprintf(cur, left, ":%s ", + grp->gr_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, ":%u ", + rule->mbr_subject.mbs_gid_max); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } else { + len = snprintf(cur, left, " "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + if (!notdone && (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) { + len = snprintf(cur, left, "jailid %d ", + rule->mbr_subject.mbs_prison); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + + len = snprintf(cur, left, "object "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + if (rule->mbr_object.mbo_flags) { + if (rule->mbr_object.mbo_neg == MBO_ALL_FLAGS) { + len = snprintf(cur, left, "not "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + notdone = 1; + } else { + notdone = 0; + } + + if (!notdone && (rule->mbr_object.mbo_neg & MBO_UID_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) { + pwd = getpwuid(rule->mbr_object.mbo_uid_min); + if (pwd != NULL) { + len = snprintf(cur, left, "uid %s", + pwd->pw_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, "uid %u", + rule->mbr_object.mbo_uid_min); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_uid_min != + rule->mbr_object.mbo_uid_max) { + pwd = getpwuid(rule->mbr_object.mbo_uid_max); + if (pwd != NULL) { + len = snprintf(cur, left, ":%s ", + pwd->pw_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, ":%u ", + rule->mbr_object.mbo_uid_max); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } else { + len = snprintf(cur, left, " "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_GID_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) { + grp = getgrgid(rule->mbr_object.mbo_gid_min); + if (grp != NULL) { + len = snprintf(cur, left, "gid %s", + grp->gr_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, "gid %u", + rule->mbr_object.mbo_gid_min); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_gid_min != + rule->mbr_object.mbo_gid_max) { + grp = getgrgid(rule->mbr_object.mbo_gid_max); + if (grp != NULL) { + len = snprintf(cur, left, ":%s ", + grp->gr_name); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } else { + len = snprintf(cur, left, ":%u ", + rule->mbr_object.mbo_gid_max); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } else { + len = snprintf(cur, left, " "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) { + numfs = getmntinfo(&mntbuf, MNT_NOWAIT); + for (i = 0; i < numfs; i++) + if (memcmp(&(rule->mbr_object.mbo_fsid), + &(mntbuf[i].f_fsid), + sizeof(mntbuf[i].f_fsid)) == 0) + break; + len = snprintf(cur, left, "filesys %s ", + i == numfs ? "???" : mntbuf[i].f_mntonname); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_SUID)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_SUID) { + len = snprintf(cur, left, "suid "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_SGID)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_SGID) { + len = snprintf(cur, left, "sgid "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) { + len = snprintf(cur, left, "uid_of_subject "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) { + len = snprintf(cur, left, "gid_of_subject "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (!notdone && (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED)) { + len = snprintf(cur, left, "! "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) { + i = 0; + if (rule->mbr_object.mbo_type & MBO_TYPE_REG) + type[i++] = 'r'; + if (rule->mbr_object.mbo_type & MBO_TYPE_DIR) + type[i++] = 'd'; + if (rule->mbr_object.mbo_type & MBO_TYPE_BLK) + type[i++] = 'b'; + if (rule->mbr_object.mbo_type & MBO_TYPE_CHR) + type[i++] = 'c'; + if (rule->mbr_object.mbo_type & MBO_TYPE_LNK) + type[i++] = 'l'; + if (rule->mbr_object.mbo_type & MBO_TYPE_SOCK) + type[i++] = 's'; + if (rule->mbr_object.mbo_type & MBO_TYPE_FIFO) + type[i++] = 'p'; + if (rule->mbr_object.mbo_type == MBO_ALL_TYPE) { + i = 0; + type[i++] = 'a'; + } + type[i++] = '\0'; + len = snprintf(cur, left, "type %s ", type); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + } + } + + len = snprintf(cur, left, "mode "); + if (len < 0 || len > left) + goto truncated; + left -= len; + cur += len; + + anymode = (rule->mbr_mode & MBI_ALLPERM); + unknownmode = (rule->mbr_mode & ~MBI_ALLPERM); + + if (rule->mbr_mode & MBI_ADMIN) { + len = snprintf(cur, left, "a"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (rule->mbr_mode & MBI_READ) { + len = snprintf(cur, left, "r"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (rule->mbr_mode & MBI_STAT) { + len = snprintf(cur, left, "s"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (rule->mbr_mode & MBI_WRITE) { + len = snprintf(cur, left, "w"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (rule->mbr_mode & MBI_EXEC) { + len = snprintf(cur, left, "x"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (!anymode) { + len = snprintf(cur, left, "n"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + if (unknownmode) { + len = snprintf(cur, left, "?"); + if (len < 0 || len > left) + goto truncated; + + left -= len; + cur += len; + } + + return (0); + +truncated: + return (-1); +} + +int +bsde_parse_uidrange(char *spec, uid_t *min, uid_t *max, + size_t buflen, char *errstr){ + struct passwd *pwd; + uid_t uid1, uid2; + char *spec1, *spec2, *endp; + unsigned long value; + size_t len; + + spec2 = spec; + spec1 = strsep(&spec2, ":"); + + pwd = getpwnam(spec1); + if (pwd != NULL) + uid1 = pwd->pw_uid; + else { + value = strtoul(spec1, &endp, 10); + if (*endp != '\0') { + len = snprintf(errstr, buflen, + "invalid uid: '%s'", spec1); + return (-1); + } + uid1 = value; + } + + if (spec2 == NULL) { + *max = *min = uid1; + return (0); + } + + pwd = getpwnam(spec2); + if (pwd != NULL) + uid2 = pwd->pw_uid; + else { + value = strtoul(spec2, &endp, 10); + if (*endp != '\0') { + len = snprintf(errstr, buflen, + "invalid uid: '%s'", spec2); + return (-1); + } + uid2 = value; + } + + *min = uid1; + *max = uid2; + + return (0); +} + +int +bsde_parse_gidrange(char *spec, gid_t *min, gid_t *max, + size_t buflen, char *errstr){ + struct group *grp; + gid_t gid1, gid2; + char *spec1, *spec2, *endp; + unsigned long value; + size_t len; + + spec2 = spec; + spec1 = strsep(&spec2, ":"); + + grp = getgrnam(spec1); + if (grp != NULL) + gid1 = grp->gr_gid; + else { + value = strtoul(spec1, &endp, 10); + if (*endp != '\0') { + len = snprintf(errstr, buflen, + "invalid gid: '%s'", spec1); + return (-1); + } + gid1 = value; + } + + if (spec2 == NULL) { + *max = *min = gid1; + return (0); + } + + grp = getgrnam(spec2); + if (grp != NULL) + gid2 = grp->gr_gid; + else { + value = strtoul(spec2, &endp, 10); + if (*endp != '\0') { + len = snprintf(errstr, buflen, + "invalid gid: '%s'", spec2); + return (-1); + } + gid2 = value; + } + + *min = gid1; + *max = gid2; + + return (0); +} + +int +bsde_parse_subject(int argc, char *argv[], + struct mac_bsdextended_subject *subject, size_t buflen, char *errstr) +{ + int not_seen, flags; + int current, neg, nextnot; + char *endp; + uid_t uid_min, uid_max; + gid_t gid_min, gid_max; + int jid; + size_t len; + long value; + + current = 0; + flags = 0; + neg = 0; + nextnot = 0; + + if (strcmp("not", argv[current]) == 0) { + not_seen = 1; + current++; + } else + not_seen = 0; + + while (current < argc) { + if (strcmp(argv[current], "uid") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "uid short"); + return (-1); + } + if (flags & MBS_UID_DEFINED) { + len = snprintf(errstr, buflen, "one uid only"); + return (-1); + } + if (bsde_parse_uidrange(argv[current+1], + &uid_min, &uid_max, buflen, errstr) < 0) + return (-1); + flags |= MBS_UID_DEFINED; + if (nextnot) { + neg ^= MBS_UID_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "gid") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "gid short"); + return (-1); + } + if (flags & MBS_GID_DEFINED) { + len = snprintf(errstr, buflen, "one gid only"); + return (-1); + } + if (bsde_parse_gidrange(argv[current+1], + &gid_min, &gid_max, buflen, errstr) < 0) + return (-1); + flags |= MBS_GID_DEFINED; + if (nextnot) { + neg ^= MBS_GID_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "jailid") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "prison short"); + return (-1); + } + if (flags & MBS_PRISON_DEFINED) { + len = snprintf(errstr, buflen, "one jail only"); + return (-1); + } + value = strtol(argv[current+1], &endp, 10); + if (*endp != '\0') { + len = snprintf(errstr, buflen, + "invalid jid: '%s'", argv[current+1]); + return (-1); + } + jid = value; + flags |= MBS_PRISON_DEFINED; + if (nextnot) { + neg ^= MBS_PRISON_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "!") == 0) { + if (nextnot) { + len = snprintf(errstr, buflen, + "double negative"); + return (-1); + } + nextnot = 1; + current += 1; + } else { + len = snprintf(errstr, buflen, "'%s' not expected", + argv[current]); + return (-1); + } + } + + subject->mbs_flags = flags; + if (not_seen) + subject->mbs_neg = MBS_ALL_FLAGS ^ neg; + else + subject->mbs_neg = neg; + if (flags & MBS_UID_DEFINED) { + subject->mbs_uid_min = uid_min; + subject->mbs_uid_max = uid_max; + } + if (flags & MBS_GID_DEFINED) { + subject->mbs_gid_min = gid_min; + subject->mbs_gid_max = gid_max; + } + if (flags & MBS_PRISON_DEFINED) + subject->mbs_prison = jid; + + return (0); +} + +int +bsde_parse_type(char *spec, int *type, size_t buflen, char *errstr) +{ + size_t len; + int i; + + *type = 0; + for (i = 0; i < strlen(spec); i++) { + switch (spec[i]) { + case 'r': + case '-': + *type |= MBO_TYPE_REG; + break; + case 'd': + *type |= MBO_TYPE_DIR; + break; + case 'b': + *type |= MBO_TYPE_BLK; + break; + case 'c': + *type |= MBO_TYPE_CHR; + break; + case 'l': + *type |= MBO_TYPE_LNK; + break; + case 's': + *type |= MBO_TYPE_SOCK; + break; + case 'p': + *type |= MBO_TYPE_FIFO; + break; + case 'a': + *type |= MBO_ALL_TYPE; + break; + default: + len = snprintf(errstr, buflen, "Unknown type code: %c", + spec[i]); + return (-1); + } + } + + return (0); +} + +int +bsde_parse_fsid(char *spec, struct fsid *fsid, size_t buflen, char *errstr) +{ + size_t len; + struct statfs buf; + int i; + + if (statfs(spec, &buf) < 0) { + len = snprintf(errstr, buflen, "Unable to get id for %s: %s", + spec, strerror(errno)); + return (-1); + } + + *fsid = buf.f_fsid; + + return (0); +} + +int +bsde_parse_object(int argc, char *argv[], + struct mac_bsdextended_object *object, size_t buflen, char *errstr) +{ + int not_seen, flags; + int current, neg, nextnot; + uid_t uid_min, uid_max; + gid_t gid_min, gid_max; + int type; + struct fsid fsid; + size_t len; + + current = 0; + flags = 0; + neg = 0; + nextnot = 0; + + if (strcmp("not", argv[current]) == 0) { + not_seen = 1; + current++; + } else + not_seen = 0; + + while (current < argc) { + if (strcmp(argv[current], "uid") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "uid short"); + return (-1); + } + if (flags & MBO_UID_DEFINED) { + len = snprintf(errstr, buflen, "one uid only"); + return (-1); + } + if (bsde_parse_uidrange(argv[current+1], + &uid_min, &uid_max, buflen, errstr) < 0) + return (-1); + flags |= MBO_UID_DEFINED; + if (nextnot) { + neg ^= MBO_UID_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "gid") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "gid short"); + return (-1); + } + if (flags & MBO_GID_DEFINED) { + len = snprintf(errstr, buflen, "one gid only"); + return (-1); + } + if (bsde_parse_gidrange(argv[current+1], + &gid_min, &gid_max, buflen, errstr) < 0) + return (-1); + flags |= MBO_GID_DEFINED; + if (nextnot) { + neg ^= MBO_GID_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "filesys") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "filesys short"); + return (-1); + } + if (flags & MBO_FSID_DEFINED) { + len = snprintf(errstr, buflen, "one fsid only"); + return (-1); + } + if (bsde_parse_fsid(argv[current+1], &fsid, + buflen, errstr) < 0) + return (-1); + flags |= MBO_FSID_DEFINED; + if (nextnot) { + neg ^= MBO_FSID_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "suid") == 0) { + flags |= MBO_SUID; + if (nextnot) { + neg ^= MBO_SUID; + nextnot = 0; + } + current += 1; + } else if (strcmp(argv[current], "sgid") == 0) { + flags |= MBO_SGID; + if (nextnot) { + neg ^= MBO_SGID; + nextnot = 0; + } + current += 1; + } else if (strcmp(argv[current], "uid_of_subject") == 0) { + flags |= MBO_UID_SUBJECT; + if (nextnot) { + neg ^= MBO_UID_SUBJECT; + nextnot = 0; + } + current += 1; + } else if (strcmp(argv[current], "gid_of_subject") == 0) { + flags |= MBO_GID_SUBJECT; + if (nextnot) { + neg ^= MBO_GID_SUBJECT; + nextnot = 0; + } + current += 1; + } else if (strcmp(argv[current], "type") == 0) { + if (current + 2 > argc) { + len = snprintf(errstr, buflen, "type short"); + return (-1); + } + if (flags & MBO_TYPE_DEFINED) { + len = snprintf(errstr, buflen, "one type only"); + return (-1); + } + if (bsde_parse_type(argv[current+1], &type, + buflen, errstr) < 0) + return (-1); + flags |= MBO_TYPE_DEFINED; + if (nextnot) { + neg ^= MBO_TYPE_DEFINED; + nextnot = 0; + } + current += 2; + } else if (strcmp(argv[current], "!") == 0) { + if (nextnot) { + len = snprintf(errstr, buflen, + "double negative'"); + return (-1); + } + nextnot = 1; + current += 1; + } else { + len = snprintf(errstr, buflen, "'%s' not expected", + argv[current]); + return (-1); + } + } + + object->mbo_flags = flags; + if (not_seen) + object->mbo_neg = MBO_ALL_FLAGS ^ neg; + else + object->mbo_neg = neg; + if (flags & MBO_UID_DEFINED) { + object->mbo_uid_min = uid_min; + object->mbo_uid_max = uid_max; + } + if (flags & MBO_GID_DEFINED) { + object->mbo_gid_min = gid_min; + object->mbo_gid_max = gid_max; + } + if (flags & MBO_FSID_DEFINED) + object->mbo_fsid = fsid; + if (flags & MBO_TYPE_DEFINED) + object->mbo_type = type; + + return (0); +} + +int +bsde_parse_mode(int argc, char *argv[], mode_t *mode, size_t buflen, + char *errstr) +{ + size_t len; + int i; + + if (argc == 0) { + len = snprintf(errstr, buflen, "mode expects mode value"); + return (-1); + } + + if (argc != 1) { + len = snprintf(errstr, buflen, "'%s' unexpected", argv[1]); + return (-1); + } + + *mode = 0; + for (i = 0; i < strlen(argv[0]); i++) { + switch (argv[0][i]) { + case 'a': + *mode |= MBI_ADMIN; + break; + case 'r': + *mode |= MBI_READ; + break; + case 's': + *mode |= MBI_STAT; + break; + case 'w': + *mode |= MBI_WRITE; + break; + case 'x': + *mode |= MBI_EXEC; + break; + case 'n': + /* ignore */ + break; + default: + len = snprintf(errstr, buflen, "Unknown mode letter: %c", + argv[0][i]); + return (-1); + } + } + + return (0); +} + +int +bsde_parse_rule(int argc, char *argv[], struct mac_bsdextended_rule *rule, + size_t buflen, char *errstr) +{ + int subject, subject_elements, subject_elements_length; + int object, object_elements, object_elements_length; + int mode, mode_elements, mode_elements_length; + int error, i; + size_t len; + + bzero(rule, sizeof(*rule)); + + if (argc < 1) { + len = snprintf(errstr, buflen, "Rule must begin with subject"); + return (-1); + } + + if (strcmp(argv[0], "subject") != 0) { + len = snprintf(errstr, buflen, "Rule must begin with subject"); + return (-1); + } + subject = 0; + subject_elements = 1; + + /* Search forward for object. */ + + object = -1; + for (i = 1; i < argc; i++) + if (strcmp(argv[i], "object") == 0) + object = i; + + if (object == -1) { + len = snprintf(errstr, buflen, "Rule must contain an object"); + return (-1); + } + + /* Search forward for mode. */ + mode = -1; + for (i = object; i < argc; i++) + if (strcmp(argv[i], "mode") == 0) + mode = i; + + if (mode == -1) { + len = snprintf(errstr, buflen, "Rule must contain mode"); + return (-1); + } + + subject_elements_length = object - subject - 1; + object_elements = object + 1; + object_elements_length = mode - object_elements; + mode_elements = mode + 1; + mode_elements_length = argc - mode_elements; + + error = bsde_parse_subject(subject_elements_length, + argv + subject_elements, &rule->mbr_subject, buflen, errstr); + if (error) + return (-1); + + error = bsde_parse_object(object_elements_length, + argv + object_elements, &rule->mbr_object, buflen, errstr); + if (error) + return (-1); + + error = bsde_parse_mode(mode_elements_length, argv + mode_elements, + &rule->mbr_mode, buflen, errstr); + if (error) + return (-1); + + return (0); +} + +int +bsde_parse_rule_string(const char *string, struct mac_bsdextended_rule *rule, + size_t buflen, char *errstr) +{ + char *stringdup, *stringp, *argv[100], **ap; + int argc, error; + + stringp = stringdup = strdup(string); + while (*stringp == ' ' || *stringp == '\t') + stringp++; + + argc = 0; + for (ap = argv; (*ap = strsep(&stringp, " \t")) != NULL;) { + argc++; + if (**ap != '\0') + if (++ap >= &argv[100]) + break; + } + + error = bsde_parse_rule(argc, argv, rule, buflen, errstr); + + free(stringdup); + + return (error); +} + +int +bsde_get_mib(const char *string, int *name, size_t *namelen) +{ + size_t len; + int error; + + len = *namelen; + error = sysctlnametomib(string, name, &len); + if (error) + return (error); + + *namelen = len; + return (0); +} + +int +bsde_check_version(size_t buflen, char *errstr) +{ + size_t len; + int error; + int version; + + len = sizeof(version); + error = sysctlbyname(MIB ".rule_version", &version, &len, NULL, 0); + if (error) { + len = snprintf(errstr, buflen, "version check failed: %s", + strerror(errno)); + return (-1); + } + if (version != MB_VERSION) { + len = snprintf(errstr, buflen, "module v%d != library v%d", + version, MB_VERSION); + return (-1); + } + return (0); +} + +int +bsde_get_rule_count(size_t buflen, char *errstr) +{ + size_t len; + int error; + int rule_count; + + len = sizeof(rule_count); + error = sysctlbyname(MIB ".rule_count", &rule_count, &len, NULL, 0); + if (error) { + len = snprintf(errstr, buflen, strerror(errno)); + return (-1); + } + if (len != sizeof(rule_count)) { + len = snprintf(errstr, buflen, "Data error in %s.rule_count", + MIB); + return (-1); + } + + return (rule_count); +} + +int +bsde_get_rule_slots(size_t buflen, char *errstr) +{ + size_t len; + int error; + int rule_slots; + + len = sizeof(rule_slots); + error = sysctlbyname(MIB ".rule_slots", &rule_slots, &len, NULL, 0); + if (error) { + len = snprintf(errstr, buflen, strerror(errno)); + return (-1); + } + if (len != sizeof(rule_slots)) { + len = snprintf(errstr, buflen, "Data error in %s.rule_slots", + MIB); + return (-1); + } + + return (rule_slots); +} + +/* + * Returns 0 for success; + * Returns -1 for failure; + * Returns -2 for not present + */ +int +bsde_get_rule(int rulenum, struct mac_bsdextended_rule *rule, size_t errlen, + char *errstr) +{ + int name[10]; + size_t len, size; + int error; + + if (bsde_check_version(errlen, errstr) != 0) + return (-1); + + len = 10; + error = bsde_get_mib(MIB ".rules", name, &len); + if (error) { + len = snprintf(errstr, errlen, "%s: %s", MIB ".rules", + strerror(errno)); + return (-1); + } + + size = sizeof(*rule); + name[len] = rulenum; + len++; + error = sysctl(name, len, rule, &size, NULL, 0); + if (error == -1 && errno == ENOENT) + return (-2); + if (error) { + len = snprintf(errstr, errlen, "%s.%d: %s", MIB ".rules", + rulenum, strerror(errno)); + return (-1); + } else if (size != sizeof(*rule)) { + len = snprintf(errstr, errlen, "Data error in %s.%d: %s", + MIB ".rules", rulenum, strerror(errno)); + return (-1); + } + + return (0); +} + +int +bsde_delete_rule(int rulenum, size_t buflen, char *errstr) +{ + struct mac_bsdextended_rule rule; + int name[10]; + size_t len, size; + int error; + + if (bsde_check_version(buflen, errstr) != 0) + return (-1); + + len = 10; + error = bsde_get_mib(MIB ".rules", name, &len); + if (error) { + len = snprintf(errstr, buflen, "%s: %s", MIB ".rules", + strerror(errno)); + return (-1); + } + + name[len] = rulenum; + len++; + + size = sizeof(rule); + error = sysctl(name, len, NULL, NULL, &rule, 0); + if (error) { + len = snprintf(errstr, buflen, "%s.%d: %s", MIB ".rules", + rulenum, strerror(errno)); + return (-1); + } + + return (0); +} + +int +bsde_set_rule(int rulenum, struct mac_bsdextended_rule *rule, size_t buflen, + char *errstr) +{ + int name[10]; + size_t len, size; + int error; + + if (bsde_check_version(buflen, errstr) != 0) + return (-1); + + len = 10; + error = bsde_get_mib(MIB ".rules", name, &len); + if (error) { + len = snprintf(errstr, buflen, "%s: %s", MIB ".rules", + strerror(errno)); + return (-1); + } + + name[len] = rulenum; + len++; + + size = sizeof(*rule); + error = sysctl(name, len, NULL, NULL, rule, size); + if (error) { + len = snprintf(errstr, buflen, "%s.%d: %s", MIB ".rules", + rulenum, strerror(errno)); + return (-1); + } + + return (0); +} + +int +bsde_add_rule(int *rulenum, struct mac_bsdextended_rule *rule, size_t buflen, + char *errstr) +{ + char charstr[BUFSIZ]; + int name[10]; + size_t len, size; + int error, rule_slots; + + if (bsde_check_version(buflen, errstr) != 0) + return (-1); + + len = 10; + error = bsde_get_mib(MIB ".rules", name, &len); + if (error) { + len = snprintf(errstr, buflen, "%s: %s", MIB ".rules", + strerror(errno)); + return (-1); + } + + rule_slots = bsde_get_rule_slots(BUFSIZ, charstr); + if (rule_slots == -1) { + len = snprintf(errstr, buflen, "unable to get rule slots: %s", + strerror(errno)); + return (-1); + } + + name[len] = rule_slots; + len++; + + size = sizeof(*rule); + error = sysctl(name, len, NULL, NULL, rule, size); + if (error) { + len = snprintf(errstr, buflen, "%s.%d: %s", MIB ".rules", + rule_slots, strerror(errno)); + return (-1); + } + + if (rulenum != NULL) + *rulenum = rule_slots; + + return (0); +} diff --git a/lib/libugidfw/ugidfw.h b/lib/libugidfw/ugidfw.h new file mode 100644 index 0000000..5b7fcf2 --- /dev/null +++ b/lib/libugidfw/ugidfw.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002, 2004 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Network Associates + * Laboratories, the Security Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _UGIDFW_H +#define _UGIDFW_H + +__BEGIN_DECLS +int bsde_rule_to_string(struct mac_bsdextended_rule *rule, char *buf, + size_t buflen); +int bsde_parse_mode(int argc, char *argv[], mode_t *mode, size_t buflen, + char *errstr); +int bsde_parse_rule(int argc, char *argv[], + struct mac_bsdextended_rule *rule, size_t buflen, char *errstr); +int bsde_parse_rule_string(const char *string, + struct mac_bsdextended_rule *rule, size_t buflen, char *errstr); +int bsde_get_mib(const char *string, int *name, size_t *namelen); +int bsde_get_rule_count(size_t buflen, char *errstr); +int bsde_get_rule_slots(size_t buflen, char *errstr); +int bsde_get_rule(int rulenum, struct mac_bsdextended_rule *rule, + size_t errlen, char *errstr); +int bsde_delete_rule(int rulenum, size_t buflen, char *errstr); +int bsde_set_rule(int rulenum, struct mac_bsdextended_rule *rule, + size_t buflen, char *errstr); +int bsde_add_rule(int *rulename, struct mac_bsdextended_rule *rule, + size_t buflen, char *errstr); +__END_DECLS + +#endif |