Optimize nss plugin memory usage 88/209388/12
authorTomasz Swierczek <t.swierczek@samsung.com>
Fri, 5 Jul 2019 05:21:11 +0000 (07:21 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 12 Jul 2019 14:07:06 +0000 (14:07 +0000)
Made the nss module not linked with commons or client library.
Using security-manager client library in nss module caused
additional memory usage by private data in each loaded libaries
out of which most were not needed for nss (smack, pcap, procps, rt,
sqlite, cynara-*, security-privilege-manager, mount, crypt, blkid,
pkgmgr_parser, vconf, minizip, pcre, uuid, xml2, gio, z, buxton2,
lzma, gmodule, resolv, ffi, tzplatformconfig, dlog).

Linking with dlog & tzplatformconfig left only in debug mode.

To test it, use "gdb id", break point on getgrgid, measure change of PSS after
finishing the function execution with vs. without the patch.

The PSS value of id process should go down by approx. 0.4 - 0.5 MB
(depending on the system load & number of processes).

Change-Id: If2cede89885320ea83ca79fd54770a7ea24d87d8

23 files changed:
CMakeLists.txt
src/client/CMakeLists.txt
src/client/client-common.cpp
src/client/client-label-monitor.cpp
src/client/client-offline.cpp
src/client/client-security-manager-internal.cpp [new file with mode: 0644]
src/client/client-security-manager.cpp
src/client/include/client-common.h [deleted file]
src/client/include/client-security-manager-internal.h [new file with mode: 0644]
src/cmd/security-manager-cmd.cpp
src/common/CMakeLists.txt
src/common/db-config.cpp [moved from src/common/config.cpp with 75% similarity]
src/common/include/config.h
src/common/include/db-config.h [new file with mode: 0644]
src/common/include/privilege_db.h
src/common/include/utils.h
src/common/utils.cpp
src/nss/CMakeLists.txt
src/nss/nss_securitymanager.cpp
src/server/rules-loader/security-manager-rules-loader.cpp
test/CMakeLists.txt
test/privilege_db_fixture.cpp
test/test_privilege_db_migration.cpp

index 4e794c6..d6c8416 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2011 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");
 #    you may not use this file except in compliance with the License.
@@ -73,18 +73,6 @@ ADD_DEFINITIONS("-DASKUSER_ENABLED")
 OPTION(DPL_WITH_DLOG "DPL DLOG backend" ON)
 OPTION(DPL_WITH_SYSTEMD_JOURNAL "DPL systemd-journal backend" OFF)
 
-IF(DPL_WITH_DLOG)
-    ADD_DEFINITIONS("-DDPL_DLOG_ENABLED")
-ENDIF(DPL_WITH_DLOG)
-
-IF(DPL_WITH_SYSTEMD_JOURNAL)
-    ADD_DEFINITIONS("-DDPL_SYSTEMD_JOURNAL_ENABLED")
-ENDIF(DPL_WITH_SYSTEMD_JOURNAL)
-
-IF(DB_LOGS)
-    ADD_DEFINITIONS("-DDB_LOGS")
-ENDIF(DB_LOGS)
-
 ADD_DEFINITIONS("-DBUILD_TYPE_${CMAKE_BUILD_TYPE}")
 
 SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/src/include)
@@ -102,9 +90,9 @@ SET(TARGET_CLIENT "security-manager-client")
 SET(TARGET_COMMON "security-manager-commons")
 SET(TARGET_CMD    "security-manager-cmd")
 SET(TARGET_CLEANUP "security-manager-cleanup")
-SET(TARGET_NSS     "security-manager-nss")
 SET(TARGET_LOADER  "security-manager-rules-loader")
 SET(TARGET_TEST_LOADER "security-manager-test-rules-loader")
+SET(TARGET_NSS     "security-manager-nss")
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(pc)
@@ -112,3 +100,28 @@ ADD_SUBDIRECTORY(systemd)
 ADD_SUBDIRECTORY(db)
 ADD_SUBDIRECTORY(policy)
 ADD_SUBDIRECTORY(test)
+
+SET(LOG_TARGET_LIST ${TARGET_SERVER}
+                    ${TARGET_CLIENT}
+                    ${TARGET_COMMON}
+                    ${TARGET_CMD}
+                    ${TARGET_CLEANUP}
+                    ${TARGET_LOADER}
+                    ${TARGET_TEST_LOADER})
+
+# NSS target doesn't get ANY logs by design in release mode
+IF(CMAKE_BUILD_TYPE MATCHES "DEBUG")
+    LIST(APPEND ${LOG_TARGET_LIST} ${TARGET_NSS})
+ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG")
+
+FOREACH(TARGET_NAME ${LOG_TARGET_LIST})
+    IF(DPL_WITH_DLOG)
+        TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DPL_DLOG_ENABLED)
+    ENDIF(DPL_WITH_DLOG)
+    IF(DPL_WITH_SYSTEMD_JOURNAL)
+        TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DPL_SYSTEMD_JOURNAL_ENABLED)
+    ENDIF(DPL_WITH_SYSTEMD_JOURNAL)
+    IF(DB_LOGS)
+        TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DB_LOGS)
+    ENDIF(DB_LOGS)
+ENDFOREACH(TARGET_NAME)
index 8862ca0..d99027b 100644 (file)
@@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES(
 
 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
index 16050f5..3ac353b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
  * @brief       This file is implementation of client-common functions.
  */
 
-#include <iostream>
-#include <cxxabi.h>
-#include <stdexcept>
-#include <system_error>
-
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/smack.h>
-#include <sys/xattr.h>
-#include <linux/xattr.h>
-#include <unistd.h>
-
 #include <dpl/log/log.h>
-#include <dpl/serialization.h>
 #include <dpl/singleton.h>
 
-#include <message-buffer.h>
-
-#include <protocols.h>
-
 namespace {
 
 void securityClientEnableLogSystem(void) {
@@ -55,36 +35,6 @@ void securityClientEnableLogSystem(void) {
 
 } // namespace anonymous
 
-namespace SecurityManager {
-
-int try_catch(const std::function<int()>& func)
-{
-    try {
-        return func();
-    } catch (abi::__forced_unwind &) {
-        throw;
-    } catch (const Exception &e) {
-        LogError("SecurityManager::Exception " << e.DumpToString());
-        std::cerr << "SecurityManager::Exception " << e.DumpToString() << std::endl;
-    } catch (const std::bad_alloc &e) {
-        LogError("Memory allocation failed: " << e.what());
-        std::cerr << "Memory allocation failed: " << e.what() << std::endl;
-        return SECURITY_MANAGER_ERROR_MEMORY;
-    } catch (const std::system_error &e) {
-        LogError("STD system_error: " <<  e.code() << "-" << e.what());
-        std::cerr << "STD system_error: " <<  e.code() << "-" << e.what() << std::endl;
-    } catch (const std::exception &e) {
-        LogError("STD exception " << e.what());
-        std::cerr << "STD exception " << e.what() << std::endl;
-    } catch (...) {
-        LogError("Unknown exception occurred");
-        std::cerr << "Unknown exception occurred" << std::endl;
-    }
-    return SECURITY_MANAGER_ERROR_UNKNOWN;
-}
-
-} // namespace SecurityMANAGER
-
 static void init_lib(void) __attribute__ ((constructor));
 static void init_lib(void)
 {
index 757be3a..10a5687 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -40,7 +40,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <client-common.h>
 #include <config.h>
 #include <dpl/log/log.h>
 #include <dpl/errno_string.h>
index b8f39e8..87420d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -22,7 +22,7 @@
  * @brief       Helper class for client "off-line" mode detection
  */
 
-#include <client-common.h>
+#include <utils.h>
 #include <client-offline.h>
 #include <client-request.h>
 #include <dpl/log/log.h>
diff --git a/src/client/client-security-manager-internal.cpp b/src/client/client-security-manager-internal.cpp
new file mode 100644 (file)
index 0000000..b0c807c
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  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
+ *
+ *  Security Manager NSS library
+ */
+/*
+ * @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);
+    });
+}
index 8c2a4f7..3419094 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -54,8 +54,8 @@
 #include <dpl/exception.h>
 #include <smack-check.h>
 #include <smack-labels.h>
-#include <client-common.h>
 #include <client-request.h>
+#include <client-security-manager-internal.h>
 #include <service_impl.h>
 #include <check-proper-drop.h>
 #include <utils.h>
@@ -1307,95 +1307,16 @@ void security_manager_policy_levels_free(char **levels, size_t levels_count)
     delete[] levels;
 }
 
-static void loadGroups(std::vector<gid_t> &vgroups)
-{
-    auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read();
-    for (const 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);
-    }
-}
-
-static int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count)
-{
-    if (vgroups.empty()) {
-        *groups_count = 0;
-        *groups = NULL;
-        return SECURITY_MANAGER_SUCCESS;
-    }
-
-    size_t size = vgroups.size() * sizeof(gid_t);
-    *groups = static_cast<gid_t*>(malloc(size));
-    if (*groups == nullptr)
-        return SECURITY_MANAGER_ERROR_MEMORY;
-
-    *groups_count = vgroups.size();
-    memcpy(*groups, vgroups.data(), size);
-
-    return SECURITY_MANAGER_SUCCESS;
-}
-
 SECURITY_MANAGER_API
 int security_manager_groups_get(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);
-    });
+    return security_manager_groups_get_internal(groups, groups_count);
 }
 
 SECURITY_MANAGER_API
 int security_manager_groups_get_for_user(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);
-    });
+    return security_manager_groups_get_for_user_internal(uid, groups, groups_count);
 }
 
 static lib_retcode get_app_and_pkg_id_from_smack_label(
diff --git a/src/client/include/client-common.h b/src/client/include/client-common.h
deleted file mode 100644 (file)
index e9ff18e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Contact: Rafal Krypa <r.krypa@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-common.h
- * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
- * @version     1.0
- * @brief       This file constains implementation of common types
- *              used in security manager.
- */
-
-#pragma once
-
-#include <functional>
-
-#define SECURITY_MANAGER_API __attribute__((visibility("default")))
-
-namespace SecurityManager {
-
-/*
- * Decorator function that performs frequently repeated exception handling in
- * SS client API functions. Accepts lambda expression as an argument.
- */
-int try_catch(const std::function<int()>& func);
-
-} // namespace SecurityManager
diff --git a/src/client/include/client-security-manager-internal.h b/src/client/include/client-security-manager-internal.h
new file mode 100644 (file)
index 0000000..e6c3578
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  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
+ *
+ *  Security Manager NSS library
+ */
+/*
+ * @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);
index 89faebf..c200813 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -39,6 +39,7 @@
 #include <boost/exception/diagnostic_information.hpp>
 
 #include <config.h>
+#include <db-config.h>
 #include <filesystem.h>
 
 namespace po = boost::program_options;
index 6222ba6..2d1422a 100644 (file)
@@ -49,11 +49,11 @@ SET(COMMON_SOURCES
     ${DPL_PATH}/db/src/naive_synchronization_object.cpp
     ${DPL_PATH}/db/src/sql_connection.cpp
     ${COMMON_PATH}/channel.cpp
-    ${COMMON_PATH}/config.cpp
     ${COMMON_PATH}/config-file.cpp
     ${COMMON_PATH}/connection.cpp
     ${COMMON_PATH}/credentials.cpp
     ${COMMON_PATH}/cynara.cpp
+    ${COMMON_PATH}/db-config.cpp
     ${COMMON_PATH}/filesystem.cpp
     ${COMMON_PATH}/file-lock.cpp
     ${COMMON_PATH}/permissible-set.cpp
similarity index 75%
rename from src/common/config.cpp
rename to src/common/db-config.cpp
index 17d3641..23ac592 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *  Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
- *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *  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.
  *  limitations under the License
  */
 /*
- * @file        config.cpp
- * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @file        db-config.cpp
+ * @author      Tomasz Swierczek <t.swierczek@samsung.com>
  * @version     1.0
- * @brief       Setting values of Configuration options
+ * @brief       Configuration options for DB - implementation
  */
 
-#include <config.h>
+#include <db-config.h>
+#include <tzplatform-config.h>
 
 namespace SecurityManager {
 
index 230f15b..24e0eac 100644 (file)
 
 #pragma once
 
-#include <string>
-#include <tzplatform-config.h>
-
-namespace SecurityManager {
-
-namespace Config {
-
-std::string getPrivilegeDbPath();
-std::string getPrivilegeDbFallbackPath();
-
-};
-
-} /* namespace SecurityManager */
-
-// If database initialization fails, restoration to a fallback snapshot is
-// attempted. If the restoration succeeds, a file flag is created to notify
-// other system components.
-// For database placed in "$f" the filename is ("$f" DB_RECOVERED_SUFFIX).
-#define DB_RECOVERED_SUFFIX "-recovered"
-#define DB_JOURNAL_SUFFIX "-journal"
-
-#define DB_OK_MARKER "/tmp/.security-manager.db.ok"
-
-
 /* Service name */
 #define SERVICE_NAME                "security-manager"
 
diff --git a/src/common/include/db-config.h b/src/common/include/db-config.h
new file mode 100644 (file)
index 0000000..e4f0268
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  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        db-config.h
+ * @author      Tomasz Swierczek
+ * @version     1.0
+ * @brief       Definition of configuration options for DB
+ */
+
+#pragma once
+
+#include <string>
+
+namespace SecurityManager {
+
+namespace Config {
+
+std::string getPrivilegeDbPath();
+std::string getPrivilegeDbFallbackPath();
+
+};
+
+} /* namespace SecurityManager */
+
+// If database initialization fails, restoration to a fallback snapshot is
+// attempted. If the restoration succeeds, a file flag is created to notify
+// other system components.
+// For database placed in "$f" the filename is ("$f" DB_RECOVERED_SUFFIX).
+#define DB_RECOVERED_SUFFIX "-recovered"
+#define DB_JOURNAL_SUFFIX "-journal"
+
+#define DB_OK_MARKER "/tmp/.security-manager.db.ok"
index 8e20650..b84aa04 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * security-manager, database access
  *
- * Copyright (c) 2000 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -41,6 +41,7 @@
 #include <vector>
 
 #include <config.h>
+#include <db-config.h>
 #include <dpl/db/sql_connection.h>
 #include <utils.h>
 #include "security-manager-types.h"
index a1d0514..60e0200 100644 (file)
 
 #include <credentials.h>
 
+#define SECURITY_MANAGER_API __attribute__((visibility("default")))
+
 namespace SecurityManager {
 
+/*
+ * Decorator function that performs frequently repeated exception handling in
+ * SS client API functions. Accepts lambda expression as an argument.
+ */
+int try_catch(const std::function<int()>& func);
+
 time_t monotonicNow();
 
 // Used for measuring function/method/scope execution time
@@ -57,6 +65,10 @@ private:
 #define LOG_EXECUTION_TIME(location, creds)    do {} while (0)
 #endif
 
+// Group operations
+void loadGroups(std::vector<gid_t> &vgroups);
+int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count);
+
 // Pointer
 template<typename T>
 std::unique_ptr<T> makeUnique(T *ptr)
index fb215ed..32b06d6 100644 (file)
  * @brief       Implementation of utility functions
  */
 
+#include <iostream>
+#include <cxxabi.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <stdexcept>
+#include <system_error>
 #include <utils.h>
 
+#include <config.h>
+#include <config-file.h>
+
 #include <dpl/log/log.h>
 #include <dpl/errno_string.h>
+#include <protocols.h>
+
+#include <security-manager-types.h>
 
 namespace SecurityManager {
 
+int try_catch(const std::function<int()>& func)
+{
+    try {
+        return func();
+    } catch (abi::__forced_unwind &) {
+        throw;
+    } catch (const Exception &e) {
+        LogError("SecurityManager::Exception " << e.DumpToString());
+        std::cerr << "SecurityManager::Exception " << e.DumpToString() << std::endl;
+    } catch (const std::bad_alloc &e) {
+        LogError("Memory allocation failed: " << e.what());
+        std::cerr << "Memory allocation failed: " << e.what() << std::endl;
+        return SECURITY_MANAGER_ERROR_MEMORY;
+    } catch (const std::system_error &e) {
+        LogError("STD system_error: " <<  e.code() << "-" << e.what());
+        std::cerr << "STD system_error: " <<  e.code() << "-" << e.what() << std::endl;
+    } catch (const std::exception &e) {
+        LogError("STD exception " << e.what());
+        std::cerr << "STD exception " << e.what() << std::endl;
+    } catch (...) {
+        LogError("Unknown exception occurred");
+        std::cerr << "Unknown exception occurred" << std::endl;
+    }
+    return SECURITY_MANAGER_ERROR_UNKNOWN;
+}
+
 time_t monotonicNow() {
     struct timespec now;
     if (clock_gettime(CLOCK_MONOTONIC_RAW, &now) == -1) {
@@ -65,4 +103,54 @@ ScopedTimeStamper::~ScopedTimeStamper()
     LogDebug("Execution of " << m_locationStr << " took " << sec << " seconds");
 }
 
+void loadGroups(std::vector<gid_t> &vgroups)
+{
+    auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read();
+    for (const 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);
+    }
+}
+
+int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count)
+{
+    if (vgroups.empty()) {
+        *groups_count = 0;
+        *groups = NULL;
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
+    size_t size = vgroups.size() * sizeof(gid_t);
+    *groups = static_cast<gid_t*>(malloc(size));
+    if (*groups == nullptr)
+        return SECURITY_MANAGER_ERROR_MEMORY;
+
+    *groups_count = vgroups.size();
+    memcpy(*groups, vgroups.data(), size);
+
+    return SECURITY_MANAGER_SUCCESS;
+}
+
 } /* namespace SecurityManager */
index 446002d..29f8556 100644 (file)
@@ -3,6 +3,10 @@ SET(NSS_PLUGIN_VERSION ${NSS_PLUGIN_VERSION_MAJOR}.0.0)
 
 SET(LIBRARY_FILE_NAME "nss_securitymanager")
 
+IF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG)
+    PKG_CHECK_MODULES(NSS_DLOG_DEP REQUIRED dlog libtzplatform-config)
+ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG)
+
 INCLUDE_DIRECTORIES(
     ${INCLUDE_PATH}
     ${CLIENT_PATH}/include
@@ -10,12 +14,37 @@ INCLUDE_DIRECTORIES(
     ${DPL_PATH}/core/include
     ${DPL_PATH}/log/include
     ${COMMON_PATH}/include
+    ${NSS_DLOG_DEP_INCLUDE_DIRS}
     )
 
 SET(NSS_SOURCES
     ${NSS_PATH}/nss_securitymanager.cpp
+    ${DPL_PATH}/log/src/abstract_log_provider.cpp
+    ${DPL_PATH}/log/src/log.cpp
+    ${DPL_PATH}/log/src/old_style_log_provider.cpp
+    ${DPL_PATH}/core/src/assert.cpp
+    ${DPL_PATH}/core/src/binary_queue.cpp
+    ${DPL_PATH}/core/src/colors.cpp
+    ${DPL_PATH}/core/src/exception.cpp
+    ${DPL_PATH}/core/src/noncopyable.cpp
+    ${DPL_PATH}/core/src/serialization.cpp
+    ${DPL_PATH}/core/src/errno_string.cpp
+    ${COMMON_PATH}/channel.cpp
+    ${COMMON_PATH}/config-file.cpp
+    ${COMMON_PATH}/connection.cpp
+    ${COMMON_PATH}/filesystem.cpp
+    ${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)
+    SET(NSS_SOURCES
+        ${NSS_SOURCES}
+        ${DPL_PATH}/log/src/dlog_log_provider.cpp)
+ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG)
+
 ADD_LIBRARY(${TARGET_NSS} SHARED ${NSS_SOURCES})
 
 SET_TARGET_PROPERTIES(${TARGET_NSS}
@@ -26,9 +55,6 @@ SET_TARGET_PROPERTIES(${TARGET_NSS}
         VERSION ${NSS_PLUGIN_VERSION}
     )
 
-TARGET_LINK_LIBRARIES(${TARGET_NSS}
-    ${TARGET_CLIENT}
-    ${TARGET_COMMON}
-    )
+TARGET_LINK_LIBRARIES(${TARGET_NSS} ${NSS_DLOG_DEP_LIBRARIES} "-z defs")
 
 INSTALL(TARGETS ${TARGET_NSS} LIBRARY DESTINATION ${LIB_INSTALL_DIR} NAMELINK_SKIP)
index 4c7eef3..873622d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
 #include <sys/types.h>
 #include <pwd.h>
 #include <nss.h>
+#include <cxxabi.h>
 #include <unistd.h>
 #include <cstdlib>
-
 #include <vector>
 #include <algorithm>
 
-#include <security-manager.h>
+#include <client-security-manager-internal.h>
+#include <dpl/log/log.h>
+#include <dpl/singleton.h>
+#include <security-manager-types.h>
 #include <utils.h>
 
 namespace {
@@ -87,6 +90,9 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou
         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)
@@ -106,11 +112,11 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou
 
         gid_t *groups = NULL;
         size_t groupsCount;
-        ret = security_manager_groups_get_for_user(pwnam->pw_uid, &groups, &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(&groups, &groupsCount);
+            ret = security_manager_groups_get_internal(&groups, &groupsCount);
         }
 
         if (ret == SECURITY_MANAGER_ERROR_MEMORY) {
index 748f186..45d32c1 100644 (file)
@@ -33,6 +33,7 @@
 #include <tzplatform_config.h>
 
 #include <config.h>
+#include <db-config.h>
 #include <testconfig.h>
 #include <utils.h>
 
index 4efb856..888162f 100644 (file)
@@ -72,8 +72,8 @@ SET(SM_TESTS_SOURCES
     ${DPL_PATH}/log/src/abstract_log_provider.cpp
     ${DPL_PATH}/log/src/log.cpp
     ${DPL_PATH}/log/src/old_style_log_provider.cpp
-    ${PROJECT_SOURCE_DIR}/src/common/config.cpp
     ${PROJECT_SOURCE_DIR}/src/common/config-file.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/db-config.cpp
     ${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp
     ${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp
     ${PROJECT_SOURCE_DIR}/src/common/smack-check.cpp
@@ -100,7 +100,7 @@ SET(SM_PERFORMANCE_TESTS_SOURCES
     ${DPL_PATH}/log/src/abstract_log_provider.cpp
     ${DPL_PATH}/log/src/log.cpp
     ${DPL_PATH}/log/src/old_style_log_provider.cpp
-    ${PROJECT_SOURCE_DIR}/src/common/config.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/db-config.cpp
     ${PROJECT_SOURCE_DIR}/src/common/config-file.cpp
     #${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp
     ${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp
index 4643e62..4b352f7 100644 (file)
@@ -29,6 +29,7 @@
 #include <boost/test/results_reporter.hpp>
 
 #include <config.h>
+#include <db-config.h>
 #include <filesystem.h>
 #include <testconfig.h>
 #include <utils.h>
index 56b6a64..7b1a522 100644 (file)
@@ -23,6 +23,7 @@
 #include <boost/test/unit_test_monitor.hpp>
 
 #include <config.h>
+#include <db-config.h>
 #include <filesystem.h>
 #include <testconfig.h>
 #include "privilege_db.h"