INSTALL(FILES "author-rules-template.smack" DESTINATION ${POLICY_DIR})
INSTALL(FILES "privilege-group.list" DESTINATION ${POLICY_DIR})
INSTALL(FILES "privilege-mount.list" DESTINATION ${POLICY_DIR})
+INSTALL(FILES "privilege-managed-by-systemd-for-daemons.list" DESTINATION ${POLICY_DIR})
INSTALL(PROGRAMS "update.sh" DESTINATION ${POLICY_DIR})
INSTALL(DIRECTORY "updates" USE_SOURCE_PERMISSIONS DESTINATION ${POLICY_DIR})
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/security-manager-policy-reload DESTINATION ${BIN_INSTALL_DIR})
--- /dev/null
+# List of privileges that are also used for inter-daemon access control.
+# That access control is done using systemd SupplementaryGroups configuration and DBus GID-based policy,
+# so enforcement of these privileges cannot be configured for a new process using nss plugin
+# (which assigns associated GIDs). Also, Cynara policy for User, System & System::Privileged
+# Cynara clients has to be configured with default "DENY".
+#
+# This file will not be needed anymore once all privileges for daemons will be managed by systemd
+# and not by Security FW (no need for nss, Cynara policy for daemon labels, etc.).
+#
+# Format:
+# - each line stores one privilege "<PRIVILEGE>"
+# - lines starting with '#' are ignored
+# - lines having more than 1 white-space separated items will be ignored too
+http://tizen.org/privilege/internal/sysadmin
+http://tizen.org/privilege/internal/livecoredump
PATH=/bin:/usr/bin:/sbin:/usr/sbin
POLICY_PATH=@POLICY_DIR@
PRIVILEGE_GROUP_MAPPING=$POLICY_PATH/privilege-group.list
+PRIVILEGE_SYSTEMD_LIST=$POLICY_PATH/privilege-managed-by-systemd-for-daemons.list
DB_FILE=`tzplatform-get TZ_SYS_DB | cut -d= -f2`/.security-manager.db
cyad --set-policy --bulk=-
done
-# Non-application programs get access to all privileges
+# Non-application programs get access to all privileges...
for client in User System System::Privileged
do
cyad --set-policy --bucket=MANIFESTS_GLOBAL --client="$client" --user="*" --privilege="*" --type=ALLOW
-# Non-application programs will have these privileges disabled in order NOT to get it automatically
- cyad --set-policy --bucket=MANIFESTS_GLOBAL --client="$client" --user="*" --privilege="http://tizen.org/privilege/internal/sysadmin" --type=DENY
- cyad --set-policy --bucket=MANIFESTS_GLOBAL --client="$client" --user="*" --privilege="http://tizen.org/privilege/internal/livecoredump" --type=DENY
+done
+
+# ...except these that have their GIDs managed by systemd
+grep -v '^#' "$PRIVILEGE_SYSTEMD_LIST" |
+while read privilege
+do
+ for client in User System System::Privileged
+ do
+ cyad --set-policy --bucket=MANIFESTS_GLOBAL --client="$client" --user="*" --privilege="$privilege" --type=DENY
+ done
done
# Root shell get access to all privileges
SET(CLIENT_SOURCES
${CLIENT_PATH}/client-security-manager.cpp
- ${CLIENT_PATH}/client-security-manager-internal.cpp
${CLIENT_PATH}/client-common.cpp
${CLIENT_PATH}/client-offline.cpp
${CLIENT_PATH}/client-label-monitor.cpp
+++ /dev/null
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Tomasz Swierczek <t.swierczek@samsung.com>
- *
- * 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
- */
-/*
- * @file client-security-manager-internal.cpp
- * @author Tomasz Swierczek <t.swierczek@samsung.com>
- * @version 1.0
- * @brief This file contains implementation of SM APIs needed to be linked separately into NSS module
- */
-
-#include <client-security-manager-internal.h>
-
-#include <grp.h>
-
-#include <client-request.h>
-#include <security-manager-types.h>
-#include <utils.h>
-
-int security_manager_groups_get_internal(gid_t **groups, size_t *groups_count)
-{
- using namespace SecurityManager;
- if (!groups || !groups_count)
- return SECURITY_MANAGER_ERROR_INPUT_PARAM;
- return try_catch([&]() -> int {
- std::vector<gid_t> vgroups;
- loadGroups(vgroups);
- return group_vector_to_array(vgroups, groups, groups_count);
- });
-}
-
-int security_manager_groups_get_for_user_internal(uid_t uid, gid_t **groups, size_t *groups_count)
-{
- using namespace SecurityManager;
- if (!groups || !groups_count)
- return SECURITY_MANAGER_ERROR_INPUT_PARAM;
-
- // Security manager does not manage platform system daemons
- // This 5000 value is defined only in this document:
- // https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy
- // TODO: Value 5000 should be defined in tizen-platform-config
-
- if (uid < 5000) {
- return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
- }
-
- return try_catch([&]() -> int {
- ClientRequest request(SecurityModuleCall::GROUPS_FOR_UID);
- if (request.send(uid).failed())
- return request.getStatus();
-
- std::vector<gid_t> vgroups;
- request.recv(vgroups);
-
- return group_vector_to_array(vgroups, groups, groups_count);
- });
-}
#include <smack-check.h>
#include <smack-labels.h>
#include <client-request.h>
-#include <client-security-manager-internal.h>
#include <service_impl.h>
#include <check-proper-drop.h>
#include <utils.h>
SECURITY_MANAGER_API
int security_manager_groups_get(gid_t **groups, size_t *groups_count)
{
- return security_manager_groups_get_internal(groups, groups_count);
+ using namespace SecurityManager;
+ if (!groups || !groups_count)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ return try_catch([&]() -> int {
+ std::vector<gid_t> vgroups;
+ loadGroups(vgroups);
+ return group_vector_to_array(vgroups, groups, groups_count);
+ });
}
SECURITY_MANAGER_API
int security_manager_groups_get_for_user(uid_t uid, gid_t **groups, size_t *groups_count)
{
- return security_manager_groups_get_for_user_internal(uid, groups, groups_count);
+ using namespace SecurityManager;
+ if (!groups || !groups_count)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
+ // Security manager does not manage platform system daemons
+ // This 5000 value is defined only in this document:
+ // https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy
+ // TODO: Value 5000 should be defined in tizen-platform-config
+
+ if (uid < 5000) {
+ return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+ }
+
+ return try_catch([&]() -> int {
+ ClientRequest request(SecurityModuleCall::GROUPS_FOR_UID);
+ if (request.send(uid).failed())
+ return request.getStatus();
+
+ std::vector<gid_t> vgroups;
+ request.recv(vgroups);
+
+ return group_vector_to_array(vgroups, groups, groups_count);
+ });
}
static lib_retcode get_app_and_pkg_id_from_smack_label(
+++ /dev/null
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Tomasz Swierczek <t.swierczek@samsung.com>
- *
- * 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
- */
-/*
- * @file client-security-manager-internal.h
- * @author Tomasz Swierczek <t.swierczek@samsung.com>
- * @version 1.0
- * @brief This file contains declaration of SM APIs needed to be linked separately into NSS module
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-int security_manager_groups_get_internal(gid_t **groups, size_t *groups_count);
-int security_manager_groups_get_for_user_internal(uid_t uid, gid_t **groups, size_t *groups_count);
/*
- * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
/* Policy files */
#define PRIVILEGE_GROUP_LIST_FILE POLICY_DIR "/privilege-group.list"
#define PRIVILEGE_MOUNT_LIST_FILE POLICY_DIR "/privilege-mount.list"
+#define PRIVILEGE_SYSTEMD_LIST_FILE POLICY_DIR "/privilege-managed-by-systemd-for-daemons.list"
#define SKEL_DIR "/etc/skel"
/*
- * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#endif
// Group operations
-void loadGroups(std::vector<gid_t> &vgroups);
+void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges = NULL);
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)
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Tomasz Swierczek <t.swierczek@samsung.com>
*
LogDebug("Execution of " << m_locationStr << " took " << sec << " seconds");
}
-void loadGroups(std::vector<gid_t> &vgroups)
+void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges)
{
auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read();
- for (const auto &groupsMapEntry : groupsMapData) {
+ for (auto &groupsMapEntry : groupsMapData) {
if (groupsMapEntry.size() != 2)
continue;
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]));
}
}
/*
- * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
int security_manager_groups_get(gid_t **groups, size_t *groups_count);
/**
- * This function returns array of groups bound to privileges, the process
- * run by particular user should get.
+ * This function returns maximum array of groups bound to privileges that
+ * the application run by particular user is able to get.
*
* Caller needs to free memory allocated for the list using free().
*
${COMMON_PATH}/protocols.cpp
${COMMON_PATH}/message-buffer.cpp
${COMMON_PATH}/utils.cpp
- ${CLIENT_PATH}/client-security-manager-internal.cpp
)
IF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG)
/*
- * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#include <cerrno>
#include <cstddef>
#include <sys/types.h>
-#include <pwd.h>
#include <nss.h>
#include <cxxabi.h>
#include <unistd.h>
#include <vector>
#include <algorithm>
-#include <client-security-manager-internal.h>
+#include <config-file.h>
#include <dpl/log/log.h>
#include <dpl/singleton.h>
#include <security-manager-types.h>
namespace {
-size_t getBufferSize()
+int security_manager_groups_get_for_daemons_internal(gid_t *&groups, size_t &groups_count)
{
- size_t max = 4096, tmp;
- max = max < (tmp = sysconf(_SC_GETPW_R_SIZE_MAX)) ? tmp : max;
- return max < (tmp = sysconf(_SC_GETGR_R_SIZE_MAX)) ? tmp : max;
+ 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);
+ });
+
}
-} // anonymous namespace
+} // namespace anonymous
extern "C" {
* | | - space not allocated by groupsp
*/
__attribute__((visibility("default")))
-enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t group_gid, long int *start,
+enum nss_status _nss_securitymanager_initgroups_dyn(const char */*user*/, gid_t group_gid, long int *start,
long int *size, gid_t **groupsp,
long int limit, int *errnop)
{
(void) group_gid;
int ret;
- const static size_t BUFFER_SIZE = getBufferSize();
- const static size_t MEMORY_LIMIT = BUFFER_SIZE << 3;
- std::vector<char> buffer(BUFFER_SIZE);
- passwd pwnambuffer;
- passwd *pwnam = NULL;
auto& logSystem = SecurityManager::Singleton<SecurityManager::Log::LogSystem>::Instance();
logSystem.SetTag("SECURITY_MANAGER_NSS");
- while (ERANGE == (ret = TEMP_FAILURE_RETRY(getpwnam_r(user, &pwnambuffer, buffer.data(), buffer.size(), &pwnam)))
- && buffer.size() < MEMORY_LIMIT)
- {
- buffer.resize(buffer.size() << 1);
- }
-
- if (ret == ERANGE) {
- *errnop = ENOMEM;
- return NSS_STATUS_UNAVAIL;
- }
-
- if (ret || pwnam == NULL) {
- *errnop = ENOENT;
- return NSS_STATUS_NOTFOUND;
- }
-
gid_t *groups = NULL;
size_t groupsCount;
- ret = security_manager_groups_get_for_user_internal(pwnam->pw_uid, &groups, &groupsCount);
-
- if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) {
- // If user is not managed by Security Manager, we want to apply all the groups
- ret = security_manager_groups_get_internal(&groups, &groupsCount);
- }
+ ret = security_manager_groups_get_for_daemons_internal(groups, groupsCount);
if (ret == SECURITY_MANAGER_ERROR_MEMORY) {
*errnop = ENOMEM;