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 app_defined_privilege (
+app_id INTEGER NOT NULL,
+uid INTEGER NOT NULL,
+privilege VARCHAR NOT NULL,
+type INTEGER NOT NULL CHECK (type >= 0 AND type <= 1),
+FOREIGN KEY (app_id, uid) REFERENCES user_app (app_id, uid) ON UPDATE CASCADE 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 app_defined_privilege_view;
+CREATE VIEW app_defined_privilege_view AS
+SELECT
+ name AS app_name,
+ uid,
+ privilege,
+ type
+FROM app_defined_privilege
+LEFT JOIN app USING (app_id)
+LEFT JOIN user_app USING (uid);
+
+DROP TRIGGER IF EXISTS app_defined_privilege_view_insert_trigger;
+CREATE TRIGGER app_defined_privilege_view_insert_trigger
+INSTEAD OF INSERT ON app_defined_privilege_view
+BEGIN
+ SELECT RAISE(ABORT, 'App defined privilege already defined by different application')
+ WHERE EXISTS (SELECT 1 FROM app_defined_privilege_view
+ WHERE privilege=NEW.privilege AND app_name!=NEW.app_name);
+
+ SELECT RAISE(ABORT, 'Application was not found')
+ WHERE NOT EXISTS (SELECT 1 FROM user_app_pkg_view
+ WHERE uid=NEW.uid AND app_name=NEW.app_name);
+
+ INSERT OR IGNORE INTO app_defined_privilege (app_id, uid, privilege, type)
+ VALUES ((SELECT app_id FROM app WHERE name=NEW.app_name), NEW.uid, NEW.privilege, NEW.type);
+END;
+
+DROP TRIGGER IF EXISTS app_defined_privilege_view_delete_trigger;
+CREATE TRIGGER app_defined_privilege_view_delete_trigger
+INSTEAD OF DELETE ON app_defined_privilege_view
+BEGIN
+ DELETE FROM app_defined_privilege
+ WHERE app_id=(SELECT app_id FROM app WHERE name=OLD.app_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
\ No newline at end of file
#include "dpl/db/sql_connection.h"
#include "tzplatform-config.h"
+#include "security-manager-types.h"
#include "pkg-info.h"
EIsPackageSharedRO,
EIsPackageHybrid,
EGetPackagesInfo,
+ EAddAppDefinedPrivilege,
+ ERemoveAppDefinedPrivileges,
+ EGetAppDefinedPrivileges,
+ EGetAppForAppDefinedPrivilege,
};
+typedef std::pair<std::string, int> Privilege;
+typedef std::vector<Privilege> PrivilegesVector;
+
class PrivilegeDb {
/**
* PrivilegeDb database class
{ 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::EAddAppDefinedPrivilege, "INSERT INTO app_defined_privilege_view (app_name, uid, privilege, type) VALUES (?, ?, ?, ?)"},
+ { StmtType::ERemoveAppDefinedPrivileges, "DELETE FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
+ { StmtType::EGetAppDefinedPrivileges, "SELECT privilege, type FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"},
+ { StmtType::EGetAppForAppDefinedPrivilege, "SELECT app_name FROM app_defined_privilege_view WHERE privilege = ? AND uid = ?"},
};
/**
* @exception PrivilegeDb::Exception::ConstraintError on constraint violation
*/
void GetPackagesInfo(std::vector<PkgInfo> &packages);
+
+ /**
+ * Add new privilege defined by application
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ * @param[in] privilege - privilege identifier
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void AddAppDefinedPrivilege(const std::string &appName, uid_t uid, const Privilege &privilege);
+
+ /**
+ * Remove privileges defined by application
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void RemoveAppDefinedPrivileges(const std::string &appName, uid_t uid);
+
+ /**
+ * Retrieve vector of pairs with privilege (1st value) and privilege type (2nd value)
+ *
+ * @param[in] appName - application identifier
+ * @param[in] uid - user identifier
+ * @param[out] privileges - list of privileges
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void GetAppDefinedPrivileges(const std::string &appName, uid_t uid, PrivilegesVector &privileges);
+
+ /**
+ * Retrieve application which define privilege
+ *
+ * @param[in] privilege - privilege identifier
+ * @param[in] uid - user identifier
+ * @param[out] appName - application identifier
+ *
+ * @exception PrivilegeDb::Exception::InternalError on internal error
+ * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+ */
+ void GetAppForAppDefinedPrivilege(const Privilege &privilege, uid_t uid, std::string &appName);
};
} //namespace SecurityManager
});
}
+void PrivilegeDb::AddAppDefinedPrivilege(const std::string &appName, uid_t uid, const Privilege &privilege)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::EAddAppDefinedPrivilege);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+ command->BindString(3, privilege.first);
+ command->BindInteger(4, privilege.second);
+
+ if (command->Step())
+ LogDebug("Added privilege: " << privilege.first << " defined by: " << appName <<
+ " and user: " << uid);
+ });
+}
+
+void PrivilegeDb::RemoveAppDefinedPrivileges(const std::string &appName, uid_t uid)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::ERemoveAppDefinedPrivileges);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+
+ if (command->Step())
+ LogDebug("Removed privileges defined by: " << appName << " and user: " << uid);
+ });
+}
+
+void PrivilegeDb::GetAppDefinedPrivileges(const std::string &appName, uid_t uid, PrivilegesVector &privileges)
+{
+ try_catch<void>([&] {
+ privileges.clear();
+
+ auto command = getStatement(StmtType::EGetAppDefinedPrivileges);
+ command->BindString(1, appName);
+ command->BindInteger(2, uid);
+ while (command->Step()) {
+ auto privilege = command->GetColumnString(0);
+ auto type = command->GetColumnInteger(1);
+ LogDebug("App: " << appName << " installed by: " << uid << " defines privilege: " << privilege);
+ privileges.push_back(std::make_pair(privilege, type));
+ }
+ });
+}
+
+void PrivilegeDb::GetAppForAppDefinedPrivilege(const Privilege &privilege, uid_t uid, std::string &appName)
+{
+ try_catch<void>([&] {
+ appName.clear();
+
+ auto command = getStatement(StmtType::EGetAppForAppDefinedPrivilege);
+ command->BindString(1, privilege.first);
+ command->BindInteger(2, uid);
+
+ if (command->Step())
+ appName = command->GetColumnString(0);
+
+ if (!appName.empty())
+ LogDebug("Privilege: " << privilege.first << " defined by " << appName);
+ else
+ LogDebug("Privilege: " << privilege.first << " not exist");
+ });
+}
+
} //namespace SecurityManager