diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index ea65aae0f..137bc18d0 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -16,7 +16,7 @@ use std::os::unix::net::UnixListener; use std::path::{Path, PathBuf, StripPrefixError}; use std::{fmt, io}; #[cfg(all(unix, not(target_os = "android")))] -use uucore::fsxattr::copy_xattrs; +use uucore::fsxattr::{copy_acl_xattrs, copy_xattrs}; use uucore::translate; use clap::{Arg, ArgAction, ArgMatches, Command, builder::ValueParser, value_parser}; @@ -1715,6 +1715,12 @@ pub(crate) fn copy_attributes( exacl::getfacl(source, None) .and_then(|acl| exacl::setfacl(&[dest], &acl, None)) .map_err(|err| CpError::Error(err.to_string()))?; + + // When preserving mode with -p, also preserve ACL xattrs + // ACLs are stored as xattrs (system.posix_acl_*) and should be + // preserved even when general xattrs are not + #[cfg(all(unix, not(target_os = "android")))] + copy_acl_xattrs(source, dest)?; } Ok(()) diff --git a/src/uucore/src/lib/features/fsxattr.rs b/src/uucore/src/lib/features/fsxattr.rs index 1f1356ee5..2dce1e899 100644 --- a/src/uucore/src/lib/features/fsxattr.rs +++ b/src/uucore/src/lib/features/fsxattr.rs @@ -29,6 +29,32 @@ pub fn copy_xattrs>(source: P, dest: P) -> std::io::Result<()> { Ok(()) } +/// Copies only ACL-related xattrs (system.posix_acl_*) from source to dest. +/// +/// This is used for preserving ACLs with `-p` flag, which should preserve +/// ACLs but not other extended attributes. +/// +/// # Arguments +/// +/// * `source` - A reference to the source path. +/// * `dest` - A reference to the destination path. +/// +/// # Returns +/// +/// A result indicating success or failure. +pub fn copy_acl_xattrs>(source: P, dest: P) -> std::io::Result<()> { + for attr_name in xattr::list(&source)? { + if let Some(name_str) = attr_name.to_str() { + if name_str.starts_with("system.posix_acl_") { + if let Some(value) = xattr::get(&source, &attr_name)? { + xattr::set(&dest, &attr_name, &value)?; + } + } + } + } + Ok(()) +} + /// Retrieves the extended attributes (xattrs) of a given file or directory. /// /// # Arguments