Add privilege-Smack mapping 62/224862/13
authorZofia Grzelewska <z.abramowska@samsung.com>
Wed, 12 Feb 2020 17:50:21 +0000 (18:50 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Fri, 17 Apr 2020 10:27:26 +0000 (12:27 +0200)
Add privilege-Smack mapping configuration:
* privilege-smack.list which describes privilege mapping
  to Smack label and Smack rules template
* priv-rules-default-template.smack which is an example
  of Smack rules template for privilege
* this implementation currently only applies policy on
  application launch (no runtime policy changes modify it)
and draft implementation.

IMPORTANT: This mechanism can be used, when *only one* user
           is used on Tizen.

Change-Id: Iafc999793e6fe465279d0e63ca087ae6b836181a

CMakeLists.txt
policy/CMakeLists.txt
policy/priv-rules-default-template.smack [new file with mode: 0644]
policy/privilege-smack.list [new file with mode: 0644]
src/common/include/config.h
src/common/include/service_impl.h
src/common/include/smack-rules.h
src/common/service_impl.cpp
src/common/smack-rules.cpp
src/server/service/service.cpp

index 79733d4..d6f2f60 100644 (file)
@@ -64,11 +64,17 @@ SET(DB_TEST_INSTALL_DIR
     CACHE PATH
     "Read-only test database directory")
 
+SET(PRIV_MAPPING_INSTALL_SUBDIR
+    "privilege-mapping"
+    CACHE PATH
+    "Read-only privilege Smack mapping directory")
+
 ADD_DEFINITIONS("-DDB_INSTALL_DIR=\"${DB_INSTALL_DIR}\"")
 ADD_DEFINITIONS("-DLOCAL_STATE_INSTALL_DIR=\"${LOCAL_STATE_INSTALL_DIR}\"")
 ADD_DEFINITIONS("-DDATA_INSTALL_DIR=\"${DATA_INSTALL_DIR}\"")
 ADD_DEFINITIONS("-DPOLICY_INSTALL_DIR=\"${POLICY_INSTALL_DIR}\"")
 ADD_DEFINITIONS("-DDB_TEST_INSTALL_DIR=\"${DB_TEST_INSTALL_DIR}\"")
+ADD_DEFINITIONS("-DPRIV_MAPPING_INSTALL_SUBDIR=\"${PRIV_MAPPING_INSTALL_SUBDIR}\"")
 
 ############################# compiler flags ##################################
 
index 2848fe2..499606e 100644 (file)
@@ -4,12 +4,21 @@ FILE(GLOB USERTYPE_POLICY_FILES usertype-*.profile)
 
 CONFIGURE_FILE(security-manager-policy-reload.in security-manager-policy-reload @ONLY)
 
+SET(PRIV_MAPPING_TEMPLATE_FILES
+    "priv-rules-default-template.smack")
+SET(INSTALL_TEMPLATE_FILES
+    "app-rules-template.smack"
+    "pkg-rules-template.smack"
+    "author-rules-template.smack"
+    )
+
 INSTALL(FILES ${USERTYPE_POLICY_FILES} DESTINATION ${POLICY_INSTALL_DIR})
-INSTALL(FILES "app-rules-template.smack" DESTINATION ${POLICY_INSTALL_DIR})
-INSTALL(FILES "pkg-rules-template.smack" DESTINATION ${POLICY_INSTALL_DIR})
-INSTALL(FILES "author-rules-template.smack" DESTINATION ${POLICY_INSTALL_DIR})
+INSTALL(FILES ${PRIV_MAPPING_TEMPLATE_FILES}
+    DESTINATION "${POLICY_INSTALL_DIR}/${PRIV_MAPPING_INSTALL_SUBDIR}")
+INSTALL(FILES ${INSTALL_TEMPLATE_FILES} DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(FILES "privilege-group.list" DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(FILES "privilege-mount.list" DESTINATION ${POLICY_INSTALL_DIR})
+INSTALL(FILES "privilege-smack.list" DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(FILES "privilege-managed-by-systemd-for-daemons.list" DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(PROGRAMS "update.sh" DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(DIRECTORY "updates" USE_SOURCE_PERMISSIONS DESTINATION ${POLICY_INSTALL_DIR})
@@ -23,7 +32,7 @@ SET(GENERATOR "./generate-rule-code")
 
 ADD_CUSTOM_COMMAND(OUTPUT ${GEN_FILE}
   COMMAND mkdir -p "${GEN_PATH}"
-  COMMAND ${GENERATOR} *.smack > ${GEN_FILE}
-  DEPENDS ${GENERATOR} "*.smack"
+  COMMAND ${GENERATOR} ${INSTALL_TEMPLATE_FILES} > ${GEN_FILE}
+  DEPENDS ${GENERATOR} ${INSTALL_TEMPLATE_FILES}
 )
 ADD_CUSTOM_TARGET(generate_rule_template_code DEPENDS ${GEN_FILE})
diff --git a/policy/priv-rules-default-template.smack b/policy/priv-rules-default-template.smack
new file mode 100644 (file)
index 0000000..09c5be6
--- /dev/null
@@ -0,0 +1,2 @@
+~PROCESS~ ~PRIVILEGE~ w
+~PRIVILEGE~ ~PROCESS~ w
diff --git a/policy/privilege-smack.list b/policy/privilege-smack.list
new file mode 100644 (file)
index 0000000..f73816a
--- /dev/null
@@ -0,0 +1,16 @@
+# Configuration of Smack label and rules mapping of privileges
+# Format:
+# - Each line of "<PRIVILEGE> <SMACK LABEL> <SMACK RULES TEMPLATE>" describes
+#   single mapping
+#   * <PRIVILEGE>: name of enforced privilege
+#   * <SMACK LABEL>: unique Smack label mapped to given privilege
+#   * <SMACK RULES TEMPLATE>: full filename of existing template file in security-manager
+#      policy configuration dir (usually /usr/share/security-manager/policy/), which will be
+#      used to generate Smack rules
+#
+# - <SMACK RULES TEMPLATE> may be set to special value "default".
+#   In such case 'priv-rules-default-template.smack' will be used.
+#
+# - lines starting with '#' or empty lines are ignored
+
+http://tizen.org/privilege/internet System::Privilege::Internet default
index 281b838..1fef74f 100644 (file)
 #define APPS_LABELS_FILE           "apps-labels"
 
 /* Policy files */
+
 #define PRIVILEGE_GROUP_LIST_FILE  POLICY_INSTALL_DIR "/privilege-group.list"
 #define PRIVILEGE_MOUNT_LIST_FILE  POLICY_INSTALL_DIR "/privilege-mount.list"
+#define PRIVILEGE_SMACK_LIST_FILE  POLICY_INSTALL_DIR "/privilege-smack.list"
 #define PRIVILEGE_SYSTEMD_LIST_FILE  POLICY_INSTALL_DIR "/privilege-managed-by-systemd-for-daemons.list"
 
 #define SKEL_DIR                   "/etc/skel"
index 80c0a82..76239b2 100644 (file)
@@ -175,20 +175,33 @@ public:
     int policyGetDesc(std::vector<std::string> &descriptions);
 
     /**
+     * Get vector of privileges allowed for given application.
+     *
+     * @param[in] appProcessLabel Smack label of application process
+     * @param[in] uid user id of given application process
+     * @param[out] allowedPrivilege vector of privileges allowed for given application
+     *
+     * @return API return code, as defined in protocols.h
+     */
+    int getAppAllowedPrivileges(const std::string &appProcessLabel, uid_t uid,
+                                std::vector<std::string> &allowedPrivileges);
+
+    /**
     * Process query for resources group list and supplementary groups allowed for the application.
     * For given \ref appProcessLabel and \ref uid, calculate allowed privileges that give
     * direct access to file system resources. For each permission Cynara will be
     * queried.
     * Returns set of group ids that are permitted.
     *
-    * @param[in]  creds credentials of the requesting process
     * @param[in]  appProcessLabel application name
+    * @param[in]  allowedPrivileges privileges allowed for application
     * @param[out] forbiddenGroups returned sorted vector of forbidden groups
     * @param[out] allowedGroups returned sorted vector of allowed groups
     *
     * @return API return code, as defined in protocols.h
     */
-    int getForbiddenAndAllowedGroups(const Credentials &creds, const std::string &appProcessLabel,
+    int getForbiddenAndAllowedGroups(const std::string &appProcessLabel,
+        const std::vector<std::string> &allowedPrivileges,
         std::vector<gid_t> &forbiddenGroups, std::vector<gid_t> &allowedGroups);
 
     /**
index 8398ee0..b69c170 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -61,6 +61,20 @@ public:
             const std::string &pkgName,
             const int authorId);
 
+    void addFromPrivTemplate(
+            const RuleVector &templateRules,
+            const std::string &appProcessLabel,
+            const std::string &privilegeLabel,
+            const std::string &pkgName,
+            int authorId);
+
+    void addFromPrivTemplateFile(
+            const std::string &templatePath,
+            const std::string &appProcessLabel,
+            const std::string &privilegeLabel,
+            const std::string &pkgName,
+            int authorId);
+
     void apply() const;
     void clear() const;
 
@@ -92,6 +106,23 @@ public:
             const Labels &pkgLabels);
 
     /**
+     * Enable privilege-specific smack rules for given application
+     *
+     * Function creates privilege-specific smack rules using predefined templates.
+     * Rules are applied to the kernel.
+     *
+     * @param[in] appProcessLabel - process label of the application
+     * @param[in] pkgName - package id of given application
+     * @param[in] authorId - author id of given application (if not applicable, set to -1)
+     * @param[in] privileges - a list of privileges allowed for given application
+     */
+    static void enablePrivilegeRules(
+        const std::string &appProcessLabel,
+        const std::string &pkgName,
+        int authorId,
+        const std::vector<std::string> &privileges);
+
+    /**
      * Uninstall package-specific smack rules.
      *
      * Function loads package-specific smack rules, revokes them from the kernel.
@@ -179,6 +210,13 @@ public:
                                         bool isPathSharedNoMore,
                                         bool isTargetSharingNoMore);
 
+    /**
+     * Revoke rules for which label of given \ref appName is a subject.
+     *
+     * @param[in] appProcessLabel = application process label
+     */
+    static void revokeAppSubject(const std::string &appProcessLabel);
+
 private:
     static void useTemplate(
             const std::string &templatePath,
@@ -198,13 +236,6 @@ private:
             const std::string &replace);
 
     smack_accesses *m_handle;
-
-    /**
-     * Revoke rules for which label of given \ref appName is a subject.
-     *
-     * @param[in] appProcessLabel = application process label
-     */
-    static void revokeAppSubject(const std::string &appProcessLabel);
 };
 
 } // namespace SecurityManager
index 98b86b8..6f40dd1 100644 (file)
@@ -1400,37 +1400,54 @@ int ServiceImpl::policyGetDesc(std::vector<std::string> &levels)
     return ret;
 }
 
-int ServiceImpl::getForbiddenAndAllowedGroups(const Credentials &creds, const std::string &appProcessLabel,
-    std::vector<gid_t> &forbiddenGroups, std::vector<gid_t> &allowedGroups)
+int ServiceImpl::getAppAllowedPrivileges(const std::string &appProcessLabel,
+    uid_t uid, std::vector<std::string> &allowedPrivileges)
 {
     try {
-        LogDebug("smack label: " << appProcessLabel);
+        LogDebug("Getting allowed privileges for " << appProcessLabel << " and user " << uid);
+        std::string uidStr = std::to_string(uid);
 
         std::vector<std::string> privileges;
-
-        std::string uidStr = std::to_string(creds.uid);
         m_cynaraAdmin.getAppPolicy(appProcessLabel, uidStr, privileges);
         m_cynaraAdmin.getAppPolicy(appProcessLabel, CYNARA_ADMIN_WILDCARD, privileges);
         m_cynaraAdmin.getAppPolicy(CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_WILDCARD, privileges);
 
         vectorRemoveDuplicates(privileges);
+        for (auto &privilege : privileges) {
+            if (m_cynara.check(appProcessLabel, privilege, uidStr, "")) {
+                allowedPrivileges.push_back(privilege);
+            }
+        }
+    } catch (const CynaraException::Base &e) {
+        LogError("Error while querying Cynara for permissions: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    } catch (const std::bad_alloc &e) {
+        LogError("Memory allocation failed " << e.what());
+        return SECURITY_MANAGER_ERROR_MEMORY;
+    }
 
-        std::string pidStr = std::to_string(creds.pid);
-        for (const auto &privilege : privileges) {
+    return SECURITY_MANAGER_SUCCESS;
+}
+
+int ServiceImpl::getForbiddenAndAllowedGroups(
+    const std::string &appProcessLabel, const std::vector<std::string> &allowedPrivileges,
+    std::vector<gid_t> &forbiddenGroups, std::vector<gid_t> &allowedGroups)
+{
+
+    try {
+        LogDebug("smack label: " << appProcessLabel);
+
+        for (const auto &privilege : allowedPrivileges) {
             const auto &pgids = m_privilegeGids.getGids(privilege);
 
-            LogDebug("Considering privilege " << privilege << " with " <<
+            LogDebug("Using privilege " << privilege << " with " <<
                      pgids.size() << " groups assigned");
 
             if (pgids.empty())
                 continue;
 
-            if (m_cynara.check(appProcessLabel, privilege, uidStr, pidStr)) {
-                allowedGroups.insert(allowedGroups.end(), pgids.begin(), pgids.end());
-                LogDebug("Cynara allowed, adding groups");
-            } else {
-                LogDebug("Cynara denied, not adding groups");
-            }
+            allowedGroups.insert(allowedGroups.end(), pgids.begin(), pgids.end());
+
         }
         vectorRemoveDuplicates(allowedGroups); // sorted
 
@@ -1438,9 +1455,6 @@ int ServiceImpl::getForbiddenAndAllowedGroups(const Credentials &creds, const st
         forbiddenGroups.reserve(gids.size());
         std::set_difference(gids.begin(), gids.end(), allowedGroups.begin(), allowedGroups.end(),
                 std::back_inserter(forbiddenGroups)); // sorted
-    } catch (const CynaraException::Base &e) {
-        LogError("Error while querying Cynara for permissions: " << e.DumpToString());
-        return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
         LogError("Memory allocation failed: " << e.what());
         return SECURITY_MANAGER_ERROR_MEMORY;
@@ -2133,7 +2147,25 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
         return SECURITY_MANAGER_ERROR_UNKNOWN;
     label = SmackLabels::generateProcessLabel(appName, pkgName, isHybrid);
 
-    int ret = getForbiddenAndAllowedGroups(creds, label, forbiddenGroups, allowedGroups);
+    std::vector<std::string> allowedPrivileges;
+    int ret = getAppAllowedPrivileges(label, creds.uid, allowedPrivileges);
+    if (ret != SECURITY_MANAGER_SUCCESS) {
+        LogError("Failed to fetch allowed privileges for " << label);
+        return ret;
+    }
+
+    int authorId;
+    m_privilegeDb.GetPkgAuthorId(pkgName, authorId);
+
+    std::vector<std::string> pkgLabels;
+    getPkgLabels(pkgName, pkgLabels);
+
+    SmackRules::revokeAppSubject(label);
+    SmackRules::installApplicationRules(label, pkgName, authorId, pkgLabels);
+    SmackRules::enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+
+    ret = getForbiddenAndAllowedGroups(label, allowedPrivileges, forbiddenGroups,
+                                       allowedGroups);
     return ret != SECURITY_MANAGER_SUCCESS ? ret
         : appSetupNamespace(creds, label, privilegeVector, privilegeStatusVector);
 }
index df3fd44..d7963d8 100644 (file)
@@ -32,6 +32,7 @@
 #include <memory>
 #include <algorithm>
 
+#include "config.h"
 #include "config-file.h"
 #include "dpl/log/log.h"
 #include "dpl/errno_string.h"
@@ -48,22 +49,31 @@ const std::string SMACK_PROCESS_LABEL_TEMPLATE     = "~PROCESS~";
 const std::string SMACK_PATH_RW_LABEL_TEMPLATE     = "~PATH_RW~";
 const std::string SMACK_PATH_RO_LABEL_TEMPLATE     = "~PATH_RO~";
 const std::string SMACK_PATH_TRUSTED_LABEL_TEMPLATE  = "~PATH_TRUSTED~";
+const std::string SMACK_PRIVILEGE_LABEL_TEMPLATE   = "~PRIVILEGE~";
 
 enum POLICY_FILE {
     APP_RULES_TEMPLATE,
     PKG_RULES_TEMPLATE,
-    AUTHOR_RULES_TEMPLATE
+    AUTHOR_RULES_TEMPLATE,
+    PRIV_DEFAULT_RULES_TEMPLATE,
+    PRIV_RULES_TEMPLATE
 };
 
 const std::string POLICY_DIR_STR = POLICY_INSTALL_DIR;
+const std::string PRIV_MAPPING_DIR_STR = POLICY_INSTALL_DIR "/" PRIV_MAPPING_INSTALL_SUBDIR;
 
 std::map<POLICY_FILE, std::string> POLICY_FILE_PATH_MAP = {
     {POLICY_FILE::APP_RULES_TEMPLATE, POLICY_DIR_STR + "/app-rules-template.smack"},
     {POLICY_FILE::PKG_RULES_TEMPLATE, POLICY_DIR_STR + "/pkg-rules-template.smack"},
-    {POLICY_FILE::AUTHOR_RULES_TEMPLATE, POLICY_DIR_STR + "/author-rules-template.smack"}
+    {POLICY_FILE::AUTHOR_RULES_TEMPLATE, POLICY_DIR_STR + "/author-rules-template.smack"},
+    {POLICY_FILE::PRIV_DEFAULT_RULES_TEMPLATE,
+     PRIV_MAPPING_DIR_STR + "/priv-rules-default-template.smack"}
 };
 
-std::string getPolicyFile(enum POLICY_FILE policyFile) {
+std::string getPolicyFile(enum POLICY_FILE policyFile, const std::string &privFile = "") {
+    if (policyFile == POLICY_FILE::PRIV_RULES_TEMPLATE) {
+        return PRIV_MAPPING_DIR_STR + "/" + privFile;
+    }
     return POLICY_FILE_PATH_MAP[policyFile];
 }
 
@@ -77,6 +87,8 @@ const std::string SMACK_SYSTEM_PRIVILEGED = "System::Privileged";
 const std::string SMACK_APP_PATH_SYSTEM_PERMS = "rwxat";
 const std::string SMACK_APP_PATH_USER_PERMS = "rwxat";
 
+const std::string PRIV_TEMPLATE_DEFAULT = "default";
+
 SmackRules::SmackRules()
 {
     if (smack_accesses_new(&m_handle) < 0) {
@@ -169,6 +181,64 @@ void SmackRules::addFromTemplate(
     }
 }
 
+void SmackRules::addFromPrivTemplate(
+        const RuleVector &templateRules,
+        const std::string &appProcessLabel,
+        const std::string &privilegeLabel,
+        const std::string &pkgName,
+        int authorId)
+{
+    std::string pathRWLabel, pathROLabel;
+    std::string pathTrustedLabel;
+
+    if (!pkgName.empty()) {
+        pathRWLabel = SmackLabels::generatePathRWLabel(pkgName);
+        pathROLabel = SmackLabels::generatePathROLabel(pkgName);
+    }
+
+    if (authorId >= 0)
+        pathTrustedLabel = SmackLabels::generatePathTrustedLabel(authorId);
+
+    for (auto &rule : templateRules) {
+        if (rule.size() != 3) {
+            LogError("Invalid rule template: " << rule.size() << " tokens");
+            ThrowMsg(SmackException::FileError, "Invalid rule template: " << rule.size() << " tokens");
+        }
+
+        std::string subject = rule[0];
+        std::string object = rule[1];
+        std::string permissions = rule[2];
+
+        strReplace(subject, SMACK_PROCESS_LABEL_TEMPLATE, appProcessLabel);
+        strReplace(subject, SMACK_PRIVILEGE_LABEL_TEMPLATE, privilegeLabel);
+        strReplace(object,  SMACK_PROCESS_LABEL_TEMPLATE, appProcessLabel);
+        strReplace(object,  SMACK_PRIVILEGE_LABEL_TEMPLATE, privilegeLabel);
+        strReplace(object,  SMACK_PATH_RW_LABEL_TEMPLATE, pathRWLabel);
+        strReplace(object,  SMACK_PATH_RO_LABEL_TEMPLATE, pathROLabel);
+        strReplace(object,  SMACK_PATH_TRUSTED_LABEL_TEMPLATE, pathTrustedLabel);
+
+        if (subject.empty() || object.empty())
+            continue;
+        add(subject, object, permissions);
+    }
+}
+
+void SmackRules::addFromPrivTemplateFile(
+        const std::string &templatePath,
+        const std::string &appProcessLabel,
+        const std::string &privilegeLabel,
+        const std::string &pkgName,
+        int authorId)
+{
+    try {
+        addFromPrivTemplate(ConfigFile(templatePath).read(), appProcessLabel, privilegeLabel,
+                            pkgName, authorId);
+    } catch (FS::Exception::Base &) {
+        LogError("Error reading template file: " << templatePath);
+        ThrowMsg(SmackException::FileError, "Error reading template file: " << templatePath);
+    }
+}
+
 void SmackRules::generatePackageCrossDeps(const Labels &pkgLabels)
 {
     LogDebug("Generating cross-package rules");
@@ -215,6 +285,48 @@ void SmackRules::installApplicationRules(
     updatePackageRules(pkgName, pkgLabels);
 }
 
+void SmackRules::enablePrivilegeRules(
+        const std::string &appProcessLabel,
+        const std::string &pkgName,
+        int authorId,
+        const std::vector<std::string> &privileges)
+{
+    if (privileges.empty()) {
+        // No rules to apply
+        return;
+    }
+
+    SmackRules smackRules;
+
+    auto privMapping = ConfigFile(PRIVILEGE_SMACK_LIST_FILE).read();
+
+    for (auto &mapping : privMapping) {
+        if (mapping.size() != 3)
+            continue;
+
+        auto &privName = mapping[0];
+        auto &privLabel = mapping[1];
+        auto &privTemplate = mapping[2];
+
+        if (privTemplate == PRIV_TEMPLATE_DEFAULT) {
+            privTemplate = getPolicyFile(POLICY_FILE::PRIV_DEFAULT_RULES_TEMPLATE);
+        } else {
+            privTemplate = getPolicyFile(POLICY_FILE::PRIV_RULES_TEMPLATE, privTemplate);
+        }
+
+        for (auto &privilege : privileges) {
+            if (privilege == privName) {
+                smackRules.addFromPrivTemplateFile(privTemplate, appProcessLabel, privLabel,
+                                                   pkgName, authorId);
+                break;
+            }
+        }
+    }
+
+    if (smack_check())
+        smackRules.apply();
+}
+
 void SmackRules::updatePackageRules(
         const std::string &pkgName,
         const Labels &pkgLabels)
index e29a807..e367b12 100644 (file)
@@ -351,7 +351,17 @@ void Service::processGetForbiddenAndAllowedGroups(MessageBuffer &buffer, Message
     std::vector<gid_t> forbiddenGroups, allowedGroups;
 
     Deserialization::Deserialize(buffer, appName);
-    int ret = serviceImpl.getForbiddenAndAllowedGroups(creds, serviceImpl.getProcessLabel(appName), forbiddenGroups, allowedGroups);
+
+    std::string label = serviceImpl.getProcessLabel(appName);
+    std::vector<std::string> allowedPrivileges;
+    int ret = serviceImpl.getAppAllowedPrivileges(label, creds.uid, allowedPrivileges);
+    if (ret != SECURITY_MANAGER_SUCCESS) {
+        LogError("Failed to fetch allowed privileges for " << label);
+        Serialization::Serialize(send, ret);
+        return;
+    }
+    ret = serviceImpl.getForbiddenAndAllowedGroups(label, allowedPrivileges, forbiddenGroups,
+                                                   allowedGroups);
     Serialization::Serialize(send, ret);
     if (ret == SECURITY_MANAGER_SUCCESS) {
         Serialization::Serialize(send, forbiddenGroups, allowedGroups);