]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix setting empty default ACL
authorYan, Zheng <zyan@redhat.com>
Wed, 11 May 2016 13:46:23 +0000 (21:46 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 11 May 2016 14:04:42 +0000 (22:04 +0800)
'cp -a ...' may call setxattr(..., "system.posix_acl_default",
"\2\0\0", 4, 0). The ACL xattr only include ACL header. Client
should remove ACL in this case.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/posix_acl.cc

index 7fcd907bc6898df80b1fe8760b64f2e27633cbf7..61238091836fa3bf080bb4d8f4ac9f3b95690024 100644 (file)
@@ -9887,8 +9887,13 @@ int Client::_setxattr(Inode *in, const char *name, const void *value,
       if (value) {
        if (!S_ISDIR(in->mode))
          return -EACCES;
-       if (!posix_acl_check(value, size))
+       int ret = posix_acl_check(value, size);
+       if (ret < 0)
          return -EINVAL;
+       if (ret == 0) {
+         value = NULL;
+         size = 0;
+       }
       }
     } else {
       return -EOPNOTSUPP;
index 50cb85176bc72381d64bc45d43d41ca02c9687d9..c5277ab7b060e55a92bd51cae8edeccd3f311fca 100644 (file)
@@ -7,19 +7,22 @@ int posix_acl_check(const void *xattr, size_t size)
 {
   const acl_ea_header *header;
   if (size < sizeof(*header))
-    return 0;
+    return -1;
   header = reinterpret_cast<const acl_ea_header*>(xattr);
   ceph_le32 expected_version;
   expected_version = ACL_EA_VERSION;
   if (header->a_version != expected_version)
-    return 0;
+    return -1;
 
   const acl_ea_entry *entry = header->a_entries;
   size -= sizeof(*header);
   if (size % sizeof(*entry))
-    return 0;
+    return -1;
 
   int count = size / sizeof(*entry);
+  if (count == 0)
+    return 0;
+
   int state = ACL_USER_OBJ;
   int needs_mask = 0;
   for (int i = 0; i < count; ++i) {
@@ -30,10 +33,10 @@ int posix_acl_check(const void *xattr, size_t size)
         state = ACL_USER;
         break;
       }
-      return 0;
+      return -1;
     case ACL_USER:
       if (state != ACL_USER)
-        return 0;
+        return -1;
       needs_mask = 1;
       break;
     case ACL_GROUP_OBJ:
@@ -41,15 +44,15 @@ int posix_acl_check(const void *xattr, size_t size)
         state = ACL_GROUP;
         break;
       }
-      return 0;
+      return -1;
     case ACL_GROUP:
       if (state != ACL_GROUP)
-        return 0;
+        return -1;
       needs_mask = 1;
       break;
     case ACL_MASK:
       if (state != ACL_GROUP)
-        return 0;
+        return -1;
       state = ACL_OTHER;
       break;
     case ACL_OTHER:
@@ -60,17 +63,17 @@ int posix_acl_check(const void *xattr, size_t size)
       }
       // fall-thru
     default:
-      return 0;
+      return -1;
     }
     ++entry;
   }
 
-  return state == 0;
+  return state == 0 ? count : -1;
 }
 
 int posix_acl_equiv_mode(const void *xattr, size_t size, mode_t *mode_p)
 {
-  if (!posix_acl_check(xattr, size))
+  if (posix_acl_check(xattr, size) < 0)
     return -EINVAL;
 
   int not_equiv = 0;
@@ -111,7 +114,7 @@ int posix_acl_equiv_mode(const void *xattr, size_t size, mode_t *mode_p)
 
 int posix_acl_inherit_mode(bufferptr& acl, mode_t *mode_p)
 {
-  if (!posix_acl_check(acl.c_str(), acl.length()))
+  if (posix_acl_check(acl.c_str(), acl.length()) <= 0)
     return -EIO;
 
   acl_ea_entry *group_entry = NULL, *mask_entry = NULL;
@@ -173,7 +176,7 @@ int posix_acl_inherit_mode(bufferptr& acl, mode_t *mode_p)
 
 int posix_acl_access_chmod(bufferptr& acl, mode_t mode)
 {
-  if (!posix_acl_check(acl.c_str(), acl.length()))
+  if (posix_acl_check(acl.c_str(), acl.length()) <= 0)
     return -EIO;
 
   acl_ea_entry *group_entry = NULL, *mask_entry = NULL;
@@ -215,7 +218,7 @@ int posix_acl_access_chmod(bufferptr& acl, mode_t mode)
 int posix_acl_permits(const bufferptr& acl, uid_t i_uid, gid_t i_gid,
                         uid_t uid, UserGroups& groups, unsigned want)
 {
-  if (!posix_acl_check(acl.c_str(), acl.length()))
+  if (posix_acl_check(acl.c_str(), acl.length()) < 0)
     return -EIO;
 
   const acl_ea_header *header = reinterpret_cast<const acl_ea_header*>(acl.c_str());