0

I'm trying to copy a folder (SRC) containing some files and subfolders.

The content and SRC itself have setgid bit enabled (that is the s in place of the x in the group triplet). Furthermore, the group of the whole content is srcgrp while the files have different owners (let's say me, she and they).

Now, I want to copy all the folder (SRC included) into another folder (let's say /mnt/d/SRC to /home/dog/data/SRC).

The problem is as follows: when I prompt cp -Rp /mnt/d/SRC /home/dog/data/SRC the folder is being copied in /home/dog/data/SRC but the owner of all the contents become me, even if I give chmod g-s /home/dog/data previously.

I'd like to keep the owners of source files. How could I get it?

Thank you.

1

3 Answers 3

2

You must run the copy command as root as otherwise the owner will be reset to you, and the group may be reset.

sudo cp -a /mnt/d/SRC /home/dog/data/SRC

The full rules are considered in order:

  1. If you are root then all owner/group and permissions are kept
  2. If you are a member of the group then the group name and permissions are kept
  3. Otherwise owner and group are reset to you and your primary group

These rules are honoured using rsync. However, using (GNU) cp a further restriction is applied in that setuid/setgid bits are removed if the owner or group cannot be kept.

Example using a copy from src to dst, and then sdiff to list differences between the two directories.

Initial state for each attempt:

ls -l src
total 36
drwxr-xr-x 2 chris chris 4096 May  6 15:16 chris-dir
-rwxr-xr-x 1 chris chris    0 May  6 15:16 chris-file
drwxr-sr-x 2 chris chris 4096 May  6 15:16 chris-sgid-dir
-rwxr-sr-x 1 chris chris    0 May  6 15:16 chris-sgid-file
drwsr-xr-x 2 chris chris 4096 May  6 15:16 chris-suid-dir
-rwsr-xr-x 1 chris chris    0 May  6 15:16 chris-suid-file
drwxr-xr-x 2 root  root  4096 May  6 15:16 root-dir
-rwxr-xr-x 1 root  root     0 May  6 15:16 root-file
drwxr-sr-x 2 root  root  4096 May  6 15:16 root-sgid-dir
-rwxr-sr-x 1 root  root     0 May  6 15:16 root-sgid-file
drwsr-xr-x 2 root  root  4096 May  6 15:16 root-suid-dir
-rwsr-xr-x 1 root  root     0 May  6 15:16 root-suid-file
drwxr-xr-x 2 test1 test1 4096 May  6 15:16 test1-dir
-rwxr-xr-x 1 test1 test1    0 May  6 15:16 test1-file
drwxr-sr-x 2 test1 test1 4096 May  6 15:16 test1-sgid-dir
-rwxr-sr-x 1 test1 test1    0 May  6 15:16 test1-sgid-file
drwsr-xr-x 2 test1 test1 4096 May  6 15:16 test1-suid-dir
-rwsr-xr-x 1 test1 test1    0 May  6 15:16 test1-suid-file

Using (GNU) cp

cp -a src/. dst/ && sdiff -lw132 <(ls -l src | sort -k9) <(ls -l dst | sort -k9)
total 36                                                      (
drwxr-xr-x 2 chris chris 4096 May  6 15:16 chris-dir          (
-rwxr-xr-x 1 chris chris    0 May  6 15:16 chris-file         (
drwxr-sr-x 2 chris chris 4096 May  6 15:16 chris-sgid-dir     (
-rwxr-sr-x 1 chris chris    0 May  6 15:16 chris-sgid-file    (
drwsr-xr-x 2 chris chris 4096 May  6 15:16 chris-suid-dir     (
-rwsr-xr-x 1 chris chris    0 May  6 15:16 chris-suid-file    (
drwxr-xr-x 2 root  root  4096 May  6 15:16 root-dir           | drwxr-xr-x 2 chris chris 4096 May  6 15:16 root-dir
-rwxr-xr-x 1 root  root     0 May  6 15:16 root-file          | -rwxr-xr-x 1 chris chris    0 May  6 15:16 root-file
drwxr-sr-x 2 root  root  4096 May  6 15:16 root-sgid-dir      | drwxr-xr-x 2 chris chris 4096 May  6 15:16 root-sgid-dir
-rwxr-sr-x 1 root  root     0 May  6 15:16 root-sgid-file     | -rwxr-xr-x 1 chris chris    0 May  6 15:16 root-sgid-file
drwsr-xr-x 2 root  root  4096 May  6 15:16 root-suid-dir      | drwxr-xr-x 2 chris chris 4096 May  6 15:16 root-suid-dir
-rwsr-xr-x 1 root  root     0 May  6 15:16 root-suid-file     | -rwxr-xr-x 1 chris chris    0 May  6 15:16 root-suid-file
drwxr-xr-x 2 test1 test1 4096 May  6 15:16 test1-dir          | drwxr-xr-x 2 chris chris 4096 May  6 15:16 test1-dir
-rwxr-xr-x 1 test1 test1    0 May  6 15:16 test1-file         | -rwxr-xr-x 1 chris chris    0 May  6 15:16 test1-file
drwxr-sr-x 2 test1 test1 4096 May  6 15:16 test1-sgid-dir     | drwxr-xr-x 2 chris chris 4096 May  6 15:16 test1-sgid-dir
-rwxr-sr-x 1 test1 test1    0 May  6 15:16 test1-sgid-file    | -rwxr-xr-x 1 chris chris    0 May  6 15:16 test1-sgid-file
drwsr-xr-x 2 test1 test1 4096 May  6 15:16 test1-suid-dir     | drwxr-xr-x 2 chris chris 4096 May  6 15:16 test1-suid-dir
-rwsr-xr-x 1 test1 test1    0 May  6 15:16 test1-suid-file    | -rwxr-xr-x 1 chris chris    0 May  6 15:16 test1-suid-file

Using rsync:

rsync -a src/ dst && sdiff -lw132 <(ls -l src | sort -k9) <(ls -l dst | sort -k9)
total 36                                                      (
drwxr-xr-x 2 chris chris 4096 May  6 15:17 chris-dir          (
-rwxr-xr-x 1 chris chris    0 May  6 15:17 chris-file         (
drwxr-sr-x 2 chris chris 4096 May  6 15:17 chris-sgid-dir     (
-rwxr-sr-x 1 chris chris    0 May  6 15:17 chris-sgid-file    (
drwsr-xr-x 2 chris chris 4096 May  6 15:17 chris-suid-dir     (
-rwsr-xr-x 1 chris chris    0 May  6 15:17 chris-suid-file    (
drwxr-xr-x 2 root  root  4096 May  6 15:17 root-dir           | drwxr-xr-x 2 chris chris 4096 May  6 15:17 root-dir
-rwxr-xr-x 1 root  root     0 May  6 15:17 root-file          | -rwxr-xr-x 1 chris chris    0 May  6 15:17 root-file
drwxr-sr-x 2 root  root  4096 May  6 15:17 root-sgid-dir      | drwxr-sr-x 2 chris chris 4096 May  6 15:17 root-sgid-dir
-rwxr-sr-x 1 root  root     0 May  6 15:17 root-sgid-file     | -rwxr-sr-x 1 chris chris    0 May  6 15:17 root-sgid-file
drwsr-xr-x 2 root  root  4096 May  6 15:17 root-suid-dir      | drwsr-xr-x 2 chris chris 4096 May  6 15:17 root-suid-dir
-rwsr-xr-x 1 root  root     0 May  6 15:17 root-suid-file     | -rwsr-xr-x 1 chris chris    0 May  6 15:17 root-suid-file
drwxr-xr-x 2 test1 test1 4096 May  6 15:17 test1-dir          | drwxr-xr-x 2 chris chris 4096 May  6 15:17 test1-dir
-rwxr-xr-x 1 test1 test1    0 May  6 15:17 test1-file         | -rwxr-xr-x 1 chris chris    0 May  6 15:17 test1-file
drwxr-sr-x 2 test1 test1 4096 May  6 15:17 test1-sgid-dir     | drwxr-sr-x 2 chris chris 4096 May  6 15:17 test1-sgid-dir
-rwxr-sr-x 1 test1 test1    0 May  6 15:17 test1-sgid-file    | -rwxr-sr-x 1 chris chris    0 May  6 15:17 test1-sgid-file
drwsr-xr-x 2 test1 test1 4096 May  6 15:17 test1-suid-dir     | drwsr-xr-x 2 chris chris 4096 May  6 15:17 test1-suid-dir
-rwsr-xr-x 1 test1 test1    0 May  6 15:17 test1-suid-file    | -rwsr-xr-x 1 chris chris    0 May  6 15:17 test1-suid-file

Note that where rsync has maintained the group it is because the non-root user running the command is a member of that group. Otherwise the group will be reset to the user's primary group.

5
  • I can't use root user Commented May 6, 2024 at 9:51
  • @user9952796 : An additional reason for preferring rsync, please see my updated answer. Commented May 6, 2024 at 10:34
  • Same applies to rsync. You cannot carry forward setuid/setgid permissions unless you are running it as root. You can backup them into extended attributes (--fake-super) but you cannot restore them unless you are root. Commented May 6, 2024 at 11:57
  • @ChrisDavies so, is test1 and chris different users the reason why test-1-sgid-dir loses the s in a cp execution? Commented May 8, 2024 at 13:01
  • 1
    @user9952796 yes, exactly :-) Commented May 8, 2024 at 16:04
1

I believe rsync is the tool you should use for that operation since it preserves owners, permissions etc… Something like :

rsync -aXHv /mnt/d/SRC /home/dog/data/

should do the trick, do first check with the --dry-run option that it does what you want.

Since you apparently will transfer the files from one filesystem to another (/mnt to /home), if you get symlinks or hardlinks among the files to be copied, you may want to read more in the manual what you can precisely do with them thanks to the l, L, k, K and H options.

In addition, noticing from your comment that you can't be root, do consider the --fake-super option :

When this option is enabled, rsync simulates super-user activities by saving/restoring the privileged attributes via special extended attributes that are attached to each file (as needed). This includes the file's owner and group (if it is not the default), the file's device info (device & special files are created as empty text files), and any permission bits that we won't allow to be set on the real file (e.g. the real file gets u-s,g-s,o-t for safety) or that would limit the owner's access (since the real super-user can always access/change a file, the files we create can always be accessed/changed by the creating user). This option also handles ACLs (if --acls was specified) and non-user extended attributes (if --xattrs was specified).

6
  • 1
    You cannot carry forward setuid/setgid permissions unless you are running rsync as root. You can backup them into extended attributes (--fake-super) but you cannot restore them unless you are root. Commented May 6, 2024 at 12:01
  • Thanks for the info @ChrisDavies : I must have been misunderstanding the "saving/restoring" mentioned in the manual for years… ;-) Commented May 6, 2024 at 12:41
  • 1
    @ChrisDavies I've just tried the MC68020's command and it has copied all the content keeping the setgid (even if the owner has become me). Is this a secure behaviour? Commented May 6, 2024 at 12:47
  • @user9952796 : What makes you wonder my answer would suggest anything un-secure ? Commented May 6, 2024 at 13:20
  • 1
    I will double-check. Thank you for the heads-up Commented May 6, 2024 at 13:38
1

whenever I need to do a copy of a folder and all of its [unknown] on contents or when I know it has some fancy file/folder permissions happening within that I want preserved, use tar.

# per your description:

cd /mnt/d/
tar -cf SRC.tar SRC
cp src.tar  /dog/data/
cd /dog/data/
tar -xf SRC.tar
rm SRC.tar

downside it is a handful of steps vs one cp or rsync, but the upside is when you have a folder with a lot of files then the copy of just one tar file over the network can happen at max speed versus taking seemingly forever when it is doing thousands of sub files & folders. And the tar archive and its subsequent extraction will preserve everything of the folder as it was at the source location, on that system.

Useful if you need to copy something from a linux file system such as XFS or EXT4 to an NTFS disk, where many things from linux simply are not supported in the NTFS file system. But if it's contained within an archive file such as a .tar then it is all preserved within so you won't lose it as long as you have that .tar file.

2
  • Ok, but I need to work with uncompressed data. From what I understand, this isn't the solution for me Commented May 6, 2024 at 14:33
  • ( cd src && tar cf - . ) | ( cd dst && tar xf - ) avoids the temporary file. But tar strips setuid/setgid bits on extraction unless running as root Commented May 8, 2024 at 8:47

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.