.output "/opt/etc/smack/boot-rules.smack"
-SELECT subject, object, access_to_str(access), "-"
-FROM all_smack_binary_rules
-WHERE all_smack_binary_rules.is_volatile = 0;
-COMMIT TRANSACTION;
\ No newline at end of file
+SELECT subject, object, access_to_str(bitwise_or(access)), "-"
+FROM all_smack_binary_rules
+WHERE is_volatile = 0
+GROUP BY subject, object
+ORDER BY subject, object ASC;
+
+COMMIT TRANSACTION;
BEGIN EXCLUSIVE TRANSACTION;
-- Update here on every schema change! Integer value.
-PRAGMA user_version = 2;
+PRAGMA user_version = 3;
CREATE TABLE IF NOT EXISTS app (
app_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
FOREIGN KEY(label_id) REFERENCES label(label_id)
);
-CREATE INDEX IF NOT EXISTS app_index ON app(app_id, label_id);
CREATE TABLE IF NOT EXISTS app_permission (
FOREIGN KEY(permission_id) REFERENCES permission(permission_id)
);
+-- Used by ltl_ view
+CREATE INDEX IF NOT EXISTS app_permission_permission_id_index ON app_permission(permission_id);
+
CREATE TABLE IF NOT EXISTS app_path (
app_id INTEGER NOT NULL,
path TEXT NOT NULL,
FOREIGN KEY(app_path_type_id) REFERENCES app_path_type(app_path_type_id)
);
+-- Used by ltl_ view
+CREATE INDEX IF NOT EXISTS app_path_app_path_type_id_index ON app_path(app_path_type_id);
+
CREATE TABLE IF NOT EXISTS app_path_type (
app_path_type_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL ,
UNIQUE (name)
);
--- CREATE INDEX IF NOT EXISTS app_path_type_index ON app_path_type(app_path_type_id, name);
CREATE TABLE IF NOT EXISTS permission_permission_rule (
FOREIGN KEY(label_id) REFERENCES label(label_id)
);
+-- Used by ltl_ view
+CREATE INDEX IF NOT EXISTS permission_label_rule_label_id_index ON permission_label_rule(label_id);
+
CREATE TABLE IF NOT EXISTS permission_app_path_type_rule (
permission_id INTEGER NOT NULL,
app_path_type_id INTEGER NOT NULL,
FOREIGN KEY(app_path_type_id) REFERENCES app_path_type(app_path_type_id)
);
+-- Used by ltl_ view
+CREATE INDEX IF NOT EXISTS permission_app_path_type_rule_app_path_type_id_index
+ ON permission_app_path_type_rule(app_path_type_id);
+
CREATE TABLE IF NOT EXISTS label_app_path_type_rule (
label_id INTEGER NOT NULL,
app_path_type_id INTEGER NOT NULL,
FOREIGN KEY(permission_type_id) REFERENCES permission_type(permission_type_id)
);
-
+-- Not aggregated rules
CREATE TABLE IF NOT EXISTS all_smack_binary_rules(
subject TEXT NOT NULL,
object TEXT NOT NULL,
is_volatile INTEGER NOT NULL
);
+-- Index used for grouping and sorting by (subject, object)
+-- and used for filtering by subject
+CREATE INDEX IF NOT EXISTS all_smack_binary_rules_subject_object_index
+ ON all_smack_binary_rules(subject, object);
+
+-- Index used for filtering by object
+CREATE INDEX IF NOT EXISTS all_smack_binary_rules_object_index
+ ON all_smack_binary_rules(object);
+
-- TEMPORARY TABLES ------------------------------------------------------------
-- Definitions are repeated in code.
-CREATE TEMPORARY TABLE history_smack_rule(
- subject TEXT NOT NULL,
- object TEXT NOT NULL,
- access INTEGER NOT NULL
-);
-
CREATE TEMPORARY TABLE modified_label(
- name TEXT NOT NULL,
- UNIQUE (name)
+ name TEXT NOT NULL PRIMARY KEY
);
-
+-- Not aggregated subset of modified rules
CREATE TEMPORARY TABLE all_smack_binary_rules_modified(
subject TEXT NOT NULL,
object TEXT NOT NULL,
- access INTEGER NOT NULL
+ access INTEGER NOT NULL,
+ is_volatile INTEGER NOT NULL
);
+-- Aggregated subset of rules after changes
+CREATE TEMPORARY TABLE current_smack_rule_modified(
+ subject TEXT NOT NULL,
+ object TEXT NOT NULL,
+ access INTEGER NOT NULL
+);
+-- Aggregated subset of rules before changes
CREATE TEMPORARY TABLE history_smack_rule_modified(
subject TEXT NOT NULL,
object TEXT NOT NULL,
-- ltl = label to label
DROP VIEW IF EXISTS ltl_permission_permission_rule_view;
CREATE VIEW ltl_permission_permission_rule_view AS
-SELECT (CASE WHEN is_reverse = 0 THEN app1.name ELSE app2.name END) AS subject,
- (CASE WHEN is_reverse = 1 THEN app1.name ELSE app2.name END) AS object,
+SELECT app1.name AS subject,
+ app2.name AS object,
p.access,
app1.is_volatile OR app2.is_volatile AS is_volatile
FROM permission_permission_rule AS p
INNER JOIN app_label_with_permission_view AS app1 USING(permission_id)
INNER JOIN app_label_with_permission_view AS app2
ON app2.permission_id = p.target_permission_id
-WHERE app1.app_id != app2.app_id;
+WHERE is_reverse = 0 AND app1.app_id != app2.app_id
+UNION ALL
+SELECT app2.name AS subject,
+ app1.name AS object,
+ p.access,
+ app1.is_volatile OR app2.is_volatile AS is_volatile
+FROM permission_permission_rule AS p
+INNER JOIN app_label_with_permission_view AS app1 USING(permission_id)
+INNER JOIN app_label_with_permission_view AS app2
+ ON app2.permission_id = p.target_permission_id
+WHERE is_reverse = 1 AND app1.app_id != app2.app_id;
-- PERMISSION TO LABEL RULE VIEW -----------------------------------------------
-- ltl = label to label
DROP VIEW IF EXISTS ltl_permission_label_rule_view;
CREATE VIEW ltl_permission_label_rule_view AS
-SELECT (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
- (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
+SELECT app.name AS subject,
+ label.name AS object,
p.access,
app.is_volatile
FROM permission_label_rule AS p
INNER JOIN app_label_with_permission_view AS app USING(permission_id)
INNER JOIN label USING(label_id)
-WHERE app.name != label.name;
+WHERE is_reverse = 0 AND app.name != label.name
+UNION ALL
+SELECT label.name AS subject,
+ app.name AS object,
+ p.access,
+ app.is_volatile
+FROM permission_label_rule AS p
+INNER JOIN app_label_with_permission_view AS app USING(permission_id)
+INNER JOIN label USING(label_id)
+WHERE is_reverse = 1 AND app.name != label.name;
+
-- ltl = label to label
DROP VIEW IF EXISTS ltl_permission_app_path_type_rule_view;
CREATE VIEW ltl_permission_app_path_type_rule_view AS
-SELECT (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
- (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
+SELECT app.name AS subject,
+ label.name AS object,
+ p.access,
+ app.is_volatile
+FROM permission_app_path_type_rule AS p
+INNER JOIN app_label_with_permission_view AS app USING(permission_id)
+INNER JOIN app_path USING(app_path_type_id)
+INNER JOIN label USING(label_id)
+WHERE is_reverse = 0 AND app.name != label.name
+UNION ALL
+SELECT label.name AS subject,
+ app.name AS object,
p.access,
app.is_volatile
FROM permission_app_path_type_rule AS p
INNER JOIN app_label_with_permission_view AS app USING(permission_id)
INNER JOIN app_path USING(app_path_type_id)
INNER JOIN label USING(label_id)
-WHERE app.name != label.name;
+WHERE is_reverse = 1 AND app.name != label.name;
-- LABEL TO PATH TYPE RULE VIEW -------------------------------------------
-- ltl = label to label
DROP VIEW IF EXISTS ltl_label_app_path_type_rule_view;
CREATE VIEW ltl_label_app_path_type_rule_view AS
-SELECT (CASE WHEN is_reverse = 0 THEN label.name ELSE path_label.name END) AS subject,
- (CASE WHEN is_reverse = 1 THEN label.name ELSE path_label.name END) AS object,
+SELECT label.name AS subject,
+ path_label.name AS object,
l.access AS access,
0 AS is_volatile
FROM label_app_path_type_rule AS l
INNER JOIN label USING(label_id)
INNER JOIN app_path USING(app_path_type_id)
INNER JOIN label AS path_label ON app_path.label_id = path_label.label_id
-WHERE path_label.name != label.name;
+WHERE is_reverse = 0 AND path_label.name != label.name
+UNION ALL
+SELECT path_label.name AS subject,
+ label.name AS object,
+ l.access AS access,
+ 0 AS is_volatile
+FROM label_app_path_type_rule AS l
+INNER JOIN label USING(label_id)
+INNER JOIN app_path USING(app_path_type_id)
+INNER JOIN label AS path_label ON app_path.label_id = path_label.label_id
+WHERE is_reverse = 1 AND path_label.name != label.name;
-- PERMISSION TO APPLICATION'S OWN PATHS ---------------------------------------
CREATE VIEW all_smack_binary_rules_view AS
SELECT subject,
object,
- bitwise_or(access) AS access,
- MIN(is_volatile) AS is_volatile
+ access,
+ is_volatile
FROM (SELECT subject, object, access, is_volatile
FROM ltl_permission_permission_rule_view
UNION ALL
UNION ALL
SELECT subject, object, access, 0
FROM ltl_app_path_reverse_view
- )
-GROUP BY subject, object
-ORDER BY subject, object ASC;
+ );
-- ALL INSERTED DATA VIEW ------------------------------------------------------
-- This view is used to clear the database from inserted rules.
SELECT subject, object,
s1.access & ~s2.access AS access_add,
s2.access & ~s1.access AS access_del
- FROM all_smack_binary_rules AS s1
- INNER JOIN history_smack_rule AS s2
+ FROM current_smack_rule_modified AS s1
+ INNER JOIN history_smack_rule_modified AS s2
USING (subject, object)
WHERE s1.access != s2.access
SELECT subject, object,
s1.access AS access_add,
0 AS access_del
- FROM all_smack_binary_rules AS s1
- LEFT JOIN history_smack_rule s2
+ FROM current_smack_rule_modified AS s1
+ LEFT JOIN history_smack_rule_modified s2
USING (subject, object)
WHERE s2.subject IS NULL AND
s2.object IS NULL
SELECT subject, object,
0 AS access_add,
s1.access AS access_del
- FROM history_smack_rule s1
- LEFT JOIN all_smack_binary_rules AS s2
+ FROM history_smack_rule_modified s1
+ LEFT JOIN current_smack_rule_modified AS s2
USING (subject, object)
WHERE s2.subject IS NULL AND
s2.object IS NULL
+.load librules-db-sql-udf.so
+PRAGMA foreign_keys = ON;
+
BEGIN EXCLUSIVE TRANSACTION;
--assume, that database is in version V2
---place your queries for updating data to V3 here
+
+-- From now on all_smack_binary_rules keeps SMACK rules, that are neither grouped nor ordered.
+DROP VIEW IF EXISTS all_smack_binary_rules_view;
+CREATE VIEW all_smack_binary_rules_view AS
+SELECT subject,
+ object,
+ access,
+ is_volatile
+FROM (SELECT subject, object, access, is_volatile
+ FROM ltl_permission_permission_rule_view
+ UNION ALL
+ SELECT subject, object, access, is_volatile
+ FROM ltl_permission_label_rule_view
+ UNION ALL
+ SELECT subject, object, access, is_volatile
+ FROM ltl_permission_app_path_type_rule_view
+ UNION ALL
+ SELECT subject, object, access, is_volatile
+ FROM ltl_label_app_path_type_rule_view
+ UNION ALL
+ SELECT subject, object, access, 0
+ FROM ltl_app_path_view
+ UNION ALL
+ SELECT subject, object, access, 0
+ FROM ltl_app_path_reverse_view
+ );
+
+DELETE FROM all_smack_binary_rules;
+
+INSERT INTO all_smack_binary_rules
+SELECT subject, object, access, is_volatile
+FROM all_smack_binary_rules_view;
COMMIT TRANSACTION;
---smaple file for future work
+
BEGIN EXCLUSIVE TRANSACTION;
--assume, that database is in version V2
---place your queries to update the database schema to V3 here
-
-
-
PRAGMA user_version = 3;
COMMIT TRANSACTION;
/**
- * Saves present smack rules in a temporary table: history_smack_rule
- *
- * @ingroup RDB internal functions
- *
- * @param p_db pointer to a SQLite3 database object
- * @return PC_OPERATION_SUCCESS on success, error code otherwise
- */
-int save_smack_rules(sqlite3 *p_db);
-
-
-/**
* Prepare tables with smack rules.
*
* @ingroup RDB internal functions
// Create the temporary tables:
if(sqlite3_exec(*p_db,
"PRAGMA foreign_keys = ON; \
- CREATE TEMPORARY TABLE history_smack_rule( \
- subject VARCHAR NOT NULL, \
- object VARCHAR NOT NULL, \
- access INTEGER NOT NULL); \
\
CREATE TEMPORARY TABLE modified_label( \
- name VARCHAR NOT NULL, \
- UNIQUE(name)); \
+ name VARCHAR NOT NULL PRIMARY KEY); \
\
- CREATE TEMPORARY TABLE all_smack_binary_rule_modified( \
+ 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); \
+ 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, \
+ 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, \
+ FROM ( \
+ SELECT subject, object, \
s1.access & ~s2.access AS access_add, \
s2.access & ~s1.access AS access_del \
- FROM all_smack_binary_rule_modified AS s1 \
+ FROM current_smack_rule_modified AS s1 \
INNER JOIN history_smack_rule_modified AS s2 \
USING (subject, object) \
WHERE s1.access != s2.access \
SELECT subject, object, \
s1.access AS access_add, \
0 AS access_del \
- FROM all_smack_binary_rule_modified s1 \
+ FROM current_smack_rule_modified s1 \
LEFT JOIN history_smack_rule_modified s2 \
USING (subject, object) \
WHERE s2.subject IS NULL AND \
0 AS access_add, \
s1.access AS access_del \
FROM history_smack_rule_modified s1 \
- LEFT JOIN all_smack_binary_rule_modified s2 \
+ LEFT JOIN current_smack_rule_modified s2 \
USING (subject, object) \
WHERE s2.subject IS NULL AND \
s2.object IS NULL \
return ret;
}
-
-int save_smack_rules(sqlite3 *p_db)
-{
- RDB_LOG_ENTRY;
-
- if(sqlite3_exec(p_db,
- "DELETE FROM history_smack_rule; \
- \
- INSERT INTO history_smack_rule \
- SELECT subject, object, access \
- FROM all_smack_binary_rules; \
- \
- CREATE INDEX history_smack_rule_subject_object_index \
- ON history_smack_rule(subject, object);",
- 0, 0, 0) != SQLITE_OK) {
- C_LOGE("RDB: Error during saving history table: %s",
- sqlite3_errmsg(p_db));
- return PC_ERR_DB_OPERATION;
- }
-
- return PC_OPERATION_SUCCESS;
-}
-
-
int update_rules_in_db(sqlite3 *p_db)
{
RDB_LOG_ENTRY;
- // All rules generated by the present state of the database
if(sqlite3_exec(p_db,
- "DELETE FROM all_smack_binary_rules; \
- \
- INSERT INTO all_smack_binary_rules \
- SELECT subject, object, access, is_volatile \
- FROM all_smack_binary_rules_view; \
- \
- DELETE FROM all_smack_binary_rule_modified; \
- \
- INSERT INTO all_smack_binary_rule_modified \
- SELECT subject, object, access \
- FROM all_smack_binary_rules, \
- modified_label \
- WHERE subject IN modified_label OR \
- object IN modified_label; \
- \
- DELETE FROM history_smack_rule_modified; \
- \
- INSERT INTO history_smack_rule_modified \
- SELECT subject, object, access \
- FROM history_smack_rule, \
- modified_label \
- WHERE subject IN modified_label OR \
- object IN modified_label; \
+ "\
+ -- clean temporary tables\n \
+ DELETE FROM all_smack_binary_rules_modified; \
+ DELETE FROM current_smack_rule_modified; \
+ DELETE FROM history_smack_rule_modified; \
+ \
+ -- gather possibly modified rules\n \
+ INSERT INTO all_smack_binary_rules_modified \
+ SELECT subject, object, access, is_volatile \
+ FROM all_smack_binary_rules_view \
+ WHERE subject IN modified_label; \
+ \
+ INSERT INTO all_smack_binary_rules_modified \
+ SELECT subject, object, access, is_volatile \
+ FROM all_smack_binary_rules_view \
+ WHERE object IN modified_label AND subject NOT IN modified_label; \
+ \
+ -- prepare aggregated rules for diff algorithm\n \
+ INSERT INTO current_smack_rule_modified \
+ SELECT subject, object, bitwise_or(access) \
+ FROM all_smack_binary_rules_modified \
+ GROUP BY subject, object \
+ ORDER BY subject, object ASC; \
+ \
+ INSERT INTO history_smack_rule_modified \
+ SELECT subject, object, bitwise_or(access) \
+ FROM all_smack_binary_rules \
+ WHERE subject IN modified_label OR object IN modified_label \
+ GROUP BY subject, object \
+ ORDER BY subject, object ASC; \
+ \
+ -- apply changes to all_smack_binary_rules\n \
+ DELETE FROM all_smack_binary_rules \
+ WHERE subject IN modified_label OR \
+ object IN modified_label; \
+ \
+ INSERT INTO all_smack_binary_rules \
+ SELECT subject, object, access, is_volatile \
+ FROM all_smack_binary_rules_modified; \
+ \
+ -- cleanup\n \
+ DELETE FROM modified_label; \
",
0, 0, 0) != SQLITE_OK) {
C_LOGE("RDB: Error during updating rules: %s",
return PC_ERR_DB_CONNECTION;
}
- ret = save_smack_rules(*pp_db);
return ret;
}