diff options
author | Dariusz Michaluk <d.michaluk@samsung.com> | 2019-12-17 18:54:40 +0100 |
---|---|---|
committer | Dariusz Michaluk <d.michaluk@samsung.com> | 2019-12-19 14:01:29 +0100 |
commit | 78b7c6faca87be282b7af7283909f3893ce5b1c7 (patch) | |
tree | 03b38af38ac84fbc39d055e50b2ababad0db1fd3 | |
parent | 55b36e93d2f6fb1d7640fb7cbb5be54bf382e6f7 (diff) | |
download | security-manager-78b7c6faca87be282b7af7283909f3893ce5b1c7.tar.gz security-manager-78b7c6faca87be282b7af7283909f3893ce5b1c7.tar.bz2 security-manager-78b7c6faca87be282b7af7283909f3893ce5b1c7.zip |
Skip mount namespace setup specific to privacy privileges
In case of empty privacy privilege to filesystem path mapping (privilege-mount.list file)
we can skip mount namespace setup specific to privacy privileges.
Change-Id: I7f1f4ef8e5f0614d7b232529f4ff665c2dfeaf5f
-rw-r--r-- | src/client/client-security-manager.cpp | 102 | ||||
-rw-r--r-- | src/common/include/mount-namespace.h | 2 | ||||
-rw-r--r-- | src/common/include/protocols.h | 2 | ||||
-rw-r--r-- | src/common/include/service_impl.h | 29 | ||||
-rw-r--r-- | src/common/mount-namespace.cpp | 11 | ||||
-rw-r--r-- | src/common/nsmount-logic.cpp | 2 | ||||
-rw-r--r-- | src/common/protocols.cpp | 3 | ||||
-rw-r--r-- | src/common/service_impl.cpp | 25 | ||||
-rw-r--r-- | src/server/main/server-main.cpp | 4 | ||||
-rw-r--r-- | src/server/service/include/service.h | 15 | ||||
-rw-r--r-- | src/server/service/service.cpp | 38 |
11 files changed, 119 insertions, 114 deletions
diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 24ab61bb..a62c1c8b 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -416,18 +416,25 @@ static int setup_smack(const char *label) return SECURITY_MANAGER_SUCCESS; } -static int fetchLabelForProcess(const std::string &appName, std::string &label) +static int fetchAppInfo(const std::string &appName, std::string &label, std::string &pkgName, bool &enabledSharedRO) { using namespace SecurityManager; - ClientRequest request(SecurityModuleCall::LABEL_FOR_PROCESS); + ClientRequest request(SecurityModuleCall::GET_APP_INFO); if (request.send(appName).failed()) return request.getStatus(); - request.recv(label); + request.recv(label, pkgName, enabledSharedRO); return SECURITY_MANAGER_SUCCESS; } +static int fetchLabelForProcess(const std::string &appName, std::string &label) +{ + std::string pkgName; + bool enabledSharedRO; + return fetchAppInfo(appName, label, pkgName, enabledSharedRO); +} + SECURITY_MANAGER_API int security_manager_set_process_label_from_appid(const char *app_name) { @@ -807,6 +814,10 @@ static int setupSharedRO(const std::string &pkg_name, bool enabledSharedRO) std::string userPkgAppsRWSharedDir = userAppsRWSharedDir + pkg_name + "/"; std::string userPkgAppsRWSharedTmpDir = userAppsRWDir + "/.shared_tmp/" + pkg_name + "/"; + ret = MountNS::makeMountSlave("/"); + if (ret != SECURITY_MANAGER_SUCCESS) + return ret; + if (enabledSharedRO) { if (FS::directoryStatus(userPkgAppsRWSharedDir) == 1 && FS::directoryStatus(userPkgAppsRWSharedTmpDir) == 1) { ret = MountNS::bindMountRW(userPkgAppsRWSharedDir, userPkgAppsRWSharedTmpDir); @@ -832,14 +843,37 @@ static int setupSharedRO(const std::string &pkg_name, bool enabledSharedRO) return SECURITY_MANAGER_SUCCESS; } -static int setupMountNamespace(const std::string &appName, const std::string &appProcessLabel, - std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName) +static int setupPrivacyPrivilegeMountNamespace(const std::string &app_label) { + if (!MountNS::isPrivacyPrivilegeMountNamespaceEnabled()) + return SECURITY_MANAGER_SUCCESS; + ClientRequest request(SecurityModuleCall::APP_SETUP_NAMESPACE); - if (request.send(appName, appProcessLabel).failed()) + if (request.send(app_label).failed()) return request.getStatus(); - request.recv(privilegeStatusVector, pkgName, enabledSharedRO); + std::vector<std::pair<std::string, bool>> privilegeStatusVector; + request.recv(privilegeStatusVector); + + auto storagePrivilegePathMap = MountNS::getPrivilegePathMap(getuid()); + for (auto &privilegeStatus : privilegeStatusVector) { + auto it = storagePrivilegePathMap.find(privilegeStatus.first); + if (it == storagePrivilegePathMap.end()) + continue; + + for (auto &privilegePath : it->second) { + if (FS::directoryStatus(privilegePath.dstPath) == 0) { + LogWarning("Not enforcing privilege " << it->first << " for application " << app_label << " : " << + "directory " << privilegePath.dstPath << " doesn't exist"); + continue; + } + + int ret = MountNS::applyPrivilegePath(privilegeStatus.second, privilegePath); + if (ret != SECURITY_MANAGER_SUCCESS) + return ret; + } + } + return SECURITY_MANAGER_SUCCESS; } @@ -848,8 +882,6 @@ int security_manager_prepare_app_candidate(void) { return try_catch([&]() -> int { LogDebug("security_manager_prepare_app_candidate() called"); - if (!MountNS::isMountNamespaceEnabled()) - return SECURITY_MANAGER_SUCCESS; FS::FileNameVector files = FS::getSubDirectoriesFromDirectory("/proc/self/task"); if (files.size() > 3) { // 3 because we have ., we have .. and we should have only one thread here @@ -861,55 +893,28 @@ int security_manager_prepare_app_candidate(void) }); } -static inline int security_manager_setup_namespace_internal(const std::string &app_name, const std::string &app_label) +static inline int security_manager_setup_namespace_internal(const std::string &app_label, const std::string &pkg_name, bool enabledSharedRO) { - if (!MountNS::isMountNamespaceEnabled()) - return SECURITY_MANAGER_SUCCESS; - - int ret = MountNS::makeMountSlave("/"); - if (ret != SECURITY_MANAGER_SUCCESS) - return ret; - - std::vector<std::pair<std::string, bool>> privilegeStatusVector; - bool enabledSharedRO; - std::string pkg_name; - ret = setupMountNamespace(app_name, app_label, privilegeStatusVector, enabledSharedRO, pkg_name); + int ret = setupSharedRO(pkg_name, enabledSharedRO); if (ret != SECURITY_MANAGER_SUCCESS) { - LogError("Failed to setup app namespace: " << security_manager_strerror(static_cast<lib_retcode>(ret))); + LogError("Failed to setup app SharedRO: " << security_manager_strerror(static_cast<lib_retcode>(ret))); return ret; } - ret = setupSharedRO(pkg_name, enabledSharedRO); + ret = setupPrivacyPrivilegeMountNamespace(app_label); if (ret != SECURITY_MANAGER_SUCCESS) { - LogError("Failed to setup app SharedRO: " << security_manager_strerror(static_cast<lib_retcode>(ret))); + LogError("Failed to setup app namespace: " << security_manager_strerror(static_cast<lib_retcode>(ret))); return ret; } - auto storagePrivilegePathMap = MountNS::getPrivilegePathMap(getuid()); - for (auto &privilegeStatus : privilegeStatusVector) { - auto it = storagePrivilegePathMap.find(privilegeStatus.first); - if (it == storagePrivilegePathMap.end()) - continue; - - for (auto &privilegePath : it->second) { - if (FS::directoryStatus(privilegePath.dstPath) == 0) { - LogWarning("Not enforcing privilege " << it->first << " for application " << app_label << " : " << - "directory " << privilegePath.dstPath << " doesn't exist"); - continue; - } - - ret = MountNS::applyPrivilegePath(privilegeStatus.second, privilegePath); - if (ret != SECURITY_MANAGER_SUCCESS) - return ret; - } - } - return SECURITY_MANAGER_SUCCESS; } SECURITY_MANAGER_API int security_manager_prepare_app(const char *app_name) { + LOG_EXECUTION_TIME("security_manager_prepare_app(" + std::string(app_name) + ")", Credentials::getCredentialsFromSelf()); + return try_catch([&] { if (app_name == nullptr) { LogError("app_name is NULL"); @@ -918,10 +923,11 @@ int security_manager_prepare_app(const char *app_name) LogDebug("security_manager_prepare_app() called for app " << app_name); - std::string app_label; - int ret = fetchLabelForProcess(app_name, app_label); + std::string app_label, pkg_name; + bool enabledSharedRO; + int ret = fetchAppInfo(app_name, app_label, pkg_name, enabledSharedRO); if (ret != SECURITY_MANAGER_SUCCESS) { - LogError("Failed to generate smack label for appName: " << app_name); + LogError("Failed to get app info for appName: " << app_name); return ret; } @@ -931,7 +937,7 @@ int security_manager_prepare_app(const char *app_name) return ret; } - ret = security_manager_setup_namespace_internal(app_name, app_label); + ret = security_manager_setup_namespace_internal(app_label, pkg_name, enabledSharedRO); if (ret != SECURITY_MANAGER_SUCCESS) { LogError("Unable to setup namespace for application " << app_name); return ret; @@ -971,7 +977,7 @@ int security_manager_cleanup_app(const char *app_name, uid_t uid, pid_t pid) return SECURITY_MANAGER_ERROR_INPUT_PARAM; } - if (MountNS::isMountNamespaceEnabled()) { + if (MountNS::isPrivacyPrivilegeMountNamespaceEnabled()) { ClientRequest request(SecurityModuleCall::APP_CLEAN_NAMESPACE); return request.send(std::string(app_name), uid, pid).getStatus(); } diff --git a/src/common/include/mount-namespace.h b/src/common/include/mount-namespace.h index 6c649f09..49b5587e 100644 --- a/src/common/include/mount-namespace.h +++ b/src/common/include/mount-namespace.h @@ -50,7 +50,7 @@ std::string getUserAppMountPointPath(uid_t uid, const std::string &smackLabel); std::string getUserAppServiceMountPointPath(uid_t uid, const std::string &smackLabel, pid_t pid); int applyPrivilegePath(bool allow, const PrivilegePath &privilegePath); -bool isMountNamespaceEnabled(void); +bool isPrivacyPrivilegeMountNamespaceEnabled(void); int createMountNamespace(void); bool enterMountNamespace(const Path &mntPath); int makeMountSlave(const Path &mountPoint); diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h index 006c8a7b..4029c6b3 100644 --- a/src/common/include/protocols.h +++ b/src/common/include/protocols.h @@ -121,7 +121,6 @@ enum class SecurityModuleCall APP_HAS_PRIVILEGE, PATHS_REGISTER, GROUPS_FOR_UID, - LABEL_FOR_PROCESS, SHM_APP_NAME, GET_APP_DEFINED_PRIVILEGE_PROVIDER, GET_APP_DEFINED_PRIVILEGE_LICENSE, @@ -129,6 +128,7 @@ enum class SecurityModuleCall APP_SETUP_NAMESPACE, APP_CLEAN_NAMESPACE, GET_APP_MANIFEST_POLICY, + GET_APP_INFO, NOOP = 0x90, }; diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 804d8bc4..2adb2021 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -254,15 +254,6 @@ public: */ int pathsRegister(const Credentials &creds, path_req p_req); - /** - * Generate label for process. - * - * @param[in] appName application identifier - * @param[out] label generated label - * - * @return API return code, as defined in protocols.h - */ - int labelForProcess(const std::string &appName, std::string &label); /* * Request for access to shared memory segment for * appName application. @@ -322,17 +313,13 @@ public: * Setup app namespace * * @param[in] creds credentials of the requesting process - * @param[in] appName application identifier * @param[in] appProcessLabel application identifier * @param[out] privilegeStatusVector returned vector of privilege-status pair - * @param[out] enabledSharedRO placeholder for check shared_ro result - * @param[out] pkgName application package name * * @return API return code, as defined in protocols.h */ - int appSetupNamespace(const Credentials &creds, const std::string &appName, const std::string &appProcessLabel, - std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName); - + int appSetupNamespace(const Credentials &creds, const std::string &appProcessLabel, + std::vector<std::pair<std::string, bool>> &privilegeStatusVector); /** * Return list of privileges requested by application at install time @@ -367,6 +354,18 @@ public: */ int appCleanNamespace(const Credentials &creds, const std::string &appName, uid_t uid, pid_t pid); + /** + * Get app info (process label, package name, shared_ro flag) + * + * @param[in] appName application identifier + * @param[out] label generated label + * @param[out] pkgName application package name + * @param[out] enabledSharedRO placeholder for check shared_ro result + * + * @return API return code, as defined in protocols.h + */ + int getAppInfo(const std::string &appName, std::string &label, std::string &pkgName, bool &enabledSharedRO); + private: int appInstallInitialChecks(const Credentials &creds, app_inst_req &req); diff --git a/src/common/mount-namespace.cpp b/src/common/mount-namespace.cpp index b1283724..2b6a0f2d 100644 --- a/src/common/mount-namespace.cpp +++ b/src/common/mount-namespace.cpp @@ -123,7 +123,7 @@ std::string getUserAppServiceMountPointPath(uid_t uid, const std::string &smackL return getUserAppMountPointPath(uid, smackLabel) + "/" + std::to_string(pid); } -bool isMountNamespaceEnabled(void) +bool isPrivacyPrivilegeMountNamespaceEnabled(void) { auto getStatus = []() -> bool { try { @@ -135,6 +135,11 @@ bool isMountNamespaceEnabled(void) return false; if (st.st_size == 0) return false; + + // File exists and is not empty. + // Let's check if it contains any relevant configuration entries. + if (getPrivilegePathMap(getuid()).empty()) + return false; } catch (...) { return false; } @@ -142,9 +147,9 @@ bool isMountNamespaceEnabled(void) return true; }; - static bool isMountNamespaceEnabled = getStatus(); + static bool enabled = getStatus(); - return isMountNamespaceEnabled; + return enabled; } int createMountNamespace(void) diff --git a/src/common/nsmount-logic.cpp b/src/common/nsmount-logic.cpp index 4fc2d3ef..83165398 100644 --- a/src/common/nsmount-logic.cpp +++ b/src/common/nsmount-logic.cpp @@ -129,7 +129,7 @@ bool NSMountLogic::sendJobs(EntryVector &entryVector) bool NSMountLogic::enabled() { - static bool enabled = MountNS::isMountNamespaceEnabled(); + static bool enabled = MountNS::isPrivacyPrivilegeMountNamespaceEnabled(); return enabled; } diff --git a/src/common/protocols.cpp b/src/common/protocols.cpp index 465b844b..35caba32 100644 --- a/src/common/protocols.cpp +++ b/src/common/protocols.cpp @@ -53,7 +53,6 @@ const char * SecurityModuleCallToString(SecurityModuleCall call_num) { SM_CODE_DESCRIBE(SecurityModuleCall::APP_HAS_PRIVILEGE); SM_CODE_DESCRIBE(SecurityModuleCall::PATHS_REGISTER); SM_CODE_DESCRIBE(SecurityModuleCall::GROUPS_FOR_UID); - SM_CODE_DESCRIBE(SecurityModuleCall::LABEL_FOR_PROCESS); SM_CODE_DESCRIBE(SecurityModuleCall::SHM_APP_NAME); SM_CODE_DESCRIBE(SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER); SM_CODE_DESCRIBE(SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE); @@ -61,6 +60,7 @@ const char * SecurityModuleCallToString(SecurityModuleCall call_num) { SM_CODE_DESCRIBE(SecurityModuleCall::APP_SETUP_NAMESPACE); SM_CODE_DESCRIBE(SecurityModuleCall::APP_CLEAN_NAMESPACE); SM_CODE_DESCRIBE(SecurityModuleCall::GET_APP_MANIFEST_POLICY); + SM_CODE_DESCRIBE(SecurityModuleCall::GET_APP_INFO); SM_CODE_DESCRIBE(SecurityModuleCall::NOOP); default: return "Code not defined"; } @@ -68,4 +68,3 @@ const char * SecurityModuleCallToString(SecurityModuleCall call_num) { #undef SM_CODE_DESCRIBE } // namespace SecurityManager - diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 99dab448..3d64f113 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -1823,14 +1823,6 @@ int ServiceImpl::pathsRegister(const Credentials &creds, path_req req) isRequestSharedRO); } -int ServiceImpl::labelForProcess(const std::string &appName, std::string &label) -{ - LogDebug("Requested label generation for process of application " << appName); - label = getAppProcessLabel(appName); - - return SECURITY_MANAGER_SUCCESS; -} - int ServiceImpl::shmAppName(const Credentials &creds, const std::string &shmName, const std::string &appName) { try { @@ -1999,8 +1991,8 @@ int ServiceImpl::getClientPrivilegeLicense( return SECURITY_MANAGER_SUCCESS; } -int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string &appName, const std::string &appProcessLabel, - std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName) +int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string &appProcessLabel, + std::vector<std::pair<std::string, bool>> &privilegeStatusVector) { int ret; if (!authenticate(creds, PRIVILEGE_APP_NAMESPACE)) { @@ -2045,9 +2037,6 @@ int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string & privilegeStatusVector.push_back(make_pair(it.first, result)); } - m_privilegeDb.GetAppPkgName(appName, pkgName); - enabledSharedRO = m_privilegeDb.IsPackageSharedRO(pkgName); - } catch (const PrivilegeDb::Exception::Base &e) { LogError("Error while getting shared_ro flag from database: " << e.DumpToString()); return SECURITY_MANAGER_ERROR_SERVER_ERROR; @@ -2130,4 +2119,14 @@ int ServiceImpl::appCleanNamespace(const Credentials &creds, const std::string & return ret; } +int ServiceImpl::getAppInfo(const std::string &appName, std::string &label, std::string &pkgName, bool &enabledSharedRO) +{ + LogDebug("Requested fetching label of process, package name and shared_ro flag for application " << appName); + m_privilegeDb.GetAppPkgName(appName, pkgName); + label = getAppProcessLabel(appName, pkgName); + enabledSharedRO = m_privilegeDb.IsPackageSharedRO(pkgName); + + return SECURITY_MANAGER_SUCCESS; +} + } /* namespace SecurityManager */ diff --git a/src/server/main/server-main.cpp b/src/server/main/server-main.cpp index ccd3fa7f..8cdc94a7 100644 --- a/src/server/main/server-main.cpp +++ b/src/server/main/server-main.cpp @@ -109,8 +109,8 @@ int main() return EXIT_FAILURE; } - if (!MountNS::isMountNamespaceEnabled()) { - // Lagacy systems without mount namespace. + if (!MountNS::isPrivacyPrivilegeMountNamespaceEnabled()) { + // Lagacy systems without privacy privilege mount namespace. // In this case security-manager will run without WORKER return security_manager(Channel()); } diff --git a/src/server/service/include/service.h b/src/server/service/include/service.h index 3cb97d67..bd9d03be 100644 --- a/src/server/service/include/service.h +++ b/src/server/service/include/service.h @@ -203,14 +203,6 @@ private: void processPathsRegister(MessageBuffer &recv, MessageBuffer &send, const Credentials &creds); /** - * Generate process label request - * - * @param recv Raw received data buffer - * @param send Raw data buffer to be sent - */ - void processLabelForProcess(MessageBuffer &buffer, MessageBuffer &send); - - /** * Process shared memory access request * * @param recv Raw received data buffer @@ -261,6 +253,13 @@ private: */ void processAppCleanNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds); + /** + * Get app info (process label, package name, shared_ro flag) + * + * @param recv Raw received data buffer + * @param send Raw data buffer to be sent + */ + void processGetAppInfo(MessageBuffer &buffer, MessageBuffer &send); }; } // namespace SecurityManager diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 7d4255c9..8fe311e5 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -144,9 +144,6 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer, case SecurityModuleCall::PATHS_REGISTER: processPathsRegister(buffer, send, creds); break; - case SecurityModuleCall::LABEL_FOR_PROCESS: - processLabelForProcess(buffer, send); - break; case SecurityModuleCall::SHM_APP_NAME: processShmAppName(buffer, send, creds); break; @@ -174,6 +171,9 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer, LogDebug("call_type: SecurityModuleCall::GET_APP_MANIFEST_POLICY"); processAppGetManifestPolicy(buffer, send, creds); break; + case SecurityModuleCall::GET_APP_INFO: + processGetAppInfo(buffer, send); + break; default: LogError("Invalid call: " << call_type_int); Throw(ServiceException::InvalidAction); @@ -425,17 +425,6 @@ void Service::processPathsRegister(MessageBuffer &recv, MessageBuffer &send, con Serialization::Serialize(send, ret); } -void Service::processLabelForProcess(MessageBuffer &buffer, MessageBuffer &send) -{ - std::string appName; - Deserialization::Deserialize(buffer, appName); - std::string label; - int ret = serviceImpl.labelForProcess(appName, label); - Serialization::Serialize(send, ret); - if (ret == SECURITY_MANAGER_SUCCESS) - Serialization::Serialize(send, label); -} - void Service::processShmAppName(MessageBuffer &recv, MessageBuffer &send, const Credentials &creds) { std::string shmName, appName; @@ -485,16 +474,14 @@ void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuf void Service::processAppSetupNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds) { - std::string appName, appProcessLabel; + std::string appProcessLabel; std::vector<std::pair<std::string, bool>> privilegeStatusVector; - bool enabledSharedRO; - std::string pkgName; - Deserialization::Deserialize(buffer, appName, appProcessLabel); - int ret = serviceImpl.appSetupNamespace(creds, appName, appProcessLabel, privilegeStatusVector, enabledSharedRO, pkgName); + Deserialization::Deserialize(buffer, appProcessLabel); + int ret = serviceImpl.appSetupNamespace(creds, appProcessLabel, privilegeStatusVector); Serialization::Serialize(send, ret); if (ret == SECURITY_MANAGER_SUCCESS) - Serialization::Serialize(send, privilegeStatusVector, pkgName, static_cast<int>(enabledSharedRO)); + Serialization::Serialize(send, privilegeStatusVector); } void Service::processAppCleanNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds) @@ -507,4 +494,15 @@ void Service::processAppCleanNamespace(MessageBuffer &buffer, MessageBuffer &sen Serialization::Serialize(send, ret); } +void Service::processGetAppInfo(MessageBuffer &buffer, MessageBuffer &send) +{ + std::string appName, pkgName, label; + bool enabledSharedRO; + Deserialization::Deserialize(buffer, appName); + int ret = serviceImpl.getAppInfo(appName, label, pkgName, enabledSharedRO); + Serialization::Serialize(send, ret); + if (ret == SECURITY_MANAGER_SUCCESS) + Serialization::Serialize(send, label, pkgName, static_cast<int>(enabledSharedRO)); +} + } // namespace SecurityManager |