summaryrefslogtreecommitdiffstats
path: root/lib/libugidfw
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libugidfw')
-rw-r--r--lib/libugidfw/Makefile17
-rw-r--r--lib/libugidfw/bsde_get_rule.3159
-rw-r--r--lib/libugidfw/bsde_get_rule_count.393
-rw-r--r--lib/libugidfw/bsde_parse_rule.3105
-rw-r--r--lib/libugidfw/bsde_rule_to_string.382
-rw-r--r--lib/libugidfw/libugidfw.3115
-rw-r--r--lib/libugidfw/ugidfw.c1323
-rw-r--r--lib/libugidfw/ugidfw.h58
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
OpenPOWER on IntegriCloud