Store group ids in a new configuartion file to avoid calculating it every time.
Those are written in $POLICY_PATH/group-id.list when policy rpm is installed.
These changes will speed up about 10 times for calulating group ids.
Change-Id: I0d71a44fdb7513a1c63c107062bfbe344b6889e8
Requires(post): cyad
Requires(post): sqlite
Requires(post): tizen-platform-config-tools
+Requires(post): security-config
%description policy
Set of security rules that constitute security policy in the system
%post policy
%{_datadir}/%{name}/policy/update.sh
+%{_datadir}/%{name}/policy/update_group_id_list.sh
%{_bindir}/security-manager-policy-reload
%post -n security-manager-tests
FILE(GLOB USERTYPE_POLICY_FILES usertype-*.profile)
CONFIGURE_FILE(security-manager-policy-reload.in security-manager-policy-reload @ONLY)
+CONFIGURE_FILE(update_group_id_list.sh.in update_group_id_list.sh @ONLY)
SET(PRIV_MAPPING_TEMPLATE_FILES
"priv-rules-default-template.smack")
INSTALL(PROGRAMS "update.sh" DESTINATION ${POLICY_INSTALL_DIR})
INSTALL(DIRECTORY "updates" USE_SOURCE_PERMISSIONS DESTINATION ${POLICY_INSTALL_DIR})
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/security-manager-policy-reload DESTINATION ${BIN_INSTALL_DIR})
+INSTALL(PROGRAMS "update_group_id_list.sh" DESTINATION ${POLICY_INSTALL_DIR})
# FOTA updater
INSTALL(FILES 241.security-manager.policy-update.sh DESTINATION ${FOTA_DIR})
--- /dev/null
+#!/bin/sh -e
+
+#
+# Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+#
+# This file is licensed under the terms of MIT License or the Apache License
+# Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
+# See the LICENSE file or the notice below for Apache License Version 2.0
+# details.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+POLICY_PATH=@POLICY_INSTALL_DIR@
+PRIVILEGE_GROUP_MAPPING=$POLICY_PATH/privilege-group.list
+PRIVILEGE_SYSTEMD_LIST=$POLICY_PATH/privilege-managed-by-systemd-for-daemons.list
+GROUP_LIST=$POLICY_PATH/group-id.list
+
+# Init group ID list file. If failed, script will be terminated. (In case of RO mount case)
+cat /dev/null > $GROUP_LIST
+
+# Create group ID lists into $GROUP_LIST.
+grep -v '^#' "$PRIVILEGE_GROUP_MAPPING" |
+while read privilege group
+do
+ gid=$(getent group "$group" | cut -d ":" -f3)
+ if [ "$(grep -x $privilege $PRIVILEGE_SYSTEMD_LIST)" == "" ]; then
+ echo "common" "$gid" >> $GROUP_LIST
+ else
+ echo "systemd_managed" "$gid" >> $GROUP_LIST
+ fi
+done
+
/* 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_SYSTEMD_LIST_FILE POLICY_INSTALL_DIR "/privilege-managed-by-systemd-for-daemons.list"
+#define GROUP_ID_FILE POLICY_INSTALL_DIR "/group-id.list"
#define SKEL_DIR "/etc/skel"
#endif
// Group operations
-void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges = NULL);
+void loadGroups(std::vector<gid_t> &vgroups, bool is_nss = false);
int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count);
-// Loading list of privileges that have GIDs managed by systemd for inter-daemon access control
-void loadSystemdManagedPrivileges(std::vector<std::string> &privileges);
-
// Pointer
template<typename T>
std::unique_ptr<T> makeUnique(T *ptr)
LogDebug("Execution of " << m_locationStr << " took " << sec << " seconds");
}
-void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges)
+void loadGroups(std::vector<gid_t> &vgroups, bool is_nss)
{
- auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read();
+ auto groupsMapData = ConfigFile(GROUP_ID_FILE).read();
for (auto &groupsMapEntry : groupsMapData) {
if (groupsMapEntry.size() != 2)
continue;
-
- const std::string &groupName = groupsMapEntry[1];
- std::vector<char> buf(1024);
- group *result = nullptr;
- group grp;
-
- for (;;) {
- int ret = TEMP_FAILURE_RETRY(getgrnam_r(groupName.c_str(), &grp, buf.data(), buf.size(), &result));
- if (ret == ERANGE) {
- buf.resize(buf.size() * 2);
- continue;
- }
- if (result == nullptr && ret == 0)
- ret = ENOENT;
-
- if (ret != 0) {
- LogError("Cannot map group " + groupName + " to gid");
- throw std::system_error(ret, std::system_category(), "getgrnam_r() failed");
- }
- break;
- }
- vgroups.push_back(result->gr_gid);
- if (privileges)
- privileges->emplace_back(std::move(groupsMapEntry[0]));
- }
-}
-
-void loadSystemdManagedPrivileges(std::vector<std::string> &privileges)
-{
- auto groupsMapData = ConfigFile(PRIVILEGE_SYSTEMD_LIST_FILE).read();
- for (auto &privEntry : groupsMapData) {
- if (privEntry.size() != 1)
- continue;
- privileges.emplace_back(std::move(privEntry[0]));
+ if (!is_nss || (is_nss && !groupsMapEntry[0].compare("common")))
+ vgroups.push_back(std::stoi(groupsMapEntry[1]));
}
}
{
using namespace SecurityManager;
return try_catch([&]() -> int {
- std::vector<gid_t> vgroups, vdaemongroups;
- std::vector<std::string> privileges;
- loadGroups(vgroups, &privileges);
- if (vgroups.size() != privileges.size())
- return SECURITY_MANAGER_ERROR_UNKNOWN; // this should not happen
- std::vector<std::string> systemdPrivileges;
- loadSystemdManagedPrivileges(systemdPrivileges);
- for (unsigned i = 0; i < privileges.size(); ++i) {
- bool skip = false;
- for (auto systemPriv: systemdPrivileges)
- if (privileges[i] == systemPriv) {
- skip = true;
- break;
- }
- if (!skip)
- vdaemongroups.push_back(vgroups[i]);
- }
- return group_vector_to_array(vdaemongroups, &groups, &groups_count);
+ std::vector<gid_t> vgroups;
+ loadGroups(vgroups, true);
+ return group_vector_to_array(vgroups, &groups, &groups_count);
});
-
}
} // namespace anonymous
size_t groups_count = 1;
BOOST_REQUIRE_NO_THROW(group_vector_to_array(vgroups, &groups, &groups_count));
BOOST_REQUIRE_MESSAGE(!groups && !groups_count, "Invalid output from group_vector_to_array");
- BOOST_REQUIRE_NO_THROW(loadGroups(vgroups, &privileges));
+ BOOST_REQUIRE_NO_THROW(loadGroups(vgroups));
// current configuration has some groups and some privileges
- BOOST_REQUIRE_MESSAGE(vgroups.size() > 0 && privileges.size() == vgroups.size(),
- "Invalid output from loadGroups");
+ BOOST_REQUIRE_MESSAGE(vgroups.size() > 0, "Invalid output from loadGroups");
BOOST_REQUIRE_NO_THROW(group_vector_to_array(vgroups, &groups, &groups_count));
auto gPtr2 = makeUnique(groups, free);
BOOST_REQUIRE_MESSAGE(groups, "NULL returned from group_vector_to_array");
BOOST_REQUIRE_MESSAGE(t > 0, "Invalid monotonic time value");
}
-POSITIVE_TEST_CASE(T289_loadSystemdManagedPrivileges)
-{
- std::vector<std::string> privs;
- BOOST_REQUIRE_NO_THROW(loadSystemdManagedPrivileges(privs));
-}
-
-NEGATIVE_TEST_CASE(T290_creds)
+NEGATIVE_TEST_CASE(T289_creds)
{
BOOST_REQUIRE_THROW(Credentials::getCredentialsFromSocket(-1), Credentials::Exception::SocketError);
}
-NEGATIVE_TEST_CASE(T291_creds)
+NEGATIVE_TEST_CASE(T290_creds)
{
BOOST_REQUIRE_THROW(Credentials::getCredentialsFromFd(-1), Credentials::Exception::FdError);
}
-POSITIVE_TEST_CASE(T292_tzplatform_config)
+POSITIVE_TEST_CASE(T291_tzplatform_config)
{
TizenPlatformConfig cfg(0);
BOOST_REQUIRE_NO_THROW(cfg.ctxMakePath(
"/just a string 1/", "/just a string 2/", "/just a string 3/"));
}
-POSITIVE_TEST_CASE(T293_exception_class)
+POSITIVE_TEST_CASE(T292_exception_class)
{
Exception e("path", "function", 1, "message");
std::string s = Exception::KnownExceptionToString(e);