bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Use xattr (Linux) in copy-acl.c


From: Ondrej Valousek
Subject: [PATCH] Use xattr (Linux) in copy-acl.c
Date: Tue, 3 Jan 2023 15:08:17 +0100

The following patch is aiming to improve & simplify ACL handling in copy-acl.c
Changes/Benefits:
* we no longer try to decode ACLs, instead we just copy the whole xattr with 
ACLs
making the code simpler and faster
* side effect is support for NFSv4 acls
Disadvantages:
* it pulls in dependency on libattr. We still need dependency on libacl
because of set-acl.c which would have to be cared of separately. The
idea I have here is to confirm if it's safe to replace set_acl() with
chmod_or_fchmod() at least in Linux. It probably has something to do
with ACL inheritance.
Anyhow - with this patch copy_acl() does NOT honor inherited ACLs. It copies 
ACLs to dest
file exactly - i.e. the same way the old code worked.
* we can't do any ACLs conversions, but these are not (AFAIK) being done anyway 
in the
old code (the old code only worked with Posix)

The goal is for "cp -p" to preserve ACLs regardless of the type.
I tried to experiment with variety of filesystems (posix and nfs) and it seems 
to me
to work exactly the way the old code worked (plus handy support for NFSv4).

Ondrej


---
 lib/copy-acl.c | 31 ++++++++++++++++++++++++++++++-
 m4/xattr.m4    | 43 +++++++++++++++++++++++++++++++++++++++++++
 modules/acl    |  1 +
 3 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 m4/xattr.m4

diff --git a/lib/copy-acl.c b/lib/copy-acl.c
index 5fc42b7f6..341d1f605 100644
--- a/lib/copy-acl.c
+++ b/lib/copy-acl.c
@@ -29,6 +29,20 @@
 #define _(msgid) gettext (msgid)
 
 
+#if USE_XATTR
+
+# include <attr/libattr.h>
+
+static int
+copy_attr_permissions (const char *name, struct error_context *ctx)
+{
+       int action = attr_copy_action (name, ctx);
+       return action == ATTR_ACTION_PERMISSIONS;
+}
+
+#endif  /* USE_XATTR */
+
+
 /* Copy access control lists from one file to another. If SOURCE_DESC is
    a valid file descriptor, use file descriptor operations, else use
    filename based operations on SRC_NAME. Likewise for DEST_DESC and
@@ -43,7 +57,22 @@ int
 copy_acl (const char *src_name, int source_desc, const char *dst_name,
           int dest_desc, mode_t mode)
 {
-  int ret = qcopy_acl (src_name, source_desc, dst_name, dest_desc, mode);
+  int ret;
+#ifdef USE_XATTR
+  ret = chmod_or_fchmod (dst_name, dest_desc, mode);
+  /* Rather than fiddling with acls one by one, we just copy the whole ACL 
xattrs 
+   * (Posix or NFSv4). Of course, that won't address ACLs conversion 
+   * (i.e. posix <-> nfs4) but we can't do it anyway, so for now, we don't care
+   */
+  if(ret == 0)
+    ret = source_desc <= 0 && dest_desc <= 0
+      ? attr_copy_file (src_name, dst_name, copy_attr_permissions, NULL)
+      : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, 
copy_attr_permissions, NULL);
+#else
+  /* no XATTR, so we proceed the old dusty way */
+  ret = qcopy_acl (src_name, source_desc, dst_name, dest_desc, mode);
+#endif
+
   switch (ret)
     {
     case -2:
diff --git a/m4/xattr.m4 b/m4/xattr.m4
new file mode 100644
index 000000000..5f9248939
--- /dev/null
+++ b/m4/xattr.m4
@@ -0,0 +1,43 @@
+# xattr.m4 - check for Extended Attributes (Linux)
+# serial 4
+
+# Copyright (C) 2003-2021 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Originally written by Andreas Gruenbacher.
+
+AC_DEFUN([gl_FUNC_XATTR],
+[
+  AC_ARG_ENABLE([xattr],
+        AS_HELP_STRING([--disable-xattr],
+                       [do not support extended attributes]),
+        [use_xattr=$enableval], [use_xattr=yes])
+
+  LIB_XATTR=
+  AC_SUBST([LIB_XATTR])
+
+  if test "$use_xattr" = "yes"; then
+    AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h])
+    use_xattr=no
+    if test $ac_cv_header_attr_libattr_h = yes \
+        && test $ac_cv_header_attr_error_context_h = yes; then
+      xattr_saved_LIBS=$LIBS
+      AC_SEARCH_LIBS([attr_copy_file], [attr],
+                     [test "$ac_cv_search_attr_copy_file" = "none required" ||
+                        LIB_XATTR=$ac_cv_search_attr_copy_file])
+      AC_CHECK_FUNCS([attr_copy_file])
+      LIBS=$xattr_saved_LIBS
+      if test $ac_cv_func_attr_copy_file = yes; then
+        use_xattr=yes
+      fi
+    fi
+    if test $use_xattr = no; then
+      AC_MSG_WARN([libattr development library was not found or not usable.])
+      AC_MSG_WARN([AC_PACKAGE_NAME will be built without xattr support.])
+    fi
+  fi
+  AC_DEFINE_UNQUOTED([USE_XATTR], [`test $use_xattr != yes; echo $?`],
+                     [Define if you want extended attribute support.])
+])
diff --git a/modules/acl b/modules/acl
index 1a3a14e6c..ca2239823 100644
--- a/modules/acl
+++ b/modules/acl
@@ -4,6 +4,7 @@ Access control lists of files, with diagnostics.  (Unportable.)
 Files:
 lib/copy-acl.c
 lib/set-acl.c
+m4/xattr.m4
 
 Depends-on:
 error
-- 
2.38.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]