Sanitize handling of global application user.
[platform/core/security/security-manager.git] / src / server / service / service.cpp
index 6539b7f..2c26d1b 100644 (file)
  * @brief       Implementation of security-manager service.
  */
 
-#include <dpl/log/log.h>
-#include <dpl/serialization.h>
-
-#include <unordered_set>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <pwd.h>
+#include <grp.h>
 #include <limits.h>
+#include <pwd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
 #include <cstring>
+#include <unordered_set>
 
-#include "service.h"
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <tzplatform_config.h>
+
+#include "privilege_db.h"
 #include "protocols.h"
 #include "security-manager.h"
+#include "service.h"
 #include "smack-common.h"
 #include "smack-rules.h"
 #include "smack-labels.h"
-#include "privilege_db.h"
 
 namespace SecurityManager {
 
 const InterfaceID IFACE = 1;
 
 
+
+static uid_t getGlobalUserId(void) {
+    static uid_t globaluid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+    return globaluid;
+}
+
+/**
+ * Unifies user data of apps installed for all users
+ * @param  uid            peer's uid - may be changed during process
+ * @param  cynaraUserStr  string to which cynara user parameter will be put
+ */
+static void checkGlobalUser(uid_t &uid, std::string &cynaraUserStr)
+{
+    static uid_t globaluid = getGlobalUserId();
+    if (uid == 0 || uid == globaluid) {
+        uid = globaluid;
+        cynaraUserStr = CYNARA_ADMIN_WILDCARD;
+    } else {
+        cynaraUserStr = std::to_string(static_cast<unsigned int>(uid));
+    }
+}
+
 Service::Service()
 {
 }
@@ -193,9 +218,6 @@ static inline bool isSubDir(const char *parent, const char *subdir)
 
 static inline bool installRequestAuthCheck(const app_inst_req &req, uid_t uid)
 {
-    if (uid == 0)
-        return true;
-
     struct passwd *pwd;
     do {
         errno = 0;
@@ -251,6 +273,8 @@ bool Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_
     Deserialization::Deserialize(buffer, req.pkgId);
     Deserialization::Deserialize(buffer, req.privileges);
     Deserialization::Deserialize(buffer, req.appPaths);
+    std::string uidstr;
+    checkGlobalUser(uid, uidstr);
 
     if(!installRequestAuthCheck(req, uid)) {
         LogError("Request from uid " << uid << " for app installation denied");
@@ -278,8 +302,6 @@ bool Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_
 
     try {
         std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
-        std::string uidstr = uid ? std::to_string(static_cast<unsigned int>(uid))
-                             : CYNARA_ADMIN_WILDCARD;
 
         LogDebug("Install parameters: appId: " << req.appId << ", pkgId: " << req.pkgId
                  << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
@@ -346,6 +368,8 @@ bool Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, ui
     bool removePkg = false;
 
     Deserialization::Deserialize(buffer, appId);
+    std::string uidstr;
+    checkGlobalUser(uid, uidstr);
 
     try {
         std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
@@ -357,17 +381,15 @@ bool Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, ui
             m_privilegeDb.RollbackTransaction();
             appExists = false;
         } else {
+
+            LogDebug("Uninstall parameters: appId: " << appId << ", pkgId: " << pkgId
+                     << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
+
             if (!generateAppLabel(pkgId, smackLabel)) {
                 LogError("Cannot generate Smack label for package: " << pkgId);
                 goto error_label;
             }
 
-            std::string uidstr = uid ? std::to_string(static_cast<unsigned int>(uid))
-                                 : CYNARA_ADMIN_WILDCARD;
-
-            LogDebug("Uninstall parameters: appId: " << appId << ", pkgId: " << pkgId
-                     << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
-
             m_privilegeDb.GetPkgPrivileges(pkgId, uid, oldPkgPrivileges);
             m_privilegeDb.UpdateAppPrivileges(appId, uid, std::vector<std::string>());
             m_privilegeDb.RemoveApplication(appId, uid, removePkg);
@@ -471,13 +493,21 @@ bool Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, ui
         std::vector<std::string> privileges;
         m_privilegeDb.GetPkgPrivileges(pkgId, uid, privileges);
         for (const auto &privilege : privileges) {
-            std::vector<gid_t> gidsTmp;
-            m_privilegeDb.GetPrivilegeGids(privilege, gidsTmp);
+            std::vector<std::string> gidsTmp;
+            m_privilegeDb.GetPrivilegeGroups(privilege, gidsTmp);
             if (!gidsTmp.empty()) {
                 LogDebug("Considering privilege " << privilege << " with " <<
                     gidsTmp.size() << " groups assigned");
                 if (m_cynara.check(smackLabel, privilege, uidStr, pidStr)) {
-                    gids.insert(gidsTmp.begin(), gidsTmp.end());
+                    for_each(gidsTmp.begin(), gidsTmp.end(), [&] (std::string group)
+                    {
+                        struct group *grp = getgrnam(group.c_str());
+                        if (grp == NULL) {
+                                LogError("No such group: " << group.c_str());
+                                return;
+                        }
+                        gids.insert(grp->gr_gid);
+                    });
                     LogDebug("Cynara allowed, adding groups");
                 } else
                     LogDebug("Cynara denied, not adding groups");