Implement service side of privileges mapping
[platform/core/security/security-manager.git] / src / server / service / service.cpp
index ca0bf52..45cdcf3 100644 (file)
 
 #include <dpl/log/log.h>
 #include <dpl/serialization.h>
+#include <sys/smack.h>
 
+#include "connection.h"
 #include "protocols.h"
 #include "service.h"
 #include "service_impl.h"
+#include "master-req.h"
 
 namespace SecurityManager {
 
 const InterfaceID IFACE = 1;
 
-Service::Service()
+Service::Service(const bool isSlave):
+        m_isSlave(isSlave)
 {
 }
 
 GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription()
 {
-    return ServiceDescriptionVector {
-        {SERVICE_SOCKET,  /* path */
-         "*",   /* smackLabel label (not used, we rely on systemd) */
-         IFACE, /* InterfaceID */
-         false, /* useSendMsg */
-         true}, /* systemdOnly */
-    };
+    if (m_isSlave)
+        return ServiceDescriptionVector {
+            {SLAVE_SERVICE_SOCKET,  /* path */
+             "*",   /* smackLabel label (not used, we rely on systemd) */
+             IFACE, /* InterfaceID */
+             false, /* useSendMsg */
+             true}, /* systemdOnly */
+        };
+    else
+        return ServiceDescriptionVector {
+            {SERVICE_SOCKET,  /* path */
+             "*",   /* smackLabel label (not used, we rely on systemd) */
+             IFACE, /* InterfaceID */
+             false, /* useSendMsg */
+             true}, /* systemdOnly */
+        };
 }
 
-static bool getPeerID(int sock, uid_t &uid, pid_t &pid) {
+static bool getPeerID(int sock, uid_t &uid, pid_t &pid, std::string &smackLabel)
+{
     struct ucred cr;
     socklen_t len = sizeof(cr);
 
     if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
+        char *smk;
+        ssize_t ret = smack_new_label_from_socket(sock, &smk);
+        if (ret < 0)
+            return false;
+        smackLabel = smk;
         uid = cr.uid;
         pid = cr.pid;
+        free(smk);
         return true;
     }
 
@@ -79,9 +99,10 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
 
     uid_t uid;
     pid_t pid;
+    std::string smackLabel;
 
-    if (!getPeerID(conn.sock, uid, pid)) {
-        LogError("Closing socket because of error: unable to get peer's uid and pid");
+    if (!getPeerID(conn.sock, uid, pid, smackLabel)) {
+        LogError("Closing socket because of error: unable to get peer's uid, pid or smack label");
         m_serviceManager->Close(conn);
         return false;
     }
@@ -118,6 +139,24 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
                 case SecurityModuleCall::USER_DELETE:
                     processUserDelete(buffer, send, uid);
                     break;
+                case SecurityModuleCall::POLICY_UPDATE:
+                    processPolicyUpdate(buffer, send, uid, pid, smackLabel);
+                    break;
+                case SecurityModuleCall::GET_CONF_POLICY_ADMIN:
+                    processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, true);
+                    break;
+                case SecurityModuleCall::GET_CONF_POLICY_SELF:
+                    processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, false);
+                    break;
+                case SecurityModuleCall::GET_POLICY:
+                    processGetPolicy(buffer, send, uid, pid, smackLabel);
+                    break;
+                case SecurityModuleCall::POLICY_GET_DESCRIPTIONS:
+                    processPolicyGetDesc(send);
+                    break;
+                case SecurityModuleCall::GET_PRIVILEGES_MAPPING:
+                    processPrivilegesMappings(buffer, send);
+                    break;
                 default:
                     LogError("Invalid call: " << call_type_int);
                     Throw(ServiceException::InvalidAction);
@@ -158,7 +197,7 @@ void Service::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_
     Deserialization::Deserialize(buffer, req.privileges);
     Deserialization::Deserialize(buffer, req.appPaths);
     Deserialization::Deserialize(buffer, req.uid);
-    Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
+    Serialization::Serialize(send, ServiceImpl::appInstall(req, uid, m_isSlave));
 }
 
 void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
@@ -166,7 +205,7 @@ void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, ui
     std::string appId;
 
     Deserialization::Deserialize(buffer, appId);
-    Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
+    Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid, m_isSlave));
 }
 
 void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
@@ -189,7 +228,7 @@ void Service::processGetAppGroups(MessageBuffer &buffer, MessageBuffer &send, ui
     int ret;
 
     Deserialization::Deserialize(buffer, appId);
-    ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
+    ret = ServiceImpl::getAppGroups(appId, uid, pid, m_isSlave, gids);
     Serialization::Serialize(send, ret);
     if (ret == SECURITY_MANAGER_API_SUCCESS) {
         Serialization::Serialize(send, static_cast<int>(gids.size()));
@@ -208,7 +247,7 @@ void Service::processUserAdd(MessageBuffer &buffer, MessageBuffer &send, uid_t u
     Deserialization::Deserialize(buffer, uidAdded);
     Deserialization::Deserialize(buffer, userType);
 
-    ret = ServiceImpl::userAdd(uidAdded, userType, uid);
+    ret = ServiceImpl::userAdd(uidAdded, userType, uid, m_isSlave);
     Serialization::Serialize(send, ret);
 }
 
@@ -219,9 +258,99 @@ void Service::processUserDelete(MessageBuffer &buffer, MessageBuffer &send, uid_
 
     Deserialization::Deserialize(buffer, uidRemoved);
 
-    ret = ServiceImpl::userDelete(uidRemoved, uid);
+    ret = ServiceImpl::userDelete(uidRemoved, uid, m_isSlave);
+    Serialization::Serialize(send, ret);
+}
+
+void Service::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
+{
+    int ret;
+    std::vector<policy_entry> policyEntries;
+
+    Deserialization::Deserialize(buffer, policyEntries);
+
+    if (m_isSlave) {
+        ret = MasterReq::PolicyUpdate(policyEntries, uid, pid, smackLabel);
+    } else {
+        ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
+    }
+    Serialization::Serialize(send, ret);
+}
+
+void Service::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel, bool forAdmin)
+{
+    int ret;
+    policy_entry filter;
+    Deserialization::Deserialize(buffer, filter);
+    std::vector<policy_entry> policyEntries;
+
+    if (m_isSlave) {
+        ret = MasterReq::GetConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
+    } else {
+        ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel,
+                                               policyEntries);
+    }
+
+    Serialization::Serialize(send, ret);
+    Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
+    for (const auto &policyEntry : policyEntries) {
+        Serialization::Serialize(send, policyEntry);
+    };
+}
+
+void Service::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
+{
+    int ret;
+    policy_entry filter;
+    Deserialization::Deserialize(buffer, filter);
+    std::vector<policy_entry> policyEntries;
+
+    if (m_isSlave) {
+        ret = MasterReq::GetPolicy(filter, uid, pid, smackLabel, policyEntries);
+    } else {
+        ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
+    }
+
     Serialization::Serialize(send, ret);
+    Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
+    for (const auto &policyEntry : policyEntries) {
+        Serialization::Serialize(send, policyEntry);
+    };
 }
 
+void Service::processPolicyGetDesc(MessageBuffer &send)
+{
+    int ret;
+    std::vector<std::string> descriptions;
+
+    if (m_isSlave) {
+        ret = MasterReq::PolicyGetDesc(descriptions);
+    } else {
+        ret = ServiceImpl::policyGetDesc(descriptions);
+    }
+    Serialization::Serialize(send, ret);
+    if (ret == SECURITY_MANAGER_API_SUCCESS) {
+        Serialization::Serialize(send, static_cast<int>(descriptions.size()));
+
+        for(std::vector<std::string>::size_type i = 0; i != descriptions.size(); i++) {
+            Serialization::Serialize(send, descriptions[i]);
+        }
+    }
+}
+
+void Service::processPrivilegesMappings(MessageBuffer &recv, MessageBuffer &send)
+{
+    std::vector<std::string> privileges;
+    std::string version_from, version_to;
+    Deserialization::Deserialize(recv, version_from);
+    Deserialization::Deserialize(recv, version_to);
+    Deserialization::Deserialize(recv, privileges);
+
+    std::vector<std::string> mappings;
+    int ret = ServiceImpl::getPrivilegesMappings(version_from, version_to, privileges, mappings);
+
+    Serialization::Serialize(send, ret);
+    Serialization::Serialize(send, mappings);
+}
 
 } // namespace SecurityManager