From ce137aaf4b0d62b3e4c88816485a3ab0f5c4b3f3 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 6 Dec 2018 13:14:00 +0100 Subject: [PATCH] cp --preserve=xattr: preserve NFSv4 ACL extended attributes ... that cannot be preserved by other means --- src/copy.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/copy.c b/src/copy.c index 1a9cdd1..d227e3e 100644 --- a/src/copy.c +++ b/src/copy.c @@ -640,6 +640,17 @@ copy_attr_free (struct error_context *ctx _GL_UNUSED, { } +/* Include NFSv4 ACL extended attributes that cannot be preserved by + other means. Otherwise honor attributes configured for exclusion + in /etc/xattr.conf. Return zero to skip. */ +static int +check_not_nfs4_acl (const char *name, struct error_context *ctx) +{ + return attr_copy_check_permissions(name, ctx) + || !STRNCMP_LIT (name, "system.nfs4_acl") + || !STRNCMP_LIT (name, "system.nfs4acl"); +} + /* Exclude SELinux extended attributes that are otherwise handled, and are problematic to copy again. Also honor attributes configured for exclusion in /etc/xattr.conf. @@ -649,7 +660,7 @@ static int check_selinux_attr (const char *name, struct error_context *ctx) { return STRNCMP_LIT (name, "security.selinux") - && attr_copy_check_permissions (name, ctx); + && check_not_nfs4_acl (name, ctx); } /* If positive SRC_FD and DST_FD descriptors are passed, @@ -663,6 +674,9 @@ copy_attr (char const *src_path, int src_fd, bool all_errors = (!x->data_copy_required || x->require_preserve_xattr); bool some_errors = (!all_errors && !x->reduce_diagnostics); bool selinux_done = (x->preserve_security_context || x->set_security_context); + int (*check) (const char *, struct error_context *) = (selinux_done) + ? check_selinux_attr + : check_not_nfs4_acl; struct error_context ctx = { .error = all_errors ? copy_attr_allerror : copy_attr_error, @@ -670,12 +684,10 @@ copy_attr (char const *src_path, int src_fd, .quote_free = copy_attr_free }; if (0 <= src_fd && 0 <= dst_fd) - ret = attr_copy_fd (src_path, src_fd, dst_path, dst_fd, - selinux_done ? check_selinux_attr : NULL, + ret = attr_copy_fd (src_path, src_fd, dst_path, dst_fd, check, (all_errors || some_errors ? &ctx : NULL)); else - ret = attr_copy_file (src_path, dst_path, - selinux_done ? check_selinux_attr : NULL, + ret = attr_copy_file (src_path, dst_path, check, (all_errors || some_errors ? &ctx : NULL)); return ret == 0; -- 2.17.2