#include <db.hh>
Inheritance diagram for sefs_db:

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_t * | runQuery (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_t * | associatePolicy () 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_node * | getContext (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_node * | getContext (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_t * | policy |
| apol_bst * | user_tree |
| apol_bst * | role_tree |
| apol_bst * | type_tree |
| apol_bst * | range_tree |
| apol_bst * | path_tree |
| apol_bst * | dev_tree |
| apol_bst * | context_tree |
Private Member Functions | |
| void | upgradeToDB2 () throw (std::runtime_error) |
| Upgrade an existing version 1 database to version 2. | |
| const struct sefs_context_node * | getContextNode (const sefs_entry *entry) |
| sefs_entry * | getEntry (const struct sefs_context_node *context, uint32_t objectClass, const char *path, ino64_t inode, const char *dev) throw (std::bad_alloc) |
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_node * | db_get_context (sefs_db *, const char *, const char *, const char *, const char *) throw (std::bad_alloc) |
| sefs_entry * | db_get_entry (sefs_db *, const struct sefs_context_node *, uint32_t, const char *, ino64_t, const char *) throw (std::bad_alloc) |
|
||||||||||||||||
|
Allocate and return a new sefs database initialized with entries from the filesystem fs.
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 }
|
|
||||||||||||||||
|
Allocate and return a new sefs database, loading the entries from an existing database stored at path.
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 }
|
|
|
Definition at line 656 of file db.cc. References _db.
|
|
||||||||||||||||
|
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.
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 }
|
|
|
Determine if the contexts stored in this database contain MLS fields.
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 }
|
|
|
Write a database to disk, overwriting any existing file. The database may then be read by calling the appropriate constructor.
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 }
|
|
|
Get the creation time of a sefs database.
Definition at line 1035 of file db.cc. Referenced by sefs_db_get_ctime(). 01036 {
01037 return _ctime;
01038 }
|
|
|
Determine if the given file is a valid sefs_db. This does not thoroughly load the file, rather just the header of the file.
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 }
|
|
|
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 }
|
|
|
Definition at line 1080 of file db.cc. References sefs_entry::_context. Referenced by db_create_from_filesystem(). 01081 {
01082 return entry->_context;
01083 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
|
Perform a sefs query on the given file context list object and return a list of matching entries.
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 }
|
|
|
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.
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 }
|
|
|
Return the policy currently associated with this fclist. Do not destroy the policy without first unassociating it (via call to sefs_fclist::associatePolicy(NULL)).
Definition at line 190 of file fclist.cc. References apol_policy_t. 00191 {
00192 return policy;
00193 }
|
|
|
Get the type of fclist object represented by fclist.
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 }
|
|
||||||||||||||||||||
|
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.
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 }
|
|
|
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.
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
Definition at line 61 of file db.cc. 00063 {
00064 return db->getContext(user, role, type, range);
00065 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 67 of file db.cc. 00069 {
00070 return db->getEntry(node, objClass, path, inode, dev);
00071 }
|
|
|
Definition at line 161 of file db.hh. Referenced by isMLS(), upgradeToDB2(), and ~sefs_db(). |
|
|
Definition at line 162 of file db.hh. Referenced by upgradeToDB2(). |
|
|
Definition at line 239 of file fclist.hh. Referenced by sefs_fclist::associatePolicy(). |
|
|
Definition at line 240 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 240 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 240 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 240 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 240 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 241 of file fclist.hh. Referenced by sefs_fclist::~sefs_fclist(). |
|
|
Definition at line 242 of file fclist.hh. Referenced by sefs_fclist::associatePolicy(), and sefs_fclist::~sefs_fclist(). |