Move smack files to new directory 96/64996/9
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 5 Apr 2016 18:35:53 +0000 (20:35 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 21 Apr 2016 16:03:04 +0000 (09:03 -0700)
All smack rules generated by security-manager will be merged to one
file. This will speed up start process as reading one big file is
much faster than opening and reading a lot of small ones.

The rules related with apps are loaded by security-manager-rules-loader
service after local-fs.target. Before local-fs.terget smack rules
related to user app are not required. We may load this rules in
service that is triggered after local-fs.target and improve systemd
start time.

Change-Id: I64c961b90ee84772815f41dceefa15b567399763

14 files changed:
CMakeLists.txt
migration/CMakeLists.txt [new file with mode: 0644]
migration/security-manager-migration.in [new file with mode: 0644]
packaging/security-manager.spec
src/common/CMakeLists.txt
src/common/filesystem.cpp [new file with mode: 0644]
src/common/include/filesystem-exception.h [new file with mode: 0644]
src/common/include/filesystem.h [new file with mode: 0644]
src/common/include/smack-rules.h
src/common/service_impl.cpp
src/common/smack-rules.cpp
src/dpl/core/include/dpl/fstream_accessors.h [new file with mode: 0644]
systemd/CMakeLists.txt
systemd/security-manager-rules-loader.service.in [new file with mode: 0644]

index 28790d8..1d9c1af 100644 (file)
@@ -26,6 +26,15 @@ PROJECT("security-manager")
 
 INCLUDE(FindPkgConfig)
 
+######################### let's setup directories #############################
+
+SET(LOCAL_STATE_DIR
+    "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALSTATEDIR}"
+    CACHE PATH
+    "Modifiable single-machine data directory")
+
+ADD_DEFINITIONS("-DLOCAL_STATE_DIR=\"${LOCAL_STATE_DIR}\"")
+
 ############################# compiler flags ##################################
 
 SET(CMAKE_C_FLAGS_PROFILING    "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE")
@@ -63,3 +72,4 @@ ADD_SUBDIRECTORY(pc)
 ADD_SUBDIRECTORY(systemd)
 ADD_SUBDIRECTORY(db)
 ADD_SUBDIRECTORY(policy)
+ADD_SUBDIRECTORY(migration)
diff --git a/migration/CMakeLists.txt b/migration/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0094aa6
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (c) 2016 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.
+#    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        CMakeLists.txt
+# @author      Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+# @brief       CMake for migration script
+#
+
+CONFIGURE_FILE(security-manager-migration.in security-manager-migration @ONLY)
+
+INSTALL(PROGRAMS
+    ${CMAKE_BINARY_DIR}/migration/security-manager-migration
+    DESTINATION
+    ${BIN_INSTALL_DIR}
+    )
+
+
+
diff --git a/migration/security-manager-migration.in b/migration/security-manager-migration.in
new file mode 100644 (file)
index 0000000..f08469c
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+SRC_PATH=/etc/smack/accesses.d
+DSC_PATH=@LOCAL_STATE_DIR@/security-manager/rules
+MRG_PATH=@LOCAL_STATE_DIR@/security-manager/rules-merged/rules.merged
+
+if [ -e $MRG_PATH ]; then
+    echo "No migration needed. File ${MRG_PATH} already exists."
+    exit 0
+fi
+
+echo "Running migration process"
+echo "Moving files from ${SRC_PATH} to ${DSC_PATH}"
+mv ${SRC_PATH}/app_* ${SRC_PATH}/pkg_* ${SRC_PATH}/author_* ${DSC_PATH}
+echo "Merging files from ${DSC_PATH} to ${MRG_PATH}"
+cat ${DSC_PATH}/* > ${MRG_PATH}
+echo "Migration process was finished"
+
index 34819da..97eec65 100755 (executable)
@@ -76,6 +76,7 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir}"
 %cmake . -DVERSION=%{version} \
         -DBIN_INSTALL_DIR=%{_bindir} \
         -DDB_INSTALL_DIR=%{TZ_SYS_DB} \
+        -DLOCAL_STATE_DIR=%{TZ_SYS_VAR} \
         -DSYSTEMD_INSTALL_DIR=%{_unitdir} \
         -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \
         -DCMAKE_VERBOSE_MAKEFILE=ON
@@ -90,8 +91,10 @@ cp LICENSE %{buildroot}%{_datadir}/license/libsecurity-manager-client
 
 mkdir -p %{buildroot}/%{_unitdir}/sockets.target.wants
 mkdir -p %{buildroot}/%{_unitdir}/sysinit.target.wants
+mkdir -p %{buildroot}/%{_unitdir}/basic.target.wants
 ln -s ../security-manager.socket %{buildroot}/%{_unitdir}/sockets.target.wants/security-manager.socket
 ln -s ../security-manager-cleanup.service %{buildroot}/%{_unitdir}/sysinit.target.wants/security-manager-cleanup.service
+ln -s ../security-manager-rules-loader.service %{buildroot}/%{_unitdir}/basic.target.wants/security-manager-rules-loader.service
 
 mkdir -p %{buildroot}/%{TZ_SYS_DB}
 touch %{buildroot}/%{TZ_SYS_DB}/.security-manager.db
@@ -111,6 +114,7 @@ fi
 
 if [ $1 = 2 ]; then
     # update
+    %{_bindir}/security-manager-migration
     systemctl restart security-manager.service
     %{_datadir}/security-manager/db/update.sh
 fi
@@ -140,15 +144,20 @@ fi
 %files -n security-manager
 %manifest security-manager.manifest
 %defattr(-,root,root,-)
+%attr(755,root,root) %{_bindir}/security-manager-migration
 %attr(755,root,root) %{_bindir}/security-manager
 %attr(755,root,root) %{_bindir}/security-manager-cmd
 %attr(755,root,root) %{_bindir}/security-manager-cleanup
 %attr(755,root,root) %{_sysconfdir}/gumd/useradd.d/50_security-manager-add.post
 %attr(755,root,root) %{_sysconfdir}/gumd/userdel.d/50_security-manager-remove.pre
+%dir %attr(700,root,root) %{TZ_SYS_VAR}/security-manager/rules
+%dir %attr(700,root,root) %{TZ_SYS_VAR}/security-manager/rules-merged
 
 %{_libdir}/libsecurity-manager-commons.so.*
 %attr(-,root,root) %{_unitdir}/security-manager.*
 %attr(-,root,root) %{_unitdir}/security-manager-cleanup.*
+%attr(-,root,root) %{_unitdir}/security-manager-rules-loader.service
+%attr(-,root,root) %{_unitdir}/basic.target.wants/security-manager-rules-loader.service
 %attr(-,root,root) %{_unitdir}/sockets.target.wants/security-manager.*
 %attr(-,root,root) %{_unitdir}/sysinit.target.wants/security-manager-cleanup.*
 %config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.security-manager.db
index 582f7db..45b3d83 100644 (file)
@@ -54,6 +54,7 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/smack-rules.cpp
     ${COMMON_PATH}/smack-check.cpp
     ${COMMON_PATH}/service_impl.cpp
+    ${COMMON_PATH}/filesystem.cpp
     )
 
 ADD_LIBRARY(${TARGET_COMMON} SHARED ${COMMON_SOURCES})
@@ -71,3 +72,6 @@ TARGET_LINK_LIBRARIES(${TARGET_COMMON}
     )
 
 INSTALL(TARGETS ${TARGET_COMMON} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY DESTINATION ${LOCAL_STATE_DIR}/security-manager/rules)
+INSTALL(DIRECTORY DESTINATION ${LOCAL_STATE_DIR}/security-manager/rules-merged)
+
diff --git a/src/common/filesystem.cpp b/src/common/filesystem.cpp
new file mode 100644 (file)
index 0000000..b278ef1
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (c) 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        filesystem.cpp
+ * @author      Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @version     1.0
+ * @brief       Wrappers for filesystem operations.
+ *
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <vector>
+#include <memory>
+#include <string>
+
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <smack-exceptions.h>
+
+#include <filesystem.h>
+#include <filesystem-exception.h>
+
+namespace SecurityManager {
+namespace FS {
+
+FileNameVector getFilesFromDirectory(const std::string &path)
+{
+    FileNameVector result;
+    dirent tmp, *ptr;
+    int err;
+    std::unique_ptr<DIR, std::function<void(DIR*)>> dir(opendir(path.c_str()), closedir);
+
+    if (!dir.get()) {
+        err = errno;
+        ThrowMsg(FS::Exception::FileError, "Error opening directory: " << GetErrnoString(err));
+    }
+
+    while (true) {
+        if (readdir_r(dir.get(), &tmp, &ptr)) {
+            err = errno;
+            ThrowMsg(FS::Exception::FileError, "Error reading directory: " << GetErrnoString(err));
+        }
+
+        if (!ptr)
+            break;
+
+        struct stat finfo;
+        std::string filepath = path + "/" + ptr->d_name;
+        if (0 > stat(filepath.c_str(), &finfo)) {
+            ThrowMsg(FS::Exception::FileError, "Error reading: " << filepath);
+            continue;
+        }
+
+        if (S_ISREG(finfo.st_mode)) {
+            result.push_back(ptr->d_name);
+        }
+    }
+
+    return result;
+}
+
+} // namespace FS
+} // nanespace SecurityManager
+
diff --git a/src/common/include/filesystem-exception.h b/src/common/include/filesystem-exception.h
new file mode 100644 (file)
index 0000000..4e13019
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2015 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        fs-exceptions.h
+ * @author      Rafal Krypa <r.krypa@samsung.com>
+ * @version     1.0
+ * @brief       Declaration of Smack-specific exceptions
+ *
+ */
+#ifndef _FILESYSTEM_EXCEPTIONS_H_
+#define _FILESYSTEM_EXCEPTIONS_H_
+
+#include <dpl/exception.h>
+
+namespace SecurityManager {
+namespace FS {
+
+class Exception {
+public:
+    DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, FileError)
+};
+
+} // namespace FS
+} // namespace SecurityManager
+
+#endif /* _FILESYSTEM_EXCEPTIONS_H_ */
diff --git a/src/common/include/filesystem.h b/src/common/include/filesystem.h
new file mode 100644 (file)
index 0000000..e2f15f8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 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        filesystem.h
+ * @author      Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @version     1.0
+ * @brief       Very simple wrapper for opendir/readdir.
+ *
+ */
+#ifndef _FILESYSTEM_H_
+#define _FILESYSTEM_H_
+
+#include <vector>
+#include <string>
+#include <filesystem-exception.h>
+
+namespace SecurityManager {
+namespace FS {
+
+typedef std::vector<std::string> FileNameVector;
+
+FileNameVector getFilesFromDirectory(const std::string &path);
+
+} // namespace FS
+} // nanespace SecurityManager
+
+#endif // _FILESYSTEM_H_
+
index 7a5b5b0..2a88b60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
@@ -62,7 +62,7 @@ public:
 
     void apply() const;
     void clear() const;
-    void saveToFile(const std::string &path, bool truncFile = true) const;
+    void saveToFile(const std::string &path) const;
 
     /**
      * Create cross dependencies for all applications in a package
@@ -196,6 +196,13 @@ public:
 
     static void updatePackageRules(const std::string &pkgName, const std::vector<std::string> &pkgContents);
 
+    /**
+     * This function will read all rules created by security-manager and
+     * save them in one file. This file will be used during next system
+     * boot.
+     */
+    static void mergeRules();
+
 private:
     static void useTemplate(
             const std::string &templatePath,
index 35b4d69..bd8e740 100755 (executable)
@@ -411,6 +411,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
         LogDebug("Adding Smack rules for new appName: " << req.appName << " with pkgName: "
                 << req.pkgName << ". Applications in package: " << pkgContents.size());
         SmackRules::installApplicationRules(req.appName, req.pkgName, authorId, pkgContents, allTizen2XApps, allTizen2XPackages);
+        SmackRules::mergeRules();
     } catch (const SmackException::InvalidParam &e) {
         LogError("Invalid paramater during labeling: " << e.GetMessage());
         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
@@ -521,6 +522,8 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req,
             LogDebug("Removing Smack rules for authorId " << authorId);
             SmackRules::uninstallAuthorRules(authorId);
         }
+
+        SmackRules::mergeRules();
     } catch (const SmackException::Base &e) {
         LogError("Error while removing Smack rules for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
index 494fe1c..f00fd33 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Rafal Krypa <r.krypa@samsung.com>
  *
 #include <cstring>
 #include <sstream>
 #include <memory>
+#include <algorithm>
 
 #include <dpl/log/log.h>
 #include <tzplatform_config.h>
 #include <dpl/errno_string.h>
+#include <dpl/fstream_accessors.h>
 
+#include <filesystem.h>
 #include "smack-labels.h"
 #include "smack-rules.h"
 
@@ -49,6 +52,9 @@ const char *const APP_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath4(TZ_SYS_RO_SH
 const char *const PKG_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath4(TZ_SYS_RO_SHARE, "security-manager", "policy", "pkg-rules-template.smack");
 const char *const AUTHOR_RULES_TEMPLATE_FILE_PATH =
     tzplatform_mkpath4(TZ_SYS_RO_SHARE, "security-manager", "policy", "author-rules-template.smack");
+const char *const SMACK_RULES_PATH_MERGED      = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged";
+const char *const SMACK_RULES_PATH_MERGED_T    = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged.temp";
+const char *const SMACK_RULES_PATH             = LOCAL_STATE_DIR "/security-manager/rules";
 const char *const SMACK_APP_IN_PACKAGE_PERMS   = "rwxat";
 const char *const SMACK_APP_CROSS_PKG_PERMS    = "rx";
 const char *const SMACK_APP_PATH_OWNER_PERMS = "rwxat";
@@ -58,6 +64,7 @@ const char *const SMACK_USER = "User";
 const char *const SMACK_SYSTEM = "System";
 const char *const SMACK_APP_PATH_SYSTEM_PERMS = "rwxat";
 const char *const SMACK_APP_PATH_USER_PERMS = "rwxat";
+const std::string TEMPORARY_FILE_SUFFIX = ".temp";
 
 SmackRules::SmackRules()
 {
@@ -119,10 +126,11 @@ void SmackRules::loadFromFile(const std::string &path)
     }
 }
 
-void SmackRules::saveToFile(const std::string &path, bool truncFile) const
+void SmackRules::saveToFile(const std::string &destPath) const
 {
     int fd;
-    int flags = O_CREAT | O_WRONLY | (truncFile ? O_TRUNC : O_APPEND);
+    int flags = O_CREAT | O_WRONLY | O_TRUNC;
+    std::string path = destPath + TEMPORARY_FILE_SUFFIX;
 
     fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, 0644));
     if (fd == -1) {
@@ -147,6 +155,12 @@ void SmackRules::saveToFile(const std::string &path, bool truncFile) const
             LogWarning("Error while closing the file: " << path << ", error: " << GetErrnoString(errno));
         }
     }
+
+    if (0 > rename(path.c_str(), destPath.c_str())) {
+        LogError("Error moving file " << path << " to " << destPath << ". Errno: " << GetErrnoString(errno));
+        unlink(path.c_str());
+        ThrowMsg(SmackException::FileError, "Error moving file " << path << " to " << destPath << ". Errno: " << GetErrnoString(errno));
+    }
 }
 
 void SmackRules::addFromTemplateFile(
@@ -287,20 +301,91 @@ void SmackRules::generateAllowOther2XApplicationDeps(
 
 std::string SmackRules::getPackageRulesFilePath(const std::string &pkgName)
 {
-    std::string path(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", ("pkg_" + pkgName).c_str()));
-    return path;
+    return std::string(SMACK_RULES_PATH) + "/pkg_" + pkgName;
 }
 
 std::string SmackRules::getApplicationRulesFilePath(const std::string &appName)
 {
-    std::string path(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", ("app_" +  appName).c_str()));
-    return path;
+    return std::string(SMACK_RULES_PATH) + "/app_" + appName;
 }
 
 std::string SmackRules::getAuthorRulesFilePath(const int authorId)
 {
-    std::string authorIdStr = std::to_string(authorId);
-    return tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", ("author_" + authorIdStr).c_str());
+    return std::string(SMACK_RULES_PATH) + "/author_" + std::to_string(authorId);
+}
+
+void SmackRules::mergeRules()
+{
+    int tmp;
+    FS::FileNameVector files = FS::getFilesFromDirectory(SMACK_RULES_PATH);
+
+    // remove ignore files with ".temp" suffix
+    files.erase(
+        std::remove_if(files.begin(), files.end(),
+            [&](const std::string &path) -> bool {
+                if (path.size() < TEMPORARY_FILE_SUFFIX.size())
+                    return false;
+                return std::equal(
+                    TEMPORARY_FILE_SUFFIX.rbegin(),
+                    TEMPORARY_FILE_SUFFIX.rend(),
+                    path.rbegin());
+            }),
+        files.end());
+
+    std::ofstream dst(SMACK_RULES_PATH_MERGED_T, std::ios::binary);
+
+    if (dst.fail()) {
+        LogError("Error creating file: " << SMACK_RULES_PATH_MERGED_T);
+        ThrowMsg(SmackException::FileError, "Error creating file: " << SMACK_RULES_PATH_MERGED_T);
+    }
+
+    for(auto const &e : files) {
+        std::ifstream src(std::string(SMACK_RULES_PATH) + "/" + e, std::ios::binary);
+        dst << src.rdbuf() << '\n';
+        if (dst.bad()) {
+            LogError("I/O Error. File " << SMACK_RULES_PATH_MERGED << " will not be updated!");
+            unlink(SMACK_RULES_PATH_MERGED_T);
+            ThrowMsg(SmackException::FileError,
+                "I/O Error. File " << SMACK_RULES_PATH_MERGED << " will not be updated!");
+        }
+
+        if (dst.fail()) {
+            // src.rdbuf() was empty
+            dst.clear();
+        }
+    }
+
+    if (dst.flush().fail()) {
+        LogError("Error flushing file: " << SMACK_RULES_PATH_MERGED_T);
+        unlink(SMACK_RULES_PATH_MERGED_T);
+        ThrowMsg(SmackException::FileError, "Error flushing file: " << SMACK_RULES_PATH_MERGED_T);
+    }
+
+    if (0 > fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(dst))) {
+        LogError("Error fsync on file: " << SMACK_RULES_PATH_MERGED_T);
+        unlink(SMACK_RULES_PATH_MERGED_T);
+        ThrowMsg(SmackException::FileError, "Error fsync on file: " << SMACK_RULES_PATH_MERGED_T);
+    }
+
+    dst.close();
+    if (dst.fail()) {
+        LogError("Error closing file: "  << SMACK_RULES_PATH_MERGED_T);
+        unlink(SMACK_RULES_PATH_MERGED_T);
+        ThrowMsg(SmackException::FileError, "Error closing file: " << SMACK_RULES_PATH_MERGED_T);
+    }
+
+    if ((tmp = rename(SMACK_RULES_PATH_MERGED_T, SMACK_RULES_PATH_MERGED)) == 0)
+        return;
+
+    int err = errno;
+
+    LogError("Error during file rename: "
+        << SMACK_RULES_PATH_MERGED_T << " to "
+        << SMACK_RULES_PATH_MERGED << " Errno: " << GetErrnoString(err));
+    unlink(SMACK_RULES_PATH_MERGED_T);
+    ThrowMsg(SmackException::FileError, "Error during file rename: "
+        << SMACK_RULES_PATH_MERGED_T << " to "
+        << SMACK_RULES_PATH_MERGED << " Errno: " << GetErrnoString(err));
 }
 
 void SmackRules::useTemplate(
@@ -341,10 +426,12 @@ void SmackRules::updatePackageRules(
         const std::vector<std::string> &pkgContents,
         const std::vector<std::string> &appsGranted)
 {
-    useTemplate(PKG_RULES_TEMPLATE_FILE_PATH, getPackageRulesFilePath(pkgName), std::string(), pkgName);
-
     SmackRules smackRules;
-    std::string pkgPath = getPackageRulesFilePath(pkgName);
+    smackRules.addFromTemplateFile(
+            PKG_RULES_TEMPLATE_FILE_PATH,
+            std::string(),
+            pkgName,
+            -1);
 
     smackRules.generatePackageCrossDeps(pkgContents);
     smackRules.generateAllowOther2XApplicationDeps(pkgName, appsGranted);
@@ -352,7 +439,7 @@ void SmackRules::updatePackageRules(
     if (smack_smackfs_path() != NULL)
         smackRules.apply();
 
-    smackRules.saveToFile(pkgPath, false);
+    smackRules.saveToFile(getPackageRulesFilePath(pkgName));
 }
 
 
diff --git a/src/dpl/core/include/dpl/fstream_accessors.h b/src/dpl/core/include/dpl/fstream_accessors.h
new file mode 100644 (file)
index 0000000..bc0e167
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2000 - 2016 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.
+ *  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        fstream-helper.h
+ * @author      Marek Smolinski (m.smolinski@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of fstream-helper
+ *
+ */
+
+#ifndef _FSTREAM_ACCESSORS_H
+#define _FSTREAM_ACCESSORS_H
+
+namespace DPL {
+
+/*
+ * Bypass lack of public member function to get file
+ * descriptor from fstream objects in std
+ * This feature is needed for flushing data from kernel space buffer to
+ * physical device [fsync(int fd) - syscall] on opened fstream object
+*/
+
+template<typename T>
+class FstreamAccessors : T::__filebuf_type {
+    typedef FstreamAccessors<T> MyType;
+public:
+    static int GetFd(T &strm) {
+        return static_cast<MyType *>(strm.rdbuf())->_M_file.fd();
+    }
+};
+
+} // namespace DPL
+
+#endif // _FSTREAM_ACCESSORS_H
index 2d14d5f..8bba273 100644 (file)
@@ -1,10 +1,12 @@
 CONFIGURE_FILE(security-manager.service.in security-manager.service @ONLY)
 CONFIGURE_FILE(security-manager-cleanup.service.in security-manager-cleanup.service @ONLY)
+CONFIGURE_FILE(security-manager-rules-loader.service.in security-manager-rules-loader.service @ONLY)
 
 INSTALL(FILES
     security-manager.service
     security-manager.socket
     security-manager-cleanup.service
+    security-manager-rules-loader.service
     DESTINATION
     ${SYSTEMD_INSTALL_DIR}
 )
diff --git a/systemd/security-manager-rules-loader.service.in b/systemd/security-manager-rules-loader.service.in
new file mode 100644 (file)
index 0000000..d10a3b5
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=SMACK merged rules loading
+After=local-fs.target
+Before=basic.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/bin/dd if=@LOCAL_STATE_DIR@/security-manager/rules-merged/rules.merged of=/sys/fs/smackfs/load2 bs=20M
+
+[Install]
+WantedBy=basic.target
+