diff options
Diffstat (limited to 'libsefs/include/sefs/fclist.hh')
-rw-r--r-- | libsefs/include/sefs/fclist.hh | 323 |
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 */ |