Linux – Why does cp not respect ACLs

access-control-listlinux

A common way to set up a directory for file sharing within a group, is:

$ mkdir foo
$ chgrp felles foo
$ chmod g+ws foo
$ setfacl -m group:felles:rwx foo
$ setfacl -dm group:felles:rwx foo

This ensures that any files created in foo is readable and writable by the group felles:

$ umask
0022
$ echo hi > foo/bar
$ ls -l foo
total 4
-rw-rw-r--+ 1 bhm felles 3 2010-09-23 00:18 bar

However, if you copy a file into foo, the default ACLs are not applied:

$ echo you > baz
$ cp baz foo/
$ ls -l foo
total 8
-rw-rw-r--+ 1 bhm felles 3 2010-09-23 00:18 bar
-rw-r--r--+ 1 bhm felles 4 2010-09-23 00:19 baz
$ getfacl foo/baz
# file: foo/baz
# owner: bhm
# group: felles
user::rw-
group::rwx          #effective:r--
group:felles:rwx        #effective:r--
mask::r--
other::r--

Why does this happen, and is there a way around it?

(Moving a file into the directory does not respect either ACLs or group ownership, but I can understand why: you might not want the permissions of a file to change simply because you change its name.)

Best Answer

If cp creates the destination file, it replicates the permissions of the source file, except for the bits that are set in the umask. This is standard behavior (see e.g. step 3.b in the Single Unix v3 (POSIX 2001) specification.

Why was cp designed this way? Because there are many cases where this behavior is desirable, for example preserving a file's privacy when the original permissions are restrictive, and preserving executability is almost always the right thing to do. It is however unfortunate that not even GNU cp has an option to turn this behavior off.

Most copy tools (e.g. pax, rsync) behave in the same way. You can ensure the file will be created with the default permission by decoupling the source from the destination, for example with cat <baz >foo/baz.