summaryrefslogtreecommitdiffstats
path: root/libsefs/include/sefs/fclist.hh
diff options
context:
space:
mode:
Diffstat (limited to 'libsefs/include/sefs/fclist.hh')
-rw-r--r--libsefs/include/sefs/fclist.hh323
1 files changed, 323 insertions, 0 deletions
diff --git a/libsefs/include/sefs/fclist.hh b/libsefs/include/sefs/fclist.hh
new file mode 100644
index 0000000..63eeeba
--- /dev/null
+++ b/libsefs/include/sefs/fclist.hh
@@ -0,0 +1,323 @@
+/**
+ * @file
+ * Defines the public interface for the file context list abstract
+ * object. A user must call a constructor for one of sefs_fcfile_t,
+ * sefs_db_t, or sefs_filesystem_t to create a sefs_fclist_t object.
+ *
+ * @author Jeremy A. Mowery jmowery@tresys.com
+ * @author Jason Tang jtang@tresys.com
+ *
+ * Copyright (C) 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 SEFS_FCLIST_H
+#define SEFS_FCLIST_H
+
+#include <sefs/entry.hh>
+#include <sefs/query.hh>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <selinux/selinux.h>
+#include <stdarg.h>
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#include <apol/policy.h>
+
+#define SEFS_MSG_ERR 1 /*!< Message describes a fatal error. */
+#define SEFS_MSG_WARN 2 /*!< Message is issued as a warning but does not represent a fatal error. */
+#define SEFS_MSG_INFO 3 /*!< Message is issued for inormational reasons and does not represent an atypical state. */
+
+ struct sefs_fclist;
+
+ typedef void (*sefs_callback_fn_t) (void *varg, const struct sefs_fclist * fclist, int level, const char *fmt,
+ va_list argp);
+
+/**
+ * Possible types of fclist for use with sefs_fclist_get_data().
+ */
+ typedef enum sefs_fclist_type
+ {
+ SEFS_FCLIST_TYPE_NONE = 0, /*!< Not an actual type, used for error conditions */
+ SEFS_FCLIST_TYPE_FILESYSTEM, /*!< get_data returns sefs_filesystem_t, a representation of a file system */
+ SEFS_FCLIST_TYPE_FCFILE, /*!< get_data returns sefs_fcfile_t, a representation of a collection of file_context files */
+ SEFS_FCLIST_TYPE_DB /*!< get_data returns sefs_db_t, a representation of a database of file system contexts */
+ } sefs_fclist_type_e;
+
+/**
+ * Invoke a sefs_fclist_t's callback for an error, passing it a format
+ * string and arguments.
+ */
+#define SEFS_ERR(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_ERR, format, __VA_ARGS__)
+
+/**
+ * Invoke a sefs_fclist_t's callback for a warning, passing it a
+ * format string and arguments.
+ */
+#define SEFS_WARN(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_WARN, format, __VA_ARGS__)
+
+/**
+ * Invoke a sefs_fclist's callback for an informational message,
+ * passing it a format string and arguments.
+ */
+#define SEFS_INFO(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_INFO, format, __VA_ARGS__)
+
+ extern void sefs_fclist_handleMsg(const struct sefs_fclist *fclist, int level, const char *fmt, ...);
+
+ __attribute__ ((format(printf, 3, 4))) void sefs_fclist_handleMsg(const struct sefs_fclist *fclist, int level,
+ const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+struct apol_bst;
+struct context_node;
+
+#define SEFS_MAP_FUNC_DEFINED
+
+/**
+ * Function invoked upon each matching file context entry during a query.
+ */
+typedef int (*sefs_fclist_map_fn_t) (sefs_fclist *, const sefs_entry *, void *);
+/**
+ * An abstract class the represents a list of file contexts. Contexts
+ * may be read from a filesystem, inferred from a file_contexts file,
+ * or read from a database.
+ */
+class sefs_fclist
+{
+#ifndef SWIG_FRIENDS
+ friend void sefs_fclist_handleMsg(const sefs_fclist * fclist, int level, const char *fmt, ...);
+ friend class sefs_entry;
+#endif
+
+ public:
+ virtual ~sefs_fclist();
+
+ /**
+ * Perform a sefs query on the given file context list object,
+ * and then invoke a callback upon each matching entry.
+ * Mapping occurs in the order of entries as specified by the
+ * file context list.
+ * @param query Query object containing search parameters. If
+ * NULL, invoke the callback on all entries.
+ * @param fn Function to invoke upon matching entries. This
+ * function will be called with three parameters: a pointer to
+ * this fclist, pointer to a matching entry, and an arbitrary
+ * data pointer. It should return a non-negative value upon
+ * success, negative value upon error and to abort the
+ * mapping. Be aware that the entry may go out of scope upon
+ * conclusion of runQueryMap(), so \a fn will need to clone
+ * the entry if it needs it later.
+ * <p>
+ * <b>This function must not throw any exceptions.</b> Doing
+ * so will most likely corrupt fclist's internal state.
+ * Instead, return a negative value to abort processing.
+ * @param data Arbitrary pointer to be passed into \a fn as a
+ * third parameter.
+ * @return Last value returned by fn() (i.e., >= on success, <
+ * 0 on failure). If the fclist has no entries then return 0.
+ * @exception std::runtime_error Error while reading contexts
+ * from the fclist.
+ * @exception std::invalid_argument One or more query arguments
+ * is invalid.
+ */
+ virtual int runQueryMap(sefs_query * query, sefs_fclist_map_fn_t fn, void *data) throw(std::runtime_error,
+ std::invalid_argument) = 0;
+
+ /**
+ * Perform a sefs query on the given file context list object
+ * and return a list of matching entries.
+ * @param query Query object containing search parameters. If
+ * NULL, return all contexts.
+ * @return A newly allocated unsorted vector (of class
+ * sefs_entry *) containing all entries matching the query.
+ * Do not modify the returned entries. Note that the vector
+ * may be empty. The caller is responsible for calling
+ * apol_vector_destroy() on the returned vector.
+ * @exception std::bad_alloc Out of memory.
+ * @exception std::runtime_error Error while reading contexts
+ * from the fclist.
+ * @exception std::invalid_argument One or more query arguments
+ * is invalid.
+ */
+ apol_vector_t *runQuery(sefs_query * query) throw(std::bad_alloc, std::runtime_error, std::invalid_argument);
+
+ /**
+ * Determine if the contexts in the fclist contain MLS fields.
+ * @return \a true if MLS fields are present, \a false if not
+ * or undeterminable.
+ */
+ virtual bool isMLS() const = 0;
+
+ /**
+ * Associate a policy with the fclist. This is needed to
+ * resolve attributes and MLS ranges in queries. If a policy
+ * is already associated, then calling this function removes
+ * that previous association.
+ * @param policy Policy to associate with \a fclist. If NULL,
+ * remove any policy association. While \a policy is
+ * associated with \a fclist the caller should not destroy \a
+ * policy.
+ * @see sefs_query_set_type()
+ * @see sefs_query_set_range()
+ */
+ void associatePolicy(apol_policy_t * new_policy);
+
+ /**
+ * Return the policy currently associated with this fclist.
+ * Do not destroy the policy without first unassociating it
+ * (via call to sefs_fclist::associatePolicy(NULL)).
+ * @return Currently associated policy, or NULL if none is
+ * set.
+ */
+ apol_policy_t *associatePolicy() const;
+
+ /**
+ * Get the type of fclist object represented by \a fclist.
+ * @return The type of fclist object or SEFS_FCLIST_TYPE_NONE
+ * on error.
+ */
+ sefs_fclist_type_e fclist_type() const;
+
+ protected:
+ sefs_fclist(sefs_fclist_type_e type, sefs_callback_fn_t callback, void *varg) throw(std::bad_alloc);
+
+ /**
+ * Given the parts of a context, return a context node (which
+ * would contain an apol_context_t). If the context already
+ * exists, then a pointer to the existing one is returned.
+ *
+ * @param user User component of the context. The string will
+ * be duplicated.
+ * @param role Role component of the context. The string will
+ * be duplicated.
+ * @param type Type component of the context. The string will
+ * be duplicated.
+ * @param range Range component of the context. The string
+ * will be duplicated, or NULL if no range exists.
+ *
+ * @return A context node. Do not free() it.
+ */
+ struct sefs_context_node *getContext(const char *user, const char *role, const char *type,
+ const char *range) throw(std::bad_alloc);
+
+ /**
+ * Given a SELinux security context, return a context node
+ * (which would contain an apol_context_t). If the context
+ * already exists, then a pointer to the existing one is
+ * returned.
+ *
+ * @param scon Security context from which to obtain a node.
+ *
+ * @return A context node. Do not free() it.
+ */
+ struct sefs_context_node *getContext(const security_context_t scon) throw(std::bad_alloc);
+
+ apol_policy_t *policy;
+ struct apol_bst *user_tree, *role_tree, *type_tree, *range_tree, *path_tree;
+ struct apol_bst *dev_tree;
+ struct apol_bst *context_tree;
+
+ private:
+
+ /**
+ * Write a message to the callback stored within a fclist
+ * error handler. If the msg_callback field is empty, then
+ * the default message callback will be used.
+ * @param level Severity of message, one of SEFS_MSG_*.
+ * @param fmt Format string to print, using syntax of
+ * printf(3).
+ */
+ void handleMsg(int level, const char *fmt, va_list va_args) const;
+
+ sefs_callback_fn_t _callback;
+ void *_varg;
+ sefs_fclist_type_e _fclist_type;
+};
+
+extern "C"
+{
+#endif
+
+//we do not want to wrap two copies of everything so have SWIG ignore
+//the compatibility section.
+#ifndef SWIG
+
+ typedef struct sefs_fclist sefs_fclist_t;
+
+#ifndef SEFS_MAP_FUNC_DEFINED
+ struct sefs_fclist;
+ struct sefs_entry;
+ typedef int (*sefs_fclist_map_fn_t) (struct sefs_fclist *, const struct sefs_entry *, void *);
+#endif
+
+/**
+ * Deallocate all memory associated with the referenced fclist object,
+ * and then set it to NULL. This function does nothing if the fclist
+ * object is already NULL.
+ * @param Reference to a fclist object to destroy.
+ */
+ extern void sefs_fclist_destroy(sefs_fclist_t ** fclist);
+
+/**
+ * Perform a sefs query on the given file context list object.
+ * @see sefs_fclist::runQueryMap()
+ */
+ extern int sefs_fclist_run_query_map(sefs_fclist_t * fclist, sefs_query_t * query, sefs_fclist_map_fn_t fn, void *data);
+
+/**
+ * Perform a sefs query on the given file context list object.
+ * @see sefs_fclist::runQuery()
+ */
+ extern apol_vector_t *sefs_fclist_run_query(sefs_fclist_t * fclist, sefs_query_t * query);
+
+/**
+ * Determine if the contexts in the fclist contain MLS fields.
+ * @see sefs_fclist::isMLS()
+ */
+ extern bool sefs_fclist_get_is_mls(const sefs_fclist_t * fclist);
+
+/**
+ * Associate a policy with the fclist.
+ * @see sefs_fclist::associatePolicy()
+ * @see sefs_query_set_type()
+ * @see sefs_query_set_range()
+ */
+ extern void sefs_fclist_associate_policy(sefs_fclist_t * fclist, apol_policy_t * policy);
+
+/**
+ * Get the type of fclist object represented by \a fclist.
+ * @see sefs_fclist::fclist_type()
+ */
+ extern sefs_fclist_type_e sefs_fclist_get_fclist_type(const sefs_fclist_t * fclist);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_FCLIST_H */