Extend support to all apps instead of only 2.x apps.
Migrate database to version 7:
Add shared_ro INTEGER column in pkg table
Conflicts:
src/common/include/privilege_db.h
src/common/privilege_db.cpp
Change-Id: Id925342c37651ee0d87cf14de4d806ef63c678fb
BEGIN EXCLUSIVE TRANSACTION;
-PRAGMA user_version = 6;
+PRAGMA user_version = 7;
CREATE TABLE IF NOT EXISTS pkg (
pkg_id INTEGER PRIMARY KEY,
name VARCHAR NOT NULL,
author_id INTEGER,
+shared_ro INTEGER NOT NULL DEFAULT 0,
UNIQUE (name)
FOREIGN KEY (author_id) REFERENCES author (author_id)
);
--- /dev/null
+BEGIN EXCLUSIVE TRANSACTION;
+
+PRAGMA user_version = 7;
+
+ALTER TABLE pkg ADD shared_ro INTEGER NOT NULL DEFAULT 0;
+
+UPDATE pkg
+SET shared_ro = 1
+WHERE pkg_id IN (SELECT pkg_id FROM app WHERE version < 3);
+
+COMMIT TRANSACTION;
EClearPrivatePaths,
EGetPrivilegeGroups,
EGetUserApps,
- EGetTizen2XPackages,
+ EGetAllPackages,
EGetAppsInPkg,
EGetGroups,
EGetPkgAuthorId,
EAuthorIdExists,
EGetAuthorIdByName,
+ EGetSharedROPackages,
+ ESetPackageSharedRO,
+ EIsPackageSharedRO,
};
class PrivilegeDb {
{ StmtType::EClearPrivatePaths, "DELETE FROM shared_path;"},
{ StmtType::EGetPrivilegeGroups, " SELECT group_name FROM privilege_group WHERE privilege_name = ?" },
{ StmtType::EGetUserApps, "SELECT app_name FROM user_app_pkg_view WHERE uid=?" },
- { StmtType::EGetTizen2XPackages, "SELECT DISTINCT pkg_name FROM user_app_pkg_view WHERE version LIKE '2.%%'" },
+ { StmtType::EGetAllPackages, "SELECT DISTINCT pkg_name FROM user_app_pkg_view" },
{ StmtType::EGetAppsInPkg, " SELECT app_name FROM user_app_pkg_view WHERE pkg_name = ?" },
{ StmtType::EGetGroups, "SELECT DISTINCT group_name, privilege_name FROM privilege_group" },
{ StmtType::EGetPkgAuthorId, "SELECT author_id FROM pkg WHERE name = ? AND author_id IS NOT NULL"},
{ StmtType::EAuthorIdExists, "SELECT count(*) FROM author where author_id=?"},
{ StmtType::EGetAuthorIdByName, "SELECT author_id FROM author WHERE name=?"},
+ { StmtType::EGetSharedROPackages, "SELECT DISTINCT name FROM pkg WHERE shared_ro = 1;"},
+ { StmtType::ESetPackageSharedRO, "UPDATE pkg SET shared_ro=1 WHERE name=?"},
+ { StmtType::EIsPackageSharedRO, "SELECT shared_ro FROM pkg WHERE name=?"},
};
/**
void GetPkgApps(const std::string &pkgName, std::vector<std::string> &appNames);
/**
- * Retrieve list of all Tizen 2.X packages
+ * Retrieve list of all packages
*
- * @param[out] packages - vector of package identifiers describing installed 2.x packages,
- * this parameter do not need to be empty, but
- * it is being overwritten during function call.
+ * @param[out] packages - vector of package identifiers describing installed packages,
+ * this parameter do not need to be empty, but
+ * it is being overwritten during function call.
* @exception DB::SqlConnection::Exception::InternalError on internal error
* @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
*/
- void GetTizen2XPackages(std::vector<std::string> &packages);
+ void GetAllPackages(std::vector<std::string> &packages);
/* Retrive an id of an author from database
*
*/
void GetGroupsRelatedPrivileges(std::vector<std::pair<std::string, std::string>> &privileges);
+ /**
+ * Retrieve list of packages with shared RO set to 1
+ *
+ * @param[out] packages - vector of package identifiers describing installed packages,
+ * this parameter do not need to be empty, but
+ * it is being overwritten during function call.
+ * @exception DB::SqlConnection::Exception::InternalError on internal error
+ * @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
+ */
+ void GetSharedROPackages(std::vector<std::string> &packages);
+
+ /**
+ * Set shared_ro field to 1 in package given by name
+ *
+ * @exception DB::SqlConnection::Exception::InternalError on internal error
+ * @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
+ */
+ void SetSharedROPackage(const std::string& pkgName);
+
+ /**
+ * Check whether package has shared_ro field set to 1 in db
+ *
+ * @exception DB::SqlConnection::Exception::InternalError on internal error
+ * @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
+ */
+ bool IsPackageSharedRO(const std::string& pkgName);
};
} //namespace SecurityManager
const std::vector<std::string> &allowedDirs);
static int labelPaths(const pkg_paths &paths,
- const std::string &pkgName,
- app_install_type installationType,
- const uid_t &uid);
+ const std::string &pkgName,
+ app_install_type installationType,
+ const uid_t &uid);
- static void getTizen2XApps(SmackRules::PkgsApps &pkgsApps);
+ static void getAllApps(SmackRules::PkgsApps &pkgsApps);
+
+ static void getSharedROApps(SmackRules::PkgsApps &sharedROPkgsApps);
+
+ static bool isSharedRO(const pkg_paths& paths);
static bool isPrivilegePrivacy(const std::string &privilege);
void generatePackageCrossDeps(const std::vector<std::string> &pkgContents);
/**
- * Generate SharedRO rules for Tizen 2.x applications
- * Each 2.X application gets read-only access to files shared by all other 2.X packages.
+ * Generate RO rules for all applications to SharedRO apps during appInstall/Uninstall
+ * Each application gets read-only access to files shared by SharedRO packages.
*
- * @param[in] pkgsApps vector of Tizen 2.X applications - each element contains
- * a pair with package name and contents
+ * @param[in] pkgsApps vector of all applications - each element contains
+ * a pair with package name and contents
+ * @param[in] sharedROPkgsApps vector of applications having sharedRO directory in their package -
+ * each element contains a pair with package name and contents
*/
- static void generateSharedRORules(PkgsApps &pkgsApps);
+ static void generateSharedRORules(PkgsApps &pkgsApps, PkgsApps &sharedROPkgsApps);
/**
- * Revoke SharedRO rules for Tizen 2.x applications when a package is being removed
+ * Revoke SharedRO rules for applications when a package is being removed
* Rules from all applications in \ref pkgsApps to SharedRO label of the package
* under removal will be revoked from kernel.
*
- * @param[in] pkgsApps vector of Tizen 2.X applications - each element contains
+ * @param[in] pkgsApps vector of applications - each element contains
* a pair with package name and contents
* @param[in] revokePkg package name being removed
*/
});
}
-void PrivilegeDb::GetTizen2XPackages(std::vector<std::string> &packages)
+void PrivilegeDb::GetAllPackages(std::vector<std::string> &packages)
{
try_catch<void>([&] {
- auto command = getStatement(StmtType::EGetTizen2XPackages);
+ auto command = getStatement(StmtType::EGetAllPackages);
packages.clear();
while (command->Step()) {
- const std::string & tizen2XPkg = command->GetColumnString(0);
- LogDebug("Found " << tizen2XPkg << " Tizen 2.X packages installed");
- packages.push_back(tizen2XPkg);
+ const std::string &pkg = command->GetColumnString(0);
+ LogDebug("Found " << pkg << " package installed");
+ packages.push_back(pkg);
+ };
+ });
+}
+
+void PrivilegeDb::GetSharedROPackages(std::vector<std::string> &packages)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::EGetSharedROPackages);
+ packages.clear();
+ while (command->Step()) {
+ const std::string &pkg = command->GetColumnString(0);
+ LogDebug("Found " << pkg << " package installed");
+ packages.push_back(pkg);
};
});
}
});
}
+void PrivilegeDb::SetSharedROPackage(const std::string &pkgName)
+{
+ try_catch<void>([&] {
+ auto command = getStatement(StmtType::ESetPackageSharedRO);
+ command->BindString(1, pkgName);
+
+ if (command->Step())
+ LogDebug("shared_ro has been set to 1 for pkg: " << pkgName);
+ });
+}
+
+bool PrivilegeDb::IsPackageSharedRO(const std::string &pkgName)
+{
+ return try_catch<bool>([&]() -> bool {
+ auto command = getStatement(StmtType::EIsPackageSharedRO);
+ command->BindString(1, pkgName);
+ int shared_ro = 0;
+
+ if (command->Step())
+ shared_ro = command->GetColumnInteger(0);
+
+ LogDebug("Package " << pkgName << "has shared_ro set to " << shared_ro);
+
+ return (shared_ro > 0);
+ });
+}
+
} //namespace SecurityManager
return SECURITY_MANAGER_SUCCESS;
}
-bool isTizen2XVersion(const std::string &version)
-{
- std::size_t notWhitePos = version.find_first_not_of(" \t");
- if (notWhitePos == std::string::npos)
- return false;
- if (version.at(notWhitePos) == '2')
- return true;
- return false;
-}
-
bool sharingExists(const std::string &targetAppName, const std::string &path)
{
int targetPathCount;
}
}
-void ServiceImpl::getTizen2XApps(SmackRules::PkgsApps &pkgsApps)
+void ServiceImpl::getAllApps(SmackRules::PkgsApps &pkgsApps)
+{
+ std::vector<std::string> pkgs;
+ PrivilegeDb::getInstance().GetAllPackages(pkgs);
+
+ pkgsApps.resize(pkgs.size());
+ for (size_t i = 0; i < pkgs.size(); ++i) {
+ pkgsApps[i].first = std::move(pkgs[i]);
+ PrivilegeDb::getInstance().GetPkgApps(pkgsApps[i].first, pkgsApps[i].second);
+ }
+}
+
+void ServiceImpl::getSharedROApps(SmackRules::PkgsApps &pkgsApps)
{
std::vector<std::string> pkgs;
- PrivilegeDb::getInstance().GetTizen2XPackages(pkgs);
+ PrivilegeDb::getInstance().GetSharedROPackages(pkgs);
pkgsApps.resize(pkgs.size());
for (size_t i = 0; i < pkgs.size(); ++i) {
return false;
}
+bool ServiceImpl::isSharedRO(const pkg_paths& paths)
+{
+ for (const auto& pkgPath : paths) {
+ auto pathType = static_cast<app_install_path_type>(pkgPath.second);
+ if (pathType == SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO)
+ return true;
+ }
+
+ return false;
+}
+
int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
{
std::vector<std::string> addedPermissions;
std::string pkgBasePath;
std::string appLabel;
std::string pkgLabel;
- SmackRules::PkgsApps tizen2XpkgsApps;
+ SmackRules::PkgsApps sharedROPkgsApps;
+ SmackRules::PkgsApps allApps;
int authorId;
+ bool hasSharedRO = isSharedRO(req.pkgPaths);
try {
installRequestMangle(req, cynaraUserStr);
PrivilegeDb::getInstance().GetPkgApps(req.pkgName, pkgContents);
PrivilegeDb::getInstance().GetPkgAuthorId(req.pkgName, authorId);
CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, cynaraUserStr, req.privileges, isPrivilegePrivacy);
- // if app is targetted to Tizen 2.X, give other 2.X apps RO rules to it's shared dir
- if (isTizen2XVersion(req.tizenVersion))
- getTizen2XApps(tizen2XpkgsApps);
+
+ if (hasSharedRO)
+ PrivilegeDb::getInstance().SetSharedROPackage(req.pkgName);
// WTF? Why this commit is here? Shouldn't it be at the end of this function?
PrivilegeDb::getInstance().CommitTransaction();
<< req.pkgName << ". Applications in package: " << pkgContents.size());
SmackRules::installApplicationRules(req.appName, req.pkgName, authorId, pkgContents);
- if (isTizen2XVersion(req.tizenVersion))
- SmackRules::generateSharedRORules(tizen2XpkgsApps);
+ getSharedROApps(sharedROPkgsApps);
+ getAllApps(allApps);
+
+ SmackRules::generateSharedRORules(allApps, sharedROPkgsApps);
SmackRules::mergeRules();
} catch (const SmackException::InvalidParam &e) {
bool removePkg = false;
bool removeAuthor = false;
std::string cynaraUserStr;
- SmackRules::PkgsApps tizen2XpkgsApps;
+ SmackRules::PkgsApps pkgsApps, sharedROPkgsApps;
std::map<std::string, std::vector<std::string>> asOwnerSharing;
std::map<std::string, std::vector<std::string>> asTargetSharing;
int authorId;
PrivilegeDb::getInstance().RemoveApplication(req.appName, req.uid, removeApp, removePkg, removeAuthor);
- // if uninstalled app is targetted to Tizen 2.X, remove other 2.X apps RO rules it's shared dir
- if (isTizen2XVersion(req.tizenVersion))
- getTizen2XApps(tizen2XpkgsApps);
+ getAllApps(pkgsApps);
+ getSharedROApps(sharedROPkgsApps);
CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, cynaraUserStr, std::vector<std::string>(), isPrivilegePrivacy);
PrivilegeDb::getInstance().CommitTransaction();
SmackRules::updatePackageRules(req.pkgName, pkgContents);
}
- if (isTizen2XVersion(req.tizenVersion)) {
- SmackRules::generateSharedRORules(tizen2XpkgsApps);
- if (removePkg)
- SmackRules::revokeSharedRORules(tizen2XpkgsApps, req.pkgName);
- }
+ SmackRules::generateSharedRORules(pkgsApps, sharedROPkgsApps);
+ if (removePkg)
+ SmackRules::revokeSharedRORules(pkgsApps, req.pkgName);
}
if (authorId != -1 && removeAuthor) {
return SECURITY_MANAGER_ERROR_MEMORY;
}
+ try {
+ if (isSharedRO(req.pkgPaths)) {
+ PrivilegeDb::getInstance().BeginTransaction();
+
+ if (!PrivilegeDb::getInstance().IsPackageSharedRO(req.pkgName)) {
+
+ PrivilegeDb::getInstance().SetSharedROPackage(req.pkgName);
+
+ SmackRules::PkgsApps pkgsApps;
+ SmackRules::PkgsApps allApps;
+
+ getSharedROApps(pkgsApps);
+ getAllApps(allApps);
+
+ SmackRules::generateSharedRORules(allApps, pkgsApps);
+ SmackRules::mergeRules();
+ }
+ PrivilegeDb::getInstance().CommitTransaction();
+ }
+ } catch (const PrivilegeDb::Exception::IOError &e) {
+ LogError("Cannot access application database: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ } catch (const PrivilegeDb::Exception::InternalError &e) {
+ PrivilegeDb::getInstance().RollbackTransaction();
+ LogError("Error while saving application info to database: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ }
+
return labelPaths(req.pkgPaths,
req.pkgName,
static_cast<app_install_type>(req.installationType),
const std::string SMACK_RULES_PATH_MERGED = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged";
const std::string SMACK_RULES_PATH_MERGED_T = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged.temp";
const std::string SMACK_RULES_PATH = LOCAL_STATE_DIR "/security-manager/rules";
-const std::string SMACK_RULES_SHARED_RO_PATH = LOCAL_STATE_DIR "/security-manager/rules/2x_shared_ro";
+const std::string SMACK_RULES_SHARED_RO_PATH = LOCAL_STATE_DIR "/security-manager/rules/shared_ro";
const std::string SMACK_APP_IN_PACKAGE_PERMS = "rwxat";
const std::string SMACK_APP_CROSS_PKG_PERMS = "rx";
const std::string SMACK_APP_PATH_OWNER_PERMS = "rwxat";
}
}
-void SmackRules::generateSharedRORules(PkgsApps &pkgsApps)
+void SmackRules::generateSharedRORules(PkgsApps &pkgsApps, PkgsApps &sharedROPkgsApps)
{
LogDebug("Generating SharedRO rules");
for (size_t i = 0; i < pkgsApps.size(); ++i) {
for (const std::string &appName : pkgsApps[i].second) {
std::string appLabel = SmackLabels::generateAppLabel(appName);
- for (size_t j = 0; j < pkgsApps.size(); ++j) {
- if (j != i) { // Rules for SharedRO files from own pkg are generated elsewhere
- std::string &pkgName = pkgsApps[j].first;
+ for (size_t j = 0; j < sharedROPkgsApps.size(); ++j) {
+ // Rules for SharedRO files from own pkg are generated elsewhere
+ if (pkgsApps[i] != sharedROPkgsApps[j]) {
+ const std::string &pkgName = sharedROPkgsApps[j].first;
rules.add(appLabel,
- SmackLabels::generatePkgLabelOwnerRWothersRO(pkgName),
- SMACK_APP_CROSS_PKG_PERMS);
+ SmackLabels::generatePkgLabelOwnerRWothersRO(pkgName),
+ SMACK_APP_CROSS_PKG_PERMS);
}
}
}
for (const std::string &appName : pkgsApps[i].second) {
std::string appLabel = SmackLabels::generateAppLabel(appName);
rules.add(appLabel,
- SmackLabels::generatePkgLabelOwnerRWothersRO(revokePkg),
- SMACK_APP_CROSS_PKG_PERMS);
+ SmackLabels::generatePkgLabelOwnerRWothersRO(revokePkg),
+ SMACK_APP_CROSS_PKG_PERMS);
}
}
SECURITY_MANAGER_PATH_RW,
//! RO access for given application package
SECURITY_MANAGER_PATH_RO,
- //! RW access for the owner, RO for other 2.X applications
- //! (other 3.0 apps will not have access to the shared folder)
+ //! RW access for the owner, RO for other applications
SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO,
//! RW access for application packages coming from the same author
SECURITY_MANAGER_PATH_TRUSTED_RW,