summaryrefslogtreecommitdiffstats
path: root/libsefs/include
diff options
context:
space:
mode:
Diffstat (limited to 'libsefs/include')
-rw-r--r--libsefs/include/Makefile.am1
-rw-r--r--libsefs/include/sefs/Makefile.am10
-rw-r--r--libsefs/include/sefs/db.hh213
-rw-r--r--libsefs/include/sefs/entry.hh222
-rw-r--r--libsefs/include/sefs/fcfile.hh261
-rw-r--r--libsefs/include/sefs/fclist.hh323
-rw-r--r--libsefs/include/sefs/filesystem.hh181
-rw-r--r--libsefs/include/sefs/query.hh329
-rw-r--r--libsefs/include/sefs/util.h56
9 files changed, 1596 insertions, 0 deletions
diff --git a/libsefs/include/Makefile.am b/libsefs/include/Makefile.am
new file mode 100644
index 0000000..6f6c411
--- /dev/null
+++ b/libsefs/include/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sefs
diff --git a/libsefs/include/sefs/Makefile.am b/libsefs/include/sefs/Makefile.am
new file mode 100644
index 0000000..f38dc4b
--- /dev/null
+++ b/libsefs/include/sefs/Makefile.am
@@ -0,0 +1,10 @@
+sefsdir = $(includedir)/sefs
+
+sefs_HEADERS = \
+ db.hh \
+ entry.hh \
+ fcfile.hh \
+ fclist.hh \
+ filesystem.hh \
+ query.hh \
+ util.h
diff --git a/libsefs/include/sefs/db.hh b/libsefs/include/sefs/db.hh
new file mode 100644
index 0000000..2355547
--- /dev/null
+++ b/libsefs/include/sefs/db.hh
@@ -0,0 +1,213 @@
+/**
+ * @file
+ * Defines the public interface for the database fc list 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_DB_H
+#define SEFS_DB_H
+
+#include <sefs/fclist.hh>
+#include <sefs/filesystem.hh>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <time.h>
+#include <apol/bst.h>
+#include <apol/vector.h>
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+/**
+ * This class represents a database that maps files to their SELinux
+ * file contexts.
+ */
+class sefs_db:public sefs_fclist
+{
+#ifndef SWIG_FRIENDS
+ // private functions -- do not call these directly from
+ // outside of the library
+ friend int db_create_from_filesystem(sefs_fclist * fclist __attribute__ ((unused)), const sefs_entry * entry, void *arg);
+ friend struct sefs_context_node *db_get_context(sefs_db *, const char *, const char *, const char *,
+ const char *) throw(std::bad_alloc);
+ friend sefs_entry *db_get_entry(sefs_db *, const struct sefs_context_node *, uint32_t, const char *, ino64_t,
+ const char *) throw(std::bad_alloc);
+#endif
+
+ public:
+
+ /**
+ * Allocate and return a new sefs database initialized with
+ * entries from the filesystem \a fs.
+ * @param fs Sefs filesystem from which to create the database.
+ * @param msg_callback Callback to invoke as errors/warnings are
+ * generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to the
+ * callback function.
+ * @exception std::invalid_argument Filesystem does not exist.
+ * @exception std::runtime_error Error while reading the
+ * database.
+ */
+ sefs_db(sefs_filesystem * fs, sefs_callback_fn_t msg_callback, void *varg) throw(std::invalid_argument,
+ std::runtime_error);
+
+ /**
+ * Allocate and return a new sefs database, loading the
+ * entries from an existing database stored at \a path.
+ * @param filename Name of a sefs database from which to load.
+ * @param msg_callback Callback to invoke as errors/warnings
+ * are generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to
+ * the callback function.
+ * @exception std::invalid_argument Database does not exist.
+ * @exception std::runtime_error Error while reading the
+ * database.
+ */
+ sefs_db(const char *filename, sefs_callback_fn_t msg_callback, void *varg) throw(std::invalid_argument,
+ std::runtime_error);
+
+ ~sefs_db();
+
+ /**
+ * Perform a sefs query on this database object, and then
+ * invoke a callback upon each matching entry. Entries will
+ * be returned in alphabetical order by path.
+ * @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 database, 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.
+ * @param data Arbitrary pointer to be passed into \fn as a
+ * third parameter.
+ * @return Last value returned by fn() (i.e., >= on success, <
+ * 0 on failure). If the database has no entries then
+ * return 0.
+ * @exception std::runtime_error Error while reading contexts
+ * from the database.
+ * @exception std::invalid_argument One or more query arguments
+ * is invalid.
+ */
+ int runQueryMap(sefs_query * query, sefs_fclist_map_fn_t fn, void *data) throw(std::runtime_error, std::invalid_argument);
+
+ /**
+ * Determine if the contexts stored in this database contain
+ * MLS fields.
+ * @return \a true if MLS fields are present, \a false if not
+ * or undeterminable.
+ */
+ bool isMLS() const;
+
+ /**
+ * Write a database to disk, overwriting any existing file.
+ * The database may then be read by calling the appropriate
+ * constructor.
+ * @param filename Name of file to which write.
+ * @exception std::invalid_argument No filename given.
+ * @exception std::runtime_error Error while writing the
+ * database.
+ */
+ void save(const char *filename) throw(std::invalid_argument, std::runtime_error);
+
+ /**
+ * Get the creation time of a sefs database.
+ * @return Creation time of the database, or 0 on error.
+ */
+ time_t getCTime() const;
+
+ /**
+ * Determine if the given file is a valid sefs_db. This
+ * does not thoroughly load the file, rather just the header
+ * of the file.
+ * @param filename Name of file to check.
+ * @return True if the file appears to be a database, false if not.
+ */
+ static bool isDB(const char *filename);
+
+ private:
+ /**
+ * Upgrade an existing version 1 database to version 2.
+ */
+ void upgradeToDB2() throw(std::runtime_error);
+
+ const struct sefs_context_node *getContextNode(const sefs_entry * entry);
+ sefs_entry *getEntry(const struct sefs_context_node *context, uint32_t objectClass, const char *path, ino64_t inode,
+ const char *dev) throw(std::bad_alloc);
+ struct sqlite3 *_db;
+ time_t _ctime;
+};
+
+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_db sefs_db_t;
+ typedef struct sefs_filesystem sefs_filesystem_t;
+
+/**
+ * Allocate and return a new sefs database from the filesystem \a fs.
+ * @see sefs_db::sefs_db(const sefs_filesystem &fs, sefs_callback_fn_t msg_callback, void *varg)
+ */
+ extern sefs_fclist_t *sefs_db_create_from_filesystem(sefs_filesystem_t * fs, sefs_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Allocate and return a new sefs database, loading the entries from
+ * the saved database \a path.
+ * @see sefs_db::sefs_db(const char *filename, sefs_callback_fn_t msg_callback, void *varg)
+ */
+ extern sefs_fclist_t *sefs_db_create_from_file(const char *path, sefs_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Write a database to disk, overwriting any existing file.
+ * @see sefs_db::save()
+ */
+ extern int sefs_db_save(sefs_db_t * db, const char *filename);
+
+/**
+ * Get the creation time of a sefs database.
+ * @see sefs_db::getCTime()
+ */
+ extern time_t sefs_db_get_ctime(sefs_db_t * db);
+
+/**
+ * Determine if the given file is a valid sefs_db.
+ * @see sefs_db::isDB()
+ */
+ extern bool sefs_db_is_db(const char *filename);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_DB_H */
diff --git a/libsefs/include/sefs/entry.hh b/libsefs/include/sefs/entry.hh
new file mode 100644
index 0000000..34fae73
--- /dev/null
+++ b/libsefs/include/sefs/entry.hh
@@ -0,0 +1,222 @@
+/**
+ * @file
+ * Defines the public interface for file context entries.
+ *
+ * @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_ENTRY_H
+#define SEFS_ENTRY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <sys/types.h>
+#include <apol/context-query.h>
+#include <apol/vector.h>
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+class sefs_fclist;
+struct sefs_context_node;
+
+/**
+ * This class represents an individual entry within a list an fcfile
+ * object. Note that the entry's contents (even upon a
+ * copy-constructed version of the entry) are always tied to its
+ * fclist, so do not access entries whose fclist has been destroyed.
+ */
+class sefs_entry
+{
+ friend class sefs_db;
+ friend class sefs_fcfile;
+ friend class sefs_filesystem;
+
+ public:
+
+ /**
+ * Perform a deep copy of an entry object.
+ */
+ sefs_entry(const sefs_entry * e);
+
+ ~sefs_entry();
+
+ /**
+ * Get the context from a sefs entry. If the entry has no
+ * context (such as being marked <tt>&lt;&lt;none&gt;&gt;</tt>
+ * in a file_contexts file) then apol_context_get_user() and
+ * others will return an empty string.
+ * @return A pointer to the context, or NULL on error. The
+ * caller should not modify or destroy the returned context.
+ */
+ const apol_context_t *context() const;
+
+ /**
+ * Get the inode number associated with a sefs entry.
+ * @return Inode number associated with the entry or 0 on
+ * error. Entries originating from a file_contexts object
+ * will have no inode and thus return 0.
+ */
+ ino64_t inode() const;
+
+ /**
+ * Get the device name associated with a sefs entry. For
+ * example, if /dev/sda5 is mounted as /home, the device name
+ * for entry "/home/gburdell" will be "/dev/sda5".
+ * @return Device number associated with the entry or NULL on
+ * error. Do not free() this value. Entries originating from
+ * a file_contexts object will have no device name and thus
+ * return NULL.
+ */
+ const char *dev() const;
+
+ /**
+ * Get the object class associated with a sefs entry. The
+ * returned value will be one of one of QPOL_CLASS_ALL,
+ * QPOL_CLASS_FILE, etc., as defined in
+ * <qpol/genfscon_query.h>. If this returns QPOL_CLASS_ALL
+ * then the entry is associated with all object classes.
+ * @return Entry's object class. Upon error return
+ * QPOL_CLASS_ALL.
+ * @see apol_objclass_to_str() to convert the value to a
+ * string.
+ */
+ uint32_t objectClass() const;
+
+ /**
+ * Get the paths associated with a sefs entry.
+ * @return Path for the entry.If the entry came from a
+ * file_contexts object the paths will be a regular expression
+ * rather than literal paths. Do not free() this pointer.
+ */
+ const char *path() const;
+
+ /**
+ * Get the file from which a sefs entry originated.
+ * This function is only meaningful when entries are returned
+ * from a query on a modular file context file.
+ * @return The path of the file (policy package or source
+ * file) providing the entry or NULL if the entry is not from
+ * a module. Do not free() this pointer.
+ */
+ const char *origin() const;
+
+ /**
+ * Return a string representation of this entry. The string
+ * is suitable for printing to the screen or to a
+ * file_contexts file.
+ * @return An allocated string representation. The caller is
+ * responsibily for free()ing the string afterwards.
+ * @exception std::bad_alloc Out of memory.
+ */
+ char *toString() const throw(std::bad_alloc);
+
+ private:
+ /**
+ * Create a blank entry. The entity creating this entry is
+ * responsible for setting additional values as needed.
+ * @param fclist List that will contain this entry. This
+ * constructor will not add itself to the fclist.
+ * @param new_context Context node containing the SELinux
+ * context.
+ * @param new_objectClass Object class for the entry.
+ * @param new_path Path to this entry. The entry will share
+ * this pointer.
+ * @param new_origin Name of file_contexts file from which
+ * this entry originated. The entry will share this pointer.
+ * @exception std::bad_alloc Out of memory.
+ */
+ sefs_entry(class sefs_fclist * fclist, const struct sefs_context_node *new_context, uint32_t new_objectClass,
+ const char *new_path, const char *new_origin = NULL);
+
+ // note that entry does not own any of these pointers; they
+ // are shallow copies into the fclist's BST
+ class sefs_fclist *_fclist;
+ const struct sefs_context_node *_context;
+ ino64_t _inode;
+ const char *_dev;
+ uint32_t _objectClass;
+ const char *_path, *_origin;
+};
+
+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_entry sefs_entry_t;
+
+/**
+ * Get the context from a sefs entry.
+ * @see sefs_entry::context()
+ */
+ extern const apol_context_t *sefs_entry_get_context(const sefs_entry_t * ent);
+
+/**
+ * Get the inode number associated with a sefs entry.
+ * @see sefs_entry::inode()
+ */
+ extern ino64_t sefs_entry_get_inode(const sefs_entry_t * ent);
+
+/**
+ * Get the device number associated with a sefs entry.
+ * @see sefs_entry::dev()
+ */
+ extern const char *sefs_entry_get_dev(const sefs_entry_t * ent);
+
+/**
+ * Get the object class associated with a sefs entry.
+ * @see sefs_entry::objectClass()
+ */
+ extern uint32_t sefs_entry_get_object_class(const sefs_entry_t * ent);
+
+/**
+ * Get the path associated with a sefs entry.
+ * @see sefs_entry::path()
+ */
+ extern const char *sefs_entry_get_path(const sefs_entry_t * ent);
+
+/**
+ * Get the file from which a sefs entry originated.
+ * @see sefs_entry::origin()
+ */
+ extern const char *sefs_entry_get_origin(const sefs_entry_t * ent);
+
+/**
+ * Return a string representation of this entry.
+ * @see sefs_entry::toString()
+ */
+ extern char *sefs_entry_to_string(const sefs_entry_t * ent);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_ENTRY_H */
diff --git a/libsefs/include/sefs/fcfile.hh b/libsefs/include/sefs/fcfile.hh
new file mode 100644
index 0000000..280a957
--- /dev/null
+++ b/libsefs/include/sefs/fcfile.hh
@@ -0,0 +1,261 @@
+/**
+ * @file
+ * Defines the public interface for the file_context set fc list 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_FCFILE_H
+#define SEFS_FCFILE_H
+
+#include <sefs/fclist.hh>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+#include <apol/vector.h>
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+/**
+ * This class represents file contexts entry as read from a file,
+ * typically name file_contexts.
+ */
+class sefs_fcfile:public sefs_fclist
+{
+ public:
+
+ /**
+ * Allocate and return a new (and empty) sefs file_context set
+ * structure.
+ * @param msg_callback Callback to invoke as errors/warnings
+ * are generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to
+ * the callback function.
+ * @exception std::bad_alloc if out of memory
+ */
+ sefs_fcfile(sefs_callback_fn_t msg_callback, void *varg) throw(std::bad_alloc);
+
+ /**
+ * Allocate and return a new sefs file_context set structure
+ * from a single file_contexts file.
+ * @param file File contexts file to read.
+ * @param msg_callback Callback to invoke as errors/warnings
+ * are generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to
+ * the callback function.
+ * @exception std::bad_alloc if out of memory
+ * @exception std::invalid_argument if the vector is NULL
+ * @exception std::runtime_error if the give file could not be
+ * read or is the wrong format
+ */
+ sefs_fcfile(const char *file, sefs_callback_fn_t msg_callback, void *varg) throw(std::bad_alloc, std::invalid_argument,
+ std::runtime_error);
+
+ /**
+ * Allocate and return a new sefs file_context set structure
+ * from a list of file_context files.
+ * @param files Vector of file contexts filenames (of type
+ * char *) to read.
+ * @param msg_callback Callback to invoke as errors/warnings
+ * are generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to
+ * the callback function.
+ * @exception std::bad_alloc if out of memory
+ * @exception std::invalid_argument if the vector is NULL
+ * @exception std::runtime_error if a given file could not
+ * be read or is the wrong format
+ */
+ sefs_fcfile(const apol_vector_t * files, sefs_callback_fn_t msg_callback, void *varg) throw(std::bad_alloc,
+ std::invalid_argument,
+ std::runtime_error);
+
+ ~sefs_fcfile();
+
+ /**
+ * Perform a sefs query on this fcfile object, and then invoke
+ * a callback upon each matching entry. Mapping occurs in the
+ * order of entries as given by the file_contexts, and in the
+ * order that file_contexts were appended (via appendFile())
+ * to this object.
+ * @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.
+ * @param data Arbitrary pointer to be passed into \fn as a
+ * third parameter.
+ * @return Last value returned by fn() (i.e., >= on success, <
+ * 0 on failure). If the fcfile 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.
+ */
+ int runQueryMap(sefs_query * query, sefs_fclist_map_fn_t fn, void *data) throw(std::runtime_error, std::invalid_argument);
+
+ /**
+ * Determine if the contexts in the fcfile contain MLS fields.
+ * @return \a true if MLS fields are present, \a false if not
+ * or undeterminable.
+ */
+ bool isMLS() const;
+
+ /**
+ * Append a file_contexts file to a sefs file contexts file
+ * set. If the fcfile already has a non-MLS file, subsequent
+ * appends must also be to non-MLS files. Likewise, if the
+ * fcfile already has an MLS file the file to be append must
+ * also be MLS.
+ * @param file File containing entries to append.
+ * @return 0 on success or < 0 on failure; if the call fails,
+ * the fcfile will be unchanged.
+ * @exception std::bad_alloc if out of memory
+ * @exception std::invalid_argument if the file name is NULL
+ * @exception std::runtime_error if a given file could not
+ * be read or is the wrong format
+ */
+ int appendFile(const char *file) throw(std::bad_alloc, std::invalid_argument, std::runtime_error);
+
+ /**
+ * Append a list of file_context files to a sefs file contexts
+ * file set. If the fcfile already has a non-MLS file,
+ * subsequent appends must also be to non-MLS files.
+ * Likewise, if the fcfile already has an MLS file the file to
+ * be append must also be MLS.
+ * @param files Vector of filenames (type char *) to append;
+ * these files will be appended in the order they appear in
+ * the vector.
+ * @return The number of files successfully appended. If the
+ * value returned is less than the size of the vector, then
+ * file at index (returned value) failed. If append fails for
+ * any file, the operation stops at that file; it is safe to
+ * attempt to append the files remaining after the
+ * unsuccessful file.
+ * @exception std::bad_alloc if out of memory
+ * @exception std::invalid_argument if the vector is NULL
+ * @exception std::runtime_error if a given file could not
+ * be read or is the wrong format
+ */
+ size_t appendFileList(const apol_vector_t * files) throw(std::bad_alloc, std::invalid_argument, std::runtime_error);
+
+ /**
+ * Get a list of all files contributing to the entries in a
+ * sefs file_contexts set.
+ * @return Vector of file paths (char *) of all files
+ * contributing to the set; the caller should not destroy or
+ * otherwise modify the returned vector.
+ */
+ const apol_vector_t *fileList() const;
+
+ private:
+
+ /**
+ * Parse a single line from a file_contexts file (or from any
+ * other source of file contexts information), and then add
+ * the resulting sefs_entry into the vector of entries.
+ * @param origin File from which this line originated.
+ * @param line File contexts line to parse.
+ * @param line_regex Compiled regular expression pattern for
+ * an entire line.
+ * @param context_regex Compiled regular expression pattern
+ * for the SELinux portion of a line.
+ * @exception std::bad_alloc if out of memory
+ * @exception std::runtime_error if the give file could not be
+ * read or is the wrong format
+ */
+ void parse_line(const char *origin, const char *line, regex_t * line_regex, regex_t * context_regex) throw(std::bad_alloc,
+ std::
+ runtime_error);
+
+ apol_vector_t *_files, *_entries;
+ bool _mls, _mls_set;
+};
+
+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_fcfile sefs_fcfile_t;
+
+/**
+ * Allocate and return a new sefs file_context set structure.
+ * @see sefs_fcfile::sefs_fcfile(sefs_callback_fn_t msg_callback, void *varg)
+ */
+ extern sefs_fclist_t *sefs_fcfile_create(sefs_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Allocate and return a new sefs file_context set structure from a
+ * single file_contexts file.
+ * @see sefs_fcfile::sefs_fcfile(const char *file, sefs_callback_fn_t msg_callback, void *varg)
+ */
+ extern sefs_fclist_t *sefs_fcfile_create_from_file(const char *file, sefs_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Allocate and return a new sefs file_context set structure from a
+ * list of file_context files.
+ * @see sefs_fcfile::sefs_fcfile(const apol_vector_t * files, sefs_callback_fn_t msg_callback, void *varg)
+ */
+ extern sefs_fclist_t *sefs_fcfile_create_from_file_list(const apol_vector_t * files, sefs_callback_fn_t msg_callback,
+ void *varg);
+
+/**
+ * Append a file_contexts file to a sefs file contexts file set.
+ * @return 0 on success or < 0 on failure; if the call fails, the
+ * fcfile will be unchanged.
+ * @see sefs_fcfile::appendFile()
+ */
+ extern int sefs_fcfile_append_file(sefs_fcfile_t * fcfile, const char *file);
+
+/**
+ * Append a list of file_context files to a sefs file contexts file
+ * set.
+ * @see sefs_fcfile::appendFileList()
+ */
+ extern size_t sefs_fcfile_append_file_list(sefs_fcfile_t * fcfile, const apol_vector_t * files);
+
+/**
+ * Get a list of all files contributing to the entries in a sefs
+ * file_contexts set.
+ * @see sefs_fcfile::fileList()
+ */
+ extern const apol_vector_t *sefs_fcfile_get_file_list(const sefs_fcfile_t * fcfile);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_FCFILE_H */
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 */
diff --git a/libsefs/include/sefs/filesystem.hh b/libsefs/include/sefs/filesystem.hh
new file mode 100644
index 0000000..1d2c9ed
--- /dev/null
+++ b/libsefs/include/sefs/filesystem.hh
@@ -0,0 +1,181 @@
+/**
+ * @file
+ * Defines the public interface for the filesystem fc list 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_FILESYSTEM_H
+#define SEFS_FILESYSTEM_H
+
+#include <sefs/fclist.hh>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <apol/vector.h>
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+/**
+ * This class represents the SELinux file contexts on a local on-disk
+ * filesystem. Be aware that the object will recurse beginning from
+ * the root directory, so if there are circular mounts (e.g., via
+ * something mounted with the 'bind' option) then queries against the
+ * filesystem will never terminate.
+ */
+class sefs_filesystem:public sefs_fclist
+{
+#ifndef SWIG_FRIENDS
+ // private functions -- do not call these directly from
+ // outside of the library
+ friend struct sefs_context_node *filesystem_get_context(sefs_filesystem *, security_context_t) throw(std::bad_alloc);
+ friend sefs_entry *filesystem_get_entry(sefs_filesystem *, const struct sefs_context_node *, uint32_t,
+ const char *, ino64_t, const char *) throw(std::bad_alloc);
+ friend bool filesystem_is_query_match(sefs_filesystem *, const sefs_query *, const char *, const char *,
+ const struct stat64 *, apol_vector_t *, apol_mls_range_t *) throw(std::runtime_error);
+#endif
+
+ public:
+
+ /**
+ * Allocate and return a new sefs filesystem structure
+ * representing the filesystem rooted at directory \a root.
+ * <b>Be aware that the constructor is not thread-safe.</b>
+ * @param new_root Directory to use as the root of the
+ * filesystem. This object represents this directory and all
+ * subdirectories, including other mounted filesystems.
+ * @param msg_callback Callback to invoke as errors/warnings
+ * are generated. If NULL, write messages to standard error.
+ * @param varg Value to be passed as the first parameter to
+ * the callback function.
+ * @exception bad_alloc Out of memory.
+ * @exception invalid_argument Root directory does not exist.
+ * @exception runtime_error Could not open root directory or
+ * /etc/mtab.
+ */
+ sefs_filesystem(const char *new_root, sefs_callback_fn_t msg_callback, void *varg) throw(std::bad_alloc,
+ std::invalid_argument,
+ std::runtime_error);
+
+ ~sefs_filesystem();
+
+ /**
+ * Perform a sefs query on this filesystem object, and then
+ * invoke a callback upon each matching entry. Mapping is in
+ * pre-order (i.e., directories will be mapped prior to files
+ * and subdirectories they contain.)
+ * @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 filesystem, 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.
+ * @param data Arbitrary pointer to be passed into \fn as a
+ * third parameter.
+ * @return Last value returned by fn() (i.e., >= on success, <
+ * 0 on failure). If the filesystem has no entries then
+ * return 0.
+ * @exception std::runtime_error Error while reading contexts
+ * from the filesystem.
+ * @exception std::invalid_argument One or more query arguments
+ * is invalid.
+ */
+ int runQueryMap(sefs_query * query, sefs_fclist_map_fn_t fn, void *data) throw(std::runtime_error, std::invalid_argument);
+
+ /**
+ * Determine if the contexts stored in this filesystem contain
+ * MLS fields.
+ * @return \a true if MLS fields are present, \a false if not
+ * or undeterminable.
+ */
+ bool isMLS() const;
+
+ /**
+ * Get the root directory of a sefs filesystem structure.
+ * @return The root directory of the filesystem or NULL on
+ * error. Do not free() this string.
+ */
+ const char *root() const;
+
+ /**
+ * Look up the given device number on the currently running
+ * system, and convert it to its device name.
+ * @param dev Device number to look up.
+ * @return Name of the device, or NULL if the device number
+ * was not found. Do not free() this pointer.
+ * @exception std::runtime_error Error while querying system.
+ */
+ const char *getDevName(const dev_t dev) throw(std::runtime_error);
+
+ private:
+ apol_vector_t * buildDevMap(void) throw(std::runtime_error);
+ bool isQueryMatch(const sefs_query * query, const char *path, const char *dev, const struct stat64 *sb,
+ apol_vector_t * type_list, apol_mls_range_t * range) throw(std::runtime_error);
+ sefs_entry *getEntry(const struct sefs_context_node *context, uint32_t objectClass, const char *path, ino64_t ino,
+ const char *dev_name) throw(std::bad_alloc);
+ char *_root;
+ bool _rw, _mls;
+};
+
+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_filesystem sefs_filesystem_t;
+
+/**
+ * Allocate and return a new sefs filesystem structure representing
+ * the filesystem rooted at directory \a root.
+ * @see sefs_filesystem::sefs_filesystem()
+ */
+ extern sefs_filesystem_t *sefs_filesystem_create(const char *root, sefs_callback_fn_t msg_callback, void *varg);
+
+/**
+ * Get the root directory of a sefs filesystem structure.
+ * @see sefs_filesystem::root()
+ */
+ extern const char *sefs_filesystem_get_root(const sefs_filesystem_t * fs);
+
+/**
+ * Look up the given device number on the currently running
+ * system, and convert it to its device name.
+ * @see sefs_filesystem::ged_dev_name()
+ */
+ extern const char *sefs_filesystem_get_dev_name(sefs_filesystem_t * fs, const dev_t dev);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_FILESYSTEM_H */
diff --git a/libsefs/include/sefs/query.hh b/libsefs/include/sefs/query.hh
new file mode 100644
index 0000000..c0e8921
--- /dev/null
+++ b/libsefs/include/sefs/query.hh
@@ -0,0 +1,329 @@
+/**
+ * @file
+ * Defines the public interface for file context queries.
+ *
+ * @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_QUERY_H
+#define SEFS_QUERY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <sys/types.h>
+#include <regex.h>
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#include <apol/context-query.h>
+#include <apol/mls-query.h>
+#include <apol/policy-query.h>
+#include <apol/vector.h>
+
+#ifdef __cplusplus
+}
+
+#include <stdexcept>
+
+/**
+ * This class represents a query into a (subclass of) fclist. Create
+ * a query, fill in all accessors are needed, and then run the query.
+ * All fields must match for an entry to be returned. Where a fclist
+ * does not support a particular criterion (e.g., inode numbers for
+ * fcfile) that portion of the query is considered to be matching.
+ */
+class sefs_query
+{
+ friend class sefs_db;
+ friend class sefs_fcfile;
+ friend class sefs_filesystem;
+
+ public:
+
+ /**
+ * Allocate and return a new sefs query structure. All fields
+ * are initialized, such that running this blank query results
+ * in returning all entries within a fclist.
+ */
+ sefs_query();
+
+ ~sefs_query();
+
+ /**
+ * Set a sefs query to match only entries with contexts with
+ * the user \a name.
+ * @param name Limit query to only contexts with this user, or
+ * NULL to clear this field. The string will be duplicated.
+ * @exception std::bad_alloc Out of memory.
+ */
+ void user(const char *name) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to match only entries with contexts with
+ * the role \a name.
+ * @param name Limit query to only contexts with this role, or
+ * NULL to clear this field. The string will be duplicated.
+ * @exception std::bad_alloc Out of memory.
+ */
+ void role(const char *name) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to match only entries with contexts with
+ * the type \a name.
+ * @param name Limit query to only contexts with this type, or
+ * NULL to clear this field. The string will be duplicated.
+ * @param indirect If true and if the fclist queried has
+ * access to a policy, also match contexts with types in
+ * attribute \a name or types which are an alias for \a name.
+ * If a policy is not available, this field is ignored, and
+ * exact string matching is used instead. This paramater is
+ * ignored if \a name is NULL.
+ * @exception std::bad_alloc Out of memory.
+ * @see sefs_fclist::associatePolicy() to associate a policy
+ * with a fclist.
+ */
+ void type(const char *name, bool indirect) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to match only entries with contexts with a
+ * range of \a range. If the fclist is not MLS then \a name
+ * and \a match will be ignored.
+ * @param name Limit query to only contexts matching this
+ * string representing the MLS range, or NULL to clear this
+ * field. The string will be duplicated.
+ * @param match If non-zero and the fclist queried has access
+ * to a policy, match the range using the specified semantics;
+ * this should be one of APOL_QUERY_SUB, APOL_QUERY_SUPER, or
+ * APOL_QUERY_EXACT. (The range string will be converted
+ * automatically into an apol_mls_range_t object.) If a
+ * policy is not available or \a match is zero, exact string
+ * matching is used instead. Note, if a policy is available
+ * the regex flag is ignored if \a match is non-zero. This
+ * parameter is ignored if \a range is NULL.
+ * @exception std::bad_alloc Out of memory.
+ * @see sefs_fclist::associatePolicy() to associate a policy
+ * with a fclist.
+ */
+ void range(const char *name, int match) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to match only entries with object class \a
+ * objclass.
+ *
+ * <em>Note:</em> If the query is run against a fcfile, then
+ * entries without explicit object classes (i.e., no explicit
+ * <tt>--</tt>, <tt>-d</tt>, etc.) will always match
+ * irrespective of the query's object class field.
+ *
+ * @param Numeric identifier for an objclass, one of
+ * QPOL_CLASS_FILE, QPOL_CLASS_DIR, etc., as defined in
+ * <qpol/genfscon_query.h>. Use QPOL_CLASS_ALL to match all
+ * object classes.
+ */
+ void objectClass(uint32_t objclass);
+
+ /**
+ * Set a sefs query to match only entries with object class \a
+ * name. The \a name parameter is not affected by regex().
+ *
+ * @param name Limit query to only entries with this object
+ * class, or NULL to clear this field. The incoming string
+ * must be legal according to apol_str_to_objclass().
+ *
+ * @see objectClass(uint32_t) for note about fcfiles.
+ */
+ void objectClass(const char *name);
+
+ /**
+ * Set a sefs query to match only entries with path \a path.
+ *
+ * <em>Note:</em> If the query is run against a fcfile, the
+ * behavior of matching paths is slightly different. For each
+ * of fcfile's entries, that entry's regular expression is
+ * matched against \a path. This is the reverse for other
+ * types of fclist, where \a path matches an entry's path if
+ * \a path is a substring. (If sefs_query::regex() is set to
+ * true, \a path is instead treated as a regular expression.)
+ *
+ * @param str Limit query to only entries containing this
+ * path, or NULL to clear this field. The string will be
+ * duplicated.
+ * @exception std::bad_alloc Out of memory.
+ */
+ void path(const char *str) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to match only entries with a given inode
+ * number.
+ * @param ino Limit query to only entries with this inode
+ * number, or 0 to clear this field.
+ */
+ void inode(ino64_t ino);
+
+ /**
+ * Set a sefs query to match only entries with a given device
+ * name.
+ * @param str Limit query to only entries with this device
+ * name, or NULL to clear this string. The string will be
+ * duplicated.
+ * @exception std::bad_alloc Out of memory.
+ * @see sefs_filesystem::getDevName() to convert between dev_t
+ * and a name.
+ */
+ void dev(const char *str) throw(std::bad_alloc);
+
+ /**
+ * Set a sefs query to use regular expression matching for
+ * string fields.
+ * @param r If true then use regular expression matching;
+ * otherwise use only exact string matching.
+ */
+ void regex(bool r);
+
+ private:
+ /**
+ * Compile the regular expressions stored within this query
+ * object. It is safe to call this function multiple times.
+ *
+ * @exception std::bad_alloc Out of memory.
+ * @exception std::invalid_argument One or more invalid regular
+ * expressions is invalid.
+ */
+ void compile() throw(std::bad_alloc, std::invalid_argument);
+
+ char *_user, *_role, *_type, *_range, *_path, *_dev;
+ uint32_t _objclass;
+ bool _indirect, _regex, _recursive;
+ int _rangeMatch;
+ ino64_t _inode;
+ bool _recompiled;
+ regex_t *_reuser, *_rerole, *_retype, *_rerange, *_repath, *_redev;
+};
+
+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_query sefs_query_t;
+
+/**
+ * Allocate and return a new sefs query structure.
+ * @see sefs_query::sefs_query()
+ */
+ extern sefs_query_t *sefs_query_create();
+
+/**
+ * Deallocate all memory associated with the referenced sefs query,
+ * and then set it to NULL. This function does nothing if the query
+ * is already NULL.
+ * @param query Reference to a sefs query structure to destroy.
+ */
+ extern void sefs_query_destroy(sefs_query_t ** query);
+
+/**
+ * Set a sefs query to match only entries with contexts with the user
+ * \a name.
+ * @see sefs_query::user()
+ */
+ extern int sefs_query_set_user(sefs_query_t * query, const char *name);
+
+/**
+ * Set a sefs query to match only entries with contexts with the role
+ * \a name.
+ * @see sefs_query::role()
+ */
+ extern int sefs_query_set_role(sefs_query_t * query, const char *name);
+
+/**
+ * Set a sefs query to match only entries with contexts with the type
+ * \a name.
+ * @see sefs_query::type()
+ * @see sefs_fclist_associate_policy() to associate a policy with a
+ * fclist.
+ */
+ extern int sefs_query_set_type(sefs_query_t * query, const char *name, bool indirect);
+
+/**
+ * Set a sefs query to match only entries with contexts with a range
+ * of \a range.
+ * @see sefs_query::range()
+ * @see sefs_fclist_associate_policy() to associate a policy with a
+ * fclist.
+ */
+ extern int sefs_query_set_range(sefs_query_t * query, const char *range, int match);
+
+/**
+ * Set a sefs query to match only entries with object class \a
+ * objclass.
+ * @return Always 0.
+ * @see sefs_query::objectClass(uint32_t)
+ */
+ extern int sefs_query_set_object_class(sefs_query_t * query, uint32_t objclass);
+
+/**
+ * Set a sefs query to match only entries with object class \a name.
+ * @return Always 0.
+ * @see sefs_query::objectClass(const char *)
+ */
+ extern int sefs_query_set_object_class_str(sefs_query_t * query, const char *name);
+
+/**
+ * Set a sefs query to match only entries with path \a path.
+ * @see sefs_query::path()
+ */
+ extern int sefs_query_set_path(sefs_query_t * query, const char *path);
+
+/**
+ * Set a sefs query to match only entries with a given inode number.
+ * @return Always 0.
+ * @see sefs_query::inode()
+ */
+ extern int sefs_query_set_inode(sefs_query_t * query, ino64_t inode);
+
+/**
+ * Set a sefs query to match only entries with a given device number.
+ * @see sefs_query::dev()
+ */
+ extern int sefs_query_set_dev(sefs_query_t * query, const char *dev);
+
+/**
+ * Set a sefs query to use regular expression matching for string
+ * fields.
+ * @return Always 0.
+ * @see sefs_query::regex()
+ */
+ extern int sefs_query_set_regex(sefs_query_t * query, bool regex);
+
+#endif /* SWIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SEFS_QUERY_H */
diff --git a/libsefs/include/sefs/util.h b/libsefs/include/sefs/util.h
new file mode 100644
index 0000000..24480ea
--- /dev/null
+++ b/libsefs/include/sefs/util.h
@@ -0,0 +1,56 @@
+/**
+ * @file
+ *
+ * Miscellaneous, uncategorized functions for libsefs.
+ *
+ * @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 SEFS_UTIL_H
+#define SEFS_UTIL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Return an immutable string describing this library's version.
+ *
+ * @return String describing this library.
+ */
+ extern const char *libsefs_get_version(void);
+
+/**
+ * Return the name (path + filename) of the file_contexts file for the
+ * currently running SELinux system. If the system is not running
+ * SELinux then return an empty string ("").
+ *
+ * @return The name of the default file_contexts file (if system is
+ * running SELinux), an empty string (if not SELinux), or NULL upon
+ * error. The caller must free() the string afterwards.
+ */
+ extern char *sefs_default_file_contexts_get_path(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif