fclist.hh

Go to the documentation of this file.
00001 /**
00002  *  @file
00003  *  Defines the public interface for the file context list abstract
00004  *  object.  A user must call a constructor for one of sefs_fcfile_t,
00005  *  sefs_db_t, or sefs_filesystem_t to create a sefs_fclist_t object.
00006  *
00007  *  @author Jeremy A. Mowery jmowery@tresys.com
00008  *  @author Jason Tang jtang@tresys.com
00009  *
00010  *  Copyright (C) 2007 Tresys Technology, LLC
00011  *
00012  *  This library is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU Lesser General Public
00014  *  License as published by the Free Software Foundation; either
00015  *  version 2.1 of the License, or (at your option) any later version.
00016  *
00017  *  This library is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  *  Lesser General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU Lesser General Public
00023  *  License along with this library; if not, write to the Free Software
00024  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00025  */
00026 
00027 #ifndef SEFS_FCLIST_H
00028 #define SEFS_FCLIST_H
00029 
00030 #include <sefs/entry.hh>
00031 #include <sefs/query.hh>
00032 
00033 #ifdef __cplusplus
00034 extern "C"
00035 {
00036 #endif
00037 
00038 #include <selinux/selinux.h>
00039 #include <stdarg.h>
00040 
00041 #ifndef __cplusplus
00042 #include <stdbool.h>
00043 #endif
00044 
00045 #include <apol/policy.h>
00046 
00047 #define SEFS_MSG_ERR  1                /*!< Message describes a fatal error. */
00048 #define SEFS_MSG_WARN 2                /*!< Message is issued as a warning but does not represent a fatal error. */
00049 #define SEFS_MSG_INFO 3                /*!< Message is issued for inormational reasons and does not represent an atypical state. */
00050 
00051         struct sefs_fclist;
00052 
00053         typedef void (*sefs_callback_fn_t) (void *varg, const struct sefs_fclist * fclist, int level, const char *fmt,
00054                                             va_list argp);
00055 
00056 /**
00057  * Possible types of fclist for use with sefs_fclist_get_data().
00058  */
00059         typedef enum sefs_fclist_type
00060         {
00061                 SEFS_FCLIST_TYPE_NONE = 0,      /*!< Not an actual type, used for error conditions */
00062                 SEFS_FCLIST_TYPE_FILESYSTEM,    /*!< get_data returns sefs_filesystem_t, a representation of a file system */
00063                 SEFS_FCLIST_TYPE_FCFILE,        /*!< get_data returns sefs_fcfile_t, a representation of a collection of file_context files */
00064                 SEFS_FCLIST_TYPE_DB    /*!< get_data returns sefs_db_t, a representation of a database of file system contexts */
00065         } sefs_fclist_type_e;
00066 
00067 /**
00068  * Invoke a sefs_fclist_t's callback for an error, passing it a format
00069  * string and arguments.
00070  */
00071 #define SEFS_ERR(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_ERR, format, __VA_ARGS__)
00072 
00073 /**
00074  * Invoke a sefs_fclist_t's callback for a warning, passing it a
00075  * format string and arguments.
00076  */
00077 #define SEFS_WARN(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_WARN, format, __VA_ARGS__)
00078 
00079 /**
00080  * Invoke a sefs_fclist's callback for an informational message,
00081  * passing it a format string and arguments.
00082  */
00083 #define SEFS_INFO(fclist, format, ...) sefs_fclist_handleMsg(fclist, SEFS_MSG_INFO, format, __VA_ARGS__)
00084 
00085         extern void sefs_fclist_handleMsg(const struct sefs_fclist *fclist, int level, const char *fmt, ...);
00086 
00087         __attribute__ ((format(printf, 3, 4))) void sefs_fclist_handleMsg(const struct sefs_fclist *fclist, int level,
00088                                                                           const char *fmt, ...);
00089 
00090 #ifdef __cplusplus
00091 }
00092 
00093 #include <stdexcept>
00094 
00095 struct apol_bst;
00096 struct context_node;
00097 
00098 #define SEFS_MAP_FUNC_DEFINED
00099 
00100 /**
00101  * Function invoked upon each matching file context entry during a query.
00102  */
00103 typedef int (*sefs_fclist_map_fn_t) (sefs_fclist *, const sefs_entry *, void *);
00104 /**
00105  * An abstract class the represents a list of file contexts.  Contexts
00106  * may be read from a filesystem, inferred from a file_contexts file,
00107  * or read from a database.
00108  */
00109 class sefs_fclist
00110 {
00111 #ifndef SWIG_FRIENDS
00112         friend void sefs_fclist_handleMsg(const sefs_fclist * fclist, int level, const char *fmt, ...);
00113         friend class sefs_entry;
00114 #endif
00115 
00116       public:
00117          virtual ~sefs_fclist();
00118 
00119         /**
00120          * Perform a sefs query on the given file context list object,
00121          * and then invoke a callback upon each matching entry.
00122          * Mapping occurs in the order of entries as specified by the
00123          * file context list.
00124          * @param query Query object containing search parameters.  If
00125          * NULL, invoke the callback on all entries.
00126          * @param fn Function to invoke upon matching entries.  This
00127          * function will be called with three parameters: a pointer to
00128          * this fclist, pointer to a matching entry, and an arbitrary
00129          * data pointer.  It should return a non-negative value upon
00130          * success, negative value upon error and to abort the
00131          * mapping.  Be aware that the entry may go out of scope upon
00132          * conclusion of runQueryMap(), so \a fn will need to clone
00133          * the entry if it needs it later.
00134          * <p>
00135          * <b>This function must not throw any exceptions.</b> Doing
00136          * so will most likely corrupt fclist's internal state.
00137          * Instead, return a negative value to abort processing.
00138          * @param data Arbitrary pointer to be passed into \a fn as a
00139          * third parameter.
00140          * @return Last value returned by fn() (i.e., >= on success, <
00141          * 0 on failure).  If the fclist has no entries then return 0.
00142          * @exception std::runtime_error Error while reading contexts
00143          * from the fclist.
00144          * @exception std::invalid_argument One or more query arguments
00145          * is invalid.
00146          */
00147         virtual int runQueryMap(sefs_query * query, sefs_fclist_map_fn_t fn, void *data) throw(std::runtime_error,
00148                                                                                                std::invalid_argument) = 0;
00149 
00150         /**
00151          * Perform a sefs query on the given file context list object
00152          * and return a list of matching entries.
00153          * @param query Query object containing search parameters.  If
00154          * NULL, return all contexts.
00155          * @return A newly allocated unsorted vector (of class
00156          * sefs_entry *) containing all entries matching the query.
00157          * Do not modify the returned entries.  Note that the vector
00158          * may be empty.  The caller is responsible for calling
00159          * apol_vector_destroy() on the returned vector.
00160          * @exception std::bad_alloc Out of memory.
00161          * @exception std::runtime_error Error while reading contexts
00162          * from the fclist.
00163          * @exception std::invalid_argument One or more query arguments
00164          * is invalid.
00165          */
00166         apol_vector_t *runQuery(sefs_query * query) throw(std::bad_alloc, std::runtime_error, std::invalid_argument);
00167 
00168         /**
00169          * Determine if the contexts in the fclist contain MLS fields.
00170          * @return \a true if MLS fields are present, \a false if not
00171          * or undeterminable.
00172          */
00173         virtual bool isMLS() const = 0;
00174 
00175         /**
00176          * Associate a policy with the fclist.  This is needed to
00177          * resolve attributes and MLS ranges in queries.  If a policy
00178          * is already associated, then calling this function removes
00179          * that previous association.
00180          * @param policy Policy to associate with \a fclist.  If NULL,
00181          * remove any policy association. While \a policy is
00182          * associated with \a fclist the caller should not destroy \a
00183          * policy.
00184          * @see sefs_query_set_type()
00185          * @see sefs_query_set_range()
00186          */
00187         void associatePolicy(apol_policy_t * new_policy);
00188 
00189         /**
00190          * Return the policy currently associated with this fclist.
00191          * Do not destroy the policy without first unassociating it
00192          * (via call to sefs_fclist::associatePolicy(NULL)).
00193          * @return Currently associated policy, or NULL if none is
00194          * set.
00195          */
00196         apol_policy_t *associatePolicy() const;
00197 
00198         /**
00199          * Get the type of fclist object represented by \a fclist.
00200          * @return The type of fclist object or SEFS_FCLIST_TYPE_NONE
00201          * on error.
00202          */
00203         sefs_fclist_type_e fclist_type() const;
00204 
00205       protected:
00206          sefs_fclist(sefs_fclist_type_e type, sefs_callback_fn_t callback, void *varg) throw(std::bad_alloc);
00207 
00208         /**
00209          * Given the parts of a context, return a context node (which
00210          * would contain an apol_context_t).  If the context already
00211          * exists, then a pointer to the existing one is returned.
00212          *
00213          * @param user User component of the context.  The string will
00214          * be duplicated.
00215          * @param role Role component of the context.  The string will
00216          * be duplicated.
00217          * @param type Type component of the context.  The string will
00218          * be duplicated.
00219          * @param range Range component of the context.  The string
00220          * will be duplicated, or NULL if no range exists.
00221          *
00222          * @return A context node.  Do not free() it.
00223          */
00224         struct sefs_context_node *getContext(const char *user, const char *role, const char *type,
00225                                              const char *range) throw(std::bad_alloc);
00226 
00227         /**
00228          * Given a SELinux security context, return a context node
00229          * (which would contain an apol_context_t).  If the context
00230          * already exists, then a pointer to the existing one is
00231          * returned.
00232          *
00233          * @param scon Security context from which to obtain a node.
00234          *
00235          * @return A context node.  Do not free() it.
00236          */
00237         struct sefs_context_node *getContext(const security_context_t scon) throw(std::bad_alloc);
00238 
00239         apol_policy_t *policy;
00240         struct apol_bst *user_tree, *role_tree, *type_tree, *range_tree, *path_tree;
00241         struct apol_bst *dev_tree;
00242         struct apol_bst *context_tree;
00243 
00244       private:
00245 
00246         /**
00247          * Write a message to the callback stored within a fclist
00248          * error handler.  If the msg_callback field is empty, then
00249          * the default message callback will be used.
00250          * @param level Severity of message, one of SEFS_MSG_*.
00251          * @param fmt Format string to print, using syntax of
00252          * printf(3).
00253          */
00254         void handleMsg(int level, const char *fmt, va_list va_args) const;
00255 
00256         sefs_callback_fn_t _callback;
00257         void *_varg;
00258         sefs_fclist_type_e _fclist_type;
00259 };
00260 
00261 extern "C"
00262 {
00263 #endif
00264 
00265 //we do not want to wrap two copies of everything so have SWIG ignore
00266 //the compatibility section.
00267 #ifndef SWIG
00268 
00269         typedef struct sefs_fclist sefs_fclist_t;
00270 
00271 #ifndef SEFS_MAP_FUNC_DEFINED
00272         struct sefs_fclist;
00273         struct sefs_entry;
00274         typedef int (*sefs_fclist_map_fn_t) (struct sefs_fclist *, const struct sefs_entry *, void *);
00275 #endif
00276 
00277 /**
00278  * Deallocate all memory associated with the referenced fclist object,
00279  * and then set it to NULL.  This function does nothing if the fclist
00280  * object is already NULL.
00281  * @param Reference to a fclist object to destroy.
00282  */
00283         extern void sefs_fclist_destroy(sefs_fclist_t ** fclist);
00284 
00285 /**
00286  * Perform a sefs query on the given file context list object.
00287  * @see sefs_fclist::runQueryMap()
00288  */
00289         extern int sefs_fclist_run_query_map(sefs_fclist_t * fclist, sefs_query_t * query, sefs_fclist_map_fn_t fn, void *data);
00290 
00291 /**
00292  * Perform a sefs query on the given file context list object.
00293  * @see sefs_fclist::runQuery()
00294  */
00295         extern apol_vector_t *sefs_fclist_run_query(sefs_fclist_t * fclist, sefs_query_t * query);
00296 
00297 /**
00298  * Determine if the contexts in the fclist contain MLS fields.
00299  * @see sefs_fclist::isMLS()
00300  */
00301         extern bool sefs_fclist_get_is_mls(const sefs_fclist_t * fclist);
00302 
00303 /**
00304  * Associate a policy with the fclist.
00305  * @see sefs_fclist::associatePolicy()
00306  * @see sefs_query_set_type()
00307  * @see sefs_query_set_range()
00308  */
00309         extern void sefs_fclist_associate_policy(sefs_fclist_t * fclist, apol_policy_t * policy);
00310 
00311 /**
00312  * Get the type of fclist object represented by \a fclist.
00313  * @see sefs_fclist::fclist_type()
00314  */
00315         extern sefs_fclist_type_e sefs_fclist_get_fclist_type(const sefs_fclist_t * fclist);
00316 
00317 #endif                                 /* SWIG */
00318 
00319 #ifdef __cplusplus
00320 }
00321 #endif
00322 
00323 #endif                                 /* SEFS_FCLIST_H */