}
-int open_rdb_connection(sqlite3 **p_db)
+int open_rdb_connection(sqlite3 **p_db, bool b_create_temporary_tables)
{
RDB_LOG_ENTRY;
sqlite3_free(p_err_msg);
- // Create the temporary tables:
- if(sqlite3_exec(*p_db,
- "PRAGMA foreign_keys = ON; \
- \
- PRAGMA temp_store = MEMORY; \
- \
- CREATE TEMPORARY TABLE modified_label( \
- name VARCHAR NOT NULL PRIMARY KEY); \
- \
- CREATE TEMPORARY TABLE all_smack_binary_rules_modified( \
- subject TEXT NOT NULL, \
- object TEXT NOT NULL, \
- access INTEGER NOT NULL, \
- is_volatile INTEGER NOT NULL); \
- \
- CREATE TEMPORARY TABLE current_smack_rule_modified( \
- subject VARCHAR NOT NULL, \
- object VARCHAR NOT NULL, \
- access INTEGER NOT NULL); \
- \
- CREATE TEMPORARY TABLE history_smack_rule_modified( \
- subject VARCHAR NOT NULL, \
- object VARCHAR NOT NULL, \
- access INTEGER NOT NULL); \
- \
- CREATE TEMPORARY VIEW modified_smack_rules AS \
- SELECT subject, object, \
- access_to_str(access_add) AS access_add, \
- access_to_str(access_del) AS access_del \
- FROM ( \
- SELECT subject, object, \
- s1.access & ~s2.access AS access_add, \
- s2.access & ~s1.access AS access_del \
- FROM current_smack_rule_modified AS s1 \
- INNER JOIN history_smack_rule_modified AS s2 \
- USING (subject, object) \
- WHERE s1.access != s2.access \
- UNION \
- SELECT subject, object, \
- s1.access AS access_add, \
- 0 AS access_del \
- FROM current_smack_rule_modified s1 \
- LEFT JOIN history_smack_rule_modified s2 \
- USING (subject, object) \
- WHERE s2.subject IS NULL AND \
- s2.object IS NULL \
- UNION \
- SELECT subject, object, \
- 0 AS access_add, \
- s1.access AS access_del \
- FROM history_smack_rule_modified s1 \
- LEFT JOIN current_smack_rule_modified s2 \
- USING (subject, object) \
- WHERE s2.subject IS NULL AND \
- s2.object IS NULL \
- ) \
- ORDER BY subject, object ASC;",
- 0, 0, 0) != SQLITE_OK) {
- C_LOGE("RDB: Error during preparing script: %s", sqlite3_errmsg(*p_db));
- return PC_ERR_DB_CONNECTION;
+ if (b_create_temporary_tables) {
+ // Create the temporary tables:
+ if(sqlite3_exec(*p_db,
+ "PRAGMA foreign_keys = ON; \
+ \
+ PRAGMA temp_store = MEMORY; \
+ \
+ CREATE TEMPORARY TABLE modified_label( \
+ name VARCHAR NOT NULL PRIMARY KEY); \
+ \
+ CREATE TEMPORARY TABLE all_smack_binary_rules_modified( \
+ subject TEXT NOT NULL, \
+ object TEXT NOT NULL, \
+ access INTEGER NOT NULL, \
+ is_volatile INTEGER NOT NULL); \
+ \
+ CREATE TEMPORARY TABLE current_smack_rule_modified( \
+ subject VARCHAR NOT NULL, \
+ object VARCHAR NOT NULL, \
+ access INTEGER NOT NULL); \
+ \
+ CREATE TEMPORARY TABLE history_smack_rule_modified( \
+ subject VARCHAR NOT NULL, \
+ object VARCHAR NOT NULL, \
+ access INTEGER NOT NULL); \
+ \
+ CREATE TEMPORARY VIEW modified_smack_rules AS \
+ SELECT subject, object, \
+ access_to_str(access_add) AS access_add, \
+ access_to_str(access_del) AS access_del \
+ FROM ( \
+ SELECT subject, object, \
+ s1.access & ~s2.access AS access_add, \
+ s2.access & ~s1.access AS access_del \
+ FROM current_smack_rule_modified AS s1 \
+ INNER JOIN history_smack_rule_modified AS s2 \
+ USING (subject, object) \
+ WHERE s1.access != s2.access \
+ UNION \
+ SELECT subject, object, \
+ s1.access AS access_add, \
+ 0 AS access_del \
+ FROM current_smack_rule_modified s1 \
+ LEFT JOIN history_smack_rule_modified s2 \
+ USING (subject, object) \
+ WHERE s2.subject IS NULL AND \
+ s2.object IS NULL \
+ UNION \
+ SELECT subject, object, \
+ 0 AS access_add, \
+ s1.access AS access_del \
+ FROM history_smack_rule_modified s1 \
+ LEFT JOIN current_smack_rule_modified s2 \
+ USING (subject, object) \
+ WHERE s2.subject IS NULL AND \
+ s2.object IS NULL \
+ ) \
+ ORDER BY subject, object ASC;",
+ 0, 0, 0) != SQLITE_OK) {
+ C_LOGE("RDB: Error during preparing script: %s", sqlite3_errmsg(*p_db));
+ return PC_ERR_DB_CONNECTION;
+ }
+ } else {
+ // Just enable foreign keys:
+ if(sqlite3_exec(*p_db, "PRAGMA foreign_keys = ON", 0, 0, 0) != SQLITE_OK) {
+ C_LOGE("RDB: Error during preparing script: %s", sqlite3_errmsg(*p_db));
+ return PC_ERR_DB_CONNECTION;
+ }
}
return PC_OPERATION_SUCCESS;
static sqlite3 *p_db__ = NULL;
static int i_session_ret_code__ = PC_OPERATION_SUCCESS;
+static bool b_shared_transaction__ = false;
typedef enum {
RDB_TRANSACTION_EXCLUSIVE,
RDB_LOG_ENTRY;
// If rdb_modification_start was called we use a global connection.
+ // Since global connection is always opened only for exclusive transactions, temporary
+ // tables are already created and b_shared_transaction is set to false.
if(p_db__) {
*pp_db = p_db__;
return PC_OPERATION_SUCCESS;
}
- int ret = open_rdb_connection(pp_db);
+ // Shared transaction doesn't need temporary tables because SMACK labels won't be modified.
+ bool b_create_temporary_tables = transaction_type != RDB_TRANSACTION_SHARED_READ;
+ int ret = open_rdb_connection(pp_db, b_create_temporary_tables);
if(ret != PC_OPERATION_SUCCESS) return ret;
if(transaction_type == RDB_TRANSACTION_EXCLUSIVE) {
+ b_shared_transaction__ = false;
ret = sqlite3_exec(*pp_db, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
}
else if(transaction_type == RDB_TRANSACTION_SHARED_READ) {
+ b_shared_transaction__ = true;
ret = sqlite3_exec(*pp_db, "BEGIN DEFERRED TRANSACTION", 0, 0, 0);
}
else {
if(ret != SQLITE_OK) {
C_LOGE("RDB: Error during transaction begin: %s",
sqlite3_errmsg(*pp_db));
+ b_shared_transaction__ = false;
return PC_ERR_DB_CONNECTION;
}
int ret = PC_OPERATION_SUCCESS;
// No error during the session, make updates
- if(i_session_ret == PC_OPERATION_SUCCESS) {
+ if(i_session_ret == PC_OPERATION_SUCCESS && !b_shared_transaction__) {
ret = update_rules_in_db(p_db);
if(ret != PC_OPERATION_SUCCESS) {
C_LOGE("RDB: Error during updating rules in the database: %d", ret);