2011-09-20 21:12:38 +00:00
|
|
|
From 287f507657e162bc09b5c186bbd580901fbc942a Mon Sep 17 00:00:00 2001
|
|
|
|
From: Dan Walsh <dwalsh@redhat.com>
|
|
|
|
Date: Tue, 20 Sep 2011 15:47:28 -0400
|
|
|
|
Subject: [PATCH 6/6] Changes to support named file_trans rules
|
|
|
|
|
|
|
|
---
|
|
|
|
libapol/include/apol/ftrule-query.h | 198 +++++++++++++++++++
|
|
|
|
libapol/include/apol/policy-query.h | 1 +
|
|
|
|
libapol/src/Makefile.am | 1 +
|
|
|
|
libapol/src/ftrule-query.c | 363 +++++++++++++++++++++++++++++++++++
|
|
|
|
libapol/src/libapol.map | 1 +
|
|
|
|
libqpol/include/qpol/ftrule_query.h | 116 +++++++++++
|
|
|
|
libqpol/include/qpol/policy.h | 1 +
|
|
|
|
libqpol/src/Makefile.am | 1 +
|
|
|
|
libqpol/src/ftrule_query.c | 277 ++++++++++++++++++++++++++
|
|
|
|
libqpol/src/libqpol.map | 1 +
|
|
|
|
libqpol/src/module_compiler.c | 12 ++
|
|
|
|
libqpol/src/policy_define.c | 186 ++++++++++++++++++-
|
|
|
|
libqpol/src/policy_parse.y | 13 +-
|
|
|
|
libqpol/src/policy_scan.l | 1 +
|
|
|
|
secmds/sesearch.c | 101 ++++++++++
|
|
|
|
15 files changed, 1270 insertions(+), 3 deletions(-)
|
|
|
|
create mode 100644 libapol/include/apol/ftrule-query.h
|
|
|
|
create mode 100644 libapol/src/ftrule-query.c
|
|
|
|
create mode 100644 libqpol/include/qpol/ftrule_query.h
|
|
|
|
create mode 100644 libqpol/src/ftrule_query.c
|
|
|
|
|
|
|
|
diff --git a/libapol/include/apol/ftrule-query.h b/libapol/include/apol/ftrule-query.h
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..119c52f
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libapol/include/apol/ftrule-query.h
|
|
|
|
@@ -0,0 +1,198 @@
|
|
|
|
+/**
|
|
|
|
+ * @file
|
|
|
|
+ *
|
|
|
|
+ * Routines to query filename_transition rules of a
|
|
|
|
+ * policy.
|
|
|
|
+ *
|
|
|
|
+ * @author Jeremy A. Mowery jmowery@tresys.com
|
|
|
|
+ * @author Jason Tang jtang@tresys.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#ifndef APOL_FILENAMERULE_QUERY_H
|
|
|
|
+#define APOL_FILENAMERULE_QUERY_H
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+extern "C"
|
|
|
|
+{
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#include "policy.h"
|
|
|
|
+#include "vector.h"
|
|
|
|
+#include <qpol/policy.h>
|
|
|
|
+
|
|
|
|
+ typedef struct apol_filename_trans_query apol_filename_trans_query_t;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/******************** filename_transition queries ********************/
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Execute a query against all filename_transition rules within the
|
|
|
|
+ * policy.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy within which to look up filename_transition rules.
|
|
|
|
+ * @param r Structure containing parameters for query. If this is
|
|
|
|
+ * NULL then return all filename_transition rules.
|
|
|
|
+ * @param v Reference to a vector of qpol_filename_trans_t. The vector
|
|
|
|
+ * will be allocated by this function. The caller must call
|
|
|
|
+ * apol_vector_destroy() afterwards. This will be set to NULL upon no
|
|
|
|
+ * results or upon error.
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success (including none found), negative on error.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * r, apol_vector_t ** v);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Allocate and return a new filename trans query structure. All fields
|
|
|
|
+ * are initialized, such that running this blank query results in
|
|
|
|
+ * returning all filename_transitions within the policy. The caller must
|
|
|
|
+ * call apol_filename_trans_query_destroy() upon the return value
|
|
|
|
+ * afterwards.
|
|
|
|
+ *
|
|
|
|
+ * @return An initialized filename trans query structure, or NULL upon
|
|
|
|
+ * error.
|
|
|
|
+ */
|
|
|
|
+ extern apol_filename_trans_query_t *apol_filename_trans_query_create(void);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Deallocate all memory associated with the referenced filename trans
|
|
|
|
+ * query, and then set it to NULL. This function does nothing if the
|
|
|
|
+ * query is already NULL.
|
|
|
|
+ *
|
|
|
|
+ * @param r Reference to a filename trans query structure to destroy.
|
|
|
|
+ */
|
|
|
|
+ extern void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a filename_trans query to return rules whose source symbol matches
|
|
|
|
+ * symbol. Symbol may be a type or attribute; if it is an alias then
|
|
|
|
+ * the query will convert it to its primary prior to searching. If
|
|
|
|
+ * is_indirect is non-zero then the search will be done indirectly.
|
|
|
|
+ * If the symbol is a type, then the query matches rules with one of
|
|
|
|
+ * the type's attributes. If the symbol is an attribute, then it
|
|
|
|
+ * matches rule with any of the attribute's types.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param t TE rule query to set.
|
|
|
|
+ * @param symbol Limit query to rules with this symbol as their
|
|
|
|
+ * source, or NULL to unset this field.
|
|
|
|
+ * @param is_indirect If non-zero, perform indirect matching.
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success, negative on error.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol,
|
|
|
|
+ int is_indirect);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a filename trans query to return rules with a particular target
|
|
|
|
+ * symbol. Symbol may be a type or attribute; if it is an alias then
|
|
|
|
+ * the query will convert it to its primary prior to searching. If
|
|
|
|
+ * is_indirect is non-zero then the search will be done indirectly.
|
|
|
|
+ * If the symbol is a type, then the query matches rules with one of
|
|
|
|
+ * the type's attributes. If the symbol is an attribute, then it
|
|
|
|
+ * matches rule with any of the attribute's types.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param r Role trans query to set.
|
|
|
|
+ * @param symbol Limit query to rules with this type or attribute as
|
|
|
|
+ * their target, or NULL to unset this field.
|
|
|
|
+ * @param is_indirect If non-zero, perform indirect matching.
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success, negative on error.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *symbol,
|
|
|
|
+ int is_indirect);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a filename trans query to return rules with a particular default
|
|
|
|
+ * filename. This field is ignored if
|
|
|
|
+ * apol_filename_trans_query_set_source_any() is set to non-zero.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param r Role trans query to set.
|
|
|
|
+ * @param filename Limit query to rules with this filename as their default, or
|
|
|
|
+ * NULL to unset this field.
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success, negative on error.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *filename);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set at filename_trans query to return rules with this object (non-common)
|
|
|
|
+ * class. If more than one class are appended to the query, the
|
|
|
|
+ * rule's class must be one of those appended. (I.e., the rule's
|
|
|
|
+ * class must be a member of the query's classes.) Pass a NULL to
|
|
|
|
+ * clear all classes. Note that this performs straight string
|
|
|
|
+ * comparison, ignoring the regex flag.
|
|
|
|
+
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param t TE rule query to set.
|
|
|
|
+ * @param obj_class Name of object class to add to search set.
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success, negative on error.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a filename trans query to treat the source filename as any. That is,
|
|
|
|
+ * use the same symbol for either source or default of a
|
|
|
|
+ * filename_transition rule. This flag does nothing if the source filename is
|
|
|
|
+ * not set. Note that a filename_transition's target is a type, so thus
|
|
|
|
+ * this flag does not affect its searching.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param r Role trans query to set.
|
|
|
|
+ * @param is_any Non-zero to use source symbol for source or default
|
|
|
|
+ * field, 0 to keep source as only source.
|
|
|
|
+ *
|
|
|
|
+ * @return Always 0.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_any);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Set a filename trans query to use regular expression searching for
|
|
|
|
+ * source, target, and default fields. Strings will be treated as
|
|
|
|
+ * regexes instead of literals. For the target type, matching will
|
|
|
|
+ * occur against the type name or any of its aliases.
|
|
|
|
+ *
|
|
|
|
+ * @param p Policy handler, to report errors.
|
|
|
|
+ * @param r Role trans query to set.
|
|
|
|
+ * @param is_regex Non-zero to enable regex searching, 0 to disable.
|
|
|
|
+ *
|
|
|
|
+ * @return Always 0.
|
|
|
|
+ */
|
|
|
|
+ extern int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_regex);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Render a filename_transition rule to a string.
|
|
|
|
+ *
|
|
|
|
+ * @param policy Policy handler, to report errors.
|
|
|
|
+ * @param rule The rule to render.
|
|
|
|
+ *
|
|
|
|
+ * @return A newly malloc()'d string representation of the rule, or NULL on
|
|
|
|
+ * failure; if the call fails, errno will be set. The caller is responsible
|
|
|
|
+ * for calling free() on the returned string.
|
|
|
|
+ */
|
|
|
|
+ extern char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * rule);
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
diff --git a/libapol/include/apol/policy-query.h b/libapol/include/apol/policy-query.h
|
|
|
|
index 315f70e..665e4cb 100644
|
|
|
|
--- a/libapol/include/apol/policy-query.h
|
|
|
|
+++ b/libapol/include/apol/policy-query.h
|
|
|
|
@@ -71,6 +71,7 @@ extern "C"
|
|
|
|
#include "terule-query.h"
|
|
|
|
#include "condrule-query.h"
|
|
|
|
#include "rbacrule-query.h"
|
|
|
|
+#include "ftrule-query.h"
|
|
|
|
#include "range_trans-query.h"
|
|
|
|
#include "constraint-query.h"
|
|
|
|
|
|
|
|
diff --git a/libapol/src/Makefile.am b/libapol/src/Makefile.am
|
|
|
|
index 3fa4f06..baaa4f6 100644
|
|
|
|
--- a/libapol/src/Makefile.am
|
|
|
|
+++ b/libapol/src/Makefile.am
|
|
|
|
@@ -40,6 +40,7 @@ libapol_a_SOURCES = \
|
|
|
|
render.c \
|
|
|
|
role-query.c \
|
|
|
|
terule-query.c \
|
|
|
|
+ ftrule-query.c \
|
|
|
|
type-query.c \
|
|
|
|
types-relation-analysis.c \
|
|
|
|
user-query.c \
|
|
|
|
diff --git a/libapol/src/ftrule-query.c b/libapol/src/ftrule-query.c
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..dc248de
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libapol/src/ftrule-query.c
|
|
|
|
@@ -0,0 +1,363 @@
|
|
|
|
+/**
|
|
|
|
+ * @file
|
|
|
|
+ *
|
|
|
|
+ * Provides a way for setools to make queries about type enforcement
|
|
|
|
+ * filename_transs within a policy. The caller obtains a query object, fills in
|
|
|
|
+ * its parameters, and then runs the query; it obtains a vector of
|
|
|
|
+ * results. Searches are conjunctive -- all fields of the search
|
|
|
|
+ * query must match for a datum to be added to the results query.
|
|
|
|
+ *
|
|
|
|
+ * @author Jeremy A. Mowery jmowery@tresys.com
|
|
|
|
+ * @author Jason Tang jtang@tresys.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include "policy-query-internal.h"
|
|
|
|
+
|
|
|
|
+#include <errno.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+
|
|
|
|
+struct apol_filename_trans_query
|
|
|
|
+{
|
|
|
|
+ char *source, *target, *default_type, *name;
|
|
|
|
+ apol_vector_t *classes;
|
|
|
|
+ unsigned int flags;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/******************** filename_transition queries ********************/
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * t, apol_vector_t ** v)
|
|
|
|
+{
|
|
|
|
+ apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL;
|
|
|
|
+ int retval = -1, source_as_any = 0, is_regex = 0, append_filename_trans;
|
|
|
|
+ char *bool_name = NULL;
|
|
|
|
+ *v = NULL;
|
|
|
|
+ unsigned int flags = 0;
|
|
|
|
+ qpol_iterator_t *iter = NULL, *type_iter = NULL;
|
|
|
|
+
|
|
|
|
+ if (t != NULL) {
|
|
|
|
+ flags = t->flags;
|
|
|
|
+ is_regex = t->flags & APOL_QUERY_REGEX;
|
|
|
|
+ if (t->source != NULL &&
|
|
|
|
+ (source_list =
|
|
|
|
+ apol_query_create_candidate_type_list(p, t->source, is_regex,
|
|
|
|
+ t->flags & APOL_QUERY_SOURCE_INDIRECT,
|
|
|
|
+ ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
|
|
|
|
+ APOL_QUERY_SOURCE_TYPE))) == NULL) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) {
|
|
|
|
+ default_list = target_list = source_list;
|
|
|
|
+ source_as_any = 1;
|
|
|
|
+ } else {
|
|
|
|
+ if (t->target != NULL &&
|
|
|
|
+ (target_list =
|
|
|
|
+ apol_query_create_candidate_type_list(p, t->target, is_regex,
|
|
|
|
+ t->flags & APOL_QUERY_TARGET_INDIRECT,
|
|
|
|
+ ((t->
|
|
|
|
+ flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE))
|
|
|
|
+ / APOL_QUERY_TARGET_TYPE))) == NULL) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (t->default_type != NULL &&
|
|
|
|
+ (default_list =
|
|
|
|
+ apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0,
|
|
|
|
+ APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (t->classes != NULL &&
|
|
|
|
+ apol_vector_get_size(t->classes) > 0 &&
|
|
|
|
+ (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (qpol_policy_get_filename_trans_iter(p->p, &iter) < 0) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((*v = apol_vector_create(NULL)) == NULL) {
|
|
|
|
+ ERR(p, "%s", strerror(errno));
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
|
|
|
|
+ qpol_filename_trans_t *filename_trans;
|
|
|
|
+ if (qpol_iterator_get_item(iter, (void **)&filename_trans) < 0) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ int match_source = 0, match_target = 0, match_default = 0, match_bool = 0;
|
|
|
|
+ size_t i;
|
|
|
|
+
|
|
|
|
+ if (source_list == NULL) {
|
|
|
|
+ match_source = 1;
|
|
|
|
+ } else {
|
|
|
|
+ const qpol_type_t *source_type;
|
|
|
|
+ if (qpol_filename_trans_get_source_type(p->p, filename_trans, &source_type) < 0) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) {
|
|
|
|
+ match_source = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* if source did not match, but treating source symbol
|
|
|
|
+ * as any field, then delay rejecting this filename_trans until
|
|
|
|
+ * the target and default have been checked */
|
|
|
|
+ if (!source_as_any && !match_source) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (target_list == NULL || (source_as_any && match_source)) {
|
|
|
|
+ match_target = 1;
|
|
|
|
+ } else {
|
|
|
|
+ const qpol_type_t *target_type;
|
|
|
|
+ if (qpol_filename_trans_get_target_type(p->p, filename_trans, &target_type) < 0) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) {
|
|
|
|
+ match_target = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!source_as_any && !match_target) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (default_list == NULL || (source_as_any && match_source) || (source_as_any && match_target)) {
|
|
|
|
+ match_default = 1;
|
|
|
|
+ } else {
|
|
|
|
+ const qpol_type_t *default_type;
|
|
|
|
+ if (qpol_filename_trans_get_default_type(p->p, filename_trans, &default_type) < 0) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (apol_vector_get_index(default_list, default_type, NULL, NULL, &i) == 0) {
|
|
|
|
+ match_default = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!source_as_any && !match_default) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ /* at least one thing must match if source_as_any was given */
|
|
|
|
+ if (source_as_any && (!match_source && !match_target && !match_default)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (class_list != NULL) {
|
|
|
|
+ const qpol_class_t *obj_class;
|
|
|
|
+ if (qpol_filename_trans_get_object_class(p->p, filename_trans, &obj_class) < 0) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (apol_vector_append(*v, filename_trans)) {
|
|
|
|
+ ERR(p, "%s", strerror(ENOMEM));
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ retval = 0;
|
|
|
|
+ cleanup:
|
|
|
|
+ if (retval != 0) {
|
|
|
|
+ apol_vector_destroy(v);
|
|
|
|
+ }
|
|
|
|
+ apol_vector_destroy(&source_list);
|
|
|
|
+ if (!source_as_any) {
|
|
|
|
+ apol_vector_destroy(&target_list);
|
|
|
|
+ apol_vector_destroy(&default_list);
|
|
|
|
+ }
|
|
|
|
+ apol_vector_destroy(&class_list);
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+apol_filename_trans_query_t *apol_filename_trans_query_create(void)
|
|
|
|
+{
|
|
|
|
+ apol_filename_trans_query_t *t = calloc(1, sizeof(apol_filename_trans_query_t));
|
|
|
|
+ if (t != NULL) {
|
|
|
|
+ t->flags =
|
|
|
|
+ (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE |
|
|
|
|
+ APOL_QUERY_TARGET_ATTRIBUTE);
|
|
|
|
+ }
|
|
|
|
+ return t;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r)
|
|
|
|
+{
|
|
|
|
+ if (r != NULL && *r != NULL) {
|
|
|
|
+ free((*r)->source);
|
|
|
|
+ free((*r)->target);
|
|
|
|
+ free((*r)->default_type);
|
|
|
|
+ free((*r)->name);
|
|
|
|
+ free(*r);
|
|
|
|
+ *r = NULL;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename, int is_indirect)
|
|
|
|
+{
|
|
|
|
+ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
|
|
|
|
+ return apol_query_set(p, &t->source, NULL, filename);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *type, int is_indirect)
|
|
|
|
+{
|
|
|
|
+ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
|
|
|
|
+ return apol_query_set(p, &t->target, NULL, type);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol)
|
|
|
|
+{
|
|
|
|
+ return apol_query_set(p, &t->default_type, NULL, symbol);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class)
|
|
|
|
+{
|
|
|
|
+ char *s = NULL;
|
|
|
|
+ if (obj_class == NULL) {
|
|
|
|
+ apol_vector_destroy(&t->classes);
|
|
|
|
+ } else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL)
|
|
|
|
+ || apol_vector_append(t->classes, s) < 0) {
|
|
|
|
+ ERR(p, "%s", strerror(errno));
|
|
|
|
+ free(s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_name(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename)
|
|
|
|
+{
|
|
|
|
+ return apol_query_set(p, &t->name, NULL, filename);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_any)
|
|
|
|
+{
|
|
|
|
+ return apol_query_set_flag(p, &t->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_regex)
|
|
|
|
+{
|
|
|
|
+ return apol_query_set_regex(p, &t->flags, is_regex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * filename_trans)
|
|
|
|
+{
|
|
|
|
+ char *tmp = NULL;
|
|
|
|
+ const char *tmp_name = NULL;
|
|
|
|
+ const char *filename_trans_type_str;
|
|
|
|
+ int error = 0;
|
|
|
|
+ size_t tmp_sz = 0;
|
|
|
|
+ uint32_t filename_trans_type = 0;
|
|
|
|
+ const qpol_type_t *type = NULL;
|
|
|
|
+ const qpol_class_t *obj_class = NULL;
|
|
|
|
+
|
|
|
|
+ if (!policy || !filename_trans) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* source type */
|
|
|
|
+ if (qpol_filename_trans_get_source_type(policy->p, filename_trans, &type)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (qpol_type_get_name(policy->p, type, &tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, "transition_type %s ", tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* target type */
|
|
|
|
+ if (qpol_filename_trans_get_target_type(policy->p, filename_trans, &type)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (qpol_type_get_name(policy->p, type, &tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, "%s : ", tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* object class */
|
|
|
|
+ if (qpol_filename_trans_get_object_class(policy->p, filename_trans, &obj_class)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, "%s ", tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* default type */
|
|
|
|
+ if (qpol_filename_trans_get_default_type(policy->p, filename_trans, &type)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (qpol_type_get_name(policy->p, type, &tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, "%s", tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (qpol_filename_trans_get_filename(policy->p, filename_trans, &tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, " %s", tmp_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (apol_str_appendf(&tmp, &tmp_sz, ";")) {
|
|
|
|
+ error = errno;
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ return tmp;
|
|
|
|
+
|
|
|
|
+ err:
|
|
|
|
+ free(tmp);
|
|
|
|
+ errno = error;
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
diff --git a/libapol/src/libapol.map b/libapol/src/libapol.map
|
|
|
|
index 4894374..7657a2d 100644
|
|
|
|
--- a/libapol/src/libapol.map
|
|
|
|
+++ b/libapol/src/libapol.map
|
|
|
|
@@ -34,6 +34,7 @@ VERS_4.0{
|
|
|
|
apol_protocol_to_str;
|
|
|
|
apol_qpol_context_render;
|
|
|
|
apol_range_trans_*;
|
|
|
|
+ apol_filename_trans_*;
|
|
|
|
apol_relabel_*;
|
|
|
|
apol_role_*;
|
|
|
|
apol_role_allow_*;
|
|
|
|
diff --git a/libqpol/include/qpol/ftrule_query.h b/libqpol/include/qpol/ftrule_query.h
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..1f533a4
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libqpol/include/qpol/ftrule_query.h
|
|
|
|
@@ -0,0 +1,116 @@
|
|
|
|
+/**
|
|
|
|
+ * @file
|
|
|
|
+ * Defines public interface for iterating over FTRULE rules.
|
|
|
|
+ *
|
|
|
|
+ * @author Kevin Carr kcarr@tresys.com
|
|
|
|
+ * @author Jeremy A. Mowery jmowery@tresys.com
|
|
|
|
+ * @author Jason Tang jtang@tresys.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#ifndef QPOL_FTRULERULE_QUERY
|
|
|
|
+#define QPOL_FTRULERULE_QUERY
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+extern "C"
|
|
|
|
+{
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#include <qpol/policy.h>
|
|
|
|
+#include <qpol/iterator.h>
|
|
|
|
+
|
|
|
|
+ typedef struct qpol_filename_trans qpol_filename_trans_t;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get an iterator over all filename transition rules in the policy.
|
|
|
|
+ * @param policy Policy from which to create the iterator.
|
|
|
|
+ * @param iter Iterator over items of type qpol_filename_trans_t returned.
|
|
|
|
+ * The caller is responsible for calling qpol_iterator_destroy()
|
|
|
|
+ * to free memory used by this iterator.
|
|
|
|
+ * It is important to note that this iterator is only valid as long as
|
|
|
|
+ * the policy is unmodifed.
|
|
|
|
+ * @returm 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *iter will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get the source type from a filename transition rule.
|
|
|
|
+ * @param policy The policy from which the rule comes.
|
|
|
|
+ * @param rule The rule from which to get the source type.
|
|
|
|
+ * @param source Pointer in which to store the source type.
|
|
|
|
+ * The caller should not free this pointer.
|
|
|
|
+ * @return 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *source will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const qpol_type_t ** source);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get the target type from a filename transition rule.
|
|
|
|
+ * @param policy The policy from which the rule comes.
|
|
|
|
+ * @param rule The rule from which to get the target type.
|
|
|
|
+ * @param target Pointer in which to store the target type.
|
|
|
|
+ * The caller should not free this pointer.
|
|
|
|
+ * @return 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *target will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const qpol_type_t ** target);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get the default type from a type rule.
|
|
|
|
+ * @param policy Policy from which the rule comes.
|
|
|
|
+ * @param rule The rule from which to get the default type.
|
|
|
|
+ * @param dflt Pointer in which to store the default type.
|
|
|
|
+ * The caller should not free this pointer.
|
|
|
|
+ * @returm 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *dflt will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const qpol_type_t ** dflt);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get the object class from a type rule.
|
|
|
|
+ * @param policy Policy from which the rule comes.
|
|
|
|
+ * @param rule The rule from which to get the object class.
|
|
|
|
+ * @param obj_class Pointer in which to store the object class.
|
|
|
|
+ * The caller should not free this pointer.
|
|
|
|
+ * @returm 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *obj_class will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const qpol_class_t ** obj_class);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Get the transition filename type from a type rule.
|
|
|
|
+ * @param policy Policy from which the rule comes.
|
|
|
|
+ * @param rule The rule from which to get the transition filename.
|
|
|
|
+ * @param target Pointer in which to store the transition filename.
|
|
|
|
+ * The caller should not free this pointer.
|
|
|
|
+ * @returm 0 on success and < 0 on failure; if the call fails,
|
|
|
|
+ * errno will be set and *target will be NULL.
|
|
|
|
+ */
|
|
|
|
+ extern int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const char ** name);
|
|
|
|
+
|
|
|
|
+#ifdef __cplusplus
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#endif /* QPOL_FTRULERULE_QUERY */
|
|
|
|
diff --git a/libqpol/include/qpol/policy.h b/libqpol/include/qpol/policy.h
|
|
|
|
index ae4ea08..bf85718 100644
|
|
|
|
--- a/libqpol/include/qpol/policy.h
|
|
|
|
+++ b/libqpol/include/qpol/policy.h
|
|
|
|
@@ -55,6 +55,7 @@ extern "C"
|
|
|
|
#include <qpol/polcap_query.h>
|
|
|
|
#include <qpol/portcon_query.h>
|
|
|
|
#include <qpol/rbacrule_query.h>
|
|
|
|
+#include <qpol/ftrule_query.h>
|
|
|
|
#include <qpol/role_query.h>
|
|
|
|
#include <qpol/syn_rule_query.h>
|
|
|
|
#include <qpol/terule_query.h>
|
|
|
|
diff --git a/libqpol/src/Makefile.am b/libqpol/src/Makefile.am
|
|
|
|
index 34d87a6..0889a61 100644
|
|
|
|
--- a/libqpol/src/Makefile.am
|
|
|
|
+++ b/libqpol/src/Makefile.am
|
|
|
|
@@ -48,6 +48,7 @@ libqpol_a_SOURCES = \
|
|
|
|
syn_rule_internal.h \
|
|
|
|
syn_rule_query.c \
|
|
|
|
terule_query.c \
|
|
|
|
+ ftrule_query.c \
|
|
|
|
type_query.c \
|
|
|
|
user_query.c \
|
|
|
|
util.c \
|
|
|
|
diff --git a/libqpol/src/ftrule_query.c b/libqpol/src/ftrule_query.c
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000..d6db848
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/libqpol/src/ftrule_query.c
|
|
|
|
@@ -0,0 +1,277 @@
|
|
|
|
+/**
|
|
|
|
+ * @file
|
|
|
|
+ * Defines public interface for iterating over RBAC rules.
|
|
|
|
+ *
|
|
|
|
+ * @author Jeremy A. Mowery jmowery@tresys.com
|
|
|
|
+ * @author Jason Tang jtang@tresys.com
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2006-2007 Tresys Technology, LLC
|
|
|
|
+ *
|
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
+ * Lesser General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
|
+ * License along with this library; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include <qpol/iterator.h>
|
|
|
|
+#include <qpol/policy.h>
|
|
|
|
+#include <qpol/ftrule_query.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include "iterator_internal.h"
|
|
|
|
+#include "qpol_internal.h"
|
|
|
|
+#include <sepol/policydb/policydb.h>
|
|
|
|
+
|
|
|
|
+typedef struct filename_trans_state
|
|
|
|
+{
|
|
|
|
+ filename_trans_t *head;
|
|
|
|
+ filename_trans_t *cur;
|
|
|
|
+} filename_trans_state_t;
|
|
|
|
+
|
|
|
|
+static int filename_trans_state_end(const qpol_iterator_t * iter)
|
|
|
|
+{
|
|
|
|
+ filename_trans_state_t *fts = NULL;
|
|
|
|
+
|
|
|
|
+ if (!iter || !(fts = qpol_iterator_state(iter))) {
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return fts->cur ? 0 : 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void *filename_trans_state_get_cur(const qpol_iterator_t * iter)
|
|
|
|
+{
|
|
|
|
+ filename_trans_state_t *fts = NULL;
|
|
|
|
+ const policydb_t *db = NULL;
|
|
|
|
+
|
|
|
|
+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter)) || filename_trans_state_end(iter)) {
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return fts->cur;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int filename_trans_state_next(qpol_iterator_t * iter)
|
|
|
|
+{
|
|
|
|
+ filename_trans_state_t *fts = NULL;
|
|
|
|
+ const policydb_t *db = NULL;
|
|
|
|
+
|
|
|
|
+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) {
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (filename_trans_state_end(iter)) {
|
|
|
|
+ errno = ERANGE;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fts->cur = fts->cur->next;
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static size_t filename_trans_state_size(const qpol_iterator_t * iter)
|
|
|
|
+{
|
|
|
|
+ filename_trans_state_t *fts = NULL;
|
|
|
|
+ const policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *tmp = NULL;
|
|
|
|
+ size_t count = 0;
|
|
|
|
+
|
|
|
|
+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) {
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (tmp = fts->head; tmp; tmp = tmp->next)
|
|
|
|
+ count++;
|
|
|
|
+
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_state_t *fts = NULL;
|
|
|
|
+ int error = 0;
|
|
|
|
+
|
|
|
|
+ if (iter)
|
|
|
|
+ *iter = NULL;
|
|
|
|
+
|
|
|
|
+ if (!policy || !iter) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+
|
|
|
|
+ fts = calloc(1, sizeof(filename_trans_state_t));
|
|
|
|
+ if (!fts) {
|
|
|
|
+ /* errno set by calloc */
|
|
|
|
+ ERR(policy, "%s", strerror(errno));
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+ fts->head = fts->cur = db->filename_trans;
|
|
|
|
+
|
|
|
|
+ if (qpol_iterator_create
|
|
|
|
+ (policy, (void *)fts, filename_trans_state_get_cur, filename_trans_state_next, filename_trans_state_end, filename_trans_state_size,
|
|
|
|
+ free, iter)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ free(fts);
|
|
|
|
+ errno = error;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** source)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (source) {
|
|
|
|
+ *source = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !source) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *source = (qpol_type_t *) db->type_val_to_struct[ft->stype - 1];
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** target)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (target) {
|
|
|
|
+ *target = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !target) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *target = (qpol_type_t *) db->type_val_to_struct[ft->ttype - 1];
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule,
|
|
|
|
+ const qpol_class_t ** obj_class)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (obj_class) {
|
|
|
|
+ *obj_class = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !obj_class) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *obj_class = (qpol_class_t *) db->class_val_to_struct[ft->tclass - 1];
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_trans_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** output_type)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (output_type) {
|
|
|
|
+ *output_type = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !output_type) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *output_type = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1];
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** dflt)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (dflt) {
|
|
|
|
+ *dflt = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !dflt) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *dflt = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1];
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name)
|
|
|
|
+{
|
|
|
|
+ policydb_t *db = NULL;
|
|
|
|
+ filename_trans_t *ft = NULL;
|
|
|
|
+
|
|
|
|
+ if (name) {
|
|
|
|
+ *name = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!policy || !rule || !name) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return STATUS_ERR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ db = &policy->p->p;
|
|
|
|
+ ft = (filename_trans_t *) rule;
|
|
|
|
+
|
|
|
|
+ *name = ft->name;
|
|
|
|
+
|
|
|
|
+ return STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
diff --git a/libqpol/src/libqpol.map b/libqpol/src/libqpol.map
|
|
|
|
index dd293bc..6973cca 100644
|
|
|
|
--- a/libqpol/src/libqpol.map
|
|
|
|
+++ b/libqpol/src/libqpol.map
|
|
|
|
@@ -34,6 +34,7 @@ VERS_1.2 {
|
|
|
|
qpol_policy_reevaluate_conds;
|
|
|
|
qpol_portcon_*;
|
|
|
|
qpol_range_trans_*;
|
|
|
|
+ qpol_filename_trans_*;
|
|
|
|
qpol_role_*;
|
|
|
|
qpol_syn_avrule_*;
|
|
|
|
qpol_syn_terule_*;
|
|
|
|
diff --git a/libqpol/src/module_compiler.c b/libqpol/src/module_compiler.c
|
|
|
|
index dc19798..b06e285 100644
|
|
|
|
--- a/libqpol/src/module_compiler.c
|
|
|
|
+++ b/libqpol/src/module_compiler.c
|
|
|
|
@@ -1247,6 +1247,18 @@ void append_role_allow(role_allow_rule_t * role_allow_rules)
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this doesn't actually append, but really prepends it */
|
|
|
|
+void append_filename_trans(filename_trans_rule_t * filename_trans_rules)
|
|
|
|
+{
|
|
|
|
+ avrule_decl_t *decl = stack_top->decl;
|
|
|
|
+
|
|
|
|
+ /* filename transitions are not allowed within conditionals */
|
|
|
|
+ assert(stack_top->type == 1);
|
|
|
|
+
|
|
|
|
+ filename_trans_rules->next = decl->filename_trans_rules;
|
|
|
|
+ decl->filename_trans_rules = filename_trans_rules;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* this doesn't actually append, but really prepends it */
|
|
|
|
void append_range_trans(range_trans_rule_t * range_tr_rules)
|
|
|
|
{
|
|
|
|
avrule_decl_t *decl = stack_top->decl;
|
|
|
|
diff --git a/libqpol/src/policy_define.c b/libqpol/src/policy_define.c
|
|
|
|
index c94f7aa..0f3a45a 100644
|
|
|
|
--- a/libqpol/src/policy_define.c
|
|
|
|
+++ b/libqpol/src/policy_define.c
|
|
|
|
@@ -2133,7 +2133,7 @@ int define_role_trans(void)
|
|
|
|
|
|
|
|
/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
|
|
|
|
#ifdef HAVE_SEPOL_USER_ROLE_MAPPING
|
|
|
|
- if (role_set_expand(&roles, &e_roles, policydbp, NULL))
|
|
|
|
+ if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
|
|
|
|
#else
|
|
|
|
if (role_set_expand(&roles, &e_roles, policydbp))
|
|
|
|
#endif
|
|
|
|
@@ -2226,6 +2226,190 @@ int define_role_allow(void)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+avrule_t *define_cond_filename_trans(void)
|
|
|
|
+{
|
|
|
|
+ yyerror("type transitions with a filename not allowed inside "
|
|
|
|
+ "conditionals\n");
|
|
|
|
+ return COND_ERR;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int define_filename_trans(void)
|
|
|
|
+{
|
|
|
|
+ char *id, *name = NULL;
|
|
|
|
+ type_set_t stypes, ttypes;
|
|
|
|
+ ebitmap_t e_stypes, e_ttypes;
|
|
|
|
+ ebitmap_t e_tclasses;
|
|
|
|
+ ebitmap_node_t *snode, *tnode, *cnode;
|
|
|
|
+ filename_trans_t *ft;
|
|
|
|
+ filename_trans_rule_t *ftr;
|
|
|
|
+ class_datum_t *cladatum;
|
|
|
|
+ type_datum_t *typdatum;
|
|
|
|
+ uint32_t otype;
|
|
|
|
+ unsigned int c, s, t;
|
|
|
|
+ int add;
|
|
|
|
+
|
|
|
|
+ if (pass == 1) {
|
|
|
|
+ /* stype */
|
|
|
|
+ while ((id = queue_remove(id_queue)))
|
|
|
|
+ free(id);
|
|
|
|
+ /* ttype */
|
|
|
|
+ while ((id = queue_remove(id_queue)))
|
|
|
|
+ free(id);
|
|
|
|
+ /* tclass */
|
|
|
|
+ while ((id = queue_remove(id_queue)))
|
|
|
|
+ free(id);
|
|
|
|
+ /* otype */
|
|
|
|
+ id = queue_remove(id_queue);
|
|
|
|
+ free(id);
|
|
|
|
+ /* name */
|
|
|
|
+ id = queue_remove(id_queue);
|
|
|
|
+ free(id);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ add = 1;
|
|
|
|
+ type_set_init(&stypes);
|
|
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
|
|
+ if (set_types(&stypes, id, &add, 0))
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ add =1;
|
|
|
|
+ type_set_init(&ttypes);
|
|
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
|
|
+ if (set_types(&ttypes, id, &add, 0))
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ebitmap_init(&e_tclasses);
|
|
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
|
|
+ if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
|
|
+ yyerror2("class %s is not within scope", id);
|
|
|
|
+ free(id);
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
|
|
+ if (!cladatum) {
|
|
|
|
+ yyerror2("unknown class %s", id);
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ if (ebitmap_set_bit(&e_tclasses, cladatum->s.value - 1, TRUE)) {
|
|
|
|
+ yyerror("Out of memory");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ free(id);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ id = (char *)queue_remove(id_queue);
|
|
|
|
+ if (!id) {
|
|
|
|
+ yyerror("no otype in transition definition?");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
|
|
+ yyerror2("type %s is not within scope", id);
|
|
|
|
+ free(id);
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ typdatum = hashtab_search(policydbp->p_types.table, id);
|
|
|
|
+ if (!typdatum) {
|
|
|
|
+ yyerror2("unknown type %s used in transition definition", id);
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ free(id);
|
|
|
|
+ otype = typdatum->s.value;
|
|
|
|
+
|
|
|
|
+ name = queue_remove(id_queue);
|
|
|
|
+ if (!name) {
|
|
|
|
+ yyerror("no pathname specified in filename_trans definition?");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* We expand the class set into seperate rules. We expand the types
|
|
|
|
+ * just to make sure there are not duplicates. They will get turned
|
|
|
|
+ * into seperate rules later */
|
|
|
|
+ ebitmap_init(&e_stypes);
|
|
|
|
+ if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
|
|
|
|
+ goto bad;
|
|
|
|
+
|
|
|
|
+ ebitmap_init(&e_ttypes);
|
|
|
|
+ if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
|
|
|
|
+ goto bad;
|
|
|
|
+
|
|
|
|
+ ebitmap_for_each_bit(&e_tclasses, cnode, c) {
|
|
|
|
+ if (!ebitmap_node_get_bit(cnode, c))
|
|
|
|
+ continue;
|
|
|
|
+ ebitmap_for_each_bit(&e_stypes, snode, s) {
|
|
|
|
+ if (!ebitmap_node_get_bit(snode, s))
|
|
|
|
+ continue;
|
|
|
|
+ ebitmap_for_each_bit(&e_ttypes, tnode, t) {
|
|
|
|
+ if (!ebitmap_node_get_bit(tnode, t))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ for (ft = policydbp->filename_trans; ft; ft = ft->next) {
|
|
|
|
+ if (ft->stype == (s + 1) &&
|
|
|
|
+ ft->ttype == (t + 1) &&
|
|
|
|
+ ft->tclass == (c + 1) &&
|
|
|
|
+ !strcmp(ft->name, name)) {
|
|
|
|
+ yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
|
|
|
|
+ name,
|
|
|
|
+ policydbp->p_type_val_to_name[s],
|
|
|
|
+ policydbp->p_type_val_to_name[t],
|
|
|
|
+ policydbp->p_class_val_to_name[c]);
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ft = malloc(sizeof(*ft));
|
|
|
|
+ if (!ft) {
|
|
|
|
+ yyerror("out of memory");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ memset(ft, 0, sizeof(*ft));
|
|
|
|
+
|
|
|
|
+ ft->next = policydbp->filename_trans;
|
|
|
|
+ policydbp->filename_trans = ft;
|
|
|
|
+
|
|
|
|
+ ft->name = strdup(name);
|
|
|
|
+ if (!ft->name) {
|
|
|
|
+ yyerror("out of memory");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ ft->stype = s + 1;
|
|
|
|
+ ft->ttype = t + 1;
|
|
|
|
+ ft->tclass = c + 1;
|
|
|
|
+ ft->otype = otype;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Now add the real rule since we didn't find any duplicates */
|
|
|
|
+ ftr = malloc(sizeof(*ftr));
|
|
|
|
+ if (!ftr) {
|
|
|
|
+ yyerror("out of memory");
|
|
|
|
+ goto bad;
|
|
|
|
+ }
|
|
|
|
+ filename_trans_rule_init(ftr);
|
|
|
|
+ append_filename_trans(ftr);
|
|
|
|
+
|
|
|
|
+ ftr->name = strdup(name);
|
|
|
|
+ ftr->stypes = stypes;
|
|
|
|
+ ftr->ttypes = ttypes;
|
|
|
|
+ ftr->tclass = c + 1;
|
|
|
|
+ ftr->otype = otype;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ free(name);
|
|
|
|
+ ebitmap_destroy(&e_stypes);
|
|
|
|
+ ebitmap_destroy(&e_ttypes);
|
|
|
|
+ ebitmap_destroy(&e_tclasses);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+bad:
|
|
|
|
+ free(name);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
|
|
|
|
{
|
|
|
|
constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
|
|
|
|
diff --git a/libqpol/src/policy_parse.y b/libqpol/src/policy_parse.y
|
|
|
|
index 84f4114..dc16c6f 100644
|
|
|
|
--- a/libqpol/src/policy_parse.y
|
|
|
|
+++ b/libqpol/src/policy_parse.y
|
|
|
|
@@ -98,6 +98,7 @@ extern char *qpol_src_inputlim;/* end of data */
|
|
|
|
%type <require_func> require_decl_def
|
|
|
|
|
|
|
|
%token PATH
|
|
|
|
+%token FILENAME
|
|
|
|
%token CLONE
|
|
|
|
%token COMMON
|
|
|
|
%token CLASS
|
|
|
|
@@ -360,7 +361,10 @@ cond_rule_def : cond_transition_def
|
|
|
|
| require_block
|
|
|
|
{ $$ = NULL; }
|
|
|
|
;
|
|
|
|
-cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';'
|
|
|
|
+cond_transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
|
|
|
|
+ { $$ = define_cond_filename_trans() ;
|
|
|
|
+ if ($$ == COND_ERR) return -1;}
|
|
|
|
+ | TYPE_TRANSITION names names ':' names identifier ';'
|
|
|
|
{ $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
|
|
|
|
if ($$ == COND_ERR) return -1;}
|
|
|
|
| TYPE_MEMBER names names ':' names identifier ';'
|
|
|
|
@@ -395,7 +399,9 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
|
|
|
|
{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
|
|
|
|
if ($$ == COND_ERR) return -1; }
|
|
|
|
;
|
|
|
|
-transition_def : TYPE_TRANSITION names names ':' names identifier ';'
|
|
|
|
+transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
|
|
|
|
+ {if (define_filename_trans()) return -1; }
|
|
|
|
+ | TYPE_TRANSITION names names ':' names identifier ';'
|
|
|
|
{if (define_compute_type(AVRULE_TRANSITION)) return -1;}
|
|
|
|
| TYPE_MEMBER names names ':' names identifier ';'
|
|
|
|
{if (define_compute_type(AVRULE_MEMBER)) return -1;}
|
|
|
|
@@ -752,6 +758,9 @@ identifier : IDENTIFIER
|
|
|
|
path : PATH
|
|
|
|
{ if (insert_id(yytext,0)) return -1; }
|
|
|
|
;
|
|
|
|
+filename : FILENAME
|
|
|
|
+ { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
|
|
|
|
+ ;
|
|
|
|
number : NUMBER
|
|
|
|
{ $$ = strtoul(yytext,NULL,0); }
|
|
|
|
;
|
|
|
|
diff --git a/libqpol/src/policy_scan.l b/libqpol/src/policy_scan.l
|
|
|
|
index 75485f3..30203cd 100644
|
|
|
|
--- a/libqpol/src/policy_scan.l
|
|
|
|
+++ b/libqpol/src/policy_scan.l
|
|
|
|
@@ -235,6 +235,7 @@ POLICYCAP { return(POLICYCAP); }
|
|
|
|
permissive |
|
|
|
|
PERMISSIVE { return(PERMISSIVE); }
|
|
|
|
"/"({alnum}|[_\.\-/])* { return(PATH); }
|
|
|
|
+\"({alnum}|[_\.\-])+\" { return(FILENAME); }
|
|
|
|
{letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); }
|
|
|
|
{digit}+|0x{hexval}+ { return(NUMBER); }
|
|
|
|
{digit}{1,3}(\.{digit}{1,3}){3} { return(IPV4_ADDR); }
|
|
|
|
diff --git a/secmds/sesearch.c b/secmds/sesearch.c
|
|
|
|
index ec0315f..e44b3bc 100644
|
|
|
|
--- a/secmds/sesearch.c
|
|
|
|
+++ b/secmds/sesearch.c
|
|
|
|
@@ -575,6 +575,95 @@ static void print_te_results(const apol_policy_t * policy, const options_t * opt
|
|
|
|
free(expr);
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
|
|
|
|
+{
|
|
|
|
+ apol_filename_trans_query_t *ftq = NULL;
|
|
|
|
+ int error = 0;
|
|
|
|
+
|
|
|
|
+ if (!policy || !opt || !v) {
|
|
|
|
+ ERR(policy, "%s", strerror(EINVAL));
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!opt->type == QPOL_RULE_TYPE_TRANS && !opt->all) {
|
|
|
|
+ *v = NULL;
|
|
|
|
+ return 0; /* no search to do */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ftq = apol_filename_trans_query_create();
|
|
|
|
+ if (!ftq) {
|
|
|
|
+ ERR(policy, "%s", strerror(ENOMEM));
|
|
|
|
+ errno = ENOMEM;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ apol_filename_trans_query_set_regex(policy, ftq, opt->useregex);
|
|
|
|
+ if (opt->src_name) {
|
|
|
|
+ if (apol_filename_trans_query_set_source(policy, ftq, opt->src_name)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (opt->tgt_name) {
|
|
|
|
+ if (apol_filename_trans_query_set_target(policy, ftq, opt->tgt_name, opt->indirect)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (apol_filename_trans_get_by_query(policy, ftq, v)) {
|
|
|
|
+ error = errno;
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ apol_filename_trans_query_destroy(&ftq);
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ err:
|
|
|
|
+ apol_vector_destroy(v);
|
|
|
|
+ apol_filename_trans_query_destroy(&ftq);
|
|
|
|
+ ERR(policy, "%s", strerror(error));
|
|
|
|
+ errno = error;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void print_ft_results(const apol_policy_t * policy, const options_t * opt, const apol_vector_t * v)
|
|
|
|
+{
|
|
|
|
+ qpol_policy_t *q = apol_policy_get_qpol(policy);
|
|
|
|
+ size_t i, num_rules = 0;
|
|
|
|
+ const qpol_filename_trans_t *rule = NULL;
|
|
|
|
+ char *tmp = NULL, *rule_str = NULL, *expr = NULL;
|
|
|
|
+ char enable_char = ' ', branch_char = ' ';
|
|
|
|
+ qpol_iterator_t *iter = NULL;
|
|
|
|
+ const qpol_cond_t *cond = NULL;
|
|
|
|
+ uint32_t enabled = 0, list = 0;
|
|
|
|
+
|
|
|
|
+ if (!(num_rules = apol_vector_get_size(v)))
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+ fprintf(stdout, "Found %zd named file transition rules:\n", num_rules);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < num_rules; i++) {
|
|
|
|
+ enable_char = branch_char = ' ';
|
|
|
|
+ if (!(rule = apol_vector_get_element(v, i)))
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+ if (!(rule_str = apol_filename_trans_render(policy, rule)))
|
|
|
|
+ goto cleanup;
|
|
|
|
+ fprintf(stdout, "%s %s\n", rule_str, expr ? expr : "");
|
|
|
|
+ free(rule_str);
|
|
|
|
+ rule_str = NULL;
|
|
|
|
+ free(expr);
|
|
|
|
+ expr = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cleanup:
|
|
|
|
+ free(tmp);
|
|
|
|
+ free(rule_str);
|
|
|
|
+ free(expr);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int perform_ra_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
|
|
|
|
{
|
|
|
|
apol_role_allow_query_t *raq = NULL;
|
|
|
|
@@ -1128,6 +1217,18 @@ int main(int argc, char **argv)
|
|
|
|
print_te_results(policy, &cmd_opts, v);
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ if (cmd_opts.all || cmd_opts.type == QPOL_RULE_TYPE_TRANS) {
|
|
|
|
+ apol_vector_destroy(&v);
|
|
|
|
+ if (perform_ft_query(policy, &cmd_opts, &v)) {
|
|
|
|
+ rt = 1;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ print_ft_results(policy, &cmd_opts, v);
|
|
|
|
+ fprintf(stdout, "\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
apol_vector_destroy(&v);
|
|
|
|
if (perform_ra_query(policy, &cmd_opts, &v)) {
|
|
|
|
rt = 1;
|
|
|
|
--
|
|
|
|
1.7.6.2
|
|
|
|
|
2011-10-26 20:58:38 +00:00
|
|
|
diff -up setools-3.3.7/libapol/include/apol/Makefile.am.filenametrans setools-3.3.7/libapol/include/apol/Makefile.am
|
|
|
|
--- setools-3.3.7/libapol/include/apol/Makefile.am.filenametrans 2009-07-14 14:03:27.000000000 -0400
|
|
|
|
+++ setools-3.3.7/libapol/include/apol/Makefile.am 2011-10-26 16:24:59.948130442 -0400
|
|
|
|
@@ -27,6 +27,7 @@ apol_HEADERS = \
|
|
|
|
relabel-analysis.h \
|
|
|
|
render.h \
|
|
|
|
role-query.h \
|
|
|
|
+ ftrule-query.h \
|
|
|
|
terule-query.h \
|
|
|
|
type-query.h \
|
|
|
|
types-relation-analysis.h \
|
|
|
|
diff -up setools-3.3.7/libapol/include/apol/Makefile.in.filenametrans setools-3.3.7/libapol/include/apol/Makefile.in
|
|
|
|
--- setools-3.3.7/libapol/include/apol/Makefile.in.filenametrans 2010-05-12 10:01:06.000000000 -0400
|
|
|
|
+++ setools-3.3.7/libapol/include/apol/Makefile.in 2011-10-26 16:25:07.834107745 -0400
|
|
|
|
@@ -378,6 +378,7 @@ apol_HEADERS = \
|
|
|
|
relabel-analysis.h \
|
|
|
|
render.h \
|
|
|
|
role-query.h \
|
|
|
|
+ ftrule-query.h \
|
|
|
|
terule-query.h \
|
|
|
|
type-query.h \
|
|
|
|
types-relation-analysis.h \
|
|
|
|
diff -up setools-3.3.7/libqpol/include/qpol/Makefile.am.filenametrans setools-3.3.7/libqpol/include/qpol/Makefile.am
|
|
|
|
--- setools-3.3.7/libqpol/include/qpol/Makefile.am.filenametrans 2011-10-26 16:22:28.723523155 -0400
|
|
|
|
+++ setools-3.3.7/libqpol/include/qpol/Makefile.am 2011-10-26 16:22:41.283493767 -0400
|
|
|
|
@@ -25,6 +25,7 @@ qpol_HEADERS = \
|
|
|
|
role_query.h \
|
|
|
|
syn_rule_query.h \
|
|
|
|
terule_query.h \
|
|
|
|
+ ftrule_query.h \
|
|
|
|
type_query.h \
|
|
|
|
user_query.h \
|
|
|
|
util.h
|
|
|
|
diff -up setools-3.3.7/libqpol/include/qpol/Makefile.in.filenametrans setools-3.3.7/libqpol/include/qpol/Makefile.in
|
|
|
|
--- setools-3.3.7/libqpol/include/qpol/Makefile.in.filenametrans 2010-05-12 10:01:07.000000000 -0400
|
|
|
|
+++ setools-3.3.7/libqpol/include/qpol/Makefile.in 2011-10-26 16:22:56.375457650 -0400
|
|
|
|
@@ -376,6 +376,7 @@ qpol_HEADERS = \
|
|
|
|
role_query.h \
|
|
|
|
syn_rule_query.h \
|
|
|
|
terule_query.h \
|
|
|
|
+ ftrule_query.h \
|
|
|
|
type_query.h \
|
|
|
|
user_query.h \
|
|
|
|
util.h
|