Add support for sensitive rw directories in db 42/112242/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 30 Jan 2017 10:40:31 +0000 (11:40 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 28 Feb 2017 11:55:09 +0000 (03:55 -0800)
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

db/db.sql
db/updates/update-db-to-v10.sql [new file with mode: 0644]
src/common/include/privilege_db.h
src/common/privilege_db.cpp

index f22e451873493df810bd8095e74145491b6ae447..7b6c0ec06ca6784b9f75892820718b76907e7882 100644 (file)
--- a/db/db.sql
+++ b/db/db.sql
@@ -4,7 +4,7 @@ PRAGMA auto_vacuum = NONE;
 
 BEGIN EXCLUSIVE TRANSACTION;
 
-PRAGMA user_version = 9;
+PRAGMA user_version = 10;
 
 CREATE TABLE IF NOT EXISTS pkg (
 pkg_id INTEGER PRIMARY KEY,
@@ -62,6 +62,13 @@ CREATE TABLE IF NOT EXISTS author (
        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
@@ -202,4 +209,47 @@ BEGIN
     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;
diff --git a/db/updates/update-db-to-v10.sql b/db/updates/update-db-to-v10.sql
new file mode 100644 (file)
index 0000000..66fb60b
--- /dev/null
@@ -0,0 +1 @@
+-- Dummy script. We only need to trigger db upgrade so that sql gets called and new table is created
index 1661b5ce7c3c83e896e186d8efca7f7157f56618..a5157cbffccc936e6b1ebf0c627bba4576d510d3 100644 (file)
@@ -80,6 +80,8 @@ enum class StmtType {
     EIsPackageSharedRO,
     EIsPackageHybrid,
     EGetPackagesInfo,
+    EAddSensitiveDir,
+    EGetSensitiveDirs,
 };
 
 class PrivilegeDb {
@@ -134,6 +136,8 @@ private:
         { 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 = ?"},
     };
 
     /**
@@ -527,6 +531,31 @@ public:
      * @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
index 56173018f3ee5e97adabbc5fbb1b8801df75391e..5cc53656148225452ac7469b74092b6372d77f62 100644 (file)
@@ -588,4 +588,37 @@ void PrivilegeDb::GetPackagesInfo(std::vector<PkgInfo> &packages)
      });
 }
 
+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