Limit number of sql queries during installation 29/90529/4
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 30 Sep 2016 09:56:53 +0000 (11:56 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 7 Oct 2016 09:42:02 +0000 (11:42 +0200)
Change-Id: Iaad44912ae806544822d26f66add6ce8f0908d0b

src/common/include/pkg-info.h [new file with mode: 0644]
src/common/include/privilege_db.h
src/common/include/service_impl.h
src/common/include/smack-rules.h
src/common/privilege_db.cpp
src/common/service_impl.cpp
src/common/smack-rules.cpp

diff --git a/src/common/include/pkg-info.h b/src/common/include/pkg-info.h
new file mode 100644 (file)
index 0000000..764762e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       pkg-info.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+#ifndef _PKG_INFO_H_
+#define _PKG_INFO_H_
+
+#include <string>
+
+namespace SecurityManager {
+
+struct PkgInfo {
+    std::string name;
+    bool sharedRO;
+    bool hybrid;
+};
+
+} // SecurityManager
+
+#endif /* _PKG_INFO_H_ */
index 9d1a6db57f3c8285192eae2f9b6ca1b4d68f3356..78620a1c2663f1522710134939bb8b33b74d35d8 100644 (file)
 #include <map>
 #include <stdbool.h>
 #include <string>
+#include <vector>
 
 #include "dpl/db/sql_connection.h"
 #include "tzplatform-config.h"
 
+#include "pkg-info.h"
+
 #ifndef PRIVILEGE_DB_H_
 #define PRIVILEGE_DB_H_
 
@@ -72,10 +75,10 @@ enum class StmtType {
     EGetPkgAuthorId,
     EAuthorIdExists,
     EGetAuthorIdByName,
-    EGetSharedROPackages,
     ESetPackageSharedRO,
     EIsPackageSharedRO,
     EIsPackageHybrid,
+    EGetPackagesInfo,
 };
 
 class PrivilegeDb {
@@ -131,10 +134,10 @@ private:
         { 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=?"},
         { StmtType::EIsPackageHybrid, "SELECT is_hybrid FROM pkg WHERE name=?"},
+        { StmtType::EGetPackagesInfo, "SELECT name, shared_ro, is_hybrid FROM pkg"},
     };
 
     /**
@@ -475,17 +478,6 @@ public:
      */
     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
      *
@@ -509,6 +501,18 @@ public:
      * @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
      */
     bool IsPackageHybrid(const std::string& pkgName);
+
+    /**
+     * Retrieve list of packages with information about shared RO presence and package type
+     *
+     * @param[out] packages - vector of PackageInfo objects 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 GetPackagesInfo(std::vector<PkgInfo> &packages);
 };
 
 } //namespace SecurityManager
index baa86c8f8da843907273cff475fb9e5bf512a17f..9ecadb6262d6c7a23d7a3f0ad5463c983054a639 100644 (file)
@@ -70,8 +70,6 @@ private:
                           app_install_type installationType,
                           const uid_t &uid);
 
-    static void getPkgsProcessLabels(SmackRules::PkgsLabels &pkgsLabels);
-
     static void getPkgLabels(const std::string &pkgName, SmackRules::Labels &pkgsLabels);
 
     static bool isSharedRO(const pkg_paths& paths);
index 7a2a16d9b537be13a14c25444d1429a7261f56e0..bb3cffd85c81216c11504dabc51f3751f589fc76 100644 (file)
@@ -28,6 +28,7 @@
 #include <vector>
 #include <string>
 #include <smack-exceptions.h>
+#include "pkg-info.h"
 
 struct smack_accesses;
 
@@ -83,9 +84,9 @@ public:
      * Each application gets read-only access to files shared by SharedRO packages.
      *
      * @param[in] pkgsLabels         vector of process labels per each existing package
-     * @param[in] sharedROPkgs       vector of packages having sharedRO directory
+     * @param[in] allPkgs            vector of PkgInfo objects of all existing packages
      */
-    static void generateSharedRORules(PkgsLabels &pkgsLabels, Pkgs &sharedROPkgs);
+    static void generateSharedRORules(PkgsLabels &pkgsLabels, std::vector<PkgInfo> &allPkgs);
 
     /**
      * Revoke SharedRO rules for applications when a package is being removed
index a11b3e3f25256242dec764fa06106d9f4733fe9c..199a99ee40c6c030d3a39115bce9330c787a29a1 100644 (file)
@@ -422,19 +422,6 @@ void PrivilegeDb::GetAllPackages(std::vector<std::string> &packages)
      });
 }
 
-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::GetPkgApps(const std::string &pkgName,
         std::vector<std::string> &appNames)
 {
@@ -570,4 +557,21 @@ bool PrivilegeDb::IsPackageHybrid(const std::string& pkgName)
     });
 }
 
+void PrivilegeDb::GetPackagesInfo(std::vector<PkgInfo> &packages)
+{
+    try_catch<void>([&] {
+        auto command = getStatement(StmtType::EGetPackagesInfo);
+        packages.clear();
+        while (command->Step()) {
+            PkgInfo info;
+            info.name = command->GetColumnString(0);
+            info.sharedRO = command->GetColumnInteger(1) > 0;
+            info.hybrid = command->GetColumnInteger(2) > 0;
+            LogDebug("Found package info " << info.name << " shared ro: " <<
+                     info.sharedRO << " hybrid: " << info.hybrid);
+            packages.push_back(info);
+        };
+     });
+}
+
 } //namespace SecurityManager
index 0d4c9404076e7b12fb11560b4c7272a5f1052026..93405bf26a238ec10a0e24772d9ab075c13313e6 100644 (file)
@@ -203,6 +203,20 @@ private:
     bool m_isCommited;
 };
 
+void getPkgsProcessLabels(const std::vector<PkgInfo> &pkgsInfo, SmackRules::PkgsLabels &pkgsLabels)
+{
+    pkgsLabels.resize(pkgsInfo.size());
+    for (size_t i = 0; i < pkgsInfo.size(); ++i) {
+        pkgsLabels[i].first = pkgsInfo[i].name;
+        PrivilegeDb::getInstance().GetPkgApps(pkgsLabels[i].first, pkgsLabels[i].second);
+        for (auto &appName : pkgsLabels[i].second) {
+            std::string label = SmackLabels::generateProcessLabel(appName, pkgsLabels[i].first,
+                                                                  pkgsInfo[i].hybrid);
+            appName = label;
+        }
+    }
+}
+
 } // end of anonymous namespace
 
 ServiceImpl::ServiceImpl()
@@ -428,24 +442,6 @@ int ServiceImpl::labelPaths(const pkg_paths &paths,
     }
 }
 
-void ServiceImpl::getPkgsProcessLabels(SmackRules::PkgsLabels &pkgsLabels)
-{
-    std::vector<std::string> pkgs;
-    PrivilegeDb::getInstance().GetAllPackages(pkgs);
-
-    pkgsLabels.resize(pkgs.size());
-    for (size_t i = 0; i < pkgs.size(); ++i) {
-        pkgsLabels[i].first = std::move(pkgs[i]);
-        bool isPkgHybrid = PrivilegeDb::getInstance().IsPackageHybrid(pkgsLabels[i].first);
-        PrivilegeDb::getInstance().GetPkgApps(pkgsLabels[i].first, pkgsLabels[i].second);
-        for (auto &appName : pkgsLabels[i].second) {
-            std::string label = SmackLabels::generateProcessLabel(appName, pkgsLabels[i].first,
-                                                                  isPkgHybrid);
-            appName = label;
-        }
-    }
-}
-
 bool ServiceImpl::isPrivilegePrivacy(const std::string &privilege)
 {
     if (Config::IS_ASKUSER_ENABLED) {
@@ -493,9 +489,9 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
     std::string pkgBasePath;
     std::string appLabel;
     std::string pkgLabel;
-    SmackRules::Pkgs sharedROPkgs;
     SmackRules::PkgsLabels pkgsProcessLabels;
     int authorId;
+    std::vector<PkgInfo> pkgsInfo;
     bool hasSharedRO = isSharedRO(req.pkgPaths);
 
     try {
@@ -527,8 +523,9 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
 
         if (hasSharedRO)
             PrivilegeDb::getInstance().SetSharedROPackage(req.pkgName);
-        PrivilegeDb::getInstance().GetSharedROPackages(sharedROPkgs);
-        getPkgsProcessLabels(pkgsProcessLabels);
+
+        PrivilegeDb::getInstance().GetPackagesInfo(pkgsInfo);
+        getPkgsProcessLabels(pkgsInfo, pkgsProcessLabels);
 
         // WTF? Why this commit is here? Shouldn't it be at the end of this function?
         PrivilegeDb::getInstance().CommitTransaction();
@@ -575,7 +572,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
         SmackRules::installApplicationRules(req.appName, appLabel, req.pkgName,
                                             authorId, pkgLabels);
 
-        SmackRules::generateSharedRORules(pkgsProcessLabels, sharedROPkgs);
+        SmackRules::generateSharedRORules(pkgsProcessLabels, pkgsInfo);
 
         SmackRules::mergeRules();
     } catch (const SmackException::InvalidParam &e) {
@@ -604,11 +601,11 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
     bool removeAuthor = false;
     std::string cynaraUserStr;
     SmackRules::PkgsLabels pkgsProcessLabels;
-    SmackRules::Pkgs sharedROPkgs;
     std::map<std::string, std::vector<std::string>> asOwnerSharing;
     std::map<std::string, std::vector<std::string>> asTargetSharing;
     int authorId;
     bool isPkgHybrid;
+    std::vector<PkgInfo> pkgsInfo;
 
     installRequestMangle(req, cynaraUserStr);
 
@@ -683,8 +680,8 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
 
         PrivilegeDb::getInstance().RemoveApplication(req.appName, req.uid, removeApp, removePkg, removeAuthor);
 
-        getPkgsProcessLabels(pkgsProcessLabels);
-        PrivilegeDb::getInstance().GetSharedROPackages(sharedROPkgs);
+        PrivilegeDb::getInstance().GetPackagesInfo(pkgsInfo);
+        getPkgsProcessLabels(pkgsInfo, pkgsProcessLabels);
 
         CynaraAdmin::getInstance().UpdateAppPolicy(processLabel, cynaraUserStr,
                                                    std::vector<std::string>(), isPrivilegePrivacy);
@@ -734,7 +731,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
                 SmackRules::updatePackageRules(req.pkgName, pkgLabels);
             }
 
-            SmackRules::generateSharedRORules(pkgsProcessLabels, sharedROPkgs);
+            SmackRules::generateSharedRORules(pkgsProcessLabels, pkgsInfo);
             if (removePkg)
                 SmackRules::revokeSharedRORules(pkgsProcessLabels, req.pkgName);
         }
@@ -1597,16 +1594,16 @@ int ServiceImpl::pathsRegister(const Credentials &creds, path_req req)
 
                 PrivilegeDb::getInstance().SetSharedROPackage(req.pkgName);
 
-                SmackRules::Pkgs sharedROPkgs;
                 SmackRules::PkgsLabels pkgsLabels;
 
-                PrivilegeDb::getInstance().GetSharedROPackages(sharedROPkgs);
-                getPkgsProcessLabels(pkgsLabels);
+                std::vector<PkgInfo> pkgsInfo;
+                PrivilegeDb::getInstance().GetPackagesInfo(pkgsInfo);
+                getPkgsProcessLabels(pkgsInfo, pkgsLabels);
 
-                SmackRules::generateSharedRORules(pkgsLabels, sharedROPkgs);
+                SmackRules::generateSharedRORules(pkgsLabels, pkgsInfo);
                 SmackRules::mergeRules();
             }
-        PrivilegeDb::getInstance().CommitTransaction();
+            PrivilegeDb::getInstance().CommitTransaction();
         }
     } catch (const PrivilegeDb::Exception::IOError &e) {
         LogError("Cannot access application database: " << e.DumpToString());
index bf3052cfc2f0a67ef232e43a3a61062fff0c13e0..797677c9db6bff6bca6c17ebfaffe7fc81a9fb96 100644 (file)
@@ -258,21 +258,22 @@ void SmackRules::generatePackageCrossDeps(const Labels &pkgLabels)
     }
 }
 
-void SmackRules::generateSharedRORules(PkgsLabels &pkgsLabels, Pkgs &sharedROPkgs)
+void SmackRules::generateSharedRORules(PkgsLabels &pkgsLabels, std::vector<PkgInfo> &allPkgs)
 {
     LogDebug("Generating SharedRO rules");
 
     SmackRules rules;
     for (size_t i = 0; i < pkgsLabels.size(); ++i) {
         for (const std::string &appLabel : pkgsLabels[i].second) {
-            for (size_t j = 0; j < sharedROPkgs.size(); ++j) {
+            for (size_t j = 0; j < allPkgs.size(); ++j) {
                 // Rules for SharedRO files from own package are generated elsewhere
-                if (pkgsLabels[i].first != sharedROPkgs[j]) {
-                    const std::string &pkgName = sharedROPkgs[j];
-                    rules.add(appLabel,
-                              SmackLabels::generatePathSharedROLabel(pkgName),
-                              SMACK_APP_CROSS_PKG_PERMS);
-                }
+                if (!allPkgs[j].sharedRO || pkgsLabels[i].first == allPkgs[j].name)
+                    continue;
+
+                const std::string &pkgName = allPkgs[j].name;
+                rules.add(appLabel,
+                          SmackLabels::generatePathSharedROLabel(pkgName),
+                          SMACK_APP_CROSS_PKG_PERMS);
             }
         }
     }