Support Linux ACLs (only poor testing for now...). acl_not_used
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 11 Jul 2013 13:15:45 +0000 (15:15 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Wed, 14 Aug 2013 12:09:01 +0000 (14:09 +0200)
dist/dmlite-plugins-vfs.spec
src/CMakeLists.txt
src/VfsNs.cpp

index f04d64d..9473765 100644 (file)
@@ -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
index 7c21c55..5d8445d 100644 (file)
@@ -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
index e7f1ec0..bad03f0 100644 (file)
@@ -1,8 +1,11 @@
 /// @file   VfsNs.cpp
 /// @brief  VFS namespace.
 /// @author Alejandro Álvarez Ayllón <aalvarez@cern.ch>
+#include <sys/acl.h>
 #include <cstdlib>
 #include <cstring>
+//debug...
+#include <iostream>
 #include <dmlite/cpp/dmlite.h>
 #include <dmlite/cpp/utils/urls.h>
 #include <errno.h>
@@ -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;
+  }
 }