Convert Cynara, CynaraAdmin and PrivilegeDb classes into singletons 88/30588/2
authorRafal Krypa <r.krypa@samsung.com>
Thu, 20 Nov 2014 23:45:05 +0000 (00:45 +0100)
committerRafal Krypa <r.krypa@samsung.com>
Fri, 21 Nov 2014 10:34:08 +0000 (11:34 +0100)
These classes are now used by the Service class to perform operations
requested by clients. But they will be also needed by offline client
implementation. Having them as private members of the Service class is no
longer feasible.
To keep their usage simple and available to the client as well, they are
now used as singletons.

Change-Id: I900a368ea14fbe61179c712b6e891f213ca61c5e
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
src/common/cynara.cpp
src/common/include/cynara.h
src/common/include/privilege_db.h
src/common/privilege_db.cpp
src/server/service/include/service.h
src/server/service/service.cpp

index 9ca8efc..36e79b2 100644 (file)
@@ -134,6 +134,12 @@ CynaraAdmin::~CynaraAdmin()
     cynara_admin_finish(m_CynaraAdmin);
 }
 
+CynaraAdmin &CynaraAdmin::getInstance()
+{
+    static CynaraAdmin cynaraAdmin;
+    return cynaraAdmin;
+}
+
 void CynaraAdmin::SetPolicies(const std::vector<CynaraAdminPolicy> &policies)
 {
     std::vector<const struct cynara_admin_policy *> pp_policies(policies.size() + 1);
@@ -223,6 +229,12 @@ Cynara::~Cynara()
     cynara_finish(m_Cynara);
 }
 
+Cynara &Cynara::getInstance()
+{
+    static Cynara cynara;
+    return cynara;
+}
+
 bool Cynara::check(const std::string &label, const std::string &privilege,
         const std::string &user, const std::string &session)
 {
index c660a2e..ada3994 100644 (file)
@@ -70,9 +70,10 @@ struct CynaraAdminPolicy : cynara_admin_policy
 class CynaraAdmin
 {
 public:
-    CynaraAdmin();
     virtual ~CynaraAdmin();
 
+    static CynaraAdmin &getInstance();
+
     /**
      * Update Cynara policies.
      * Caller must have permission to access Cynara administrative socket.
@@ -104,15 +105,17 @@ public:
         const std::vector<std::string> &newPrivileges);
 
 private:
+    CynaraAdmin();
     struct cynara_admin *m_CynaraAdmin;
 };
 
 class Cynara
 {
 public:
-    Cynara();
     virtual ~Cynara();
 
+    static Cynara &getInstance();
+
     /**
      * Ask Cynara for permission.
      *
@@ -126,6 +129,7 @@ public:
         const std::string &user, const std::string &session);
 
 private:
+    Cynara();
     struct cynara *m_Cynara;
 };
 
index b56f834..34a4ed1 100644 (file)
@@ -60,6 +60,13 @@ class PrivilegeDb {
      */
 
 private:
+    /**
+     * Constructor
+     * @exception DB::SqlConnection::Exception::IOError on problems with database access
+     *
+     */
+    PrivilegeDb(const std::string &path = std::string(PRIVILEGE_DB_PATH));
+
     SecurityManager::DB::SqlConnection *mSqlConnection;
     const std::map<QueryType, const char * const > Queries = {
         { QueryType::EGetPkgPrivileges, "SELECT DISTINCT privilege_name FROM app_privilege_view WHERE pkg_name=? AND uid=? ORDER BY privilege_name"},
@@ -91,15 +98,10 @@ public:
         DECLARE_EXCEPTION_TYPE(Base, InternalError)
     };
 
-    /**
-     * Constructor
-     * @exception DB::SqlConnection::Exception::IOError on problems with database access
-     *
-     */
-    PrivilegeDb(const std::string &path = std::string(PRIVILEGE_DB_PATH));
-
     ~PrivilegeDb(void);
 
+    static PrivilegeDb &getInstance();
+
     /**
      * Begin transaction
      * @exception DB::SqlConnection::Exception::InternalError on internal error
index 6c8d1f3..e1c4b14 100644 (file)
@@ -73,6 +73,12 @@ PrivilegeDb::~PrivilegeDb()
     delete mSqlConnection;
 }
 
+PrivilegeDb &PrivilegeDb::getInstance()
+{
+    static PrivilegeDb privilegeDb;
+    return privilegeDb;
+}
+
 void PrivilegeDb::BeginTransaction(void)
 {
     try_catch<void>([&] {
index 328043b..21bc19c 100644 (file)
@@ -61,8 +61,6 @@ public:
 
 private:
     ConnectionInfoMap m_connectionInfoMap;
-    PrivilegeDb m_privilegeDb;
-    Cynara m_cynara;
 
     /**
      * Handle request from a client
index 32623c0..d4b27ca 100644 (file)
@@ -311,25 +311,28 @@ bool Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_
         LogDebug("Install parameters: appId: " << req.appId << ", pkgId: " << req.pkgId
                  << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
 
-        m_privilegeDb.BeginTransaction();
-        m_privilegeDb.GetPkgPrivileges(req.pkgId, uid, oldPkgPrivileges);
-        m_privilegeDb.AddApplication(req.appId, req.pkgId, uid, pkgIdIsNew);
-        m_privilegeDb.UpdateAppPrivileges(req.appId, uid, req.privileges);
-        m_privilegeDb.GetPkgPrivileges(req.pkgId, uid, newPkgPrivileges);
+        PrivilegeDb::getInstance().BeginTransaction();
+        PrivilegeDb::getInstance().GetPkgPrivileges(req.pkgId, uid, oldPkgPrivileges);
+        PrivilegeDb::getInstance().AddApplication(req.appId, req.pkgId, uid, pkgIdIsNew);
+        PrivilegeDb::getInstance().UpdateAppPrivileges(req.appId, uid, req.privileges);
+        PrivilegeDb::getInstance().GetPkgPrivileges(req.pkgId, uid, newPkgPrivileges);
         CynaraAdmin::UpdatePackagePolicy(smackLabel, uidstr, oldPkgPrivileges,
                                          newPkgPrivileges);
-        m_privilegeDb.CommitTransaction();
+        PrivilegeDb::getInstance().CommitTransaction();
         LogDebug("Application installation commited to database");
+    } catch (const PrivilegeDb::Exception::IOError &e) {
+        LogError("Cannot access application database: " << e.DumpToString());
+        goto error_label;
     } catch (const PrivilegeDb::Exception::InternalError &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Error while saving application info to database: " << e.DumpToString());
         goto error_label;
     } catch (const CynaraException::Base &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Error while setting Cynara rules for application: " << e.DumpToString());
         goto error_label;
     } catch (const std::bad_alloc &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Memory allocation while setting Cynara rules for application: " << e.what());
         goto error_label;
     }
@@ -379,11 +382,11 @@ bool Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, ui
     try {
         std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
 
-        m_privilegeDb.BeginTransaction();
-        if (!m_privilegeDb.GetAppPkgId(appId, pkgId)) {
+        PrivilegeDb::getInstance().BeginTransaction();
+        if (!PrivilegeDb::getInstance().GetAppPkgId(appId, pkgId)) {
             LogWarning("Application " << appId <<
                 " not found in database while uninstalling");
-            m_privilegeDb.RollbackTransaction();
+            PrivilegeDb::getInstance().RollbackTransaction();
             appExists = false;
         } else {
 
@@ -395,25 +398,28 @@ bool Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, ui
                 goto error_label;
             }
 
-            m_privilegeDb.GetPkgPrivileges(pkgId, uid, oldPkgPrivileges);
-            m_privilegeDb.UpdateAppPrivileges(appId, uid, std::vector<std::string>());
-            m_privilegeDb.RemoveApplication(appId, uid, removePkg);
-            m_privilegeDb.GetPkgPrivileges(pkgId, uid, newPkgPrivileges);
+            PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, uid, oldPkgPrivileges);
+            PrivilegeDb::getInstance().UpdateAppPrivileges(appId, uid, std::vector<std::string>());
+            PrivilegeDb::getInstance().RemoveApplication(appId, uid, removePkg);
+            PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, uid, newPkgPrivileges);
             CynaraAdmin::UpdatePackagePolicy(smackLabel, uidstr, oldPkgPrivileges,
                                              newPkgPrivileges);
-            m_privilegeDb.CommitTransaction();
+            PrivilegeDb::getInstance().CommitTransaction();
             LogDebug("Application uninstallation commited to database");
         }
+    } catch (const PrivilegeDb::Exception::IOError &e) {
+        LogError("Cannot access application database: " << e.DumpToString());
+        goto error_label;
     } catch (const PrivilegeDb::Exception::InternalError &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Error while removing application info from database: " << e.DumpToString());
         goto error_label;
     } catch (const CynaraException::Base &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Error while setting Cynara rules for application: " << e.DumpToString());
         goto error_label;
     } catch (const std::bad_alloc &e) {
-        m_privilegeDb.RollbackTransaction();
+        PrivilegeDb::getInstance().RollbackTransaction();
         LogError("Memory allocation while setting Cynara rules for application: " << e.what());
         goto error_label;
     }
@@ -448,14 +454,14 @@ bool Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
     LogDebug("appId: " << appId);
 
     try {
-        if (!m_privilegeDb.GetAppPkgId(appId, pkgId)) {
+        if (!PrivilegeDb::getInstance().GetAppPkgId(appId, pkgId)) {
             LogWarning("Application " << appId << " not found in database");
             Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT);
             return false;
         } else {
             LogDebug("pkgId: " << pkgId);
         }
-    } catch (const PrivilegeDb::Exception::InternalError &e) {
+    } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while getting pkgId from database: " << e.DumpToString());
         Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SERVER_ERROR);
         return false;
@@ -481,7 +487,7 @@ bool Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, ui
         Deserialization::Deserialize(buffer, appId);
         LogDebug("appId: " << appId);
 
-        if (!m_privilegeDb.GetAppPkgId(appId, pkgId)) {
+        if (!PrivilegeDb::getInstance().GetAppPkgId(appId, pkgId)) {
             LogWarning("Application " << appId << " not found in database");
             Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT);
             return false;
@@ -496,21 +502,21 @@ bool Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, ui
         LogDebug("smack label: " << smackLabel);
 
         std::vector<std::string> privileges;
-        m_privilegeDb.GetPkgPrivileges(pkgId, uid, privileges);
+        PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, uid, privileges);
         /*there is also a need of checking, if privilege is granted to all users*/
         size_t tmp = privileges.size();
-        m_privilegeDb.GetPkgPrivileges(pkgId, getGlobalUserId(), privileges);
+        PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, getGlobalUserId(), privileges);
         /*privileges needs to be sorted and with no duplications - for cynara sake*/
         std::inplace_merge(privileges.begin(), privileges.begin() + tmp, privileges.end());
         privileges.erase( unique( privileges.begin(), privileges.end() ), privileges.end() );
 
         for (const auto &privilege : privileges) {
             std::vector<std::string> gidsTmp;
-            m_privilegeDb.GetPrivilegeGroups(privilege, gidsTmp);
+            PrivilegeDb::getInstance().GetPrivilegeGroups(privilege, gidsTmp);
             if (!gidsTmp.empty()) {
                 LogDebug("Considering privilege " << privilege << " with " <<
                     gidsTmp.size() << " groups assigned");
-                if (m_cynara.check(smackLabel, privilege, uidStr, pidStr)) {
+                if (Cynara::getInstance().check(smackLabel, privilege, uidStr, pidStr)) {
                     for_each(gidsTmp.begin(), gidsTmp.end(), [&] (std::string group)
                     {
                         struct group *grp = getgrnam(group.c_str());
@@ -525,7 +531,7 @@ bool Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, ui
                     LogDebug("Cynara denied, not adding groups");
             }
         }
-    } catch (const PrivilegeDb::Exception::InternalError &e) {
+    } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Database error: " << e.DumpToString());
         Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SERVER_ERROR);
         return false;