Fix issue with mutiple install the same app for different users 37/53837/3
authorJanusz Kozerski <j.kozerski@samsung.com>
Wed, 9 Dec 2015 15:29:43 +0000 (16:29 +0100)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 14 Jan 2016 16:59:18 +0000 (08:59 -0800)
If the same application has been installed for more than one user,
then while uninstallation Smack rule file should remain in the system
until the last "instance" of application is present.

Change-Id: Ice8b1b7afe036028efcabf5a77732db0811763c4

src/common/include/master-req.h
src/common/include/privilege_db.h
src/common/master-req.cpp
src/common/privilege_db.cpp
src/common/service_impl.cpp
src/server/service/master-service.cpp

index 15b1fdc..992d98f 100644 (file)
@@ -86,13 +86,16 @@ int SmackInstallRules(const std::string &appId, const std::string &pkgId,
  * @param[in]  appId       ID of application being removed
  * @param[in]  pkgId       ID of package being removed
  * @param[in]  pkgContents A list of all applications in the package
+ * @param[in]  removeApp   Flag stating if the application is no longer installed
+ *                         for any user and should be removed
  * @param[in]  removePkg   Flag stating if entire package should be removed
  * @return API return code, as defined in protocols.h
  *
  * @see SmackRules::uninstallPackageRules, SmackRules::uninstallApplicationRules
  */
 int SmackUninstallRules(const std::string &appId, const std::string &pkgId,
-                        const std::vector<std::string> &pkgContents, const bool removePkg);
+                        const std::vector<std::string> &pkgContents,
+                        const bool removeApp, const bool removePkg);
 
 /**
  * Forwards policyUpdate API to Master. Arguments are the same as policyUpdate.
index 27f68d6..1e7f76b 100644 (file)
@@ -53,6 +53,7 @@ enum class StmtType {
     EAddAppPrivileges,
     ERemoveAppPrivileges,
     EPkgIdExists,
+    EAppIdExists,
     EGetPkgId,
     EGetPrivilegeGroups,
     EGetUserApps,
@@ -99,6 +100,7 @@ private:
         { StmtType::EAddAppPrivileges, "INSERT INTO app_privilege_view (app_name, uid, privilege_name) VALUES (?, ?, ?)" },
         { StmtType::ERemoveAppPrivileges, "DELETE FROM app_privilege_view WHERE app_name=? AND uid=?" },
         { StmtType::EPkgIdExists, "SELECT * FROM pkg WHERE name=?" },
+        { StmtType::EAppIdExists, "SELECT * FROM app WHERE name=?" },
         { StmtType::EGetPkgId, " SELECT pkg_name FROM app_pkg_view WHERE app_name = ?" },
         { StmtType::EGetPrivilegeGroups, " SELECT group_name FROM privilege_group_view WHERE privilege_name = ?" },
         { StmtType::EGetUserApps, "SELECT name FROM app WHERE uid=?" },
@@ -148,6 +150,16 @@ private:
      */
     bool PkgIdExists(const std::string &pkgId);
 
+    /**
+     * 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);
+
 public:
     class Exception
     {
@@ -230,10 +242,12 @@ public:
      *
      * @param appId - application identifier
      * @param uid - user identifier whose application is going to be uninstalled
+     * @param[out] appIdIsNoMore - return info if appId is in the database
      * @param[out] pkgIdIsNoMore - return info if pkgId is in the database
      * @exception DB::SqlConnection::Exception::InternalError on internal error
      */
-    void RemoveApplication(const std::string &appId, uid_t uid, bool &pkgIdIsNoMore);
+    void RemoveApplication(const std::string &appId, uid_t uid,
+        bool &appIdIsNoMore, bool &pkgIdIsNoMore);
 
     /**
      * Remove privileges assigned to application
index b2c2783..a097341 100644 (file)
@@ -98,14 +98,15 @@ int SmackInstallRules(const std::string &appId, const std::string &pkgId,
 }
 
 int SmackUninstallRules(const std::string &appId, const std::string &pkgId,
-                        const std::vector<std::string> &pkgContents, const bool removePkg)
+                        const std::vector<std::string> &pkgContents,
+                        const bool removeApp, const bool removePkg)
 {
     int ret;
     MessageBuffer sendBuf, retBuf;
 
     Serialization::Serialize(sendBuf,
         static_cast<int>(MasterSecurityModuleCall::SMACK_UNINSTALL_RULES),
-        appId, pkgId, pkgContents, removePkg);
+        appId, pkgId, pkgContents, removeApp, removePkg);
 
     ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
     if (ret == SECURITY_MANAGER_API_SUCCESS)
index 9997128..50dba69 100644 (file)
@@ -136,6 +136,15 @@ bool PrivilegeDb::PkgIdExists(const std::string &pkgId)
     });
 }
 
+bool PrivilegeDb::AppIdExists(const std::string &appId)
+{
+    return try_catch<bool>([&] {
+        auto command = getStatement(StmtType::EAppIdExists);
+        command->BindString(1, appId);
+        return command->Step();
+    });
+}
+
 bool PrivilegeDb::GetAppPkgId(const std::string &appId, std::string &pkgId)
 {
     return try_catch<bool>([&] {
@@ -173,7 +182,7 @@ void PrivilegeDb::AddApplication(const std::string &appId,
 }
 
 void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
-        bool &pkgIdIsNoMore)
+        bool &appIdIsNoMore, bool &pkgIdIsNoMore)
 {
     try_catch<void>([&] {
         std::string pkgId;
@@ -193,6 +202,7 @@ void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
 
         LogDebug("Removed appId: " << appId);
 
+        appIdIsNoMore = !(this->AppIdExists(appId));
         pkgIdIsNoMore = !(this->PkgIdExists(pkgId));
     });
 }
index 82719f1..2b7aa8f 100644 (file)
@@ -391,6 +391,7 @@ int ServiceImpl::appUninstall(const std::string &appId, uid_t uid, bool isSlave)
     std::string smackLabel;
     std::vector<std::string> pkgContents;
     bool appExists = true;
+    bool removeApp = false;
     bool removePkg = false;
     std::string uidstr;
     checkGlobalUser(uid, uidstr);
@@ -420,7 +421,7 @@ int ServiceImpl::appUninstall(const std::string &appId, uid_t uid, bool isSlave)
                 package that the app appears in */
             PrivilegeDb::getInstance().GetAppIdsForPkgId(pkgId, pkgContents);
             PrivilegeDb::getInstance().UpdateAppPrivileges(appId, uid, std::vector<std::string>());
-            PrivilegeDb::getInstance().RemoveApplication(appId, uid, removePkg);
+            PrivilegeDb::getInstance().RemoveApplication(appId, uid, removeApp, removePkg);
 
             if (isSlave) {
                 int ret = MasterReq::CynaraPolicyUpdate(appId, uidstr, std::vector<std::string>());
@@ -462,7 +463,7 @@ int ServiceImpl::appUninstall(const std::string &appId, uid_t uid, bool isSlave)
             if (isSlave) {
                 LogDebug("Delegating Smack rules removal for deleted pkgId " << pkgId <<
                          " to master");
-                int ret = MasterReq::SmackUninstallRules(appId, pkgId, pkgContents, removePkg);
+                int ret = MasterReq::SmackUninstallRules(appId, pkgId, pkgContents, removeApp, removePkg);
                 if (ret != SECURITY_MANAGER_API_SUCCESS) {
                     LogError("Error while processing uninstall request on master: " << ret);
                     return ret;
@@ -472,9 +473,10 @@ int ServiceImpl::appUninstall(const std::string &appId, uid_t uid, bool isSlave)
                     LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
                     SmackRules::uninstallPackageRules(pkgId);
                 }
-
-                LogDebug ("Removing smack rules for deleted appId " << appId);
-                SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
+                if (removeApp) {
+                    LogDebug("Removing smack rules for deleted appId " << appId);
+                    SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
+                }
             }
         } catch (const SmackException::Base &e) {
             LogError("Error while removing Smack rules for application: " << e.DumpToString());
index 770820e..7e84201 100644 (file)
@@ -359,55 +359,56 @@ out:
 void MasterService::processSmackUninstallRules(MessageBuffer &buffer, MessageBuffer &send,
                                                const std::string &zoneId)
 {
-    int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
     std::string appId, pkgId;
     std::vector<std::string> pkgContents;
+    bool removeApp = false;
     bool removePkg = false;
 
     Deserialization::Deserialize(buffer, appId);
     Deserialization::Deserialize(buffer, pkgId);
     Deserialization::Deserialize(buffer, pkgContents);
+    Deserialization::Deserialize(buffer, removeApp);
     Deserialization::Deserialize(buffer, removePkg);
 
     try {
+        if (removeApp) {
+            LogDebug("Removing smack rules for deleted appId " << appId);
+            SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
+
+            std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
+            std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
+            // FIXME zoneSmackLabelUnmap should throw exception on error, not return false
+            // FIXME implement zoneSmackLabelUnmap and check if works when Smack Namespaces are implemented
+            if (!zoneSmackLabelUnmap(hostAppLabel, zoneId)) {
+                LogError("Failed to unmap Smack labels for application " << appId);
+                Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SERVER_ERROR);
+                return;
+            }
+        }
+
         if (removePkg) {
             LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
             SmackRules::uninstallPackageRules(pkgId);
-        }
-
-        LogDebug ("Removing smack rules for deleted appId " << appId);
-        SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
-
-        // FIXME implement zoneSmackLabelUnmap and check if works when Smack Namespaces are implemented
-        std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
-        std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
-        std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
-        std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
 
-        if (!zoneSmackLabelUnmap(hostAppLabel, zoneId)) {
-            LogError("Failed to unmap Smack labels for application " << appId);
-            goto out;
-        }
-
-        if (removePkg) {
+            std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
+            std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
             if (!zoneSmackLabelUnmap(hostPkgLabel, zoneId)) {
                 LogError("Failed to unmap Smack label for package " << pkgId);
-                goto out;
+                Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SERVER_ERROR);
+                return;
             }
         }
     } catch (const SmackException::Base &e) {
         LogError("Error while removing Smack rules for application: " << e.DumpToString());
-        ret = SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
-        goto out;
+        Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED);
+        return;
     } catch (const std::bad_alloc &e) {
         LogError("Memory allocation error: " << e.what());
-        ret =  SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
-        goto out;
+        Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY);
+        return;
     }
 
-    ret = SECURITY_MANAGER_API_SUCCESS;
-out:
-    Serialization::Serialize(send, ret);
+    Serialization::Serialize(send, SECURITY_MANAGER_API_SUCCESS);
 }
 
 } // namespace SecurityManager