From 3f0d4f15bf318ccd1c8306ccfbe4210fb76c3d3c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Thu, 11 Jul 2013 15:15:45 +0200 Subject: [PATCH] Support Linux ACLs (only poor testing for now...). --- dist/dmlite-plugins-vfs.spec | 1 + src/CMakeLists.txt | 2 +- src/VfsNs.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/dist/dmlite-plugins-vfs.spec b/dist/dmlite-plugins-vfs.spec index f04d64d..9473765 100644 --- a/dist/dmlite-plugins-vfs.spec +++ b/dist/dmlite-plugins-vfs.spec @@ -15,6 +15,7 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: cmake BuildRequires: cppunit-devel BuildRequires: dmlite-devel +BuildRequires: libacl-devel%{?_isa} %description This package provides the filesystem plugin for dmlite. This plugin provides both diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c21c55..5d8445d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ add_library (vfs MODULE Vfs.cpp Throw.cpp ) -target_link_libraries (vfs ${DMLITE_LIBRARIES}) +target_link_libraries (vfs ${DMLITE_LIBRARIES} -lacl) set_target_properties (vfs PROPERTIES PREFIX "plugin_") install (TARGETS vfs diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index e7f1ec0..bad03f0 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -1,8 +1,11 @@ /// @file VfsNs.cpp /// @brief VFS namespace. /// @author Alejandro Álvarez Ayllón +#include #include #include +//debug... +#include #include #include #include @@ -200,7 +203,64 @@ void VfsCatalog::setChecksum(const std::string& path, void VfsCatalog::setAcl(const std::string& path, const Acl& acl) throw (DmException) { - throw DmException(EACCES, "Write mode not supported"); + acl_t lacl; + acl_type_t ltype; + acl_entry_t lentry; + acl_tag_t ltag; + acl_permset_t lpermset; + size_t i; + uid_t uid; + gid_t gid; + + wrapCall(lacl = acl_init(acl.size()), "error initializing Linux ACL"); + ltype = ACL_TYPE_ACCESS; + try { + for (i = 0; i < acl.size(); i++) { + switch (acl[i].type) { + case AclEntry::kUserObj: ltag = ACL_USER_OBJ; break; + case AclEntry::kUser: ltag = ACL_USER; break; + case AclEntry::kGroupObj: ltag = ACL_GROUP_OBJ; break; + case AclEntry::kGroup: ltag = ACL_GROUP; break; + case AclEntry::kMask: ltag = ACL_MASK; break; + case AclEntry::kOther:ltag = ACL_OTHER; break; + case AclEntry::kDefault: + ltype = ACL_TYPE_DEFAULT; + continue; + break; + default: + vfsThrow(DMLITE_SYSERR(EINVAL), "unkown ACL type no " + std::string(1, '0' + acl[i].type)); + } + + wrapCall(acl_create_entry(&lacl, &lentry), "error creating Linux ACL entry (acl_create_entry)"); + // object type + wrapCall(acl_set_tag_type(lentry, ltag), "error setting tag type on Linux ACL (acl_set_tag_type)"); + // qualifier + if (acl[i].type == AclEntry::kUser) { + uid = acl[i].id; + wrapCall(acl_set_qualifier(lentry, &uid), "error setting uid qualifier in Linux ACL entry (acl_set_qualifier)"); + } else if (acl[i].type == AclEntry::kUser) { + gid = acl[i].id; + wrapCall(acl_set_qualifier(lentry, &gid), "error setting gid qualifier in Linux ACL entry (acl_set_qualifier)"); + } + // permission set + wrapCall(acl_get_permset(lentry, &lpermset), "error getting Linux ACL permission set (acl_get_permset)"); + wrapCall(acl_clear_perms(lpermset), "error clearing Linux ACL permission set (acl_clear_permset)"); + if ((acl[i].perm & 4)) + wrapCall(acl_add_perm(lpermset, ACL_READ), "error setting read permission on Linux ACL permission set (acl_add_perm)"); + if ((acl[i].perm & 2)) + wrapCall(acl_add_perm(lpermset, ACL_WRITE), "error setting write permission on Linux ACL permission set (acl_add_perm)"); + if ((acl[i].perm & 1)) + wrapCall(acl_add_perm(lpermset, ACL_EXECUTE), "error setting execute permission on Linux ACL permission set (acl_add_perm)"); + } + +std::cerr << "ACL: \"" << acl.serialize() << "\" ==>\n(\n" + std::string(acl_to_text(lacl, NULL)) + ")\n"; + + wrapCall(acl_set_file(path.c_str(), ltype, lacl), "error setting Linux ACL on '" + path + "'"); + wrapCall(acl_free(lacl), "error freeing Linux ACL"); + } catch (...) { + acl_free(lacl); + throw; + } } -- 1.8.2.3