sefs_db Class Reference

#include <db.hh>

Inheritance diagram for sefs_db:

sefs_fclist List of all members.

Detailed Description

This class represents a database that maps files to their SELinux file contexts.

Definition at line 48 of file db.hh.


Public Member Functions

 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 initialized with entries from the filesystem fs.
 sefs_db (const char *filename, 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 path.
 ~sefs_db ()
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 stored in this database contain MLS fields.
void save (const char *filename) throw (std::invalid_argument, std::runtime_error)
 Write a database to disk, overwriting any existing file.
time_t getCTime () const
 Get the creation time of a sefs database.
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.

Static Public Member Functions

bool isDB (const char *filename)
 Determine if the given file is a valid sefs_db.

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 upgradeToDB2 () throw (std::runtime_error)
 Upgrade an existing version 1 database to version 2.
const struct sefs_context_nodegetContextNode (const sefs_entry *entry)
sefs_entrygetEntry (const struct sefs_context_node *context, uint32_t objectClass, const char *path, ino64_t inode, const char *dev) throw (std::bad_alloc)

Private Attributes

sqlite3 * _db
time_t _ctime

Friends

int db_create_from_filesystem (sefs_fclist *fclist __attribute__((unused)), const sefs_entry *entry, void *arg)
struct sefs_context_nodedb_get_context (sefs_db *, const char *, const char *, const char *, const char *) throw (std::bad_alloc)
sefs_entrydb_get_entry (sefs_db *, const struct sefs_context_node *, uint32_t, const char *, ino64_t, const char *) throw (std::bad_alloc)

Constructor & Destructor Documentation

sefs_db::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 initialized with entries from the filesystem fs.

Parameters:
fs Sefs filesystem from which to create the database.
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::invalid_argument Filesystem does not exist.
std::runtime_error Error while reading the database.

Definition at line 521 of file db.cc.

References db_convert::_isMLS, db_create_from_filesystem(), DB_SCHEMA_MLS, DB_SCHEMA_NONMLS, SEFS_ERR, and SEFS_INFO.

00521                                                                                                                              :sefs_fclist
00522         (SEFS_FCLIST_TYPE_DB, msg_callback,
00523          varg)
00524 {
00525         if (fs == NULL)
00526         {
00527                 errno = EINVAL;
00528                 SEFS_ERR(this, "%s", strerror(EINVAL));
00529                 throw std::invalid_argument(strerror(EINVAL));
00530         }
00531 
00532         SEFS_INFO(this, "Reading contexts from filesystem %s.", fs->root());
00533         char *errmsg = NULL;
00534         try
00535         {
00536                 if (sqlite3_open(":memory:", &_db) != SQLITE_OK)
00537                 {
00538                         SEFS_ERR(this, "%s", sqlite3_errmsg(_db));
00539                         throw std::runtime_error(sqlite3_errmsg(_db));
00540                 }
00541                 int rc;
00542                 if (fs->isMLS())
00543                 {
00544                         rc = sqlite3_exec(_db, DB_SCHEMA_MLS, NULL, 0, &errmsg);
00545                 }
00546                 else
00547                 {
00548                         rc = sqlite3_exec(_db, DB_SCHEMA_NONMLS, NULL, 0, &errmsg);
00549                 }
00550                 if (rc != SQLITE_OK)
00551                 {
00552                         SEFS_ERR(this, "%s", errmsg);
00553                         throw std::runtime_error(errmsg);
00554                 }
00555 
00556                 db_convert dbc(this, _db);
00557                 dbc._isMLS = fs->isMLS();
00558                 if (fs->runQueryMap(NULL, db_create_from_filesystem, &dbc) < 0)
00559                 {
00560                         throw std::runtime_error(strerror(errno));
00561                 }
00562 
00563                 // store metadata about the database
00564                 const char *dbversion = DB_MAX_VERSION;
00565                 char hostname[64];
00566                 gethostname(hostname, sizeof(hostname));
00567                 hostname[63] = '\0';
00568                 _ctime = time(NULL);
00569                 char datetime[32];
00570                 ctime_r(&_ctime, datetime);
00571 
00572                 char *info_insert = NULL;
00573                 if (asprintf(&info_insert,
00574                              "INSERT INTO info (key,value) VALUES ('dbversion','%s');"
00575                              "INSERT INTO info (key,value) VALUES ('hostname','%s');"
00576                              "INSERT INTO info (key,value) VALUES ('datetime','%s');", dbversion, hostname, datetime) < 0)
00577                 {
00578                         SEFS_ERR(this, "%s", strerror(errno));
00579                         throw std::runtime_error(strerror(errno));
00580                 }
00581                 rc = sqlite3_exec(_db, info_insert, NULL, NULL, &errmsg);
00582                 free(info_insert);
00583                 if (rc != SQLITE_OK)
00584                 {
00585                         SEFS_ERR(this, "%s", errmsg);
00586                         throw std::runtime_error(errmsg);
00587                 }
00588 
00589         }
00590         catch(...)
00591         {
00592                 if (errmsg != NULL)
00593                 {
00594                         sqlite3_free(errmsg);
00595                 }
00596                 sqlite3_close(_db);
00597                 throw;
00598         }
00599 }

sefs_db::sefs_db const char *  filename,
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 path.

Parameters:
filename Name of a sefs database from which to load.
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::invalid_argument Database does not exist.
std::runtime_error Error while reading the database.

Definition at line 601 of file db.cc.

References db_ctime_callback(), db_row_exist_callback(), isDB(), SEFS_ERR, SEFS_INFO, and SEFS_WARN.

00603                                                                                                         :sefs_fclist
00604         (SEFS_FCLIST_TYPE_DB, msg_callback, varg)
00605 {
00606         if (filename == NULL)
00607         {
00608                 errno = EINVAL;
00609                 SEFS_ERR(this, "%s", strerror(EINVAL));
00610                 throw std::invalid_argument(strerror(EINVAL));
00611         }
00612 
00613         if (!sefs_db::isDB(filename))
00614         {
00615                 SEFS_ERR(this, "%s", strerror(errno));
00616                 throw std::runtime_error(strerror(errno));
00617         }
00618 
00619         if (sqlite3_open(filename, &_db) != SQLITE_OK)
00620         {
00621                 SEFS_ERR(this, "%s", sqlite3_errmsg(_db));
00622                 sqlite3_close(_db);
00623                 throw std::runtime_error(strerror(errno));
00624         }
00625 
00626         char *errmsg = NULL;
00627 
00628         const char *select_stmt = "SELECT * FROM info WHERE key = 'dbversion' AND value >= " DB_MAX_VERSION;
00629         bool answer = false;
00630         if (sqlite3_exec(_db, select_stmt, db_row_exist_callback, &answer, &errmsg) != SQLITE_OK)
00631         {
00632                 SEFS_ERR(this, "%s", errmsg);
00633                 sqlite3_free(errmsg);
00634                 sqlite3_close(_db);
00635                 throw std::runtime_error(strerror(errno));
00636         }
00637         if (!answer)
00638         {
00639                 SEFS_INFO(this, "Upgrading database %s.", filename);
00640                 SEFS_WARN(this, "%s is a pre-libsefs-4.0 database and will be upgraded.", filename);
00641                 upgradeToDB2();
00642         }
00643 
00644         // get ctime from db
00645         _ctime = 0;
00646         const char *ctime_stmt = "SELECT value FROM info WHERE key='datetime'";
00647         if (sqlite3_exec(_db, ctime_stmt, db_ctime_callback, &_ctime, &errmsg) != SQLITE_OK)
00648         {
00649                 SEFS_ERR(this, "%s", errmsg);
00650                 sqlite3_free(errmsg);
00651                 sqlite3_close(_db);
00652                 throw std::runtime_error(strerror(errno));
00653         }
00654 }

sefs_db::~sefs_db  ) 
 

Definition at line 656 of file db.cc.

References _db.

00657 {
00658         if (_db != NULL)
00659         {
00660                 sqlite3_close(_db);
00661                 _db = NULL;
00662         }
00663 }


Member Function Documentation

int sefs_db::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 665 of file db.cc.

References apol_mls_range_create_from_string(), apol_mls_range_destroy(), apol_str_append(), apol_str_appendf(), apol_vector_destroy(), db_query_arg::db, db_dev_compare(), db_path_compare(), db_query_callback(), db_range_compare(), db_role_compare(), db_type_compare(), db_user_compare(), query_create_candidate_type(), and SEFS_ERR.

00666 {
00667         // copy the query fields over to the C land struct; this is
00668         // because the query members are private, and thus not accessible
00669         // from a C callback
00670         struct db_query_arg q;
00671         memset(&q, 0, sizeof(q));
00672 
00673         q.db = this;
00674         if (query != NULL)
00675         {
00676                 query->compile();
00677                 if (policy != NULL)
00678                 {
00679                         if (query->_type != NULL && query->_indirect)
00680                         {
00681                                 q.type_list =
00682                                         query_create_candidate_type(policy, query->_type, query->_retype, query->_regex,
00683                                                                     query->_indirect);
00684                                 if (q.type_list == NULL)
00685                                 {
00686                                         SEFS_ERR(this, "%s", strerror(errno));
00687                                         throw std::runtime_error(strerror(errno));
00688                                 }
00689                         }
00690                         if (query->_range != NULL && query->_rangeMatch != 0)
00691                         {
00692                                 q.apol_range = apol_mls_range_create_from_string(policy, query->_range);
00693                                 if (q.apol_range == NULL)
00694                                 {
00695                                         apol_vector_destroy(&q.type_list);
00696                                         SEFS_ERR(this, "%s", strerror(errno));
00697                                         throw std::runtime_error(strerror(errno));
00698                                 }
00699                         }
00700                 }
00701                 q.user = query->_user;
00702                 q.role = query->_role;
00703                 q.type = query->_type;
00704                 q.range = query->_range;
00705                 q.path = query->_path;
00706                 q.dev = query->_dev;
00707                 q.regex = query->_regex;
00708                 q.reuser = query->_reuser;
00709                 q.rerole = query->_rerole;
00710                 q.retype = query->_retype;
00711                 q.rerange = query->_rerange;
00712                 q.repath = query->_repath;
00713                 q.redev = query->_redev;
00714                 q.rangeMatch = query->_rangeMatch;
00715         }
00716         q.policy = this->policy;
00717         q.db_is_mls = isMLS();
00718         q.fn = fn;
00719         q.data = data;
00720         q.retval = 0;
00721         q.aborted = false;
00722 
00723         char *select_stmt = NULL, *errmsg = NULL;
00724         size_t len = 0;
00725 
00726         try
00727         {
00728                 bool where_added = false;
00729 
00730                 if (apol_str_append
00731                     (&select_stmt, &len,
00732                      "SELECT paths.path, paths.ino, devs.dev_name, users.user_name, roles.role_name, types.type_name") < 0)
00733                 {
00734                         SEFS_ERR(this, "%s", strerror(errno));
00735                         throw std::runtime_error(strerror(errno));
00736                 }
00737                 if (q.db_is_mls && apol_str_append(&select_stmt, &len, ", mls.mls_range") < 0)
00738                 {
00739                         SEFS_ERR(this, "%s", strerror(errno));
00740                         throw std::runtime_error(strerror(errno));
00741                 }
00742                 if (apol_str_append(&select_stmt, &len,
00743                                     ", paths.obj_class, paths.symlink_target FROM paths, devs, users, roles, types") < 0)
00744                 {
00745                         SEFS_ERR(this, "%s", strerror(errno));
00746                         throw std::runtime_error(strerror(errno));
00747                 }
00748                 if (q.db_is_mls && apol_str_append(&select_stmt, &len, ", mls") < 0)
00749                 {
00750                         throw std::runtime_error(strerror(errno));
00751                 }
00752 
00753                 if (q.user != NULL)
00754                 {
00755                         if (sqlite3_create_function(_db, "user_compare", 1, SQLITE_UTF8, &q, db_user_compare, NULL, NULL) !=
00756                             SQLITE_OK)
00757                         {
00758                                 SEFS_ERR(this, "%s", strerror(errno));
00759                                 throw std::runtime_error(strerror(errno));
00760                         }
00761                         if (apol_str_appendf(&select_stmt, &len,
00762                                              "%s (user_compare(users.user_name))", (where_added ? " AND" : " WHERE")) < 0)
00763                         {
00764                                 SEFS_ERR(this, "%s", strerror(errno));
00765                                 throw std::runtime_error(strerror(errno));
00766                         }
00767                         where_added = true;
00768                 }
00769 
00770                 if (q.role != NULL)
00771                 {
00772                         if (sqlite3_create_function(_db, "role_compare", 1, SQLITE_UTF8, &q, db_role_compare, NULL, NULL) !=
00773                             SQLITE_OK)
00774                         {
00775                                 SEFS_ERR(this, "%s", strerror(errno));
00776                                 throw std::runtime_error(strerror(errno));
00777                         }
00778                         if (apol_str_appendf(&select_stmt, &len,
00779                                              "%s (role_compare(roles.role_name))", (where_added ? " AND" : " WHERE")) < 0)
00780                         {
00781                                 SEFS_ERR(this, "%s", strerror(errno));
00782                                 throw std::runtime_error(strerror(errno));
00783                         }
00784                         where_added = true;
00785                 }
00786 
00787                 if (q.type != NULL)
00788                 {
00789                         if (sqlite3_create_function(_db, "type_compare", 1, SQLITE_UTF8, &q, db_type_compare, NULL, NULL) !=
00790                             SQLITE_OK)
00791                         {
00792                                 SEFS_ERR(this, "%s", strerror(errno));
00793                                 throw std::runtime_error(strerror(errno));
00794                         }
00795                         if (apol_str_appendf(&select_stmt, &len,
00796                                              "%s (type_compare(types.type_name))", (where_added ? " AND" : " WHERE")) < 0)
00797                         {
00798                                 SEFS_ERR(this, "%s", strerror(errno));
00799                                 throw std::runtime_error(strerror(errno));
00800                         }
00801                         where_added = true;
00802                 }
00803 
00804                 if (q.db_is_mls && q.range != NULL)
00805                 {
00806                         if (sqlite3_create_function(_db, "range_compare", 1, SQLITE_UTF8, &q, db_range_compare, NULL, NULL) !=
00807                             SQLITE_OK)
00808                         {
00809                                 SEFS_ERR(this, "%s", strerror(errno));
00810                                 throw std::runtime_error(strerror(errno));
00811                         }
00812                         if (apol_str_appendf(&select_stmt, &len,
00813                                              "%s (range_compare(mls.mls_range))", (where_added ? " AND" : " WHERE")) < 0)
00814                         {
00815                                 SEFS_ERR(this, "%s", strerror(errno));
00816                                 throw std::runtime_error(strerror(errno));
00817                         }
00818                         where_added = true;
00819                 }
00820 
00821                 if (query->_objclass != 0)
00822                 {
00823                         if (apol_str_appendf(&select_stmt, &len,
00824                                              "%s (paths.obj_class = %d)", (where_added ? " AND" : " WHERE"), query->_objclass) < 0)
00825                         {
00826                                 SEFS_ERR(this, "%s", strerror(errno));
00827                                 throw std::runtime_error(strerror(errno));
00828                         }
00829                         where_added = true;
00830                 }
00831 
00832                 if (q.path != NULL)
00833                 {
00834                         if (sqlite3_create_function(_db, "path_compare", 1, SQLITE_UTF8, &q, db_path_compare, NULL, NULL) !=
00835                             SQLITE_OK)
00836                         {
00837                                 SEFS_ERR(this, "%s", strerror(errno));
00838                                 throw std::runtime_error(strerror(errno));
00839                         }
00840                         if (apol_str_appendf(&select_stmt, &len,
00841                                              "%s (path_compare(paths.path))", (where_added ? " AND" : " WHERE")) < 0)
00842                         {
00843                                 SEFS_ERR(this, "%s", strerror(errno));
00844                                 throw std::runtime_error(strerror(errno));
00845                         }
00846                         where_added = true;
00847                 }
00848 
00849                 if (query->_inode != 0)
00850                 {
00851                         if (apol_str_appendf(&select_stmt, &len,
00852                                              "%s (paths.ino = %lu)", (where_added ? " AND" : " WHERE"),
00853                                              static_cast < long unsigned int >(query->_inode)) < 0)
00854                         {
00855                                 SEFS_ERR(this, "%s", strerror(errno));
00856                                 throw std::runtime_error(strerror(errno));
00857                         }
00858                         where_added = true;
00859                 }
00860 
00861                 if (query->_dev != 0)
00862                 {
00863                         if (sqlite3_create_function(_db, "dev_compare", 1, SQLITE_UTF8, &q, db_dev_compare, NULL, NULL) !=
00864                             SQLITE_OK)
00865                         {
00866                                 SEFS_ERR(this, "%s", strerror(errno));
00867                                 throw std::runtime_error(strerror(errno));
00868                         }
00869                         if (apol_str_appendf(&select_stmt, &len,
00870                                              "%s (dev_compare(devs.dev_name)", (where_added ? " AND" : " WHERE")) < 0)
00871                         {
00872                                 SEFS_ERR(this, "%s", strerror(errno));
00873                                 throw std::runtime_error(strerror(errno));
00874                         }
00875                         where_added = true;
00876                 }
00877 
00878                 if (apol_str_appendf(&select_stmt, &len,
00879                                      "%s (paths.user = users.user_id AND paths.role = roles.role_id AND paths.type = types.type_id",
00880                                      (where_added ? " AND" : " WHERE")) < 0)
00881                 {
00882                         SEFS_ERR(this, "%s", strerror(errno));
00883                         throw std::runtime_error(strerror(errno));
00884                 }
00885                 if (q.db_is_mls && apol_str_appendf(&select_stmt, &len, " AND paths.range = mls.mls_id") < 0)
00886                 {
00887                         SEFS_ERR(this, "%s", strerror(errno));
00888                         throw std::runtime_error(strerror(errno));
00889                 }
00890                 if (apol_str_append(&select_stmt, &len, " AND paths.dev = devs.dev_id) ORDER BY paths.path ASC") < 0)
00891                 {
00892                         SEFS_ERR(this, "%s", strerror(errno));
00893                         throw std::runtime_error(strerror(errno));
00894                 }
00895 
00896                 int rc = sqlite3_exec(_db, select_stmt, db_query_callback, &q, &errmsg);
00897                 if (rc != SQLITE_OK && (rc != SQLITE_ABORT || !q.aborted))
00898                 {
00899                         SEFS_ERR(this, "%s", errmsg);
00900                         throw std::runtime_error(errmsg);
00901                 }
00902         }
00903         catch(...)
00904         {
00905                 apol_vector_destroy(&q.type_list);
00906                 apol_mls_range_destroy(&q.apol_range);
00907                 free(select_stmt);
00908                 sqlite3_free(errmsg);
00909                 throw;
00910         }
00911 
00912         apol_vector_destroy(&q.type_list);
00913         apol_mls_range_destroy(&q.apol_range);
00914         free(select_stmt);
00915         sqlite3_free(errmsg);
00916         return q.retval;
00917 }

bool sefs_db::isMLS  )  const [virtual]
 

Determine if the contexts stored in this database contain MLS fields.

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

Implements sefs_fclist.

Definition at line 919 of file db.cc.

References _db, db_row_exist_callback(), and SEFS_ERR.

Referenced by upgradeToDB2().

00920 {
00921         int rc;
00922         bool answer = false;
00923         char *errmsg = NULL;
00924         const char *select_stmt = "SELECT * FROM sqlite_master WHERE name='mls'";
00925         rc = sqlite3_exec(_db, select_stmt, db_row_exist_callback, &answer, &errmsg);
00926         if (rc != SQLITE_OK)
00927         {
00928                 SEFS_ERR(this, "%s", errmsg);
00929                 sqlite3_free(errmsg);
00930                 answer = false;
00931         }
00932         return answer;
00933 }

void sefs_db::save const char *  filename  )  throw (std::invalid_argument, std::runtime_error)
 

Write a database to disk, overwriting any existing file.

The database may then be read by calling the appropriate constructor.

Parameters:
filename Name of file to which write.
Exceptions:
std::invalid_argument No filename given.
std::runtime_error Error while writing the database.

Definition at line 935 of file db.cc.

References db_callback_arg::db, db_copy_schema(), db_copy_table(), db_callback_arg::errmsg, SEFS_ERR, db_callback_arg::source_db, and db_callback_arg::target_db.

Referenced by main(), and sefs_db_save().

00936 {
00937         FILE *fp = NULL;
00938         struct db_callback_arg diskdb;
00939         diskdb.db = NULL;
00940         diskdb.errmsg = NULL;
00941         bool in_transaction = false;
00942 
00943         try
00944         {
00945                 if (filename == NULL)
00946                 {
00947                         errno = EINVAL;
00948                         throw std::invalid_argument(strerror(errno));
00949                 }
00950                 // check that target file is creatable; this will also
00951                 // remove the file if it already exists
00952                 if ((fp = fopen(filename, "w")) == NULL)
00953                 {
00954                         SEFS_ERR(this, "%s", strerror(errno));
00955                         throw std::runtime_error(strerror(errno));
00956                 }
00957                 fclose(fp);
00958                 fp = NULL;
00959 
00960                 // copy database schema from in-memory db to the one on disk
00961                 if (sqlite3_open(filename, &(diskdb.db)) != SQLITE_OK)
00962                 {
00963                         SEFS_ERR(this, "%s", sqlite3_errmsg(diskdb.db));
00964                         throw std::runtime_error(sqlite3_errmsg(diskdb.db));
00965                 }
00966                 if (sqlite3_exec(_db, "SELECT sql FROM sqlite_master WHERE sql NOT NULL", db_copy_schema, &diskdb, &diskdb.errmsg)
00967                     != SQLITE_OK)
00968                 {
00969                         SEFS_ERR(this, "%s", diskdb.errmsg);
00970                         throw std::runtime_error(diskdb.errmsg);
00971                 }
00972                 sqlite3_close(diskdb.db);
00973 
00974                 char *attach = NULL;
00975                 if (asprintf(&attach, "ATTACH '%s' AS diskdb", filename) < 0)
00976                 {
00977                         SEFS_ERR(this, "%s", strerror(errno));
00978                         throw std::runtime_error(strerror(errno));
00979                 }
00980                 diskdb.db = _db;
00981                 diskdb.source_db = "";
00982                 diskdb.target_db = "diskdb.";
00983                 int rc = sqlite3_exec(_db, attach, NULL, NULL, &diskdb.errmsg);
00984                 free(attach);
00985                 if (rc != SQLITE_OK)
00986                 {
00987                         SEFS_ERR(this, "%s", diskdb.errmsg);
00988                         throw std::runtime_error(diskdb.errmsg);
00989                 }
00990 
00991                 // copy contents from in-memory db to the one on disk
00992                 if (sqlite3_exec(_db, "BEGIN TRANSACTION", NULL, NULL, &(diskdb.errmsg)) != SQLITE_OK)
00993                 {
00994                         SEFS_ERR(this, "%s", diskdb.errmsg);
00995                         throw std::runtime_error(diskdb.errmsg);
00996                 }
00997                 in_transaction = true;
00998                 if (sqlite3_exec(_db, "SELECT name FROM sqlite_master WHERE type ='table'", db_copy_table, &diskdb, &diskdb.errmsg)
00999                     != SQLITE_OK)
01000                 {
01001                         SEFS_ERR(this, "%s", diskdb.errmsg);
01002                         throw std::runtime_error(diskdb.errmsg);
01003                 }
01004 
01005                 sqlite3_exec(_db, "DETACH diskdb", NULL, NULL, NULL);
01006 
01007                 if (sqlite3_exec(_db, "END TRANSACTION", NULL, 0, &(diskdb.errmsg)) != SQLITE_OK)
01008                 {
01009                         SEFS_ERR(this, "%s", diskdb.errmsg);
01010                         throw std::runtime_error(diskdb.errmsg);
01011                 }
01012                 in_transaction = false;
01013         }
01014         catch(...)
01015         {
01016                 if (fp != NULL)
01017                 {
01018                         fclose(fp);
01019                 }
01020                 if (in_transaction)
01021                 {
01022                         sqlite3_exec(_db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
01023                 }
01024                 if (diskdb.db != NULL)
01025                 {
01026                         sqlite3_close(diskdb.db);
01027                 }
01028                 sqlite3_free(diskdb.errmsg);
01029                 throw;
01030         }
01031         //      sqlite3_close(diskdb.db);  don't close the database -- it's pointing to this->_db
01032         sqlite3_free(diskdb.errmsg);
01033 }

time_t sefs_db::getCTime  )  const
 

Get the creation time of a sefs database.

Returns:
Creation time of the database, or 0 on error.

Definition at line 1035 of file db.cc.

Referenced by sefs_db_get_ctime().

01036 {
01037         return _ctime;
01038 }

bool sefs_db::isDB const char *  filename  )  [static]
 

Determine if the given file is a valid sefs_db.

This does not thoroughly load the file, rather just the header of the file.

Parameters:
filename Name of file to check.
Returns:
True if the file appears to be a database, false if not.

Definition at line 1040 of file db.cc.

References db_count_callback().

Referenced by main(), sefs_db(), and sefs_db_is_db().

01041 {
01042         if (filename == NULL)
01043         {
01044                 errno = EINVAL;
01045                 return false;
01046         }
01047 
01048         int rc = access(filename, R_OK);
01049         if (rc != 0)
01050         {
01051                 return false;
01052         }
01053 
01054         struct sqlite3 *db = NULL;
01055         rc = sqlite3_open(filename, &db);
01056         if (rc != SQLITE_OK)
01057         {
01058                 sqlite3_close(db);
01059                 errno = EIO;
01060                 return false;
01061         }
01062 
01063         // Run a simple query to check that the database is legal.
01064         int list_size;
01065         char *errmsg = NULL;
01066         rc = sqlite3_exec(db, "SELECT type_name FROM types", db_count_callback, &list_size, &errmsg);
01067         if (rc != SQLITE_OK)
01068         {
01069                 sqlite3_close(db);
01070                 sqlite3_free(errmsg);
01071                 errno = EIO;
01072                 return false;
01073         }
01074         sqlite3_close(db);
01075         return true;
01076 }

void sefs_db::upgradeToDB2  )  throw (std::runtime_error) [private]
 

Upgrade an existing version 1 database to version 2.

Definition at line 1151 of file db.cc.

References _ctime, _db, DB_MAX_VERSION, db_upgrade_reinsert(), isMLS(), and SEFS_ERR.

01152 {
01153         char *errmsg;
01154 
01155         // Add a role field for each inode entry within the database;
01156         // assume that the role is 'object_r'.  Also update the object
01157         // class values, from older class values to new ones.  Old
01158         // class_id values come from the old libsefs < 4.0 definitions
01159         // that were in fsdata.h; the new style is in
01160         // qpol/genfscon_query.h.
01161         _ctime = time(NULL);
01162         char datetime[32];
01163         ctime_r(&_ctime, datetime);
01164         char *alter_stmt = NULL;
01165         if (asprintf(&alter_stmt, "BEGIN TRANSACTION;" "CREATE TABLE roles (role_id INTEGER PRIMARY KEY, role_name varchar (24));"      // add a roles table
01166                      "INSERT INTO roles (role_id, role_name) VALUES (0, 'object_r');"   // assume that all previous contexts had as their role 'object_r'
01167                      "CREATE TABLE devs (dev_id INTEGER PRIMARY KEY, dev_name varchar (32));"   // add a table that maps between device names and some numeric ID
01168                      "INSERT INTO devs (dev_id, dev_name) VALUES (0, '<<unknown>>');"   // device names were not stored in old DB
01169                      "CREATE TABLE new_paths (path varchar (128) PRIMARY KEY, ino int(64), dev int, user int, role int, type int, range int, obj_class int, symlink_target varchar (128));"     // create new paths table
01170                      "SELECT paths.path, inodes.ino, inodes.user, inodes.type, %sinodes.obj_class, inodes.symlink_target FROM paths, inodes WHERE (inodes.inode_id = paths.inode)",     // rebuild new paths table from older tables
01171                      isMLS()? "inodes.range, " : "") < 0)
01172         {
01173                 SEFS_ERR(this, "%s", errmsg);
01174                 sqlite3_free(errmsg);
01175                 sqlite3_close(_db);
01176                 throw std::runtime_error(strerror(errno));
01177         }
01178         if (sqlite3_exec(_db, alter_stmt, db_upgrade_reinsert, _db, &errmsg) != SQLITE_OK)
01179         {
01180                 SEFS_ERR(this, "%s", errmsg);
01181                 free(alter_stmt);
01182                 sqlite3_free(errmsg);
01183                 sqlite3_close(_db);
01184                 throw std::runtime_error(strerror(errno));
01185         }
01186 
01187         free(alter_stmt);
01188         alter_stmt = NULL;
01189 
01190         if (asprintf(&alter_stmt, "DROP TABLE inodes; DROP TABLE paths;"        // drop the old tables
01191                      "ALTER TABLE new_paths RENAME TO paths;"   // move ver 2 paths table as main table
01192                      "UPDATE info SET value = '%s' WHERE key = 'datetime';"
01193                      "UPDATE info SET value = '%s' WHERE key = 'dbversion';"
01194                      "END TRANSACTION;" "VACUUM", datetime, DB_MAX_VERSION) < 0)
01195         {
01196                 SEFS_ERR(this, "%s", errmsg);
01197                 sqlite3_free(errmsg);
01198                 sqlite3_close(_db);
01199                 throw std::runtime_error(strerror(errno));
01200         }
01201         if (sqlite3_exec(_db, alter_stmt, NULL, NULL, &errmsg) != SQLITE_OK)
01202         {
01203                 SEFS_ERR(this, "%s", errmsg);
01204                 free(alter_stmt);
01205                 sqlite3_free(errmsg);
01206                 sqlite3_close(_db);
01207                 throw std::runtime_error(strerror(errno));
01208         }
01209         free(alter_stmt);
01210 }

const struct sefs_context_node * sefs_db::getContextNode const sefs_entry entry  )  [private]
 

Definition at line 1080 of file db.cc.

References sefs_entry::_context.

Referenced by db_create_from_filesystem().

01081 {
01082         return entry->_context;
01083 }

sefs_entry * sefs_db::getEntry const struct sefs_context_node context,
uint32_t  objectClass,
const char *  path,
ino64_t  inode,
const char *  dev
throw (std::bad_alloc) [private]
 

Definition at line 1212 of file db.cc.

References sefs_entry::_dev, sefs_entry::_inode, apol_bst_insert_and_get(), and SEFS_ERR.

01214 {
01215         char *s = strdup(path);
01216         if (s == NULL)
01217         {
01218                 SEFS_ERR(this, "%s", strerror(errno));
01219                 throw std::bad_alloc();
01220         }
01221         if (apol_bst_insert_and_get(path_tree, (void **)&s, NULL) < 0)
01222         {
01223                 SEFS_ERR(this, "%s", strerror(errno));
01224                 free(s);
01225                 throw std::bad_alloc();
01226         }
01227         sefs_entry *e = new sefs_entry(this, context, objectClass, s);
01228         e->_inode = inode;
01229 
01230         s = NULL;
01231         if ((s = strdup(dev)) == NULL || apol_bst_insert_and_get(dev_tree, (void **)&s, NULL) < 0)
01232         {
01233                 SEFS_ERR(this, "%s", strerror(errno));
01234                 free(s);
01235                 throw std::bad_alloc();
01236         }
01237         e->_dev = dev;
01238         return e;
01239 }

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 }


Friends And Related Function Documentation

int db_create_from_filesystem sefs_fclist *fclist   __attribute__((unused)),
const sefs_entry entry,
void *  arg
[friend]
 

Definition at line 455 of file db.cc.

00456 {
00457         db_convert *dbc = static_cast < db_convert * >(arg);
00458 
00459         const struct sefs_context_node *context = dbc->_db->getContextNode(entry);
00460         try
00461         {
00462 
00463                 // add the user, role, type, range, and dev into the
00464                 // target_db if needed
00465                 int user_id = dbc->getID(context->user, dbc->_user, dbc->_user_id, "users");
00466                 int role_id = dbc->getID(context->role, dbc->_role, dbc->_role_id, "roles");
00467                 int type_id = dbc->getID(context->type, dbc->_type, dbc->_type_id, "types");
00468                 int range_id = 0;
00469                 if (dbc->_isMLS)
00470                 {
00471                         range_id = dbc->getID(context->range, dbc->_range, dbc->_range_id, "mls");
00472                 }
00473                 int dev_id = dbc->getID(entry->dev(), dbc->_dev, dbc->_dev_id, "devs");
00474                 const char *path = entry->path();
00475                 const ino64_t inode = entry->inode();
00476                 const uint32_t objclass = entry->objectClass();
00477                 char link_target[128] = "";
00478                 // determine the link target as necessary
00479                 struct stat64 sb;
00480                 if (stat64(path, &sb) == -1)
00481                 {
00482                         SEFS_ERR(dbc->_db, "%s", strerror(errno));
00483                         throw std::bad_alloc();
00484                 }
00485                 if (S_ISLNK(sb.st_mode))
00486                 {
00487                         if (readlink(path, link_target, 128) == 0)
00488                         {
00489                                 SEFS_ERR(dbc->_db, "%s", strerror(errno));
00490                                 throw std::bad_alloc();
00491                         }
00492                         link_target[127] = '\0';
00493                 }
00494 
00495                 char *insert_stmt = NULL;
00496                 if (asprintf
00497                     (&insert_stmt, "INSERT INTO paths VALUES ('%s', %lu, %d, %d, %d, %d, %d, %u, '%s')", path,
00498                      static_cast < long unsigned int >(inode), dev_id, user_id, role_id, type_id, range_id, objclass,
00499                      link_target) < 0)
00500                 {
00501                         SEFS_ERR(dbc->_db, "%s", strerror(errno));
00502                         throw std::bad_alloc();
00503                 }
00504                 if (sqlite3_exec(dbc->_target_db, insert_stmt, NULL, NULL, &dbc->_errmsg) != SQLITE_OK)
00505                 {
00506                         SEFS_ERR(dbc->_db, "%s", dbc->_errmsg);
00507                         free(insert_stmt);
00508                         throw std::runtime_error(dbc->_errmsg);
00509                 }
00510                 free(insert_stmt);
00511         }
00512         catch(...)
00513         {
00514                 return -1;
00515         }
00516         return 0;
00517 }

struct sefs_context_node* db_get_context sefs_db db,
const char *  user,
const char *  role,
const char *  type,
const char *  range
throw (std::bad_alloc) [friend]
 

Definition at line 61 of file db.cc.

00063 {
00064         return db->getContext(user, role, type, range);
00065 }

sefs_entry* db_get_entry sefs_db db,
const struct sefs_context_node node,
uint32_t  objClass,
const char *  path,
ino64_t  inode,
const char *  dev
throw (std::bad_alloc) [friend]
 

Definition at line 67 of file db.cc.

00069 {
00070         return db->getEntry(node, objClass, path, inode, dev);
00071 }


Member Data Documentation

struct sqlite3* sefs_db::_db [private]
 

Definition at line 161 of file db.hh.

Referenced by isMLS(), upgradeToDB2(), and ~sefs_db().

time_t sefs_db::_ctime [private]
 

Definition at line 162 of file db.hh.

Referenced by upgradeToDB2().

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: