#include "support/cstring.h"
#include "debugfs.h"
+#include "ext2fs/ext4_acl.h"
#include "ext2fs/lfsck.h"
#define PRINT_XATTR_HEX 0x01
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;
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,
},
--- /dev/null
+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
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