Whamcloud - gitweb
LU-11604 debugfs: add support for printing ACL 84/43384/4 v1.46.2.wc1
authorLi Dongyang <dongyangli@ddn.com>
Wed, 21 Apr 2021 12:43:09 +0000 (22:43 +1000)
committerLi Dongyang <dongyangli@ddn.com>
Tue, 27 Apr 2021 00:53:25 +0000 (00:53 +0000)
decode and print Access Control Lists in debugfs stat/ea_list

Change-Id: I3ee35ddb02582ab66d4e25ff76fae35935b54508
Signed-off-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-on: https://review.whamcloud.com/43384
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
debugfs/xattrs.c
lib/ext2fs/ext4_acl.h
tests/d_print_acl/expect [new file with mode: 0644]
tests/d_print_acl/script [new file with mode: 0644]
tests/m_rootdir_acl/expect

index bab09f0..3ad368e 100644 (file)
@@ -17,6 +17,7 @@ extern char *optarg;
 #include "support/cstring.h"
 
 #include "debugfs.h"
+#include "ext2fs/ext4_acl.h"
 #include "ext2fs/lfsck.h"
 
 #define PRINT_XATTR_HEX                0x01
@@ -84,6 +85,76 @@ static void print_xattr(FILE *f, char *name, char *value, size_t value_len,
        fputc('\n', f);
 }
 
+static int print_acl(FILE *f, void *name, void *value, size_t value_len)
+{
+       const ext4_acl_header *ext_acl = (const ext4_acl_header *)value;
+       const char *cp;
+
+       if (!value ||
+           (value_len < sizeof(ext4_acl_header)) ||
+           (ext_acl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION)))
+               return -EINVAL;
+
+       cp = (const char *)value + sizeof(ext4_acl_header);
+       value_len -= sizeof(ext4_acl_header);
+
+       fprintf(f, "%s:\n", name);
+
+       while (value_len > 0) {
+               const ext4_acl_entry *disk_entry = (const ext4_acl_entry *)cp;
+               posix_acl_xattr_entry entry;
+               entry.e_tag = ext2fs_le16_to_cpu(disk_entry->e_tag);
+               entry.e_perm = ext2fs_le16_to_cpu(disk_entry->e_perm);
+
+               switch(entry.e_tag) {
+                       case ACL_USER_OBJ:
+                       case ACL_USER:
+                               fprintf(f, "    user:");
+                               if (entry.e_tag == ACL_USER)
+                                       fprintf(f, "%u",
+                                       ext2fs_le32_to_cpu(disk_entry->e_id));
+                               break;
+
+                       case ACL_GROUP_OBJ:
+                       case ACL_GROUP:
+                               fprintf(f, "    group:");
+                               if (entry.e_tag == ACL_GROUP)
+                                       fprintf(f, "%u",
+                                       ext2fs_le32_to_cpu(disk_entry->e_id));
+                               break;
+
+                       case ACL_MASK:
+                               fprintf(f, "    mask:");
+                               break;
+
+                       case ACL_OTHER:
+                               fprintf(f, "    other:");
+                               break;
+
+                       default:
+                               fprintf(stderr,
+                                       "%s: error: invalid tag %x in ACL\n",
+                                       debug_prog_name, entry.e_tag);
+                               return -EINVAL;
+               }
+               fprintf(f, ":");
+               fprintf(f, (entry.e_perm & ACL_READ) ? "r" : "-");
+               fprintf(f, (entry.e_perm & ACL_WRITE) ? "w" : "-");
+               fprintf(f, (entry.e_perm & ACL_EXECUTE) ? "x" : "-");
+               fprintf(f, "\n");
+
+               if (entry.e_tag == ACL_USER || entry.e_tag == ACL_GROUP) {
+                       cp += sizeof(ext4_acl_entry);
+                       value_len -= sizeof(ext4_acl_entry);
+               } else {
+                       cp += sizeof(ext4_acl_entry_short);
+                       value_len -= sizeof(ext4_acl_entry_short);
+               }
+       }
+
+       return 0;
+}
+
 static int print_fidstr(FILE *f, void *name, void *value, size_t value_len)
 {
        struct filter_fid_old *ff = value;
@@ -221,6 +292,14 @@ struct dump_attr_pretty {
        int (*dap_print)(FILE *f, void *name, void *value, size_t value_len);
 } dumpers[] = {
        {
+               .dap_name = "system.posix_acl_access",
+               .dap_print = print_acl,
+       },
+       {
+               .dap_name = "system.posix_acl_default",
+               .dap_print = print_acl,
+       },
+       {
                .dap_name = "trusted.fid",
                .dap_print = print_fidstr,
        },
index 8d4d974..8343086 100644 (file)
@@ -4,6 +4,12 @@
 
 #define EXT4_ACL_VERSION        0x0001
 
+/* 23.2.2 acl_perm_t values */
+
+#define ACL_READ               (0x04)
+#define ACL_WRITE              (0x02)
+#define ACL_EXECUTE            (0x01)
+
 /* 23.2.5 acl_tag_t values */
 
 #define ACL_UNDEFINED_TAG      (0x00)
diff --git a/tests/d_print_acl/expect b/tests/d_print_acl/expect
new file mode 100644 (file)
index 0000000..03dea43
--- /dev/null
@@ -0,0 +1,13 @@
+Extended attributes:
+  system.posix_acl_access:
+    user::rwx
+    group::r-x
+    group:42:r-x
+    mask::r-x
+    other::r-x
+  system.posix_acl_default:
+    user::rwx
+    group::r-x
+    group:4:r-x
+    mask::r-x
+    other::r-x
diff --git a/tests/d_print_acl/script b/tests/d_print_acl/script
new file mode 100644 (file)
index 0000000..481003b
--- /dev/null
@@ -0,0 +1,51 @@
+test_description="decode and print Access Control Lists in debugfs"
+if ! test -x $DEBUGFS_EXE; then
+       echo "$test_name: $test_description: skipped (no debugfs)"
+       return 0
+fi
+
+if ! setfacl --help > /dev/null 2>&1 ; then
+       echo "$test_name: $test_description: skipped (no setfacl)"
+       return 0
+fi
+
+MKFS_DIR=$TMPFILE.dir
+OUT=$test_name.log
+EXP=$test_dir/expect
+
+rm -rf $MKFS_DIR
+mkdir -p $MKFS_DIR
+mkdir $MKFS_DIR/acl_dir
+
+setfacl --restore=- <<EOF
+# file: $MKFS_DIR/acl_dir
+user::rwx
+group::r-x
+group:42:r-x
+mask::r-x
+other::r-x
+default:user::rwx
+default:group::r-x
+default:group:4:r-x
+default:mask::r-x
+default:other::r-x
+EOF
+
+$MKE2FS -q -F -o Linux -T ext4 -b 1024 -d $MKFS_DIR $TMPFILE 16384 > $OUT.new 2>&1
+
+$DEBUGFS -w -R "ea_list /acl_dir" $TMPFILE >> $OUT.new 2>&1
+sed -f $cmd_dir/filter.sed $OUT.new > $OUT
+rm -rf $MKFS_DIR $TMPFILE $OUT.new
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+       echo "$test_name: $test_description: ok"
+       touch $test_name.ok
+else
+        echo "$test_name: $test_description: failed"
+        diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset MKFS_DIR OUT EXP
index 951e4bd..50f32a9 100644 (file)
@@ -105,12 +105,27 @@ Extended attributes:
 debugfs: ea_list acl_dir
 Extended attributes:
   system.data (0)
-  system.posix_acl_access (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 2a 00 00 00 10 00 05 00 20 00 05 00 
-  system.posix_acl_default (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 04 00 00 00 10 00 05 00 20 00 05 00 
+  system.posix_acl_access:
+    user::rwx
+    group::r-x
+    group:42:r-x
+    mask::r-x
+    other::r-x
+  system.posix_acl_default:
+    user::rwx
+    group::r-x
+    group:4:r-x
+    mask::r-x
+    other::r-x
 debugfs: ea_list acl_dir/file
 Extended attributes:
   system.data (0)
-  system.posix_acl_access (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 2a 00 00 00 10 00 05 00 20 00 05 00 
+  system.posix_acl_access:
+    user::rwx
+    group::r-x
+    group:42:r-x
+    mask::r-x
+    other::r-x
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity