/// @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>
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;
+ }
}