Add new table(sensitive_dir) in db for pkg->sensitive_dir mapping.
Add new view with triggers for easier management.
Add API in PrivilegeDb for sensitive dir management.
Change-Id: I92304ad3c0a7bd3b33203f39c2168853aff2a63f
BEGIN EXCLUSIVE TRANSACTION;
-PRAGMA user_version = 9;
+PRAGMA user_version = 10;
CREATE TABLE IF NOT EXISTS pkg (
pkg_id INTEGER PRIMARY KEY,
UNIQUE (name)
);
+CREATE TABLE IF NOT EXISTS sensitive_dir (
+path VARCHAR PRIMARY KEY,
+pkg_id INTEGER NOT NULL,
+uid INTEGER NOT NULL,
+FOREIGN KEY(pkg_id) REFERENCES pkg (pkg_id) ON DELETE CASCADE
+);
+
DROP VIEW IF EXISTS user_app_pkg_view;
CREATE VIEW user_app_pkg_view AS
SELECT
AND app_private_sharing.target_app_name = OLD.target_app_name;
END;
+DROP VIEW IF EXISTS pkg_sensitive_dir_view;
+CREATE VIEW pkg_sensitive_dir_view AS
+SELECT
+ path,
+ name AS pkg_name,
+ uid
+FROM sensitive_dir
+INNER JOIN pkg USING (pkg_id);
+
+DROP TRIGGER IF EXISTS pkg_sensitive_dir_view_insert_trigger;
+CREATE TRIGGER pkg_sensitive_dir_view_insert_trigger
+INSTEAD OF INSERT ON pkg_sensitive_dir_view
+BEGIN
+ SELECT RAISE(ABORT, 'Sensitive dir already registered with different pkg_name')
+ WHERE EXISTS (SELECT 1 FROM pkg_sensitive_dir_view
+ WHERE path=NEW.path
+ AND pkg_name!=NEW.pkg_name);
+
+ SELECT RAISE(ABORT, 'Sensitive dir already registered with different uid')
+ WHERE EXISTS (SELECT 1 FROM pkg_sensitive_dir_view
+ WHERE path=NEW.path
+ AND uid!=NEW.uid);
+
+ SELECT RAISE(ABORT, 'No such package')
+ WHERE NOT EXISTS (SELECT 1 FROM pkg WHERE name=NEW.pkg_name);
+
+ INSERT OR IGNORE INTO sensitive_dir(path, pkg_id, uid) VALUES (
+ NEW.path,
+ (SELECT pkg_id FROM pkg WHERE name=NEW.pkg_name),
+ NEW.uid);
+END;
+
+DROP TRIGGER IF EXISTS pkg_sensitive_dir_view_delete_trigger;
+CREATE TRIGGER pkg_sensitive_dir_view_delete_trigger
+INSTEAD OF DELETE ON pkg_sensitive_dir_view
+BEGIN
+ DELETE FROM sensitive_dir WHERE
+ path=OLD.path AND
+ pkg_id=(SELECT pkg_id FROM pkg WHERE name=OLD.pkg_name) AND
+ uid=OLD.uid;
+END;
+
+
COMMIT TRANSACTION;
--- /dev/null
+-- Dummy script. We only need to trigger db upgrade so that sql gets called and new table is created
EIsPackageSharedRO,
EIsPackageHybrid,
EGetPackagesInfo,
+ EAddSensitiveDir,
+ EGetSensitiveDirs,
};
class PrivilegeDb {
{ StmtType::EIsPackageSharedRO, "SELECT shared_ro FROM pkg WHERE name=?"},
{ StmtType::EIsPackageHybrid, "SELECT is_hybrid FROM pkg WHERE name=?"},
{ StmtType::EGetPackagesInfo, "SELECT name, shared_ro, is_hybrid FROM pkg"},
+ { StmtType::EAddSensitiveDir, "INSERT INTO pkg_sensitive_dir_view VALUES (?, ?, ?)"},
+ { StmtType::EGetSensitiveDirs, "SELECT path FROM pkg_sensitive_dir_view WHERE pkg_name = ? AND uid = ?"},
};
/**
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
void GetPackagesInfo(std::vector<PkgInfo> &packages);
+
+ /**
+ * Add new sensitive directory to the package
+ *
+ * @param[in] pkgName - name of the package
+ * @param[in] uid - user identifier
+ * @param[in] path - directory paths that will be marked as sensitive
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void AddSensitiveDir(const std::string &pkgName, uid_t uid, const std::string &path);
+
+ /**
+ * Retrieve list of sensitive directories in the package
+ *
+ * @param[in] pkgName - name of the package
+ * @param[in] uid - user identifier
+ * @param[out] paths - vector of sensitive directories' paths. This parameter does not need to
+ * be empty, but it is being overwritten during function call
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void GetSensitiveDirs(const std::string &pkgName, uid_t uid, std::vector<std::string> &paths);
};
} //namespace SecurityManager
});
}
+void PrivilegeDb::AddSensitiveDir(const std::string &pkgName,
+ uid_t uid,
+ const std::string &path)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::EAddSensitiveDir);
+ command->BindString(1, path);
+ command->BindString(2, pkgName);
+ command->BindInteger(3, uid);
+
+ if (command->Step())
+ LogDebug("Added sensitive dir for package " << pkgName << " path: " << path);
+ });
+}
+
+void PrivilegeDb::GetSensitiveDirs(const std::string &pkgName,
+ uid_t uid,
+ std::vector<std::string> &paths)
+{
+ try_catch<void>([&] {
+ paths.clear();
+
+ auto command = getStatement(StmtType::EGetSensitiveDirs);
+ command->BindString(1, pkgName);
+ command->BindInteger(2, uid);
+ while (command->Step()) {
+ LogDebug("Found sensitive dir for package " << pkgName << " path: " <<
+ command->GetColumnString(0));
+ paths.push_back(command->GetColumnString(0));
+ }
+ });
+}
+
} //namespace SecurityManager