Implement logic of apply/drop sharing in ServiceImpl 38/58338/15
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 29 Jan 2016 10:06:31 +0000 (11:06 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Mon, 1 Feb 2016 21:00:49 +0000 (22:00 +0100)
Change-Id: I23ca6948cb523c336857f80ec0530f6cfebd25bc

src/client/client-security-manager.cpp
src/common/include/privilege_db.h
src/common/include/protocols.h
src/common/include/service_impl.h
src/common/service_impl.cpp
src/include/security-manager.h

index 56130cd..1341cab 100644 (file)
@@ -1373,6 +1373,10 @@ int security_manager_private_sharing_apply(const private_sharing_req *p_req)
                return SECURITY_MANAGER_ERROR_MEMORY;
            case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+           case SECURITY_MANAGER_API_ERROR_APP_UNKNOWN:
+               return SECURITY_MANAGER_ERROR_APP_UNKNOWN;
+           case SECURITY_MANAGER_API_ERROR_APP_NOT_PATH_OWNER:
+               return SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER;
            default:
                return SECURITY_MANAGER_ERROR_UNKNOWN;
        }
@@ -1411,6 +1415,10 @@ int security_manager_private_sharing_drop(const private_sharing_req *p_req)
                return SECURITY_MANAGER_ERROR_MEMORY;
            case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+           case SECURITY_MANAGER_API_ERROR_APP_UNKNOWN:
+               return SECURITY_MANAGER_ERROR_APP_UNKNOWN;
+           case SECURITY_MANAGER_API_ERROR_APP_NOT_PATH_OWNER:
+               return SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER;
            default:
                return SECURITY_MANAGER_ERROR_UNKNOWN;
        }
index a262abc..5a2a813 100644 (file)
@@ -163,6 +163,16 @@ private:
     StatementWrapper getStatement(StmtType queryType);
 
     /**
+     * Check if appId is registered in database
+     *
+     * @param appId - package identifier
+     * @exception DB::SqlConnection::Exception::InternalError on internal error
+     * @return true if appId exists in the database
+     *
+     */
+    bool AppIdExists(const std::string &appId);
+
+    /**
      * Check if pkgId is already registered in database
      *
      * @param pkgId - package identifier
@@ -207,16 +217,6 @@ public:
     void RollbackTransaction(void);
 
     /**
-     * Check if appId is registered in database
-     *
-     * @param appId - package identifier
-     * @exception DB::SqlConnection::Exception::InternalError on internal error
-     * @return true if appId exists in the database
-     *
-     */
-    bool AppIdExists(const std::string &appId);
-
-    /**
      * Return package id associated with a given application id
      *
      * @param appId - application identifier
index 828eb89..a464318 100644 (file)
 /*! \brief   indicating file deletion error  */
 #define SECURITY_MANAGER_API_ERROR_FILE_DELETION_FAILED -28
 
+/*! \brief   indicating that application is not present in the database */
+#define SECURITY_MANAGER_API_ERROR_APP_UNKNOWN -29
+
+/*! \brief   indicating that application is not owner of path */
+#define SECURITY_MANAGER_API_ERROR_APP_NOT_PATH_OWNER -30
+
 /*! \brief   indicating the error with unknown reason */
 #define SECURITY_MANAGER_API_ERROR_UNKNOWN -255
 /** @}*/
index d18e4e6..b3293c1 100644 (file)
@@ -47,6 +47,10 @@ private:
 
     static bool getZoneId(std::string &zoneId);
 
+    int 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);
+
 public:
     ServiceImpl();
     virtual ~ServiceImpl();
index 321765c..e582a8d 100644 (file)
@@ -141,6 +141,33 @@ bool isTizen2XVersion(const std::string &version)
     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()
@@ -1093,17 +1120,141 @@ int ServiceImpl::appHasPrivilege(std::string appId, std::string privilege,
     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,
@@ -1111,12 +1262,72 @@ 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 */
index 65175e0..64302a2 100644 (file)
@@ -43,6 +43,8 @@ enum lib_retcode {
     SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED,
     SECURITY_MANAGER_ERROR_ACCESS_DENIED,
     SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT,
+    SECURITY_MANAGER_ERROR_APP_UNKNOWN,
+    SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER
 };
 
 /*! \brief accesses types for application installation paths*/