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 */