return false;
}
+class ScopedTransaction {
+public:
+ ScopedTransaction() : m_isCommited(false) {
+ PrivilegeDb::getInstance().BeginTransaction();
+ }
+ ScopedTransaction(const ScopedTransaction &other) = delete;
+ ScopedTransaction& operation(const ScopedTransaction &other) = delete;
+
+ void commit() {
+ PrivilegeDb::getInstance().CommitTransaction();
+ m_isCommited = true;
+ }
+ ~ScopedTransaction() {
+ if (!m_isCommited) {
+ try {
+ PrivilegeDb::getInstance().RollbackTransaction();
+ } catch (const SecurityManager::Exception &e) {
+ LogError("Transaction rollback failed: " << e.GetMessage());
+ } catch(...) {
+ LogError("Transaction rollback failed with unknown exception");
+ }
+ }
+ }
+private:
+ bool m_isCommited;
+};
+
} // end of anonymous namespace
ServiceImpl::ServiceImpl()
return SECURITY_MANAGER_API_SUCCESS;
}
+
+int ServiceImpl::dropOnePrivateSharing(const std::string &ownerAppId, const std::string &ownerPkgId,
+ const std::vector<std::string> &ownerPkgContents, const std::string &targetAppId,
+ const std::string &path, const std::string &zoneId, bool isSlave)
+{
+ int errorRet;
+ try {
+ int targetPathCount, pathCount, ownerTargetCount;
+ PrivilegeDb::getInstance().DropPrivateSharing(ownerAppId, targetAppId, path);
+ PrivilegeDb::getInstance().GetTargetPathSharingCount(targetAppId, path, targetPathCount);
+ PrivilegeDb::getInstance().GetPathSharingCount(path, pathCount);
+ PrivilegeDb::getInstance().GetOwnerTargetSharingCount(ownerAppId, targetAppId, ownerTargetCount);
+ if (targetPathCount > 0) {
+ return SECURITY_MANAGER_API_SUCCESS;
+ }
+ if (pathCount < 1) {
+ SmackLabels::setupPath(ownerPkgId, path, SECURITY_MANAGER_PATH_RW, zoneId);
+ }
+ std::string pathLabel = zoneSmackLabelGenerate(SmackLabels::generateSharedPrivateLabel(ownerPkgId, path), zoneId);
+ if (isSlave) {
+ MasterReq::SmackDropPrivateSharingRules(ownerPkgId, ownerPkgContents, targetAppId, path, ownerTargetCount, pathCount);
+ } else {
+ SmackRules::dropPrivateSharingRules(ownerPkgId, ownerPkgContents, targetAppId, pathLabel,
+ pathCount < 1, ownerTargetCount < 1, zoneId);
+ }
+ return SECURITY_MANAGER_API_SUCCESS;
+ } catch (const SmackException::Base &e) {
+ LogError("Error performing smack operation: " << e.GetMessage());
+ errorRet = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ } catch (const std::exception &e) {
+ LogError("Some exception thrown : " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ } catch (...) {
+ LogError("Unknown exception thrown");
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ }
+ return errorRet;
+}
+
int ServiceImpl::applyPrivatePathSharing(const std::string &ownerAppId,
const std::string &targetAppId,
const std::vector<std::string> &paths,
bool isSlave)
{
- (void)ownerAppId;
- (void)targetAppId;
- (void)paths;
- (void)isSlave;
+ int errorRet;
+ int sharingAdded = 0;
+ std::string ownerPkgId;
+ std::vector<std::string> pkgContents;
+ std::string zoneId;
+ if (isSlave) {
+ if (!getZoneId(zoneId)) {
+ LogError("Failed to get Zone ID.");
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }
+ }
- return SECURITY_MANAGER_API_SUCCESS;
+ try {
+ std::string targetPkgId;
+ if (!PrivilegeDb::getInstance().GetAppPkgId(ownerAppId, ownerPkgId)) {
+ LogError(ownerAppId << " is not an installed application");
+ return SECURITY_MANAGER_API_ERROR_APP_UNKNOWN;
+ }
+ if (!PrivilegeDb::getInstance().GetAppPkgId(targetAppId, targetPkgId)) {
+ LogError(targetAppId << " is not an installed application");
+ return SECURITY_MANAGER_API_ERROR_APP_UNKNOWN;
+ }
+
+ for(const auto &path : paths) {
+ std::string pathLabel = SmackLabels::getSmackLabelFromPath(path);
+ if (pathLabel != zoneSmackLabelGenerate(SmackLabels::generatePkgLabel(ownerPkgId), zoneId)) {
+ std::string generatedPathLabel = zoneSmackLabelGenerate(SmackLabels::generateSharedPrivateLabel(ownerPkgId, path), zoneId);
+ if (generatedPathLabel != pathLabel) {
+ LogError("Path " << path << " has label " << pathLabel << " and dosen't belong"
+ " to application " << ownerAppId);
+ return SECURITY_MANAGER_API_ERROR_APP_NOT_PATH_OWNER;
+ }
+ }
+ }
+ if (ownerAppId == targetAppId) {
+ LogDebug("Owner application is the same as target application");
+ return SECURITY_MANAGER_API_SUCCESS;
+ }
+
+ if (ownerPkgId == targetPkgId) {
+ LogDebug("Owner and target belong to the same package");
+ return SECURITY_MANAGER_API_SUCCESS;
+ }
+ ScopedTransaction trans;
+ PrivilegeDb::getInstance().GetAppIdsForPkgId(ownerPkgId, pkgContents);
+ for (const auto &path : paths) {
+ int targetPathCount, pathCount, ownerTargetCount;
+ PrivilegeDb::getInstance().GetTargetPathSharingCount(targetAppId, path, targetPathCount);
+ PrivilegeDb::getInstance().GetPathSharingCount(path, pathCount);
+ PrivilegeDb::getInstance().GetOwnerTargetSharingCount(ownerAppId, targetAppId, ownerTargetCount);
+ std::string pathLabel = zoneSmackLabelGenerate(SmackLabels::generateSharedPrivateLabel(ownerPkgId, path), zoneId);
+ PrivilegeDb::getInstance().ApplyPrivateSharing(ownerAppId, targetAppId, path, pathLabel);
+ sharingAdded++;
+ if (targetPathCount > 0) {
+ //Nothing to do, only counter needed incrementing
+ continue;
+ }
+ if (pathCount <= 0) {
+ SmackLabels::setupSharedPrivatePath(ownerPkgId, path);
+ }
+ if (isSlave) {
+ MasterReq::SmackApplyPrivateSharingRules(ownerPkgId,
+ pkgContents, targetAppId, path, ownerTargetCount, pathCount);
+ } else {
+ SmackRules::applyPrivateSharingRules(ownerPkgId, pkgContents, targetAppId,
+ pathLabel, (pathCount > 0), (ownerTargetCount > 0), zoneId);
+ }
+ }
+ trans.commit();
+ return SECURITY_MANAGER_API_SUCCESS;
+ } catch (const SmackException::Base &e) {
+ LogError("Error performing smack operation: " << e.GetMessage());
+ errorRet = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ } catch (const std::exception &e) {
+ LogError("Some exception thrown : " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ } catch (...) {
+ LogError("Unknown exception thrown");
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ }
+ for (int i = 0; i < sharingAdded; i++) {
+ const std::string &path = paths[i];
+ dropOnePrivateSharing(ownerAppId, ownerPkgId, pkgContents, targetAppId, path, zoneId, isSlave);
+ }
+ return errorRet;
}
int ServiceImpl::dropPrivatePathSharing(const std::string &ownerAppId,
const std::vector<std::string> &paths,
bool isSlave)
{
- (void)ownerAppId;
- (void)targetAppId;
- (void)paths;
- (void)isSlave;
+ int errorRet;
+ try {
+ std::string zoneId;
+ if (isSlave) {
+ if (!getZoneId(zoneId)) {
+ LogError("Failed to get Zone ID.");
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }
+ }
+ std::string ownerPkgId, targetPkgId;
+ if (!PrivilegeDb::getInstance().GetAppPkgId(ownerAppId, ownerPkgId)) {
+ LogError(ownerAppId << " is not an installed application");
+ return SECURITY_MANAGER_API_ERROR_APP_UNKNOWN;
+ }
+ if (!PrivilegeDb::getInstance().GetAppPkgId(targetAppId, targetPkgId)) {
+ LogError(targetAppId << " is not an installed application");
+ return SECURITY_MANAGER_API_ERROR_APP_UNKNOWN;
+ }
- return SECURITY_MANAGER_API_SUCCESS;
+ for(const auto &path : paths) {
+ std::string pathLabel = SmackLabels::getSmackLabelFromPath(path);
+ if (pathLabel != zoneSmackLabelGenerate(SmackLabels::generatePkgLabel(ownerPkgId), zoneId)) {
+ std::string generatedPathLabel = zoneSmackLabelGenerate(SmackLabels::generateSharedPrivateLabel(ownerPkgId, path), zoneId);
+ if (generatedPathLabel != pathLabel) {
+ LogError("Path " << path << " has label " << pathLabel << " and dosen't belong"
+ " to application " << ownerAppId);
+ return SECURITY_MANAGER_API_ERROR_APP_NOT_PATH_OWNER;
+ }
+ }
+ }
+ if (ownerAppId == targetAppId) {
+ LogDebug("Owner application is the same as target application");
+ return SECURITY_MANAGER_API_SUCCESS;
+ }
+
+ if (ownerPkgId == targetPkgId) {
+ LogDebug("Owner and target belong to the same package");
+ return SECURITY_MANAGER_API_SUCCESS;
+ }
+
+ std::vector<std::string> pkgContents;
+ PrivilegeDb::getInstance().GetAppIdsForPkgId(ownerPkgId, pkgContents);
+ ScopedTransaction trans;
+ for (const auto &path : paths) {
+ int ret = dropOnePrivateSharing(ownerAppId, ownerPkgId, pkgContents, targetAppId, path, zoneId, isSlave);
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ return ret;
+ }
+ }
+ trans.commit();
+ return SECURITY_MANAGER_API_SUCCESS;
+ } catch (const SmackException::Base &e) {
+ LogError("Error performing smack operation: " << e.GetMessage());
+ errorRet = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ } catch (const std::exception &e) {
+ LogError("Some exception thrown : " << e.what());
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ } catch (...) {
+ LogError("Unknown exception thrown");
+ errorRet = SECURITY_MANAGER_API_ERROR_UNKNOWN;
+ }
+ return errorRet;
}
+
} /* namespace SecurityManager */