sefs_fcfile Class Reference

#include <fcfile.hh>

Inheritance diagram for sefs_fcfile:

sefs_fclist List of all members.

Detailed Description

This class represents file contexts entry as read from a file, typically name file_contexts.

Definition at line 48 of file fcfile.hh.


Public Member Functions

 sefs_fcfile (sefs_callback_fn_t msg_callback, void *varg) throw (std::bad_alloc)
 Allocate and return a new (and empty) sefs file_context set structure.
 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 single file_contexts file.
 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)
 Allocate and return a new sefs file_context set structure from a list of file_context files.
 ~sefs_fcfile ()
int runQueryMap (sefs_query *query, sefs_fclist_map_fn_t fn, void *data) throw (std::runtime_error, std::invalid_argument)
 Perform a sefs query on the given file context list object, and then invoke a callback upon each matching entry.
bool isMLS () const
 Determine if the contexts in the fcfile contain MLS fields.
int appendFile (const char *file) throw (std::bad_alloc, std::invalid_argument, std::runtime_error)
 Append a file_contexts file to a sefs file contexts file set.
size_t appendFileList (const apol_vector_t *files) throw (std::bad_alloc, std::invalid_argument, std::runtime_error)
 Append a list of file_context files to a sefs file contexts file set.
const apol_vector_tfileList () const
 Get a list of all files contributing to the entries in a sefs file_contexts set.
apol_vector_trunQuery (sefs_query *query) throw (std::bad_alloc, std::runtime_error, std::invalid_argument)
 Perform a sefs query on the given file context list object and return a list of matching entries.
void associatePolicy (apol_policy_t *new_policy)
 Associate a policy with the fclist.
apol_policy_tassociatePolicy () const
 Return the policy currently associated with this fclist.
sefs_fclist_type_e fclist_type () const
 Get the type of fclist object represented by fclist.

Protected Member Functions

sefs_context_nodegetContext (const char *user, const char *role, const char *type, const char *range) throw (std::bad_alloc)
 Given the parts of a context, return a context node (which would contain an apol_context_t).
sefs_context_nodegetContext (const security_context_t scon) throw (std::bad_alloc)
 Given a SELinux security context, return a context node (which would contain an apol_context_t).

Protected Attributes

apol_policy_tpolicy
apol_bstuser_tree
apol_bstrole_tree
apol_bsttype_tree
apol_bstrange_tree
apol_bstpath_tree
apol_bstdev_tree
apol_bstcontext_tree

Private Member Functions

void parse_line (const char *origin, const char *line, regex_t *line_regex, regex_t *context_regex) throw (std::bad_alloc, std:: runtime_error)
 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.

Private Attributes

apol_vector_t_files
apol_vector_t_entries
bool _mls
bool _mls_set

Constructor & Destructor Documentation

sefs_fcfile::sefs_fcfile sefs_callback_fn_t  msg_callback,
void *  varg
throw (std::bad_alloc)
 

Allocate and return a new (and empty) sefs file_context set structure.

Parameters:
msg_callback Callback to invoke as errors/warnings are generated. If NULL, write messages to standard error.
varg Value to be passed as the first parameter to the callback function.
Exceptions:
std::bad_alloc if out of memory

Definition at line 50 of file fcfile.cc.

References apol_vector_create(), apol_vector_destroy(), fcfile_entry_free(), and SEFS_ERR.

00050                                                                                        :sefs_fclist(SEFS_FCLIST_TYPE_FCFILE,
00051                                                                                                         msg_callback, varg)
00052 {
00053         _files = _entries = NULL;
00054         _mls_set = false;
00055         try
00056         {
00057                 if ((_files = apol_vector_create(free)) == NULL)
00058                 {
00059                         SEFS_ERR(this, "%s", strerror(errno));
00060                         throw std::bad_alloc();
00061                 }
00062                 if ((_entries = apol_vector_create(fcfile_entry_free)) == NULL)
00063                 {
00064                         SEFS_ERR(this, "%s", strerror(errno));
00065                         throw std::bad_alloc();
00066                 }
00067         }
00068         catch(...)
00069         {
00070                 apol_vector_destroy(&_files);
00071                 apol_vector_destroy(&_entries);
00072                 throw;
00073         }
00074 }

sefs_fcfile::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 single file_contexts file.

Parameters:
file File contexts file to read.
msg_callback Callback to invoke as errors/warnings are generated. If NULL, write messages to standard error.
varg Value to be passed as the first parameter to the callback function.
Exceptions:
std::bad_alloc if out of memory
std::invalid_argument if the vector is NULL
std::runtime_error if the give file could not be read or is the wrong format

Definition at line 76 of file fcfile.cc.

References apol_vector_create(), apol_vector_create_with_capacity(), apol_vector_destroy(), fcfile_entry_free(), and SEFS_ERR.

00078                                                                                                             :sefs_fclist
00079         (SEFS_FCLIST_TYPE_FCFILE, msg_callback, varg)
00080 {
00081         _files = _entries = NULL;
00082         _mls_set = false;
00083         try
00084         {
00085                 if ((_files = apol_vector_create_with_capacity(1, free)) == NULL)
00086                 {
00087                         SEFS_ERR(this, "%s", strerror(errno));
00088                         throw std::bad_alloc();
00089                 }
00090                 if ((_entries = apol_vector_create(fcfile_entry_free)) == NULL)
00091                 {
00092                         SEFS_ERR(this, "%s", strerror(errno));
00093                         throw std::bad_alloc();
00094                 }
00095                 if (appendFile(file) < 0)
00096                 {
00097                         SEFS_ERR(this, "%s", strerror(errno));
00098                         throw std::runtime_error("Could not construct fcfile with the given file.");
00099                 }
00100         }
00101         catch(...)
00102         {
00103                 apol_vector_destroy(&_files);
00104                 apol_vector_destroy(&_entries);
00105                 throw;
00106         }
00107 }

sefs_fcfile::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)
 

Allocate and return a new sefs file_context set structure from a list of file_context files.

Parameters:
files Vector of file contexts filenames (of type char *) to read.
msg_callback Callback to invoke as errors/warnings are generated. If NULL, write messages to standard error.
varg Value to be passed as the first parameter to the callback function.
Exceptions:
std::bad_alloc if out of memory
std::invalid_argument if the vector is NULL
std::runtime_error if a given file could not be read or is the wrong format

Definition at line 109 of file fcfile.cc.

References apol_vector_create(), apol_vector_create_with_capacity(), apol_vector_destroy(), apol_vector_get_size(), apol_vector_t, fcfile_entry_free(), and SEFS_ERR.

00112                                                                                                                        :sefs_fclist
00113         (SEFS_FCLIST_TYPE_FCFILE, msg_callback, varg)
00114 {
00115         _files = _entries = NULL;
00116         _mls_set = false;
00117         try
00118         {
00119                 if (files == NULL)
00120                 {
00121                         SEFS_ERR(this, "%s", strerror(EINVAL));
00122                         errno = EINVAL;
00123                         throw std::invalid_argument(strerror(EINVAL));
00124                 }
00125                 if ((_files = apol_vector_create_with_capacity(apol_vector_get_size(files), free)) == NULL)
00126                 {
00127                         SEFS_ERR(this, "%s", strerror(errno));
00128                         throw std::bad_alloc();
00129                 }
00130                 if ((_entries = apol_vector_create(fcfile_entry_free)) == NULL)
00131                 {
00132                         SEFS_ERR(this, "%s", strerror(errno));
00133                         throw std::bad_alloc();
00134                 }
00135                 if (appendFileList(files) != apol_vector_get_size(files))
00136                 {
00137                         SEFS_ERR(this, "%s", strerror(errno));
00138                         throw std::runtime_error("Could not construct fcfile with the given vector.");
00139                 }
00140         }
00141         catch(...)
00142         {
00143                 apol_vector_destroy(&_files);
00144                 apol_vector_destroy(&_entries);
00145                 throw;
00146         }
00147 }

sefs_fcfile::~sefs_fcfile  ) 
 

Definition at line 149 of file fcfile.cc.

References _entries, _files, and apol_vector_destroy().

00150 {
00151         apol_vector_destroy(&_files);
00152         apol_vector_destroy(&_entries);
00153 }


Member Function Documentation

int sefs_fcfile::runQueryMap sefs_query query,
sefs_fclist_map_fn_t  fn,
void *  data
throw (std::runtime_error, std::invalid_argument) [virtual]
 

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.

Parameters:
query Query object containing search parameters. If NULL, invoke the callback on all entries.
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 fn will need to clone the entry if it needs it later.
This function must not throw any exceptions. Doing so will most likely corrupt fclist's internal state. Instead, return a negative value to abort processing.
Parameters:
data Arbitrary pointer to be passed into fn as a third parameter.
Returns:
Last value returned by fn() (i.e., >= on success, < 0 on failure). If the fclist has no entries then return 0.
Exceptions:
std::runtime_error Error while reading contexts from the fclist.
std::invalid_argument One or more query arguments is invalid.

Implements sefs_fclist.

Definition at line 155 of file fcfile.cc.

References sefs_entry::_context, sefs_entry::_objectClass, sefs_entry::_path, apol_context_get_range(), apol_mls_range_compare(), apol_mls_range_create_from_string(), apol_mls_range_destroy(), apol_mls_range_t, apol_str_strcmp(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_t, sefs_context_node::context, QPOL_CLASS_ALL, query_create_candidate_type(), query_str_compare(), sefs_context_node::range, sefs_context_node::role, SEFS_ERR, sefs_context_node::type, and sefs_context_node::user.

Referenced by fcfile_query().

00157 {
00158         apol_vector_t *type_list = NULL;
00159         apol_mls_range_t *range = NULL;
00160         int retval = 0;
00161         try
00162         {
00163                 if (query != NULL)
00164                 {
00165                         query->compile();
00166                         if (policy != NULL)
00167                         {
00168                                 if (query->_type != NULL && query->_indirect &&
00169                                     (type_list =
00170                                      query_create_candidate_type(policy, query->_type, query->_retype, query->_regex,
00171                                                                  query->_indirect)) == NULL)
00172                                 {
00173                                         SEFS_ERR(this, "%s", strerror(errno));
00174                                         throw std::runtime_error(strerror(errno));
00175                                 }
00176                                 if (query->_range != NULL && query->_rangeMatch != 0 &&
00177                                     (range = apol_mls_range_create_from_string(policy, query->_range)) == NULL)
00178                                 {
00179                                         SEFS_ERR(this, "%s", strerror(errno));
00180                                         throw std::runtime_error(strerror(errno));
00181                                 }
00182                         }
00183                 }
00184 
00185                 for (size_t i = 0; i < apol_vector_get_size(_entries); i++)
00186                 {
00187                         sefs_entry *e = static_cast < sefs_entry * >(apol_vector_get_element(_entries, i));
00188                         if (query != NULL)
00189                         {
00190                                 const struct sefs_context_node *context = e->_context;
00191                                 if (!query_str_compare(context->user, query->_user, query->_reuser, query->_regex))
00192                                 {
00193                                         continue;
00194                                 }
00195                                 if (!query_str_compare(context->role, query->_role, query->_rerole, query->_regex))
00196                                 {
00197                                         continue;
00198                                 }
00199 
00200                                 bool str_matched = false, pol_matched = false;
00201                                 str_matched = query_str_compare(context->type, query->_type, query->_retype, query->_regex);
00202                                 if (type_list != NULL && !str_matched)
00203                                 {
00204                                         size_t index;
00205                                         pol_matched =
00206                                                 (apol_vector_get_index(type_list, context->type, apol_str_strcmp, NULL, &index) <
00207                                                  0);
00208                                 }
00209                                 if (!str_matched && !pol_matched)
00210                                 {
00211                                         continue;
00212                                 }
00213 
00214                                 if (isMLS())
00215                                 {
00216                                         if (range == NULL)
00217                                         {
00218                                                 if (!query_str_compare
00219                                                     (context->range, query->_range, query->_rerange, query->_regex))
00220                                                 {
00221                                                         continue;
00222                                                 }
00223                                         }
00224                                         else
00225                                         {
00226                                                 const apol_mls_range_t *context_range = apol_context_get_range(context->context);
00227                                                 int ret;
00228                                                 ret = apol_mls_range_compare(policy, context_range, range, query->_rangeMatch);
00229                                                 if (ret <= 0)
00230                                                 {
00231                                                         continue;
00232                                                 }
00233                                         }
00234                                 }
00235 
00236                                 if (e->_objectClass != QPOL_CLASS_ALL && query->_objclass != QPOL_CLASS_ALL &&
00237                                     e->_objectClass != query->_objclass)
00238                                 {
00239                                         continue;
00240                                 }
00241 
00242                                 bool path_matched;
00243 
00244                                 if (query->_path == NULL || query->_path[0] == '\0')
00245                                 {
00246                                         path_matched = true;
00247                                 }
00248                                 else
00249                                 {
00250                                         path_matched = false;
00251                                         char *anchored_path = NULL;
00252                                         if (asprintf(&anchored_path, "^%s$", e->_path) < 0)
00253                                         {
00254                                                 SEFS_ERR(this, "%s", strerror(errno));
00255                                                 throw std::runtime_error(strerror(errno));
00256                                         }
00257 
00258                                         regex_t regex;
00259                                         if (regcomp(&regex, anchored_path, REG_EXTENDED | REG_NOSUB) != 0)
00260                                         {
00261                                                 free(anchored_path);
00262                                                 SEFS_ERR(this, "%s", strerror(errno));
00263                                                 throw std::runtime_error(strerror(errno));
00264                                         }
00265 
00266                                         bool compval = query_str_compare(query->_path, anchored_path, &regex, true);
00267                                         free(anchored_path);
00268                                         regfree(&regex);
00269                                         if (compval)
00270                                         {
00271                                                 path_matched = true;
00272                                         }
00273                                 }
00274                                 if (!path_matched)
00275                                 {
00276                                         continue;
00277                                 }
00278                         }
00279 
00280                         // if reached this point, then all criteria passed, so
00281                         // invoke the mapping function
00282 
00283                         if ((retval = fn(this, e, data)) < 0)
00284                         {
00285                                 return retval;
00286                         }
00287                 }
00288         }
00289         catch(...)
00290         {
00291                 apol_vector_destroy(&type_list);
00292                 apol_mls_range_destroy(&range);
00293                 throw;
00294         }
00295         apol_vector_destroy(&type_list);
00296         return retval;
00297 }

bool sefs_fcfile::isMLS  )  const [virtual]
 

Determine if the contexts in the fcfile contain MLS fields.

Returns:
true if MLS fields are present, false if not or undeterminable.

Implements sefs_fclist.

Definition at line 299 of file fcfile.cc.

00300 {
00301         if (_mls_set)
00302         {
00303                 return _mls;
00304         }
00305         return false;
00306 }

int sefs_fcfile::appendFile const char *  file  )  throw (std::bad_alloc, std::invalid_argument, std::runtime_error)
 

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.

Parameters:
file File containing entries to append.
Returns:
0 on success or < 0 on failure; if the call fails, the fcfile will be unchanged.
Exceptions:
std::bad_alloc if out of memory
std::invalid_argument if the file name is NULL
std::runtime_error if a given file could not be read or is the wrong format

Definition at line 308 of file fcfile.cc.

References apol_vector_append(), apol_vector_get_element(), apol_vector_get_size(), apol_vector_remove(), fcfile_entry_free(), getline(), and SEFS_ERR.

Referenced by fcfile_query(), and sefs_fcfile_append_file().

00309 {
00310         FILE *fc_file = NULL;
00311         char *line = NULL, *name_dup = NULL;
00312         size_t line_len = 0;
00313         size_t last_entry = apol_vector_get_size(_entries);
00314         int retval, error = 0;
00315 
00316         regex_t line_regex, context_regex;
00317         bool is_line_compiled = false;
00318         bool is_context_compiled = false;
00319 
00320         try
00321         {
00322                 if (file == NULL)
00323                 {
00324                         errno = EINVAL;
00325                         SEFS_ERR(this, "%s", strerror(EINVAL));
00326                         throw std::invalid_argument(strerror(EINVAL));
00327                 }
00328 
00329                 fc_file = fopen(file, "r");
00330                 if (!fc_file)
00331                 {
00332                         SEFS_ERR(this, "Unable to open file %s", file);
00333                         throw std::runtime_error(strerror(error));
00334                 }
00335 
00336                 if ((name_dup = strdup(file)) == NULL)
00337                 {
00338                         SEFS_ERR(this, "%s", strerror(error));
00339                         throw std::bad_alloc();
00340                 }
00341 
00342                 if (regcomp(&line_regex, "^([^[:blank:]]+)[[:blank:]]+(-.[[:blank:]]+)?([^-].+)$", REG_EXTENDED) != 0)
00343                 {
00344                         SEFS_ERR(this, "%s", strerror(error));
00345                         throw std::bad_alloc();
00346                 }
00347                 is_line_compiled = true;
00348 
00349                 if (regcomp(&context_regex, "^([^:]+):([^:]+):([^:]+):?(.*)$", REG_EXTENDED) != 0)
00350                 {
00351                         SEFS_ERR(this, "%s", strerror(error));
00352                         throw std::bad_alloc();
00353                 }
00354                 is_context_compiled = true;
00355 
00356                 while (!feof(fc_file))
00357                 {
00358                         if (getline(&line, &line_len, fc_file) == -1)
00359                         {
00360                                 if (feof(fc_file))
00361                                 {
00362                                         break;
00363                                 }
00364                                 else
00365                                 {
00366                                         SEFS_ERR(this, "%s", strerror(error));
00367                                         throw std::bad_alloc();
00368                                 }
00369                         }
00370                         parse_line(name_dup, line, &line_regex, &context_regex);
00371                 }
00372 
00373                 if (apol_vector_append(_files, name_dup) < 0)
00374                 {
00375                         SEFS_ERR(this, "%s", strerror(error));
00376                         throw std::bad_alloc();
00377                 }
00378                 name_dup = NULL;
00379 
00380                 retval = 0;
00381         }
00382         catch(...)
00383         {
00384                 error = errno;
00385                 // discard all entries that were read from this file_contexts
00386                 size_t i = apol_vector_get_size(_entries);
00387                 for (; i > last_entry; i--)
00388                 {
00389                         sefs_entry *e = static_cast < sefs_entry * >(apol_vector_get_element(_entries, i - 1));
00390                         fcfile_entry_free(e);
00391                         apol_vector_remove(_entries, i - 1);
00392                 }
00393                 retval = -1;
00394         }
00395 
00396         if (fc_file != NULL)
00397         {
00398                 fclose(fc_file);
00399         }
00400         if (is_line_compiled)
00401         {
00402                 regfree(&line_regex);
00403         }
00404         if (is_context_compiled)
00405         {
00406                 regfree(&context_regex);
00407         }
00408         free(name_dup);
00409         free(line);
00410         errno = error;
00411         return retval;
00412 }

size_t sefs_fcfile::appendFileList const apol_vector_t files  )  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.

Parameters:
files Vector of filenames (type char *) to append; these files will be appended in the order they appear in the vector.
Returns:
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.
Exceptions:
std::bad_alloc if out of memory
std::invalid_argument if the vector is NULL
std::runtime_error if a given file could not be read or is the wrong format

Definition at line 414 of file fcfile.cc.

References apol_vector_get_element(), apol_vector_get_size(), apol_vector_t, and SEFS_ERR.

Referenced by sefs_fcfile_append_file_list().

00415 {
00416         size_t i;
00417         if (files == NULL)
00418         {
00419                 SEFS_ERR(this, "%s", strerror(EINVAL));
00420                 errno = EINVAL;
00421                 throw new std::invalid_argument(strerror(EINVAL));
00422         }
00423         for (i = 0; i < apol_vector_get_size(files); i++)
00424         {
00425                 if (appendFile(static_cast < char *>(apol_vector_get_element(files, i))) < 0)
00426                 {
00427                         return i;
00428                 }
00429         }
00430         return i;
00431 }

const apol_vector_t * sefs_fcfile::fileList  )  const
 

Get a list of all files contributing to the entries in a sefs file_contexts set.

Returns:
Vector of file paths (char *) of all files contributing to the set; the caller should not destroy or otherwise modify the returned vector.

Definition at line 433 of file fcfile.cc.

References apol_vector_t.

Referenced by sefs_fcfile_get_file_list().

00434 {
00435         return _files;
00436 }

void sefs_fcfile::parse_line const char *  origin,
const char *  line,
regex_t *  line_regex,
regex_t *  context_regex
throw (std::bad_alloc, std:: runtime_error) [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.

Parameters:
origin File from which this line originated.
line File contexts line to parse.
line_regex Compiled regular expression pattern for an entire line.
context_regex Compiled regular expression pattern for the SELinux portion of a line.
Exceptions:
std::bad_alloc if out of memory
std::runtime_error if the give file could not be read or is the wrong format

Definition at line 440 of file fcfile.cc.

References apol_bst_insert_and_get(), apol_str_trim(), apol_vector_append(), and SEFS_ERR.

00442 {
00443         int error = 0;
00444 
00445         char *s = strdup(line);
00446         char *path;
00447 
00448         if (s == NULL)
00449         {
00450                 error = errno;
00451                 SEFS_ERR(this, "%s", strerror(error));
00452                 throw std::bad_alloc();
00453         }
00454 
00455         apol_str_trim(s);
00456         if (s[0] == '#' || s[0] == '\0')
00457         {
00458                 free(s);
00459                 return;
00460         }
00461 
00462         try
00463         {
00464                 const size_t nmatch = 5;
00465                 regmatch_t pmatch[nmatch];
00466 
00467                 if (regexec(line_regex, s, nmatch, pmatch, 0) != 0)
00468                 {
00469                         error = EIO;
00470                         SEFS_ERR(this, "fcfile line is not legal:\n%s", s);
00471                         throw std::runtime_error(strerror(error));
00472                 }
00473 
00474                 assert(pmatch[1].rm_so == 0);
00475                 s[pmatch[1].rm_eo] = '\0';
00476                 if ((path = strdup(s)) == NULL)
00477                 {
00478                         SEFS_ERR(this, "%s", strerror(errno));
00479                         throw std::runtime_error(strerror(error));
00480                 }
00481                 if (apol_bst_insert_and_get(path_tree, (void **)&path, NULL) < 0)
00482                 {
00483                         free(path);
00484                         SEFS_ERR(this, "%s", strerror(errno));
00485                         throw std::runtime_error(strerror(error));
00486                 }
00487 
00488                 uint32_t objclass;
00489                 if (pmatch[2].rm_so != -1)
00490                 {
00491                         switch (s[pmatch[2].rm_so + 1])
00492                         {
00493                         case '-':
00494                                 objclass = QPOL_CLASS_FILE;
00495                                 break;
00496                         case 'd':
00497                                 objclass = QPOL_CLASS_DIR;
00498                                 break;
00499                         case 'c':
00500                                 objclass = QPOL_CLASS_CHR_FILE;
00501                                 break;
00502                         case 'b':
00503                                 objclass = QPOL_CLASS_BLK_FILE;
00504                                 break;
00505                         case 'p':
00506                                 objclass = QPOL_CLASS_FIFO_FILE;
00507                                 break;
00508                         case 'l':
00509                                 objclass = QPOL_CLASS_LNK_FILE;
00510                                 break;
00511                         case 's':
00512                                 objclass = QPOL_CLASS_SOCK_FILE;
00513                                 break;
00514                         default:
00515                                 error = EIO;
00516                                 SEFS_ERR(this, "%s", "Invalid file context object class.");
00517                                 throw std::runtime_error(strerror(error));
00518                         }
00519                 }
00520                 else
00521                 {
00522                         // no object class explicitly given
00523                         objclass = QPOL_CLASS_ALL;
00524                 }
00525 
00526                 assert(pmatch[3].rm_so != -1);
00527                 char *context_str = s + pmatch[3].rm_so;
00528                 char *user, *role, *type, *range;
00529 
00530                 if (strcmp(context_str, "<<none>>") == 0)
00531                 {
00532                         user = role = type = range = "";
00533                 }
00534                 else
00535                 {
00536                         if (regexec(context_regex, context_str, nmatch, pmatch, 0) != 0)
00537                         {
00538                                 error = EIO;
00539                                 SEFS_ERR(this, "fcfile context is not legal:\n%s", context_str);
00540                                 throw std::runtime_error(strerror(error));
00541                         }
00542 
00543                         assert(pmatch[1].rm_so == 0);
00544                         context_str[pmatch[1].rm_eo] = '\0';
00545                         user = context_str;
00546 
00547                         assert(pmatch[2].rm_so != -1);
00548                         context_str[pmatch[2].rm_eo] = '\0';
00549                         role = context_str + pmatch[2].rm_so;
00550 
00551                         assert(pmatch[3].rm_so != -1);
00552                         context_str[pmatch[3].rm_eo] = '\0';
00553                         type = context_str + pmatch[3].rm_so;
00554 
00555                         range = NULL;
00556                         if (pmatch[4].rm_so != -1)
00557                         {
00558                                 range = context_str + pmatch[4].rm_so;
00559                         }
00560                 }
00561                 if (range != NULL & range[0] != '\0')
00562                 {
00563                         if (_mls_set && !_mls)
00564                         {
00565                                 error = EIO;
00566                                 SEFS_ERR(this, "fcfile context is MLS, but fcfile is not:\n%s", context_str);
00567                                 throw std::runtime_error(strerror(error));
00568                         }
00569                         _mls = true;
00570                         _mls_set = true;
00571                 }
00572                 else
00573                 {
00574                         if (_mls_set && !_mls && strcmp(context_str, "<<none>>") != 0)
00575                         {
00576                                 error = EIO;
00577                                 SEFS_ERR(this, "fcfile context is not MLS, but fcfile is:\n%s", context_str);
00578                                 throw std::runtime_error(strerror(error));
00579                         }
00580                         _mls = true;
00581                         _mls_set = false;
00582                 }
00583                 struct sefs_context_node *context = getContext(user, role, type, range);
00584                 sefs_entry *entry = new sefs_entry(this, context, objclass, path, origin);
00585 
00586                 if (apol_vector_append(_entries, static_cast < void *>(entry)) < 0)
00587                 {
00588                         error = errno;
00589                         delete entry;
00590                         SEFS_ERR(this, "%s", strerror(error));
00591                         throw std::bad_alloc();
00592                 }
00593         }
00594 
00595         catch(...)
00596         {
00597                 free(s);
00598                 errno = error;
00599                 throw;
00600         }
00601 
00602         free(s);
00603 }

apol_vector_t * sefs_fclist::runQuery sefs_query query  )  throw (std::bad_alloc, std::runtime_error, std::invalid_argument) [inherited]
 

Perform a sefs query on the given file context list object and return a list of matching entries.

Parameters:
query Query object containing search parameters. If NULL, return all contexts.
Returns:
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.
Exceptions:
std::bad_alloc Out of memory.
std::runtime_error Error while reading contexts from the fclist.
std::invalid_argument One or more query arguments is invalid.

Definition at line 156 of file fclist.cc.

References apol_vector_create(), apol_vector_destroy(), apol_vector_t, fclist_entry_free(), and map_to_vector().

Referenced by fcfile_query(), and sefs_fclist_run_query().

00157 {
00158         apol_vector_t *v = NULL;
00159         try
00160         {
00161                 if ((v = apol_vector_create(fclist_entry_free)) == NULL)
00162                 {
00163                         throw std::bad_alloc();
00164                 }
00165                 if (runQueryMap(query, map_to_vector, v) < 0)
00166                 {
00167                         throw std::bad_alloc();
00168                 }
00169         }
00170         catch(...)
00171         {
00172                 apol_vector_destroy(&v);
00173                 throw;
00174         }
00175         return v;
00176 }

void sefs_fclist::associatePolicy apol_policy_t new_policy  )  [inherited]
 

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.

Parameters:
policy Policy to associate with fclist. If NULL, remove any policy association. While policy is associated with fclist the caller should not destroy policy.
See also:
sefs_query_set_type()

sefs_query_set_range()

Definition at line 178 of file fclist.cc.

References apol_bst_inorder_map(), apol_policy_t, sefs_fclist::context_tree, fclist_sefs_node_convert(), and sefs_fclist::policy.

Referenced by fclist_sefs_node_convert(), and sefs_fclist_associate_policy().

00179 {
00180         policy = new_policy;
00181         if (policy != NULL)
00182         {
00183                 if (apol_bst_inorder_map(context_tree, fclist_sefs_node_convert, policy) < 0)
00184                 {
00185                         throw new std::bad_alloc();
00186                 }
00187         }
00188 }

apol_policy_t * sefs_fclist::associatePolicy  )  const [inherited]
 

Return the policy currently associated with this fclist.

Do not destroy the policy without first unassociating it (via call to sefs_fclist::associatePolicy(NULL)).

Returns:
Currently associated policy, or NULL if none is set.

Definition at line 190 of file fclist.cc.

References apol_policy_t.

00191 {
00192         return policy;
00193 }

sefs_fclist_type_e sefs_fclist::fclist_type  )  const [inherited]
 

Get the type of fclist object represented by fclist.

Returns:
The type of fclist object or SEFS_FCLIST_TYPE_NONE on error.

Definition at line 195 of file fclist.cc.

References sefs_fclist_type_e.

Referenced by sefs_fclist_get_fclist_type().

00196 {
00197         return _fclist_type;
00198 }

struct sefs_context_node * sefs_fclist::getContext const char *  user,
const char *  role,
const char *  type,
const char *  range
throw (std::bad_alloc) [protected, inherited]
 

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.

Parameters:
user User component of the context. The string will be duplicated.
role Role component of the context. The string will be duplicated.
type Type component of the context. The string will be duplicated.
range Range component of the context. The string will be duplicated, or NULL if no range exists.
Returns:
A context node. Do not free() it.

Definition at line 282 of file fclist.cc.

References apol_bst_get_element(), apol_bst_insert(), apol_bst_insert_and_get(), apol_context_create(), apol_context_destroy(), apol_context_set_range(), apol_context_set_role(), apol_context_set_type(), apol_context_set_user(), apol_context_t, apol_mls_range_create_from_literal(), apol_mls_range_destroy(), apol_mls_range_t, fclist_sefs_context_node_free(), fclist_sefs_node_make_string(), and SEFS_ERR.

00284 {
00285         char *u = NULL, *r = NULL, *t = NULL, *m = NULL;
00286         if ((u = strdup(user)) == NULL)
00287         {
00288                 SEFS_ERR(this, "%s", strerror(errno));
00289                 throw std::runtime_error(strerror(errno));
00290         }
00291         if (apol_bst_insert_and_get(user_tree, (void **)&u, NULL) < 0)
00292         {
00293                 free(u);
00294                 SEFS_ERR(this, "%s", strerror(errno));
00295                 throw std::runtime_error(strerror(errno));
00296         }
00297 
00298         if ((r = strdup(role)) == NULL)
00299         {
00300                 SEFS_ERR(this, "%s", strerror(errno));
00301                 throw std::runtime_error(strerror(errno));
00302         }
00303         if (apol_bst_insert_and_get(role_tree, (void **)&r, NULL) < 0)
00304         {
00305                 free(r);
00306                 SEFS_ERR(this, "%s", strerror(errno));
00307                 throw std::runtime_error(strerror(errno));
00308         }
00309 
00310         if ((t = strdup(type)) == NULL)
00311         {
00312                 SEFS_ERR(this, "%s", strerror(errno));
00313                 throw std::runtime_error(strerror(errno));
00314         }
00315         if (apol_bst_insert_and_get(type_tree, (void **)&t, NULL) < 0)
00316         {
00317                 free(t);
00318                 SEFS_ERR(this, "%s", strerror(errno));
00319                 throw std::runtime_error(strerror(errno));
00320         }
00321 
00322         if (range == NULL || range[0] == '\0')
00323         {
00324                 m = NULL;
00325         }
00326         else
00327         {
00328                 if ((m = strdup(range)) == NULL)
00329                 {
00330                         SEFS_ERR(this, "%s", strerror(errno));
00331                         throw std::runtime_error(strerror(errno));
00332                 }
00333                 if (apol_bst_insert_and_get(range_tree, (void **)&m, NULL) < 0)
00334                 {
00335                         free(m);
00336                         SEFS_ERR(this, "%s", strerror(errno));
00337                         throw std::runtime_error(strerror(errno));
00338                 }
00339         }
00340 
00341         struct sefs_context_node *node = NULL;
00342         apol_context_t *context = NULL;
00343         try
00344         {
00345                 if ((node = static_cast < struct sefs_context_node * >(calloc(1, sizeof(*node)))) == NULL)
00346                 {
00347                         SEFS_ERR(this, "%s", strerror(errno));
00348                         throw std::runtime_error(strerror(errno));
00349                 }
00350 
00351                 node->user = u;
00352                 node->role = r;
00353                 node->type = t;
00354                 node->range = m;
00355 
00356                 void *v;
00357                 if (apol_bst_get_element(context_tree, node, NULL, &v) == 0)
00358                 {
00359                         // context already exists
00360                         fclist_sefs_context_node_free(node);
00361                         return static_cast < struct sefs_context_node *>(v);
00362                 }
00363 
00364                 apol_mls_range_t *apol_range = NULL;
00365                 if (m != NULL)
00366                 {
00367                         if ((apol_range = apol_mls_range_create_from_literal(m)) == NULL)
00368                         {
00369                                 SEFS_ERR(this, "%s", strerror(errno));
00370                                 throw std::bad_alloc();
00371                         }
00372                 }
00373 
00374                 if ((context = apol_context_create()) == NULL)
00375                 {
00376                         SEFS_ERR(this, "%s", strerror(errno));
00377                         apol_mls_range_destroy(&apol_range);
00378                         throw std::runtime_error(strerror(errno));
00379                 }
00380                 if (apol_context_set_user(NULL, context, u) < 0 ||
00381                     apol_context_set_role(NULL, context, r) < 0 || apol_context_set_type(NULL, context, t) < 0 ||
00382                     apol_context_set_range(NULL, context, apol_range) < 0)
00383                 {
00384                         SEFS_ERR(this, "%s", strerror(errno));
00385                         apol_mls_range_destroy(&apol_range);
00386                         throw std::runtime_error(strerror(errno));
00387                 }
00388 
00389                 node->context = context;
00390                 context = NULL;
00391 
00392                 if (fclist_sefs_node_make_string(node) < 0)
00393                 {
00394                         SEFS_ERR(this, "%s", strerror(errno));
00395                         throw std::runtime_error(strerror(errno));
00396                 }
00397 
00398                 if (apol_bst_insert(context_tree, node, NULL) != 0)
00399                 {
00400                         SEFS_ERR(this, "%s", strerror(errno));
00401                         throw std::runtime_error(strerror(errno));
00402                 }
00403         }
00404         catch(...)
00405         {
00406                 fclist_sefs_context_node_free(node);
00407                 apol_context_destroy(&context);
00408                 throw;
00409         }
00410 
00411         return node;
00412 }

struct sefs_context_node * sefs_fclist::getContext const security_context_t  scon  )  throw (std::bad_alloc) [protected, inherited]
 

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.

Parameters:
scon Security context from which to obtain a node.
Returns:
A context node. Do not free() it.

Definition at line 414 of file fclist.cc.

00415 {
00416         context_t con;
00417         if ((con = context_new(scon)) == 0)
00418         {
00419                 throw std::bad_alloc();
00420         }
00421         const char *user = context_user_get(con);
00422         const char *role = context_role_get(con);
00423         const char *type = context_type_get(con);
00424         const char *range = context_range_get(con);
00425         struct sefs_context_node *node = NULL;
00426         try
00427         {
00428                 node = getContext(user, role, type, range);
00429         }
00430         catch(...)
00431         {
00432                 context_free(con);
00433                 throw;
00434         }
00435         context_free(con);
00436         return node;
00437 }


Member Data Documentation

apol_vector_t* sefs_fcfile::_files [private]
 

Definition at line 198 of file fcfile.hh.

Referenced by ~sefs_fcfile().

apol_vector_t * sefs_fcfile::_entries [private]
 

Definition at line 198 of file fcfile.hh.

Referenced by ~sefs_fcfile().

bool sefs_fcfile::_mls [private]
 

Definition at line 199 of file fcfile.hh.

bool sefs_fcfile::_mls_set [private]
 

Definition at line 199 of file fcfile.hh.

apol_policy_t* sefs_fclist::policy [protected, inherited]
 

Definition at line 239 of file fclist.hh.

Referenced by sefs_fclist::associatePolicy().

struct apol_bst* sefs_fclist::user_tree [protected, inherited]
 

Definition at line 240 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst * sefs_fclist::role_tree [protected, inherited]
 

Definition at line 240 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst * sefs_fclist::type_tree [protected, inherited]
 

Definition at line 240 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst * sefs_fclist::range_tree [protected, inherited]
 

Definition at line 240 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst * sefs_fclist::path_tree [protected, inherited]
 

Definition at line 240 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst* sefs_fclist::dev_tree [protected, inherited]
 

Definition at line 241 of file fclist.hh.

Referenced by sefs_fclist::~sefs_fclist().

struct apol_bst* sefs_fclist::context_tree [protected, inherited]
 

Definition at line 242 of file fclist.hh.

Referenced by sefs_fclist::associatePolicy(), and sefs_fclist::~sefs_fclist().


The documentation for this class was generated from the following files: