Path setup refactoring 60/320160/13
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 21 Feb 2025 17:52:57 +0000 (18:52 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 13 Mar 2025 13:41:08 +0000 (14:41 +0100)
* Split common and dac/smack specific code into separate files.
* Use common exceptions for Acl, Smack & Dac.
* Pass request uid to DacSetup::setupPkgBasePath and
  DacSetup::setupPath.

Change-Id: If4e76a273e2bd11de6aad69d1f2c76a56a1c5bbd

27 files changed:
src/client/client-security-manager.cpp
src/common/CMakeLists.txt
src/common/acl.cpp
src/common/dac-setup.cpp [new file with mode: 0644]
src/common/filesystem.cpp
src/common/include/access-control-exception.h [new file with mode: 0644]
src/common/include/acl.h
src/common/include/dac-setup.h [new file with mode: 0644]
src/common/include/path-setup.h [new file with mode: 0644]
src/common/include/service_impl.h
src/common/include/smack-exceptions.h [deleted file]
src/common/include/smack-labels.h
src/common/include/smack-setup.h [new file with mode: 0644]
src/common/path-setup.cpp [new file with mode: 0644]
src/common/privilege-info.cpp
src/common/service_impl.cpp
src/common/smack-accesses.cpp
src/common/smack-common.cpp
src/common/smack-labels.cpp
src/common/smack-rules.cpp
src/common/smack-setup.cpp [new file with mode: 0644]
src/common/template-manager.cpp
src/server/cleanup/security-manager-cleanup.cpp
test/CMakeLists.txt
test/test_acl.cpp
test/test_smack-labels.cpp
test/test_smack-rules.cpp

index 83627f3dbb88b08693eefe5acbaa3d9ba97c110e..3a95fb1929fd7bfc0ca1ebe33cb0027bf83314b4 100644 (file)
  * @brief       This file contain client side implementation of security-manager API
  */
 
+#include "access-control-exception.h"
+#include "check-proper-drop.h"
+#include "client-offline.h"
+#include "client-request.h"
+#include "config.h"
+#include "config-file.h"
+#include "dpl/errno_string.h"
+#include "dpl/exception.h"
+#include "dpl/log/log.h"
+#include "filesystem.h"
+#include "group2gid.h"
+#include "mount-namespace.h"
+#include "protocols.h"
+#include "security-manager.h"
+#include "service_impl.h"
+#include "smack-check.h"
+#include "smack-labels.h"
+#include "tzplatform-config.h"
+#include "utils.h"
+
+#include <atomic>
 #include <cstdio>
 #include <cstdlib>
+#include <cxxabi.h>
 #include <functional>
 #include <memory>
-#include <utility>
-#include <atomic>
 #include <system_error>
+#include <utility>
 #include <vector>
-#include <stdlib.h>
-#include <cxxabi.h>
 
-#include <unistd.h>
-#include <grp.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/xattr.h>
-#include <sys/smack.h>
+#include <grp.h>
 #include <sys/capability.h>
-#include <sys/syscall.h>
 #include <sys/mman.h>
+#include <sys/smack.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
 #include <signal.h>
-
-#include <dpl/log/log.h>
-#include <dpl/exception.h>
-#include <smack-check.h>
-#include <smack-labels.h>
-#include <client-request.h>
-#include <service_impl.h>
-#include <check-proper-drop.h>
-#include <utils.h>
-#include <group2gid.h>
-#include <config.h>
-#include <config-file.h>
-#include <tzplatform-config.h>
-
-#include <security-manager.h>
-#include <client-offline.h>
-#include <dpl/errno_string.h>
-
-#include "filesystem.h"
-#include "mount-namespace.h"
-#include "protocols.h"
+#include <stdlib.h>
+#include <unistd.h>
 
 static const char *EMPTY = "";
 static const std::string SMACK_SYSTEM = "System";
@@ -1789,7 +1788,7 @@ static lib_retcode get_app_and_pkg_id_from_smack_label(
     try {
 
         SmackLabels::generateAppPkgNameFromLabel(label, appNameString, pkgNameString);
-    } catch (const SmackException::InvalidLabel &) {
+    } catch (const AccessControlException::InvalidLabel &) {
         return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
     }
 
index f1e6c984dad08f8359d90dc23edb39740fc86e84..d257e35d5fc7a9778dd9203f89ff3bf3a477f6ad 100644 (file)
@@ -79,17 +79,20 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/connection.cpp
     ${COMMON_PATH}/credentials.cpp
     ${COMMON_PATH}/cynara.cpp
+    ${COMMON_PATH}/dac-setup.cpp
     ${COMMON_PATH}/filesystem.cpp
     ${COMMON_PATH}/file-lock.cpp
     ${COMMON_PATH}/permissible-set.cpp
     ${COMMON_PATH}/protocols.cpp
     ${COMMON_PATH}/nsmount-logic.cpp
+    ${COMMON_PATH}/path-setup.cpp
     ${COMMON_PATH}/privilege_db.cpp
     ${COMMON_PATH}/smack-labels.cpp
     ${COMMON_PATH}/smack-accesses.cpp
     ${COMMON_PATH}/smack-common.cpp
     ${COMMON_PATH}/smack-rules.cpp
     ${COMMON_PATH}/smack-check.cpp
+    ${COMMON_PATH}/smack-setup.cpp
     ${COMMON_PATH}/template-manager.cpp
     ${COMMON_PATH}/service_impl.cpp
     ${COMMON_PATH}/service_impl_utils.cpp
index ca6f08c03b14d98cde0405f9fec2f13ef233a65f..fcfe33ccbaf0a3d6dcb7d27d32d93a12ad93894f 100644 (file)
  */
 
 #include "acl.h"
+
+#include "access-control-exception.h"
 #include "dpl/errno_string.h"
-#include "dpl/exception.h"
-#include <acl/libacl.h>
+#include "dpl/log/log.h"
+
 #include <memory>
-#include <sys/acl.h>
-#include <vector>
 
 namespace SecurityManager {
 
@@ -35,19 +35,19 @@ void Acl::Entry::syncToAssignedRawEntry() {
     acl_permset_t permset = nullptr;
 
     if (0 != acl_get_permset(m_rawEntry, &permset)) {
-        LogAndThrowErrno(Exception::Base, "acl_get_permset");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_get_permset");
     }
 
     if (0 != acl_clear_perms(permset)) {
-        LogAndThrowErrno(Exception::Base, "acl_clear_permset");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_clear_permset");
     }
 
     if (0 != acl_add_perm(permset, m_permissions)) {
-        LogAndThrowErrno(Exception::Base, "acl_add_perm");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_add_perm");
     }
 
     if (0 != acl_set_tag_type(m_rawEntry, m_tag)) {
-        LogAndThrowErrno(Exception::Base, "acl_set_tag_type");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_set_tag_type");
     }
 
     void *qualifier = nullptr;
@@ -59,7 +59,7 @@ void Acl::Entry::syncToAssignedRawEntry() {
 
     if (qualifier != nullptr) {
         if (0 != acl_set_qualifier(m_rawEntry, qualifier)) {
-            LogAndThrowErrno(Exception::Base, "acl_set_qualifier");
+            LogAndThrowErrno(AccessControlException::AclError, "acl_set_qualifier");
         }
     }
 }
@@ -75,13 +75,13 @@ Acl::Entry Acl::GidEntry(acl_perm_t permissions, gid_t gid) noexcept {
 Acl::Entry Acl::Entry::FromRawEntry(acl_entry_t entry) {
     acl_tag_t tag_type;
     if (0 != acl_get_tag_type(entry, &tag_type)) {
-        LogAndThrowErrno(Exception::Base, "acl_get_tag_type");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_get_tag_type");
     }
 
     acl_permset_t permset;
 
     if (0 != acl_get_permset(entry, &permset)) {
-        LogAndThrowErrno(Exception::Base, "acl_get_permset");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_get_permset");
     }
 
     acl_perm_t perms = 0;
@@ -92,7 +92,7 @@ Acl::Entry Acl::Entry::FromRawEntry(acl_entry_t entry) {
         } else if (ret == 1) {
             perms |= perm;
         } else {
-            LogAndThrowErrno(Exception::Base, "acl_get_perm");
+            LogAndThrowErrno(AccessControlException::AclError, "acl_get_perm");
         }
     }
 
@@ -102,7 +102,7 @@ Acl::Entry Acl::Entry::FromRawEntry(acl_entry_t entry) {
     switch (tag_type) {
     case ACL_USER: {
         if (!acl_qualifier) {
-            LogAndThrowErrno(Exception::Base, "acl_get_qualifier");
+            LogAndThrowErrno(AccessControlException::AclError, "acl_get_qualifier");
         }
         uid_t uid = *(static_cast<uid_t*>(acl_qualifier.get()));
         auto uidEntry = UidEntry(perms, uid);
@@ -111,7 +111,7 @@ Acl::Entry Acl::Entry::FromRawEntry(acl_entry_t entry) {
     }
     case ACL_GROUP: {
         if (!acl_qualifier) {
-            LogAndThrowErrno(Exception::Base, "acl_get_qualifier");
+            LogAndThrowErrno(AccessControlException::AclError, "acl_get_qualifier");
         }
         gid_t gid = *(static_cast<gid_t*>(acl_qualifier.get()));
         auto gid_entry = GidEntry(perms, gid);
@@ -120,7 +120,8 @@ Acl::Entry Acl::Entry::FromRawEntry(acl_entry_t entry) {
     }
     default: {
         if (acl_qualifier) {
-            ThrowMsg(Exception::Base, "Unexpected acl_qualifier for tag type " << tag_type);
+            ThrowMsg(AccessControlException::AclError,
+                     "Unexpected acl_qualifier for tag type " << tag_type);
         }
     }
     }
@@ -145,7 +146,7 @@ Acl Acl::Make(acl_perm_t ownerPerms,
 Acl Acl::FromFile(const std::string &path, acl_type_t acl_type) {
     acl_t acl = acl_get_file(path.c_str(), acl_type);
     if (acl == nullptr) {
-        LogAndThrowErrno(Exception::Base, "acl_get_file");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_get_file");
     }
 
     return Acl(acl);
@@ -156,7 +157,7 @@ std::vector<Acl::Entry> Acl::toEntries() const {
 
     int entries_count = acl_entries(m_acl);
     if (entries_count < 0) {
-        LogAndThrowErrno(Exception::Base, "acl_entries");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_entries");
     }
 
     entries.reserve(entries_count);
@@ -168,7 +169,7 @@ std::vector<Acl::Entry> Acl::toEntries() const {
     }
 
     if (ret == -1) {
-        LogAndThrowErrno(Exception::Base, "acl_get_entry");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_get_entry");
     }
 
     return entries;
@@ -178,7 +179,7 @@ void Acl::addEntry(Entry&& entry) {
     if (!entry.isRawEntryAssigned()) {
         acl_entry_t new_entry = nullptr;
         if (0 != acl_create_entry(&m_acl, &new_entry)) {
-            LogAndThrowErrno(Exception::Base, "acl_create_entry");
+            LogAndThrowErrno(AccessControlException::AclError, "acl_create_entry");
         }
         entry.assignRawEntry(new_entry);
     }
@@ -188,7 +189,7 @@ void Acl::addEntry(Entry&& entry) {
 
 void Acl::deleteEntry(Entry&& entry) {
     if (0 != acl_delete_entry(m_acl, entry.getAssignedRawEntry())) {
-        LogAndThrowErrno(Exception::Base, "acl_delete_entry");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_delete_entry");
     }
 }
 
@@ -202,7 +203,7 @@ Acl::Acl(std::vector<Entry> entries)
     auto freeAcl = [](acl_t *toFree) {acl_free(*toFree);};
     m_acl = acl_init(entries.size() + 1); // + 1 for ACL_MASK entry
     if (m_acl == nullptr) {
-        LogAndThrowErrno(Exception::Base, "acl_init");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_init");
     }
     std::unique_ptr<acl_t, decltype(freeAcl)> deleter(&m_acl, freeAcl);
 
@@ -213,10 +214,9 @@ Acl::Acl(std::vector<Entry> entries)
 
     // Acl requires one ACL_MASK entry if there are ACL_USER or ACL_GROUP entries present.
     if (0 != acl_calc_mask(&m_acl)) {
-        LogAndThrowErrno(Exception::Base, "acl_calc_mask");
+        LogAndThrowErrno(AccessControlException::AclError, "acl_calc_mask");
     }
 
-    LogWarning("created acl: " << toString());
     int last;
     int ret = acl_check(m_acl, &last);
     if (ret != 0) {
@@ -225,7 +225,7 @@ Acl::Acl(std::vector<Entry> entries)
         } else {
             LogErrno("acl_check");
         }
-        Throw(Exception::Base);
+        Throw(AccessControlException::AclError);
     }
 
     (void)deleter.release();
@@ -235,12 +235,11 @@ void Acl::apply(const std::string &path, acl_type_t type) const
 {
     if (m_acl == nullptr) {
         LogError("ACL object is not initialized");
-        Throw(Exception::Base);
+        Throw(AccessControlException::Base);
     }
 
     if (0 != acl_set_file(path.c_str(), type, m_acl)) {
-        LogErrno("acl_set_file for " << path);
-        Throw(Exception::Base);
+        LogAndThrowErrno(AccessControlException::FileError, "acl_set_file for " << path);
     }
 }
 
diff --git a/src/common/dac-setup.cpp b/src/common/dac-setup.cpp
new file mode 100644 (file)
index 0000000..54d03c5
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#include "dac-setup.h"
+
+#include "access-control-exception.h"
+#include "dpl/errno_string.h"
+#include "service_impl_utils.h"
+#include "utils.h"
+
+#include <filesystem>
+#include <variant>
+
+#include <fcntl.h>
+#include <fts.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+namespace SecurityManager {
+
+void DacSetup::setupPkgBasePath(uid_t owner,
+                                const std::string &basePath,
+                                const std::vector<uid_t> &processUIds)
+{
+    // apply public RO access permissions
+    if (0 != chown(basePath.c_str(), owner, getSystemAccessGid()))
+        ThrowErrno(AccessControlException::FileError, "chown() for path: " << basePath);
+
+    std::vector<Acl::Entry> entries;
+    for (auto &processUId : processUIds)
+        entries.emplace_back(Acl::UidEntry(Acl::RX, processUId));
+
+    auto acl = Acl::Make(Acl::RWX, Acl::RWX, Acl::RX, std::move(entries));
+    acl.apply(basePath, ACL_TYPE_ACCESS);
+}
+
+bool DacSetup::isAppPrivatePath(uid_t appUid, const std::string &path) {
+    static constexpr auto dir_acl_types = {ACL_TYPE_ACCESS, ACL_TYPE_DEFAULT};
+    static constexpr auto file_acl_types = {ACL_TYPE_ACCESS};
+    const auto &acl_types = std::filesystem::is_directory(path) ? dir_acl_types : file_acl_types;
+    bool has_owner_rights = false;
+    bool has_other_rights = false;
+    for (auto acl_type : acl_types) {
+        auto acl = Acl::FromFile(path, acl_type);
+        LogDebug("acl from " << path << ":\n" << acl.toString());
+        for (const auto &entry : acl.toEntries()) {
+            auto qualifier = entry.getQualifier();
+            if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
+                if (appUid == uidQualifier->uid
+                    && (entry.getPermissions() & Acl::RW) == Acl::RW)
+                {
+                    has_owner_rights = true;
+                }
+            } else if (entry.getTag() == ACL_OTHER && (entry.getPermissions() != 0)) {
+                has_other_rights = true;
+            }
+        }
+    }
+    return has_owner_rights && !has_other_rights;
+}
+
+void DacSetup::addPrivateSharing(uid_t targetAppUid, const std::string &path) {
+    LogDebug("add private sharing called for target=" << targetAppUid
+             <<" path=" << path);
+    acl_perm_t perms = std::filesystem::is_directory(path) ? Acl::X : Acl::RX;
+    auto acl = Acl::FromFile(path, ACL_TYPE_ACCESS);
+    LogDebug("acl for " << path << " before add:\n " << acl.toString());
+    bool entry_exists = false;
+    for (auto &entry: acl.toEntries()) {
+        auto qualifier = entry.getQualifier();
+        if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
+            if (targetAppUid == uidQualifier->uid) {
+                entry_exists = true;
+                break;
+            }
+        }
+    }
+    if (!entry_exists) {
+        acl.addEntry(Acl::UidEntry(perms, targetAppUid));
+    }
+    LogDebug("acl for " << path << " after add:\n " << acl.toString());
+    acl.apply(path, ACL_TYPE_ACCESS);
+}
+
+void DacSetup::removePrivateSharing(uid_t targetAppUid, const std::string &path) {
+    LogDebug("remove private sharing called for target=" << targetAppUid
+             <<" path=" << path);
+    auto acl = Acl::FromFile(path, ACL_TYPE_ACCESS);
+    LogDebug("acl for " << path << " before remove:\n " << acl.toString());
+    for (auto &entry: acl.toEntries()) {
+        auto qualifier = entry.getQualifier();
+        if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
+            if (targetAppUid == uidQualifier->uid) {
+                acl.deleteEntry(std::move(entry));
+                // No other entry for this app should be on the list
+                break;
+            }
+        }
+    }
+    LogDebug("acl for " << path << " after remove:\n " << acl.toString());
+    acl.apply(path, ACL_TYPE_ACCESS);
+}
+
+void DacSetup::setupPath(uid_t owner,
+                         const std::string &path,
+                         app_install_path_type pathType,
+                         const std::vector<uid_t> &processUIds,
+                         std::optional<gid_t> authorGId)
+{
+    Dac dac;
+    // Make the real user (owner=5001) the owner. No app should run with this uid
+    dac.owner = owner;
+    // Make system_access the group. No app should run with it.
+    dac.group = getSystemAccessGid();
+
+    acl_perm_t appPerms;
+    acl_perm_t otherPerms;
+    bool follow_symlink;
+    std::vector<Acl::Entry> entries;
+
+    switch (pathType) {
+    case SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO:
+        appPerms = Acl::RWX;
+        otherPerms = Acl::RX;
+        follow_symlink = true;
+        break;
+
+    case SECURITY_MANAGER_PATH_RW:
+        appPerms = Acl::RWX;
+        otherPerms = 0;
+        follow_symlink = false;
+        break;
+
+    case SECURITY_MANAGER_PATH_RO:
+        appPerms = Acl::RX;
+        otherPerms = 0;
+        follow_symlink = false;
+        break;
+
+    case SECURITY_MANAGER_PATH_PUBLIC_RO:
+        appPerms = Acl::RX;
+        otherPerms = Acl::RX;
+        follow_symlink = false;
+        break;
+
+    case SECURITY_MANAGER_PATH_TRUSTED_RW:
+        if (!authorGId.has_value())
+            ThrowMsg(AccessControlException::InvalidParam,
+                     "You must define author to use PATH_TRUSED_RW");
+
+        appPerms = 0;
+        otherPerms = 0;
+        follow_symlink = false;
+        entries.emplace_back(Acl::GidEntry(Acl::RWX, *authorGId));
+        break;
+
+    default:
+        LogError("Path type not known.");
+        Throw(AccessControlException::InvalidParam);
+    }
+
+    if (appPerms != 0) {
+        for (auto &processUId : processUIds)
+            entries.emplace_back(Acl::UidEntry(appPerms, processUId));
+    }
+
+    // RWX for the owner(5001) and system_access
+    dac.acl = Acl::Make(Acl::RWX, Acl::RWX, otherPerms, std::move(entries));
+
+    DacSetup dacSetup(std::move(dac));
+    if (follow_symlink)
+        dacSetup.setup(realPath(path));
+    dacSetup.setup(path);
+}
+
+void DacSetup::setupFile(FTSENT *ftsent) const
+{
+    if (0 != chown(ftsent->fts_path, m_dac.owner, m_dac.group))
+        ThrowErrno(AccessControlException::FileError, "chown() for path: " << ftsent->fts_path);
+
+    m_dac.acl.apply(ftsent->fts_path, ACL_TYPE_ACCESS);
+
+    /*
+     *  For newly created files:
+     *  - let the owner come from process (be it app PUId or system_access). The creator clearly
+     *    already has RWX.
+     *  - force the group = system_access using DAC set-group-ID bit so even files created by
+     *    app will be accessible by sys daemons. SM needs CAP_FSETID and system_access group for
+     *    that.
+     *  - Default ACL rules will be applied from the parent directory.
+     */
+    if (m_transmute && ftsent->fts_level == 0 && S_ISDIR(ftsent->fts_statp->st_mode)) {
+        // need to re-read the mode after ACL application above
+        struct stat statbuf;
+        if (0 != stat(ftsent->fts_path, &statbuf))
+            ThrowErrno(AccessControlException::FileError, "stat() for path: " << ftsent->fts_path);
+
+        // add set-group-ID for system_access
+        if (0 != chmod(ftsent->fts_path, S_ISGID | statbuf.st_mode))
+            ThrowErrno(AccessControlException::FileError, "chmod() for path: " << ftsent->fts_path);
+
+        // this works on all files/directories below
+        m_dac.acl.apply(ftsent->fts_path, ACL_TYPE_DEFAULT);
+    }
+}
+
+} // namespace SecurityManager
index 5384ab1bc3489e9dea8fc0a8d790648c35707521..111824e2bbcb36cc55f4ca891cd245d3a77ceef4 100644 (file)
  * @brief       Wrappers for filesystem operations.
  *
  */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
+
+#include "dpl/errno_string.h"
+#include "dpl/exception.h"
+#include "filesystem.h"
+#include "filesystem-exception.h"
+#include "security-manager.h"
+#include "utils.h"
 
 #include <fstream>
 #include <memory>
 #include <string>
-#include <sstream>
 
-#include <dpl/log/log.h>
-#include <dpl/exception.h>
-#include <dpl/errno_string.h>
-#include <smack-exceptions.h>
-
-#include <filesystem.h>
-#include <filesystem-exception.h>
-#include <utils.h>
-#include <security-manager.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace SecurityManager {
 namespace FS {
diff --git a/src/common/include/access-control-exception.h b/src/common/include/access-control-exception.h
new file mode 100644 (file)
index 0000000..1cd97bb
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015-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.
+ */
+#pragma once
+
+#include "dpl/exception.h"
+
+namespace SecurityManager {
+
+class AccessControlException {
+public:
+    DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, LibsmackError)
+    DECLARE_EXCEPTION_TYPE(Base, FileError)
+    DECLARE_EXCEPTION_TYPE(Base, InvalidLabel)
+    DECLARE_EXCEPTION_TYPE(Base, InvalidParam)
+    DECLARE_EXCEPTION_TYPE(Base, AclError)
+};
+
+} // namespace SecurityManager
index 7036224ee5c733b62c0158e51d7c909f8cf1c664..ee2d65cf2d52270c2b2bccb944af274440141793 100644 (file)
 #pragma once
 
 #include <acl/libacl.h>
-#include <sys/acl.h>
-#include <vector>
-#include <memory>
-#include <variant>
 
-#include "dpl/exception.h"
-#include "dpl/log/log.h"
-#include "dpl/errno_string.h"
+#include <string>
+#include <variant>
+#include <vector>
 
 namespace SecurityManager {
 
@@ -63,7 +59,6 @@ public:
             other.m_tag = ACL_UNDEFINED_TAG;
             other.m_permissions = 0;
             other.m_qualifier = NoQualifier{};
-
         }
 
         Entry& operator=(const Entry&) = delete;
@@ -115,12 +110,6 @@ public:
     static constexpr inline acl_perm_t RX = ACL_READ | ACL_EXECUTE;
     static constexpr inline acl_perm_t RWX = ACL_READ | ACL_WRITE | ACL_EXECUTE;
 
-    class Exception
-    {
-    public:
-        DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
-    };
-
     Acl() : Acl(std::vector<Entry>())
     {
     }
diff --git a/src/common/include/dac-setup.h b/src/common/include/dac-setup.h
new file mode 100644 (file)
index 0000000..09ef91f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#pragma once
+
+#include "path-setup.h"
+
+#include "acl.h"
+#include "security-manager-types.h"
+
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include <sys/types.h>
+
+namespace SecurityManager {
+
+class DacSetup : public PathSetup {
+public:
+    static void setupPkgBasePath(uid_t owner,
+                                 const std::string &basePath,
+                                 const std::vector<uid_t> &processUIds);
+
+    static bool isAppPrivatePath(uid_t appUid, const std::string &path);
+    static void addPrivateSharing(uid_t targetAppUid, const std::string &path);
+    static void removePrivateSharing(uid_t targetAppUid, const std::string &path);
+
+    static void setupPath(uid_t owner,
+                          const std::string &path,
+                          app_install_path_type pathType,
+                          const std::vector<uid_t> &processUIds,
+                          std::optional<gid_t> authorGId);
+private:
+    struct Dac {
+        // ACL for files and dirs. Effective permissions will be "ANDed" with ACL mask so
+        // non-executable files won't get 'x'
+        Acl acl;
+        uid_t owner;
+        gid_t group;
+    };
+
+    explicit DacSetup(Dac dac) : PathSetup(true), m_dac(std::move(dac)) {}
+
+    void setupFile(FTSENT *ftsent) const override;
+
+    Dac m_dac;
+};
+
+} // namespace SecurityManager
diff --git a/src/common/include/path-setup.h b/src/common/include/path-setup.h
new file mode 100644 (file)
index 0000000..447327b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <fts.h>
+
+namespace SecurityManager {
+
+class PathSetup {
+public:
+    explicit PathSetup(bool transmute) : m_transmute(transmute) {}
+    void setup(const std::string &path) const;
+    virtual ~PathSetup() = default;
+
+protected:
+    virtual void setupFile(FTSENT *ftsent) const = 0;
+
+    bool m_transmute;
+};
+
+} // namespace SecurityManager
index 200d30757612b8fd3deb63d0262191f268eb2bb5..d69452fa89a886c6a60c2929c94a53deb95319ae 100644 (file)
@@ -489,8 +489,7 @@ private:
                                         const uid_t &uid,
                                         app_install_type installationType);
 
-    int labelPaths(const Credentials &creds,
-                   const path_req &req,
+    int labelPaths(const path_req &req,
                    bool isSharedRO,
                    const std::vector<uid_t> &processUids);
 
diff --git a/src/common/include/smack-exceptions.h b/src/common/include/smack-exceptions.h
deleted file mode 100644 (file)
index ec7fd19..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2015-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.
- */
-
-/**
- * @file        smack-exceptions.h
- * @author      Rafal Krypa <r.krypa@samsung.com>
- * @version     1.0
- * @brief       Declaration of Smack-specific exceptions
- *
- */
-#pragma once
-
-#include <dpl/exception.h>
-
-namespace SecurityManager {
-
-class SmackException {
-public:
-    DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
-    DECLARE_EXCEPTION_TYPE(Base, LibsmackError)
-    DECLARE_EXCEPTION_TYPE(Base, FileError)
-    DECLARE_EXCEPTION_TYPE(Base, InvalidLabel)
-    DECLARE_EXCEPTION_TYPE(Base, InvalidPathType)
-    DECLARE_EXCEPTION_TYPE(Base, InvalidParam)
-};
-
-} // namespace SecurityManager
index 3ba55c016896f0fce09fb0c79c03d1361d70ba5c..59c144ad7101c6614283c0f9f842bacbb8ec49c1 100644 (file)
  */
 #pragma once
 
+#include "smack-common.h"
+
 #include <string>
-#include <sys/acl.h>
-#include <utility>
-#include <optional>
-#include <smack-common.h>
-#include <smack-exceptions.h>
-#include <security-manager.h>
-#include "credentials.h"
 
 namespace SecurityManager {
 namespace SmackLabels {
 
-/**
- * Sets Smack labels on a directory and its contents, recursively.
- *
- * @param pkgName[in] application's package identifier
- * @param path[in] path to a file or directory to setup
- * @param pathType[in] type of path to setup. See description of
- *         app_install_path_type in security-manager.h for details
- * @param authorHash[in] hash of author_name of given application
- *         (if not applicable, set to empty string)
- */
-void setupPath(
-        const std::string &pkgName,
-        const std::string &path,
-        app_install_path_type pathType,
-        const std::string &authorHash = std::string());
-
-/**
- * Sets ACL and DAC permissions on a directory and its contents, recursively.
- *
- * @param owner[in] app owner uid
- * @param path[in] path to a file or directory to setup
- * @param pathType[in] type of path to setup. See description of
- *         app_install_path_type in security-manager.h for details
- * @param processUIds[in] list of owner applications' process UIds (PUIDs)
- * @param authorGId[in] optional group id of all apps having the same author
- */
-void setupPath(
-        uid_t owner,
-        const std::string &path,
-        app_install_path_type pathType,
-        const std::vector<uid_t>& processUIds,
-        const std::optional<gid_t>& authorGId);
-
-/**
- * Sets Smack labels on a <ROOT_APP>/<pkg_id> non-recursively
- *
- * @param basePath[in] <ROOT_APP>/<pkg_id> path
- */
-void setupPkgBasePath(const std::string &basePath);
-
-/**
- * Sets ACL and DAC permissions on <ROOT_APP>/<pkg_id> non-recursively
- *
- * @param creds[in] client's credentials
- * @param basePath[in] <ROOT_APP>/<pkg_id> path
- * @param processUIds[in] list of owner applications' process UIds (PUIDs)
- */
-void setupPkgBasePath(
-        const Credentials &creds,
-        const std::string &basePath,
-        const std::vector<uid_t> &processUIds);
-
-/**
- * Changes Smack label on path to enable private sharing
- *
- * @param pkgName[in] package identifier
- * @param path[in] path
- */
-void setupSharedPrivatePath(const std::string &pkgName,
-                            const std::string &path);
-
-/**
- * Checks if application has RWX access to path and others do not have any access
- *
- * @param appUid[in] application uid
- * @param path[in] path
- */
-bool isAppPrivatePath(uid_t appUid, const std::string &path);
-
-/**
- * Adds ACL rules required for target application to access path.
- *
- * @param targetAppUid[in] target application uid
- * @param path[in] path
- */
-void addPrivateSharing(uid_t targetAppUid, const std::string &path);
-
-/**
- * Removes ACL rules required for target application to access path.
- *
- * @param targetAppUid[in] target application uid
- * @param path[in] path
- */
-void removePrivateSharing(uid_t targetAppUid, const std::string &path);
+// Smack label used for SECURITY_MANAGER_PATH_PUBLIC_RO paths (RO for all apps)
+inline constexpr char LABEL_FOR_APP_PUBLIC_RO_PATH[] = "User::Home";
 
 /**
  * Generates application name for a label fetched from Cynara
diff --git a/src/common/include/smack-setup.h b/src/common/include/smack-setup.h
new file mode 100644 (file)
index 0000000..83c06fd
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#pragma once
+
+#include "path-setup.h"
+#include "security-manager-types.h"
+
+#include <utility>
+
+namespace SecurityManager {
+
+class SmackSetup : public PathSetup {
+public:
+    static void setupPkgBasePath(const std::string &basePath);
+    static void setupSharedPrivatePath(const std::string &pkgName, const std::string &path);
+    static void setupPath(
+            const std::string &pkgName,
+            const std::string &path,
+            app_install_path_type pathType,
+            const std::string &authorHash = std::string());
+private:
+    SmackSetup(const std::string label, bool transmute) :
+            PathSetup(transmute), m_label(std::move(label))
+    {
+    }
+
+    void setupFile(FTSENT *ftsent) const override;
+
+    std::string m_label;
+};
+
+} // namespace SecurityManager
diff --git a/src/common/path-setup.cpp b/src/common/path-setup.cpp
new file mode 100644 (file)
index 0000000..97cc5e9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#include "path-setup.h"
+
+#include "access-control-exception.h"
+#include "dpl/errno_string.h"
+#include "utils.h"
+
+namespace SecurityManager {
+
+void PathSetup::setup(const std::string &path) const
+{
+    // setting access label on everything in given directory and below
+    char *const path_argv[] = { const_cast<char*>(path.c_str()), nullptr };
+    FTSENT *entry;
+
+    auto fts = makeUnique(fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, nullptr), fts_close);
+    if (!fts) {
+        LogAndThrowErrno(AccessControlException::FileError, "fts_open failed.");
+    }
+
+    while ((entry = fts_read(fts.get())) != nullptr) {
+        if (entry->fts_info == FTS_ERR || entry->fts_info == FTS_NS || entry->fts_info == FTS_DNR) {
+            LogAndThrowErrno(AccessControlException::FileError, "fts_read");
+        }
+
+        /* avoid to tag directories two times */
+        if (entry->fts_info == FTS_D)
+            continue;
+
+        setupFile(entry);
+    }
+
+    /* If last call to fts_read() set errno, we need to return error. */
+    if (errno != 0)
+        LogAndThrowErrno(AccessControlException::FileError, "last fts_read");
+}
+
+} // namespace SecurityManager
index 66bae6943307e70ce3fb8f70269b6e4012446347..9a2b2f82ad9d972eb1f24eb95a9819ec7f38d66f 100644 (file)
  * @version    1.0
  */
 
-#include "privilege-info.h" // header for this file
+#include "privilege-info.h"
 
-#include <dpl/log/log.h>
-#include <smack-labels.h>
+#include "access-control-exception.h"
+#include "dpl/log/log.h"
+#include "smack-labels.h"
 
 namespace SecurityManager {
 
@@ -75,7 +76,7 @@ PrivilegeInfo::PrivilegeInfo(uid_t uid, const std::string &label, const std::str
 
     try {
         SmackLabels::generateAppPkgNameFromLabel(label, m_appId, m_pkgId);
-    } catch(const SmackException::InvalidLabel&) {
+    } catch(const AccessControlException::InvalidLabel&) {
         LogDebug("Not an application label " << label);
         ThrowMsg(Exception::NotApplication, "Not an application label");
     }
index 2a6b1590fe04f27db66626d8d09dc21ba92b698c..713593673c76b4ae58d7444ad8c777845b002ee0 100644 (file)
  * @brief       Implementation of the service methods
  */
 
-#include <cassert>
-#include <fcntl.h>
-#include <linux/xattr.h>
-#include <limits.h>
-#include <pwd.h>
-#include <string>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <cstring>
-#include <algorithm>
-#include <sys/types.h>
-#include <grp.h>
-#include <optional>
-#include <sys/smack.h>
-#include <unistd.h>
-#include <stdexcept>
-#include <string_view>
-#include <unordered_set>
-
-#include <dpl/log/log.h>
-#include <dpl/errno_string.h>
+#include "service_impl.h"
 
-#include <config.h>
-#include <vector>
-#include "acl.h"
+#include "access-control-exception.h"
 #include "check-proper-drop.h"
-#include "protocols.h"
-#include "privilege_db.h"
+#include "config.h"
 #include "cynara.h"
+#include "dac-setup.h"
+#include "dpl/errno_string.h"
+#include "dpl/log/log.h"
+#include "filesystem.h"
+#include "mount-namespace.h"
 #include "permissible-set.h"
+#include "privilege_db.h"
+#include "privilege-info.h"
+#include "protocols.h"
+#include "service_impl_utils.h"
 #include "smack-check.h"
-#include "smack-exceptions.h"
-#include "smack-rules.h"
 #include "smack-labels.h"
-#include "security-manager.h"
+#include "smack-rules.h"
+#include "smack-setup.h"
 #include "tzplatform-config.h"
 #include "utils.h"
-#include "filesystem.h"
-#include "mount-namespace.h"
-#include "privilege-info.h"
-#include "service_impl_utils.h"
 
-#include "service_impl.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <optional>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <unordered_set>
+#include <vector>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <limits.h>
+#include <linux/xattr.h>
+#include <pwd.h>
+#include <sys/mman.h>
+#include <sys/smack.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace SecurityManager {
 
@@ -171,8 +171,8 @@ void labelSharedPaths(const std::string &baseDir, const std::string &pkgName)
     const auto sharedPath = baseDir + ".shared/" + pkgName;
     const auto sharedTmpPath = baseDir + ".shared_tmp/" + pkgName;
     if (FS::directoryStatus(sharedPath) > 0 && FS::directoryStatus(sharedTmpPath) > 0) {
-        SmackLabels::setupPkgBasePath(sharedPath);
-        SmackLabels::setupPkgBasePath(sharedTmpPath);
+        SmackSetup::setupPkgBasePath(sharedPath);
+        SmackSetup::setupPkgBasePath(sharedTmpPath);
     }
 }
 
@@ -398,8 +398,7 @@ bool ServiceImpl::authCheck(const Credentials &creds,
     return true;
 }
 
-int ServiceImpl::labelPaths(const Credentials &creds,
-                            const path_req &req,
+int ServiceImpl::labelPaths(const path_req &req,
                             bool isSharedRO,
                             const std::vector<uid_t> &processUIds)
 {
@@ -440,13 +439,13 @@ int ServiceImpl::labelPaths(const Credentials &creds,
             const std::string &path = pkgPath.first;
             app_install_path_type pathType = static_cast<app_install_path_type>(pkgPath.second);
             if (smack_simple_check()) {
-                SmackLabels::setupPath(req.pkgName, path, pathType, authorHash);
+                SmackSetup::setupPath(req.pkgName, path, pathType, authorHash);
             } else {
                 gid_t authorGId;
                 if (m_privilegeDb.GetAuthorGId(req.pkgName, authorGId))
-                    SmackLabels::setupPath(req.uid, path, pathType, processUIds, authorGId);
+                    DacSetup::setupPath(req.uid, path, pathType, processUIds, authorGId);
                 else
-                    SmackLabels::setupPath(req.uid, path, pathType, processUIds, std::nullopt);
+                    DacSetup::setupPath(req.uid, path, pathType, processUIds, std::nullopt);
             }
         }
 
@@ -454,9 +453,9 @@ int ServiceImpl::labelPaths(const Credentials &creds,
         for (const auto &basePath : pkgLegalBaseDirs) {
             if (containSubDir(basePath, req.pkgPaths)) {
                 if (smack_simple_check())
-                    SmackLabels::setupPkgBasePath(basePath);
+                    SmackSetup::setupPkgBasePath(basePath);
                 else
-                    SmackLabels::setupPkgBasePath(creds, basePath, processUIds);
+                    DacSetup::setupPkgBasePath(req.uid, basePath, processUIds);
             }
         }
 
@@ -464,20 +463,14 @@ int ServiceImpl::labelPaths(const Credentials &creds,
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Database error: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidParam &e) {
-        LogError("Invalid parameter during labeling: " << e.DumpToString());
-        return SECURITY_MANAGER_ERROR_INPUT_PARAM;
-    } catch (const SmackException::InvalidPathType &e) {
-        LogError("Invalid path type: " << e.DumpToString());
-        return SECURITY_MANAGER_ERROR_INPUT_PARAM;
     } catch (const TizenPlatformConfig::Exception::Base &e) {
         LogError("Error while reading configuration: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::Base &e) {
-        LogError("Error while generating Smack labels: " << e.DumpToString());
-        return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
-    } catch (const Acl::Exception::Base &e) {
-        LogError("Error while setting up ACL");
+    } catch (const AccessControlException::InvalidParam &e) {
+        LogError("Invalid parameter during access control setup: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+    } catch (const AccessControlException::Base &e) {
+        LogError("Error during access control setup: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
     } catch (const std::runtime_error &) {
         return SECURITY_MANAGER_ERROR_UNKNOWN;
@@ -638,13 +631,13 @@ int ServiceImpl::appInstallSmackRules(app_inst_req &req, InstallHelper &ih)
             if (!req.isHybrid) // is not hybrid - all labels are the same
                 break;
         }
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidParam &e) {
+    } catch (const AccessControlException::InvalidParam &e) {
         LogError("Invalid paramater during labeling: " << e.GetMessage());
         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error while applying Smack policy for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
     } catch (const SecurityManager::Exception &e) {
@@ -739,7 +732,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &req)
 
         // label paths
         LogWarning("Configuring package paths");
-        ret = labelPaths(creds, req, isAppSharedRO, processUids);
+        ret = labelPaths(req, isAppSharedRO, processUids);
         if (ret != SECURITY_MANAGER_SUCCESS)
             return ret;
 
@@ -869,7 +862,7 @@ int ServiceImpl::appUpdate(const Credentials &creds, app_inst_req &req)
 
         // label paths
         LogWarning("Configuring package paths");
-        ret = labelPaths(creds, req, isAppSharedRO, processUids);
+        ret = labelPaths(req, isAppSharedRO, processUids);
         if (ret != SECURITY_MANAGER_SUCCESS)
             return ret;
 
@@ -1067,7 +1060,7 @@ int ServiceImpl::appUninstallSmackRules(app_inst_req &req, UninstallHelper &uh)
             LogDebug("Removing Smack rules for author " << uh.authorHash);
             m_smackRules.uninstallAuthorRules(uh.authorHash);
         }
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error while removing Smack rules for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
     } catch (const TizenPlatformConfig::Exception::Base &e) {
@@ -1169,7 +1162,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &req)
     } catch (const CynaraException::Base &e) {
         LogError("Error while setting Cynara rules for application: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const TizenPlatformConfig::Exception::Base &e) {
@@ -1271,7 +1264,7 @@ int ServiceImpl::userAdd(const Credentials &creds, uid_t uidAdded, int userType)
     } catch (const PermissibleSet::PermissibleSetException::FileInitError &e) {
         LogError("Error while adding user: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
-    } catch (const SmackException::FileError &e) {
+    } catch (const AccessControlException::FileError &e) {
         LogError("Error while adding user: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
     } catch (const PrivilegeInfo::Exception::Base &e) {
@@ -1429,7 +1422,7 @@ int ServiceImpl::policyUpdate(const Credentials &creds, const std::vector<policy
                 }
                 try {
                     updateRunningAppSmackPolicy(appContext, appsAllowedPrivileges);
-                } catch (const SmackException::InvalidLabel &e) {
+                } catch (const AccessControlException::InvalidLabel &e) {
                     LogError("AppContext: " << appContext.appProcessLabel
                              << " doesn't describe an application");
                 }
@@ -1606,7 +1599,7 @@ int ServiceImpl::getConfiguredPolicy(const Credentials &creds, bool forAdmin,
     } catch (const CynaraException::Base &e) {
         LogError("Error while listing Cynara rules: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -1771,7 +1764,7 @@ int ServiceImpl::getPolicy(const Credentials &creds, const policy_entry &filter,
     } catch (const CynaraException::Base &e) {
         LogError("Error while listing Cynara rules: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -2008,7 +2001,7 @@ int ServiceImpl::appHasPrivilege(
     } catch (const CynaraException::Base &e) {
         LogError("Error while querying Cynara for permissions: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -2068,7 +2061,7 @@ int ServiceImpl::dropOnePrivateSharing(
         //This function can be also called when application is uninstalled, so path won't exist
         if (FS::fileExists(path)) {
             if (smack_simple_check() && pathCount < 1) {
-                SmackLabels::setupPath(ownerPkgName, path, SECURITY_MANAGER_PATH_RW);
+                SmackSetup::setupPath(ownerPkgName, path, SECURITY_MANAGER_PATH_RW);
             } else if (!smack_simple_check()) {
                 std::string target_puid, owner_puid, unused_agid;
                 m_privilegeDb.GetAppPuidAndAgid(targetAppName, target_puid, unused_agid);
@@ -2093,7 +2086,7 @@ int ServiceImpl::dropOnePrivateSharing(
                     auto parentDirs = getUniqueParentDirs(otherSharedPaths);
                     auto currentPath = path;
                     do {
-                        SmackLabels::removePrivateSharing(target_uid, currentPath);
+                        DacSetup::removePrivateSharing(target_uid, currentPath);
 
                         auto parentDir = FS::getParentDirectoryName(currentPath);
                         if (parentDirs.count(parentDir) == 1) {
@@ -2102,7 +2095,7 @@ int ServiceImpl::dropOnePrivateSharing(
                             break;
                         }
                         currentPath = parentDir;
-                    } while (!currentPath.empty() && SmackLabels::isAppPrivatePath(owner_uid, currentPath));
+                    } while (!currentPath.empty() && DacSetup::isAppPrivatePath(owner_uid, currentPath));
                 }
             }
         }
@@ -2116,7 +2109,7 @@ int ServiceImpl::dropOnePrivateSharing(
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while dropping private sharing in database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error performing smack operation: " << e.GetMessage());
         errorRet = SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -2185,7 +2178,7 @@ int ServiceImpl::applyPrivatePathSharing(
                     }
                 }
             } else {
-                if (!SmackLabels::isAppPrivatePath(owner_uid, path)) {
+                if (!DacSetup::isAppPrivatePath(owner_uid, path)) {
                     LogError("Path " << path << " does not belong to application " << ownerAppName);
                     return SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER;
                 }
@@ -2222,7 +2215,7 @@ int ServiceImpl::applyPrivatePathSharing(
                                                       (pathCount > 0),
                                                       (ownerTargetCount > 0));
                 if (pathCount <= 0) {
-                    SmackLabels::setupSharedPrivatePath(ownerPkgName, path);
+                    SmackSetup::setupSharedPrivatePath(ownerPkgName, path);
                 }
             } else {
                 // ACLs for parent directories
@@ -2232,9 +2225,9 @@ int ServiceImpl::applyPrivatePathSharing(
 
                 auto currentPath = path;
                 do {
-                    SmackLabels::addPrivateSharing(target_uid, currentPath);
+                    DacSetup::addPrivateSharing(target_uid, currentPath);
                     currentPath = FS::getParentDirectoryName(currentPath);
-                } while (!currentPath.empty() && SmackLabels::isAppPrivatePath(owner_uid, currentPath));
+                } while (!currentPath.empty() && DacSetup::isAppPrivatePath(owner_uid, currentPath));
             }
         }
         trans.commit();
@@ -2242,7 +2235,7 @@ int ServiceImpl::applyPrivatePathSharing(
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while applying private sharing in database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error performing smack operation: " << e.GetMessage());
         errorRet = SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -2338,7 +2331,7 @@ int ServiceImpl::dropPrivatePathSharing(
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Error while dropping private sharing in database: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error performing smack operation: " << e.GetMessage());
         errorRet = SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
@@ -2422,7 +2415,7 @@ int ServiceImpl::pathsRegister(const Credentials &creds, path_req req)
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     }
 
-    return labelPaths(creds, req, isRequestSharedRO, processUids);
+    return labelPaths(req, isRequestSharedRO, processUids);
 }
 
 int ServiceImpl::shmAppName(const Credentials &creds, const std::string &shmName, const std::string &appName)
@@ -2471,7 +2464,7 @@ int ServiceImpl::shmAppName(const Credentials &creds, const std::string &shmName
     } catch (const CynaraException::Base &e) {
         LogError("Error while querying Cynara for permissions: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::Base &e) {
+    } catch (const AccessControlException::Base &e) {
         LogError("Error while set/get smack label in /dev/shm: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const TizenPlatformConfig::Exception::Base &e) {
@@ -2643,7 +2636,7 @@ int ServiceImpl::appSetupNamespace(const Credentials &creds, uid_t appUid, const
     } catch (const CynaraException::Base &e) {
         LogError("Error while querying Cynara for permissions: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-    } catch (const SmackException::InvalidLabel &e) {
+    } catch (const AccessControlException::InvalidLabel &e) {
         LogError("Error while generating Smack labels: " << e.DumpToString());
         return SECURITY_MANAGER_ERROR_SERVER_ERROR;
     } catch (const std::bad_alloc &e) {
index 015353914f24921bc2d7c1b72932eb89ec4b6240..8fe1e86dd54049d421deb8938ddc3d91fe2dc791 100644 (file)
  *
  */
 
-#include <sys/smack.h>
+#include "smack-accesses.h"
 
-#include <dpl/log/log.h>
-#include <smack-exceptions.h>
+#include "access-control-exception.h"
+#include "dpl/log/log.h"
 
-#include "smack-accesses.h"
+#include <sys/smack.h>
 
 namespace SecurityManager {
 
@@ -52,7 +52,7 @@ void SmackAccesses::add(const Smack::Label &subject, const Smack::Label &object,
         const Smack::Permission &permissions)
 {
     if (smack_accesses_add(m_handle, subject.c_str(), object.c_str(), permissions.c_str()))
-        ThrowMsg(SmackException::LibsmackError, "smack_accesses_add");
+        ThrowMsg(AccessControlException::LibsmackError, "smack_accesses_add");
 }
 
 void SmackAccesses::add(const Smack::Rule &rule)
@@ -64,19 +64,19 @@ void SmackAccesses::addModify(const Smack::Label &subject, const Smack::Label &o
         const Smack::Permission &allowPermissions, const Smack::Permission &denyPermissions)
 {
     if (smack_accesses_add_modify(m_handle, subject.c_str(), object.c_str(), allowPermissions.c_str(), denyPermissions.c_str()))
-        ThrowMsg(SmackException::LibsmackError, "smack_accesses_add_modify");
+        ThrowMsg(AccessControlException::LibsmackError, "smack_accesses_add_modify");
 }
 
 void SmackAccesses::clear() const
 {
     if (smack_accesses_clear(m_handle))
-        ThrowMsg(SmackException::LibsmackError, "smack_accesses_clear");
+        ThrowMsg(AccessControlException::LibsmackError, "smack_accesses_clear");
 }
 
 void SmackAccesses::apply() const
 {
     if (smack_accesses_apply(m_handle))
-        ThrowMsg(SmackException::LibsmackError, "smack_accesses_apply");
+        ThrowMsg(AccessControlException::LibsmackError, "smack_accesses_apply");
 
 }
 
index bce9e71f2b3fd9b77078e43d3f443494ce11c333..0934eeefe3ee3da4c5d2ba9725ca6439be5ff4a9 100644 (file)
  * @brief       Source file of a smack utility types and functions
  *
  */
+
+#include "smack-common.h"
+
+#include "access-control-exception.h"
+#include "config-file.h"
+#include "dpl/log/log.h"
+
 #include <cassert>
-#include <config-file.h>
-#include <smack-exceptions.h>
-#include <dpl/log/log.h>
 
 #include <sys/smack.h>
 
-#include "smack-common.h"
-
 namespace SecurityManager {
 
 namespace Smack {
@@ -56,7 +58,7 @@ Rules fromConfig(const std::string &path)
             std::string errorMsg = "Invalid rule template: " + std::to_string(rawRule.size())
                 + " tokens in file " + path + ". Expected 3.";
             LogError(errorMsg);
-            ThrowMsg(SmackException::FileError, errorMsg);
+            ThrowMsg(AccessControlException::FileError, errorMsg);
         }
         rules.push_back(fromRaw(rawRule));
     }
index 7629a7ab56667441bcb47beef2ce3915d18ee5fd..012d59e237136eab775d8b2a388f46c550e64dff 100644 (file)
  *
  */
 
-#include <crypt.h>
-#include <sys/acl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/smack.h>
-#include <sys/xattr.h>
-#include <linux/xattr.h>
-#include <memory>
-#include <fts.h>
-#include <cstring>
-#include <cstdlib>
-#include <filesystem>
-#include <string>
-#include <algorithm>
-
-#include <dpl/log/log.h>
-#include <dpl/errno_string.h>
-#include <variant>
-#include <vector>
+#include "smack-labels.h"
 
-#include "acl.h"
-#include "dpl/exception.h"
-#include "security-manager.h"
-#include "service_impl_utils.h"
+#include "access-control-exception.h"
+#include "dpl/log/log.h"
+#include "protocols.h"
 #include "smack-check.h"
-#include "smack-labels.h"
 #include "utils.h"
 
+#include <crypt.h>
 
-namespace SecurityManager {
-namespace SmackLabels {
-
-//! Smack label used for SECURITY_MANAGER_PATH_PUBLIC_RO paths (RO for all apps)
-const char *const LABEL_FOR_APP_PUBLIC_RO_PATH = "User::Home";
-
-static inline void pathSetSmack(const char *path, const Smack::Label &label,
-        const char *xattr_name)
-{
-    if (smack_set_label_for_path(path, xattr_name, 0, label.c_str())) {
-        LogError("smack_set_label_for_path failed. Path: " << path << " Label:" << label);
-        ThrowMsg(SmackException::FileError,
-            "smack_set_label_for_path failed failed. Path: " << path << " Label: " << label);
-    }
-}
-
-class PathSetup {
-public:
-    explicit PathSetup(bool transmute) : m_transmute(transmute) {}
-    void setup(const std::string &path) const
-    {
-        // setting access label on everything in given directory and below
-        char *const path_argv[] = { const_cast<char*>(path.c_str()), NULL };
-        FTSENT *ftsent;
-
-        auto fts = makeUnique(fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL), fts_close);
-        if (!fts) {
-            LogError("fts_open failed.");
-            ThrowMsg(SmackException::FileError, "fts_open failed.");
-        }
-
-        while ((ftsent = fts_read(fts.get())) != NULL) {
-            /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
-            if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
-                LogError("FTS_ERR error or failed stat(2) (FTS_NS)");
-                ThrowMsg(SmackException::FileError, "FTS_ERR error or failed stat(2) (FTS_NS)");
-            }
-
-            /* avoid to tag directories two times */
-            if (ftsent->fts_info == FTS_D)
-                continue;
-
-            setupFile(ftsent);
-        }
-
-        /* If last call to fts_read() set errno, we need to return error. */
-        if ((errno != 0) && (ftsent == NULL))
-            LogAndThrowErrno(SmackException::FileError, "last fts_read");
-    }
-
-    virtual ~PathSetup() = default;
-
-protected:
-    virtual void setupFile(FTSENT *ftsent) const = 0;
-
-    bool m_transmute;
-};
-
-class SmackSetup: public PathSetup {
-public:
-    SmackSetup(const std::string label, bool transmute) :
-            PathSetup(transmute), m_label(std::move(label))
-    {
-    }
-
-protected:
-    void setupFile(FTSENT *ftsent) const override
-    {
-        pathSetSmack(ftsent->fts_path, m_label, XATTR_NAME_SMACK);
-        if (m_transmute && S_ISDIR(ftsent->fts_statp->st_mode))
-            pathSetSmack(ftsent->fts_path, "TRUE", XATTR_NAME_SMACKTRANSMUTE);
-    }
-
-private:
-    std::string m_label;
-};
-
-void setupPath(
-        const std::string &pkgName,
-        const std::string &path,
-        app_install_path_type pathType,
-        const std::string &authorHash)
-{
-    std::string label;
-    bool label_transmute, follow_symlink = false;
-
-    switch (pathType) {
-    case SECURITY_MANAGER_PATH_RW:
-        label = generatePathRWLabel(pkgName);
-        label_transmute = true;
-        break;
-    case SECURITY_MANAGER_PATH_RO:
-        label = generatePathROLabel(pkgName);
-        label_transmute = false;
-        break;
-    case SECURITY_MANAGER_PATH_PUBLIC_RO:
-        label.assign(LABEL_FOR_APP_PUBLIC_RO_PATH);
-        label_transmute = true;
-        break;
-    case SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO:
-        label = generatePathSharedROLabel();
-        label_transmute = true;
-        follow_symlink = true;
-        break;
-    case SECURITY_MANAGER_PATH_TRUSTED_RW:
-        if (authorHash.empty())
-            ThrowMsg(SmackException::InvalidParam, "You must define author to use PATH_TRUSED_RW");
-        label = generatePathTrustedLabel(authorHash);
-        label_transmute = true;
-        break;
-    default:
-        LogError("Path type not known.");
-        Throw(SmackException::InvalidPathType);
-    }
-    SmackSetup smack(label, label_transmute);
-    if (follow_symlink)
-        smack.setup(realPath(path));
-    smack.setup(path);
-}
-
-struct Dac {
-    // ACL for files and dirs. Effective permissions will be "ANDed" with ACL mask so
-    // non-executable files won't get 'x'
-    Acl acl;
-    uid_t owner;
-    gid_t group;
-};
-
-class DacSetup: public PathSetup {
-public:
-    DacSetup(Dac dac) : PathSetup(true), m_dac(std::move(dac)) {}
-
-    void setupFile(FTSENT *ftsent) const override
-    {
-        if (0 != chown(ftsent->fts_path, m_dac.owner, m_dac.group))
-            ThrowErrno(SmackException::FileError, "chown() for path: " << ftsent->fts_path);
-
-        m_dac.acl.apply(ftsent->fts_path, ACL_TYPE_ACCESS);
-
-        /*
-         *  For newly created files:
-         *  - let the owner come from process (be it app PUId or system_access). The creator clearly
-         *    already has RWX.
-         *  - force the group = system_access using DAC set-group-ID bit so even files created by
-         *    app will be accessible by sys daemons. SM needs CAP_FSETID and system_access group for
-         *    that.
-         *  - Default ACL rules will be applied from the parent directory.
-         */
-        if (m_transmute && ftsent->fts_level == 0 && ftsent->fts_info == FTS_D) {
-            // need to re-read the mode after ACL application above
-            struct stat statbuf;
-            if (0 != stat(ftsent->fts_path, &statbuf))
-                ThrowErrno(SmackException::FileError, "stat() for path: " << ftsent->fts_path);
-
-            // add set-group-ID for system_access
-            if (0 != chmod(ftsent->fts_path, S_ISGID | statbuf.st_mode))
-                ThrowErrno(SmackException::FileError, "chmod() for path: " << ftsent->fts_path);
-
-            // this works on all files/directories below
-            m_dac.acl.apply(ftsent->fts_path, ACL_TYPE_DEFAULT);
-        }
-    }
-
-private:
-    Dac m_dac;
-};
-
-void setupPath(const uid_t owner,
-               const std::string &path,
-               app_install_path_type pathType,
-               const std::vector<uid_t> &processUIds,
-               const std::optional<gid_t> &authorGId)
-{
-    Dac dac;
-    // Make the real user (owner=5001) the owner. No app should run with this uid
-    dac.owner = owner;
-    // Make system_access the group. No app should run with it.
-    dac.group = getSystemAccessGid();
-    acl_perm_t appPerms;
-    acl_perm_t otherPerms;
-    bool follow_symlink;
-    std::vector<Acl::Entry> entries;
-
-    switch (pathType) {
-    case SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO:
-        appPerms = Acl::RWX;
-        otherPerms = Acl::RX;
-        follow_symlink = true;
-        break;
-
-    case SECURITY_MANAGER_PATH_RW:
-        appPerms = Acl::RWX;
-        otherPerms = 0;
-        follow_symlink = false;
-        break;
-
-    case SECURITY_MANAGER_PATH_RO:
-        appPerms = Acl::RX;
-        otherPerms = 0;
-        follow_symlink = false;
-        break;
-
-    case SECURITY_MANAGER_PATH_PUBLIC_RO:
-        appPerms = Acl::RX;
-        otherPerms = Acl::RX;
-        follow_symlink = false;
-        break;
-
-    case SECURITY_MANAGER_PATH_TRUSTED_RW:
-        if (!authorGId.has_value())
-            ThrowMsg(SmackException::InvalidParam, "You must define author to use PATH_TRUSED_RW");
-
-        appPerms = 0;
-        otherPerms = 0;
-        follow_symlink = false;
-        entries.emplace_back(Acl::GidEntry(Acl::RWX, *authorGId));
-        break;
-
-    default:
-        LogError("Path type not known.");
-        Throw(SmackException::InvalidPathType);
-    }
-
-    if (appPerms != 0) {
-        for (auto &processUId : processUIds) {
-            entries.emplace_back(Acl::UidEntry(appPerms, processUId));
-        }
-    }
-
-    // RWX for the owner(5001) and system_access
-    dac.acl = Acl::Make(Acl::RWX, Acl::RWX, otherPerms, std::move(entries));
-
-    DacSetup dacSetup(std::move(dac));
-    if (follow_symlink)
-        dacSetup.setup(realPath(path));
-    dacSetup.setup(path);
-}
-
-void setupPkgBasePath(const std::string &basePath)
-{
-    pathSetSmack(basePath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
-}
-
-void setupPkgBasePath(const Credentials &creds,
-                      const std::string &basePath,
-                      const std::vector<uid_t> &processUIds)
-{
-    // apply public RO access permissions
-    if (0 != chown(basePath.c_str(), creds.uid, getSystemAccessGid()))
-        ThrowErrno(SmackException::FileError, "chown() for path: " << basePath);
-
-    std::vector<Acl::Entry> entries;
-    for (auto &processUId : processUIds)
-        entries.emplace_back(Acl::UidEntry(Acl::RX, processUId));
-
-    auto acl = Acl::Make(Acl::RWX, Acl::RWX, Acl::RX, std::move(entries));
-    acl.apply(basePath, ACL_TYPE_ACCESS);
-}
-
-bool isAppPrivatePath(uid_t appUid, const std::string &path) {
-    static constexpr auto dir_acl_types = {ACL_TYPE_ACCESS, ACL_TYPE_DEFAULT};
-    static constexpr auto file_acl_types = {ACL_TYPE_ACCESS};
-    const auto &acl_types = std::filesystem::is_directory(path) ? dir_acl_types : file_acl_types;
-
-    bool has_owner_rights = false;
-    bool has_other_rights = false;
-    for (auto acl_type : acl_types) {
-        auto acl = Acl::FromFile(path, acl_type);
-        LogDebug("acl from " << path << ":\n" << acl.toString());
-        for (const auto &entry : acl.toEntries()) {
-            auto qualifier = entry.getQualifier();
-            if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
-                if (appUid == uidQualifier->uid
-                    && (entry.getPermissions() & Acl::RW) == Acl::RW)
-                {
-                    has_owner_rights = true;
-                }
-            } else if (entry.getTag() == ACL_OTHER && (entry.getPermissions() != 0)) {
-                has_other_rights = true;
-            }
-        }
-    }
-
-    return has_owner_rights && !has_other_rights;
-}
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <string>
 
-void addPrivateSharing(uid_t targetAppUid, const std::string &path) {
-    LogDebug("add private sharing called for target=" << targetAppUid
-             <<" path=" << path);
-    acl_perm_t perms = std::filesystem::is_directory(path) ? Acl::X : Acl::RX;
-
-    auto acl = Acl::FromFile(path, ACL_TYPE_ACCESS);
-    LogDebug("acl for " << path << " before add:\n " << acl.toString());
-
-    bool entry_exists = false;
-    for (auto &entry: acl.toEntries()) {
-        auto qualifier = entry.getQualifier();
-        if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
-            if (targetAppUid == uidQualifier->uid) {
-                entry_exists = true;
-                break;
-            }
-        }
-    }
-    if (!entry_exists) {
-        acl.addEntry(Acl::UidEntry(perms, targetAppUid));
-    }
-    LogDebug("acl for " << path << " after add:\n " << acl.toString());
-    acl.apply(path, ACL_TYPE_ACCESS);
-}
+#include <fts.h>
+#include <linux/xattr.h>
+#include <sys/smack.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+#include <unistd.h>
 
-void removePrivateSharing(uid_t targetAppUid, const std::string &path) {
-    LogDebug("remove private sharing called for target=" << targetAppUid
-             <<" path=" << path);
-    auto acl = Acl::FromFile(path, ACL_TYPE_ACCESS);
-    LogDebug("acl for " << path << " before remove:\n " << acl.toString());
-
-    for (auto &entry: acl.toEntries()) {
-        auto qualifier = entry.getQualifier();
-        if (auto *uidQualifier = std::get_if<Acl::UidQualifier>(&qualifier)) {
-            if (targetAppUid == uidQualifier->uid) {
-                acl.deleteEntry(std::move(entry));
-                // No other entry for this app should be on the list
-                break;
-            }
-        }
-    }
-    LogDebug("acl for " << path << " after remove:\n " << acl.toString());
-    acl.apply(path, ACL_TYPE_ACCESS);
-}
+namespace SecurityManager {
+namespace SmackLabels {
 
-void setupSharedPrivatePath(const std::string &pkgName, const std::string &path) {
-    pathSetSmack(path.c_str(), generateSharedPrivateLabel(pkgName, path), XATTR_NAME_SMACK);
-}
 
-void generateAppPkgNameFromLabel(const Smack::Label &label, std::string &appName, std::string &pkgName)
+void generateAppPkgNameFromLabel(const Smack::Label &label,
+                                 std::string &appName,
+                                 std::string &pkgName)
 {
     static const char pkgPrefix[] = "User::Pkg::";
     static const char appPrefix[] = "::App::";
 
     if (label.compare(0, sizeof(pkgPrefix) - 1, pkgPrefix))
-        ThrowMsg(SmackException::InvalidLabel, "Invalid application process label " << label);
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Invalid application process label " << label);
 
     size_t pkgStartPos = sizeof(pkgPrefix) - 1;
     size_t pkgEndPos = label.find(appPrefix, pkgStartPos);
@@ -414,7 +80,7 @@ void generateAppPkgNameFromLabel(const Smack::Label &label, std::string &appName
     }
 
     if (pkgName.empty())
-        ThrowMsg(SmackException::InvalidLabel, "No pkgName in Smack label " << label);
+        ThrowMsg(AccessControlException::InvalidLabel, "No pkgName in Smack label " << label);
 }
 
 Smack::Label generateProcessLabel(const std::string &appName, const std::string &pkgName,
@@ -428,7 +94,8 @@ Smack::Label generateProcessLabel(const std::string &appName, const std::string
         label += "::App::" + appName;
 
     if (smack_label_length(label.c_str()) <= 0)
-        ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from appName " << appName);
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Invalid Smack label generated from appName " << appName);
 
     return label;
 }
@@ -449,7 +116,8 @@ Smack::Label generatePathRWLabel(const std::string &pkgName)
     Smack::Label label = "User::Pkg::" + pkgName;
 
     if (smack_label_length(label.c_str()) <= 0)
-        ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from pkgName " << pkgName);
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Invalid Smack label generated from pkgName " << pkgName);
 
     return label;
 }
@@ -462,7 +130,8 @@ Smack::Label generatePathROLabel(const std::string &pkgName)
     Smack::Label label = "User::Pkg::" + pkgName + "::RO";
 
     if (smack_label_length(label.c_str()) <= 0)
-        ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from pkgName " << pkgName);
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Invalid Smack label generated from pkgName " << pkgName);
 
     return label;
 }
@@ -478,12 +147,13 @@ Smack::Label generateSharedPrivateLabel(const std::string &pkgName, const std::s
 
     const char * cryptLabel = crypt(path.c_str(), salt.c_str());
     if (!cryptLabel) {
-        ThrowMsg(SmackException::Base, "crypt error");
+        ThrowMsg(AccessControlException::Base, "crypt error");
     }
     label += cryptLabel;
     std::replace(label.begin(), label.end(), '/', '%');
     if (smack_label_length(label.c_str()) <= 0)
-        ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from path " << path);
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Invalid Smack label generated from path " << path);
     return label;
 }
 
@@ -496,7 +166,7 @@ static Smack::Label getSmackLabel(FuncType func, ArgsType... args)
     char *label;
     ssize_t labelLen = func(args..., &label);
     if (labelLen <= 0)
-        ThrowMsg(SmackException::Base, "Error while getting Smack label");
+        ThrowMsg(AccessControlException::Base, "Error while getting Smack label");
     auto labelPtr = makeUnique(label, free);
     return Smack::Label(labelPtr.get(), labelLen);
 }
@@ -530,7 +200,8 @@ Smack::Label generatePathTrustedLabel(const std::string &authorHash)
 {
     if (authorHash.empty()) {
         LogError("Author was not set. It's not possible to generate label for unknown author.");
-        ThrowMsg(SmackException::InvalidLabel, "Could not generate valid label without author");
+        ThrowMsg(AccessControlException::InvalidLabel,
+                 "Could not generate valid label without author");
     }
 
     return "User::Author::" + authorHash;
@@ -540,14 +211,14 @@ void setSmackLabelForFd(int fd, const Smack::Label &label)
 {
     if (smack_set_label_for_file(fd, XATTR_NAME_SMACK, label.c_str())) {
         LogError("smack_set_label_for_file failed.");
-        ThrowMsg(SmackException::FileError, "smack_set_label_for_file failed.");
+        ThrowMsg(AccessControlException::FileError, "smack_set_label_for_file failed.");
     }
 }
 
 void revokeSubject(const Smack::Label &label)
 {
     if (smack_revoke_subject(label.c_str()))
-        ThrowMsg(SmackException::LibsmackError, "smack_revoke_subject failed for " + label);
+        ThrowMsg(AccessControlException::LibsmackError, "smack_revoke_subject failed for " + label);
 }
 
 } // namespace SmackLabels
index 8910634ee92f21a65a62108d8c1d741beff8ef39..faf4d7194ba9ca86e402e494c001e0aeeaba52bf 100644 (file)
  *
  */
 
-#include <string>
-#include <map>
-
-#include <config.h>
-#include <config-file.h>
-#include <dpl/log/log.h>
-#include <dpl/errno_string.h>
-#include <smack-check.h>
-#include <smack-exceptions.h>
-#include <smack-labels.h>
+#include "smack-rules.h"
+
+#include "dpl/log/log.h"
+#include "smack-check.h"
+#include "smack-labels.h"
+
 #include <tzplatform-config.h>
 
-#include "smack-rules.h"
+#include <string>
 
 namespace SecurityManager {
 
diff --git a/src/common/smack-setup.cpp b/src/common/smack-setup.cpp
new file mode 100644 (file)
index 0000000..2d03f5a
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#include "smack-setup.h"
+
+#include "access-control-exception.h"
+#include "dpl/log/log.h"
+#include "service_impl_utils.h"
+#include "smack-common.h"
+#include "smack-labels.h"
+
+#include <fts.h>
+#include <linux/xattr.h>
+#include <sys/smack.h>
+#include <sys/stat.h>
+#include <sys/xattr.h>
+
+namespace SecurityManager {
+namespace {
+
+void pathSetSmack(const char *path, const Smack::Label &label, const char *xattr_name)
+{
+    if (smack_set_label_for_path(path, xattr_name, 0, label.c_str())) {
+        LogError("smack_set_label_for_path failed. Path: " << path << " Label:" << label);
+        ThrowMsg(AccessControlException::FileError,
+            "smack_set_label_for_path failed failed. Path: " << path << " Label: " << label);
+    }
+}
+
+} // namespace
+
+void SmackSetup::setupPkgBasePath(const std::string &basePath)
+{
+    pathSetSmack(basePath.c_str(), SmackLabels::LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
+}
+
+void SmackSetup::setupSharedPrivatePath(const std::string &pkgName, const std::string &path) {
+    pathSetSmack(path.c_str(),
+                 SmackLabels::generateSharedPrivateLabel(pkgName, path),
+                 XATTR_NAME_SMACK);
+}
+
+void SmackSetup::setupPath(
+        const std::string &pkgName,
+        const std::string &path,
+        app_install_path_type pathType,
+        const std::string &authorHash)
+{
+    std::string label;
+    bool label_transmute, follow_symlink = false;
+
+    switch (pathType) {
+    case SECURITY_MANAGER_PATH_RW:
+        label = SmackLabels::generatePathRWLabel(pkgName);
+        label_transmute = true;
+        break;
+    case SECURITY_MANAGER_PATH_RO:
+        label = SmackLabels::generatePathROLabel(pkgName);
+        label_transmute = false;
+        break;
+    case SECURITY_MANAGER_PATH_PUBLIC_RO:
+        label.assign(SmackLabels::LABEL_FOR_APP_PUBLIC_RO_PATH);
+        label_transmute = true;
+        break;
+    case SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO:
+        label = SmackLabels::generatePathSharedROLabel();
+        label_transmute = true;
+        follow_symlink = true;
+        break;
+    case SECURITY_MANAGER_PATH_TRUSTED_RW:
+        if (authorHash.empty())
+            ThrowMsg(AccessControlException::InvalidParam,
+                     "You must define author to use PATH_TRUSED_RW");
+        label = SmackLabels::generatePathTrustedLabel(authorHash);
+        label_transmute = true;
+        break;
+    default:
+        LogError("Path type not known.");
+        Throw(AccessControlException::InvalidParam);
+    }
+    SmackSetup smack(label, label_transmute);
+    if (follow_symlink)
+        smack.setup(realPath(path));
+    smack.setup(path);
+}
+
+void SmackSetup::setupFile(FTSENT *ftsent) const
+{
+    pathSetSmack(ftsent->fts_path, m_label, XATTR_NAME_SMACK);
+    if (m_transmute && S_ISDIR(ftsent->fts_statp->st_mode))
+        pathSetSmack(ftsent->fts_path, "TRUE", XATTR_NAME_SMACKTRANSMUTE);
+}
+
+} // namespace SecurityManager
index 1bc75b3a589f6c429faa55d369cac41d6fe574d0..883abf7a0c05b24783dc7a6201e292b75e52b13c 100644 (file)
  * @brief       Source file of a smack rules template manager
  */
 
-#include <config.h>
-#include <config-file.h>
-#include <dpl/log/log.h>
-#include <filesystem.h>
-#include <smack-exceptions.h>
-
 #include "template-manager.h"
 
+#include "access-control-exception.h"
+#include "config-file.h"
+#include "dpl/log/log.h"
+#include "filesystem-exception.h"
+
 namespace SecurityManager {
 
 namespace {
@@ -61,7 +60,7 @@ void TemplateManager::init()
     } catch (FS::Exception::Base &e) {
         LogError("Error loading config files: " << e.DumpToString());
         Throw(TemplateManagerException::ConfigFileError);
-    } catch (SmackException::FileError &e) {
+    } catch (AccessControlException::FileError &e) {
         LogError("Error parsing config files: " << e.DumpToString());
         Throw(TemplateManagerException::ConfigParseError);
     }
index 4da06aae4be2b480fe11de751975a6c66b9a5333..0c12e92031799e6905b86ae33f86ef2cf8558ab2 100644 (file)
  * @brief       Implementation of security-manager cleanup service
  */
 
+#include "dpl/errno_string.h"
+#include "filesystem.h"
+#include "privilege_db.h"
+#include "smack-setup.h"
+
 #include <cstdlib>
 #include <cstring>
-#include <fcntl.h>
 #include <iostream>
-#include <unistd.h>
+
+#include <fcntl.h>
 #include <sys/stat.h>
-#include <privilege_db.h>
-#include <smack-labels.h>
-#include <dpl/errno_string.h>
-#include <filesystem.h>
+#include <unistd.h>
 
 namespace {
 const std::string tmp_flag = "/tmp/sm-cleanup-tmp-flag";
@@ -73,7 +75,7 @@ int main(void)
                 db.GetAppPkgName(appPaths.first, pkgName);
                 for (const auto &path : appPaths.second) {
                     //FIXME Make this service run as slave and master
-                    SmackLabels::setupPath(pkgName, path, SECURITY_MANAGER_PATH_RW);
+                    SmackSetup::setupPath(pkgName, path, SECURITY_MANAGER_PATH_RW);
                 }
             } catch (const SecurityManager::Exception &e) {
                 LogError("Got SecurityManager exception: " << e.GetMessage() << ", ignoring");
index fa3ab33718611f16c32ad54b1fb67383a2b024ec..af3c1566570a8edcc7738214a887eefc8e86f722 100644 (file)
@@ -116,8 +116,10 @@ SET(SM_TESTS_SOURCES
     ${PROJECT_SOURCE_DIR}/src/common/check-proper-drop.cpp
     ${PROJECT_SOURCE_DIR}/src/common/config-file.cpp
     ${PROJECT_SOURCE_DIR}/src/common/credentials.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/dac-setup.cpp
     ${PROJECT_SOURCE_DIR}/src/common/filesystem.cpp
     ${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/path-setup.cpp
     ${PROJECT_SOURCE_DIR}/src/common/permissible-set.cpp
     ${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp
     ${PROJECT_SOURCE_DIR}/src/common/service_impl_utils.cpp
@@ -126,6 +128,7 @@ SET(SM_TESTS_SOURCES
     ${PROJECT_SOURCE_DIR}/src/common/smack-check.cpp
     ${PROJECT_SOURCE_DIR}/src/common/smack-labels.cpp
     ${PROJECT_SOURCE_DIR}/src/common/smack-rules.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/smack-setup.cpp
     ${PROJECT_SOURCE_DIR}/src/common/template-manager.cpp
     ${PROJECT_SOURCE_DIR}/src/common/filesystem.cpp
     ${PROJECT_SOURCE_DIR}/src/common/tzplatform-config.cpp
index 73c18e857e0fae632a1ef30f5748e06a3c5e4fdd..fa0f0f469d467c9fc2fe991e1ed5798090c93358 100644 (file)
  * limitations under the License.
  */
 
-#include <sys/types.h>
-#include <sys/stat.h>
+#include "acl.h"
+#include "access-control-exception.h"
+#include "testmacros.h"
+
 #include <acl/libacl.h>
-#include <unistd.h>
-#include <fcntl.h>
+
 #include <cstdint>
-#include <unordered_set>
 #include <optional>
+#include <unordered_set>
 
-#include <testmacros.h>
-
-#include "acl.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 using namespace SecurityManager;
 
@@ -437,16 +439,16 @@ NEGATIVE_TEST_CASE(T1840_malformed)
 {
     File file(TEST_FILE, 0000);
     Acl acl;
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_ACCESS), Acl::Exception::Base);
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_DEFAULT), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_ACCESS), AccessControlException::Base);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_DEFAULT), AccessControlException::Base);
 }
 
 NEGATIVE_TEST_CASE(T1850_no_file)
 {
     auto acl = Acl::Make(0, 0, 0);
 
-    BOOST_REQUIRE_THROW(acl.apply(TEST_FILE, ACL_TYPE_DEFAULT), Acl::Exception::Base);
-    BOOST_REQUIRE_THROW(acl.apply(TEST_FILE, ACL_TYPE_DEFAULT), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(acl.apply(TEST_FILE, ACL_TYPE_DEFAULT), AccessControlException::FileError);
+    BOOST_REQUIRE_THROW(acl.apply(TEST_FILE, ACL_TYPE_DEFAULT), AccessControlException::FileError);
 }
 
 NEGATIVE_TEST_CASE(T1860_wrong_type)
@@ -455,9 +457,9 @@ NEGATIVE_TEST_CASE(T1860_wrong_type)
 
     auto acl = Acl::Make(0, 0, 0);
 
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 0), Acl::Exception::Base);
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 1), Acl::Exception::Base);
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 0xFFFF), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 0), AccessControlException::FileError);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 1), AccessControlException::FileError);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), 0xFFFF), AccessControlException::FileError);
 }
 
 NEGATIVE_TEST_CASE(T1870_default_on_file)
@@ -466,7 +468,8 @@ NEGATIVE_TEST_CASE(T1870_default_on_file)
 
     auto acl = Acl::Make(0, 0, 0);
 
-    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_DEFAULT), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(acl.apply(file.Path(), ACL_TYPE_DEFAULT),
+                        AccessControlException::FileError);
 }
 
 NEGATIVE_TEST_CASE(T1880_duplicated_entries)
@@ -477,13 +480,13 @@ NEGATIVE_TEST_CASE(T1880_duplicated_entries)
     entries.emplace_back(Acl::UidEntry(Acl::RWX, 5001));
     entries.emplace_back(Acl::UidEntry(Acl::R, 5001));
 
-    BOOST_REQUIRE_THROW(Acl::Make(0, 0, 0, std::move(entries)), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(Acl::Make(0, 0, 0, std::move(entries)), AccessControlException::AclError);
 
     entries = std::vector<Acl::Entry>{};
     entries.emplace_back(Acl::GidEntry(Acl::RWX, 100));
     entries.emplace_back(Acl::GidEntry(Acl::R, 100));
 
-    BOOST_REQUIRE_THROW(Acl::Make(0, 0, 0, std::move(entries)), Acl::Exception::Base);
+    BOOST_REQUIRE_THROW(Acl::Make(0, 0, 0, std::move(entries)), AccessControlException::AclError);
 }
 
 POSITIVE_TEST_CASE(T1890_default_file_creation)
index 2be5facac8d797f16d0914595d66803f4b256a6c..f087b7e628b107b23ee15f203828412e6c80a168 100644 (file)
  * @version    1.0
  */
 
+#include "access-control-exception.h"
+#include "protocols.h"
+#include "smack-labels.h"
+#include "smack-setup.h"
+#include "testmacros.h"
+
 #include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/xattr.h>
 #include <linux/xattr.h>
 #include <sys/smack.h>
-
-#include <dpl/log/log.h>
-#include <smack-labels.h>
-
-#include "protocols.h"
-
-#include <testmacros.h>
+#include <sys/stat.h>
+#include <sys/xattr.h>
 
 using namespace SecurityManager;
 using namespace SecurityManager::SmackLabels;
@@ -134,25 +133,26 @@ NEGATIVE_FIXTURE_TEST_CASE(T1011_set_smack_label_file, FileFixture)
 {
     int invalidFd = -1;
     const std::string validLabel = "smack_label";
-    BOOST_REQUIRE_THROW(setSmackLabelForFd(invalidFd, validLabel), SmackException::FileError);
+    BOOST_REQUIRE_THROW(setSmackLabelForFd(invalidFd, validLabel),
+                        AccessControlException::FileError);
 }
 
 NEGATIVE_FIXTURE_TEST_CASE(T1012_set_smack_label_file, FileFixture)
 {
     const std::string invalidLabel = "";
-    BOOST_REQUIRE_THROW(setSmackLabelForFd(fd, invalidLabel), SmackException::FileError);
+    BOOST_REQUIRE_THROW(setSmackLabelForFd(fd, invalidLabel), AccessControlException::FileError);
 }
 
 NEGATIVE_FIXTURE_TEST_CASE(T1013_get_smack_label_file, FileFixture)
 {
     int invalidFd = -1;
-    BOOST_REQUIRE_THROW(getSmackLabelFromFd(invalidFd), SmackException::Base);
+    BOOST_REQUIRE_THROW(getSmackLabelFromFd(invalidFd), AccessControlException::Base);
 }
 
 NEGATIVE_FIXTURE_TEST_CASE(T1014_get_smack_label_file, FileFixture)
 {
     const std::string noExistingFilePath = "/tmp/SecurityManagerUTNoExistingFile";
-    BOOST_REQUIRE_THROW(getSmackLabelFromPath(noExistingFilePath), SmackException::Base);
+    BOOST_REQUIRE_THROW(getSmackLabelFromPath(noExistingFilePath), AccessControlException::Base);
 }
 
 POSITIVE_TEST_CASE(T1020_get_smack_label_process)
@@ -170,7 +170,7 @@ POSITIVE_TEST_CASE(T1020_get_smack_label_process)
 NEGATIVE_TEST_CASE(T1021_get_smack_label_process)
 {
     pid_t invalidPid = -1;
-    BOOST_REQUIRE_THROW(getSmackLabelFromPid(invalidPid), SmackException::Base);
+    BOOST_REQUIRE_THROW(getSmackLabelFromPid(invalidPid), AccessControlException::Base);
 }
 
 NEGATIVE_TEST_CASE(T1022_generate_smack_label_invalid_pkg)
@@ -178,9 +178,9 @@ NEGATIVE_TEST_CASE(T1022_generate_smack_label_invalid_pkg)
     const std::string appName = "appNameT1030";
     const std::string invalidPkgName = "  ";
     BOOST_REQUIRE_THROW(generateProcessLabel(appName, invalidPkgName, false),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
     BOOST_REQUIRE_THROW(generateProcessLabel(appName, invalidPkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1023_generate_smack_label_invalid_app)
@@ -189,27 +189,28 @@ NEGATIVE_TEST_CASE(T1023_generate_smack_label_invalid_app)
     const std::string invalidPkgName = "  ";
     const std::string pkgName = "pkgNameT1031";
     BOOST_REQUIRE_THROW(generateProcessLabel(invalidAppName, pkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
     BOOST_REQUIRE_THROW(generateProcessLabel(invalidAppName, invalidPkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1024_generate_smack_label_path_rw_invalid_pkg)
 {
     const std::string invalidPkgName = " ";
-    BOOST_REQUIRE_THROW(generatePathRWLabel(invalidPkgName), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generatePathRWLabel(invalidPkgName), AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1025_generate_smack_label_path_ro_invalid_pkg)
 {
     const std::string invalidPkgName = "  ";
-    BOOST_REQUIRE_THROW(generatePathROLabel(invalidPkgName), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generatePathROLabel(invalidPkgName), AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1026_generate_smack_label_path_trusted_invalid_author)
 {
     const std::string invalidAuthorHash = "";
-    BOOST_REQUIRE_THROW(generatePathTrustedLabel(invalidAuthorHash), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generatePathTrustedLabel(invalidAuthorHash),
+                        AccessControlException::InvalidLabel);
 }
 
 POSITIVE_TEST_CASE(T1030_generate_smack_labels)
@@ -246,7 +247,7 @@ NEGATIVE_TEST_CASE(T1031_generate_smack_label_invalid_pkg_name_non_hybrid)
     const std::string invalidPkgName = " ";
 
     BOOST_REQUIRE_THROW(generateProcessLabel(appName, invalidPkgName, false),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1032_generate_smack_label_invalid_pkg_name_hybrid)
@@ -255,7 +256,7 @@ NEGATIVE_TEST_CASE(T1032_generate_smack_label_invalid_pkg_name_hybrid)
     const std::string invalidPkgName = " ";
 
     BOOST_REQUIRE_THROW(generateProcessLabel(appName, invalidPkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1033_generate_smack_label_invalid_app_name_hybrid)
@@ -264,7 +265,7 @@ NEGATIVE_TEST_CASE(T1033_generate_smack_label_invalid_app_name_hybrid)
     const std::string pkgName = "pkgNameT1033";
 
     BOOST_REQUIRE_THROW(generateProcessLabel(invalidAppName, pkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1034_generate_smack_label_invalid_app_and_pkg_hybrd)
@@ -273,7 +274,7 @@ NEGATIVE_TEST_CASE(T1034_generate_smack_label_invalid_app_and_pkg_hybrd)
     const std::string invalidPkgName = " ";
 
     BOOST_REQUIRE_THROW(generateProcessLabel(invalidAppName, invalidPkgName, true),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 NEGATIVE_TEST_CASE(T1035_generate_smack_label_invalid_app_and_pkg_non_hybrd)
@@ -282,7 +283,7 @@ NEGATIVE_TEST_CASE(T1035_generate_smack_label_invalid_app_and_pkg_non_hybrd)
     const std::string invalidPkgName = " ";
 
     BOOST_REQUIRE_THROW(generateProcessLabel(invalidAppName, invalidPkgName, false),
-                        SmackException::InvalidLabel);
+                        AccessControlException::InvalidLabel);
 }
 
 POSITIVE_TEST_CASE(T1041_generate_app_pkg_name_from_label)
@@ -306,23 +307,27 @@ NEGATIVE_TEST_CASE(T1042_generate_app_pkg_name_from_label)
 {
     std::string app, pkg;
     static constexpr char invalidPrefixLabel[] = "User::Pkg:InvalidPrefix";
-    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(invalidPrefixLabel, app, pkg), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(invalidPrefixLabel, app, pkg),
+                        AccessControlException::InvalidLabel);
 
     static constexpr char emptyPkgNameLabel[] = "User::Pkg::";
-    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel, app, pkg), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel, app, pkg),
+                        AccessControlException::InvalidLabel);
 
     static constexpr char emptyPkgNameLabel2[] = "User::Pkg::::App::AppName";
-    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel2, app, pkg), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel2, app, pkg),
+                        AccessControlException::InvalidLabel);
 
     static constexpr char emptyPkgNameLabel3[] = "System::Privileged";
-    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel3, app, pkg), SmackException::InvalidLabel);
+    BOOST_REQUIRE_THROW(generateAppPkgNameFromLabel(emptyPkgNameLabel3, app, pkg),
+                        AccessControlException::InvalidLabel);
 }
 
 POSITIVE_FIXTURE_TEST_CASE(T1050_setup_path_rw, DirectoryFixture)
 {
     const std::string pkgName = "pkgNameT1050";
 
-    BOOST_REQUIRE_NO_THROW(setupPath(pkgName, directoryPath, SECURITY_MANAGER_PATH_RW));
+    BOOST_REQUIRE_NO_THROW(SmackSetup::setupPath(pkgName, directoryPath, SECURITY_MANAGER_PATH_RW));
     const std::string pathRWLabel = generatePathRWLabel(pkgName);
 
     BOOST_REQUIRE(pathRWLabel == getLabel(directoryPath, XATTR_NAME_SMACK));
@@ -340,8 +345,9 @@ NEGATIVE_FIXTURE_TEST_CASE(T1052_setup_path_rw, DirectoryFixture)
 {
     const std::string pkgName = "pkgNameT1052";
 
-    BOOST_REQUIRE_THROW(setupPath(pkgName, directoryPath, static_cast<app_install_path_type>(-1)),
-                        SmackException::InvalidPathType);
+    BOOST_REQUIRE_THROW(
+            SmackSetup::setupPath(pkgName, directoryPath, static_cast<app_install_path_type>(-1)),
+            AccessControlException::InvalidParam);
 }
 
 NEGATIVE_FIXTURE_TEST_CASE(T1053_setup_path_rw, DirectoryFixture)
@@ -349,8 +355,12 @@ NEGATIVE_FIXTURE_TEST_CASE(T1053_setup_path_rw, DirectoryFixture)
     const std::string pkgName = "pkgNameT1053";
     const std::string invalidAuthorHash = "";
 
-    BOOST_REQUIRE_THROW(setupPath(pkgName, directoryPath, SECURITY_MANAGER_PATH_TRUSTED_RW, invalidAuthorHash),
-                        SmackException::InvalidParam);
+    BOOST_REQUIRE_THROW(
+            SmackSetup::setupPath(pkgName,
+                                  directoryPath,
+                                  SECURITY_MANAGER_PATH_TRUSTED_RW,
+                                  invalidAuthorHash),
+            AccessControlException::InvalidParam);
 }
 
 NEGATIVE_FIXTURE_TEST_CASE(T1054_setup_path_rw, DirectoryFixture)
@@ -358,15 +368,16 @@ NEGATIVE_FIXTURE_TEST_CASE(T1054_setup_path_rw, DirectoryFixture)
     const std::string pkgName = "pkgNameT1054";
     const std::string noExistingDirectoryPath = "/tmp/SecurityManagerUTNoExistingDirectory/";
 
-    BOOST_REQUIRE_THROW(setupPath(pkgName, noExistingDirectoryPath, SECURITY_MANAGER_PATH_RW),
-                        SmackException::FileError);
+    BOOST_REQUIRE_THROW(
+            SmackSetup::setupPath(pkgName, noExistingDirectoryPath, SECURITY_MANAGER_PATH_RW),
+            AccessControlException::FileError);
 }
 
 POSITIVE_FIXTURE_TEST_CASE(T1060_setup_path_ro, DirectoryFixture)
 {
     const std::string pkgName = "pkgNameT1060";
 
-    BOOST_REQUIRE_NO_THROW(setupPath(pkgName, directoryPath, SECURITY_MANAGER_PATH_RO));
+    BOOST_REQUIRE_NO_THROW(SmackSetup::setupPath(pkgName, directoryPath, SECURITY_MANAGER_PATH_RO));
     const std::string pathROLabel = generatePathROLabel(pkgName);
 
     BOOST_REQUIRE(pathROLabel == getLabel(directoryPath, XATTR_NAME_SMACK));
index 79d2c631e2bc0530402c44cd4599c8191784cd81..ea90747c76f0d273f734ff112028940892647d30 100644 (file)
  * @version    1.0
  */
 
+#include "access-control-exception.h"
+#include "privilege_db.h"
+#include "smack-accesses.h"
+#include "smack-labels.h"
+#include "smack-rules.h"
+#include "testmacros.h"
+
 #include <algorithm>
-#include <fstream>
 #include <string>
 #include <vector>
 
-#include <smack-accesses.h>
-#include <smack-rules.h>
-#include <smack-labels.h>
-#include <privilege_db.h>
-#include <testmacros.h>
-
 using namespace SecurityManager;
 using namespace SecurityManager::SmackLabels;
 
@@ -84,21 +84,23 @@ NEGATIVE_TEST_CASE(T1119_smack_rules_exception_invalid_perm)
     SmackAccesses smackRules;
 
     BOOST_REQUIRE_THROW(smackRules.add("subject", "object", "invalidPermission"),
-                        SmackException::LibsmackError);
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1120_smack_rules_exception_invalid_object)
 {
     SmackAccesses smackRules;
 
-    BOOST_REQUIRE_THROW(smackRules.add("subject", "", "rwxatl"), SmackException::LibsmackError);
+    BOOST_REQUIRE_THROW(smackRules.add("subject", "", "rwxatl"),
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1121_smack_rules_exception_invalid_subject)
 {
     SmackAccesses smackRules;
 
-    BOOST_REQUIRE_THROW(smackRules.add("", "object", "rwxatl"), SmackException::LibsmackError);
+    BOOST_REQUIRE_THROW(smackRules.add("", "object", "rwxatl"),
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1122_smack_rules_exception_addModify_invalid_permission)
@@ -106,7 +108,7 @@ NEGATIVE_TEST_CASE(T1122_smack_rules_exception_addModify_invalid_permission)
     SmackAccesses smackRules;
 
     BOOST_REQUIRE_THROW(smackRules.addModify("subject", "object", "invalidPermission", ""),
-                        SmackException::LibsmackError);
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1123_smack_rules_exception_addModify_invalid_permission)
@@ -114,7 +116,7 @@ NEGATIVE_TEST_CASE(T1123_smack_rules_exception_addModify_invalid_permission)
     SmackAccesses smackRules;
 
     BOOST_REQUIRE_THROW(smackRules.addModify("subject", "object", "", "invalidPermission"),
-                        SmackException::LibsmackError);
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1124_smack_rules_exception_addModify_invalid_object)
@@ -122,7 +124,7 @@ NEGATIVE_TEST_CASE(T1124_smack_rules_exception_addModify_invalid_object)
     SmackAccesses smackRules;
 
     BOOST_REQUIRE_THROW(smackRules.addModify("subject", "", "rw", "xt"),
-                        SmackException::LibsmackError);
+                        AccessControlException::LibsmackError);
 }
 
 NEGATIVE_TEST_CASE(T1125_smack_rules_exception_addModify_invalid_subject)
@@ -130,7 +132,7 @@ NEGATIVE_TEST_CASE(T1125_smack_rules_exception_addModify_invalid_subject)
     SmackAccesses smackRules;
 
     BOOST_REQUIRE_THROW(smackRules.addModify("", "object", "rw", "xt"),
-                        SmackException::LibsmackError);
+                        AccessControlException::LibsmackError);
 }
 
 POSITIVE_TEST_CASE(T1126_smack_rules_exception)
@@ -146,7 +148,7 @@ NEGATIVE_TEST_CASE(NAME)                        \
 {                                               \
     BOOST_REQUIRE_THROW(                        \
         SmackAccesses().add(SUBJ, OBJ, PERM),   \
-            SmackException::LibsmackError);     \
+            AccessControlException::LibsmackError);     \
 }
 
 NEGATIVE_RULE_ADD(T1127_smack_rules_exception_invalid_printable_character_subject, "subject/", "object", "rwxat")
@@ -169,7 +171,7 @@ NEGATIVE_TEST_CASE(T1135_smack_rules_exception_ASCII_s_check_ ## n) \
     std::string object = "object";                                  \
     subject[0] = n; /* unprintable */                               \
     BOOST_REQUIRE_THROW(smackRules.add(subject, object, "rwxat"),   \
-                        SmackException::LibsmackError);             \
+                        AccessControlException::LibsmackError);     \
 }
 
 #define NEGATIVE_ASCII_OBJECT(n)                                    \
@@ -180,7 +182,7 @@ NEGATIVE_TEST_CASE(T1136_smack_rules_exception_ASCII_o_check_ ## n) \
     std::string object = "object";                                  \
     object[0] = n; /* unprintable */                                \
     BOOST_REQUIRE_THROW(smackRules.add(subject, object, "rwxat"),   \
-                        SmackException::LibsmackError);             \
+                        AccessControlException::LibsmackError);     \
 }
 
 NEGATIVE_ASCII_SUBJECT(1)