6

I am attempting to copy a file into a directory where my user account is not the directory owner but belongs to a group that is the directory group owner. These are the steps I have taken:

Create a group and add me to that group
stephen@pi:~ $ sudo groupadd test-group
stephen@pi:~ $ sudo usermod -a -G test-group stephen
stephen@pi:~ $ grep 'test-group' /etc/group
test-group:x:1002:stephen
Create a file and list permission
stephen@pi:~ $ touch example.txt
stephen@pi:~ $ ls -l example.txt
-rw-r--r-- 1 stephen stephen 0 Feb  9 10:46 example.txt
Create a directory, modify the group owner to the new group and alter permission to the directory to grant write permission to the group
stephen@pi:~ $ sudo mkdir /var/www/testdir
stephen@pi:~ $ sudo chown :test-group /var/www/testdir/
stephen@pi:~ $ sudo chmod 664 /var/www/testdir/
stephen@pi:~ $ sudo ls -l /var/www
total 8
drwxr-xr-x 2 root    root       4096 Oct 31 12:17 html
drw-rw-r-- 2 root    test-group 4096 Feb  9 10:48 testdir
Copy the newly created file into this directory
stephen@pi:~ $ cp example.txt /var/www/testdir/straight-copy.txt
cp: failed to access '/var/www/testdir/straight-copy.txt': Permission denied

To me, this should have been successful; I'm a member of the group that has ownership of this directory, and the group permission is set to rw. Ultimately, I want any files that are copied into this directory to inherit the permission of the parent directory (/var/www/testdir).

I can copy with sudo, but this does not inherit the owner or permission from the parent directory, nor does it retain the original ownership (probably as I'm elevated to root to copy):

Copy with sudo and list ownership/permission of file
stephen@pi:~ $ sudo cp example.txt /var/www/testdir/straight-copy.txt
stephen@pi:~ $ sudo ls -l /var/www/testdir/
total 0
-rw-r--r-- 1 root root 0 Feb  9 11:06 straight-copy.txt

Please is someone able to explain to me what is happening?

2 Answers 2

9

When you did:

sudo usermod -a -G test-group stephen

Only the group database (the contents of /etc/group in your case) was modified. The corresponding gid was not automagically added to the list of supplementary gids of the process running your shell (or any process that has stephen's uid as their effective or real uids).

If you run id -Gn (which starts a new process (inheriting the uids/gids) and executes id in it), or ps -o user,group,supgrp -p "$$" (if supported by your ps) to list those for the shell process, you'll see test-group is not among the list.

You'd need to log out and log in again to start new processes with the updated list of groups (login (or other logging-in application) calls initgroups() which looks at the passwd and group database to set the list of gids of the ancestor process of your login session).

If you do sudo -u stephen id -Gn, you'll find that test-group is in there as sudo does also use initgroups() or equivalent to set the list of gids for the target user. Same with sudo zsh -c 'USERNAME=stephen; id -Gn'

Also, as mentioned separately, you need search (x) permission to a directory be able to access (including create) any of its entries.

So here, without having to log out and back in, you could still do:

# add search permissions for `a`ll:
sudo chmod a+x /var/www/testdir

# copy as the new you:
sudo -u stephen cp example.txt /var/www/testdir/

You can also use newgrp test-group to start a new shell process with test-group as its real and effective gid, and it added to the list of supplementary gids.

newgrp will allow it since you've been granted membership of that group in the group database. No need for admin privilege in this case.

Or sg test-group -c 'some command' to run something other than a shell. Doing sg test-group -c 'newgrp stephen' would have the effect of adding only adding test-group to your supplementary gids while restoring your original (e)gid.

It's also possible to make a copy of a file and specify owner, group and permissions all at once with the install utility:

sudo install -o stephen -g test-group -m a=r,ug+w example.txt /var/www/testdir/

To copy example.txt, make it owned by stephen, with group test-group and rw-rw-r-- permissions.

To copy the timestamps, ownership and permissions in addition to contents, you can also use cp -p. GNU cp also has cp -a to copy as much as possible of the metadata (short for --recursive --no-dereference --preserve=all).

3
  • Logout and login again? That's pretty drastic, when newgrp is sitting right there! I'd mention the less invasive version first. Commented Feb 10, 2022 at 15:05
  • @TobySpeight, newgrp doesn't go anywhere near fixing the problems. It starts a new shell with the new group as gid/egid which is not what we want here. Even with the sg new-group -c 'newgrp original-gid', that still doesn't fix the group membership of all the processes have been started before the change of the account. Logging out (over every logging session) is the right way. Commented Feb 10, 2022 at 15:45
  • It doesn't look like the question requires the changed permissions for any other process. But who knows? Question askers can be vague (since they by definition don't fully grasp what's happening). I certainly wouldn't like to have to restart every process I have running (including X sessions) when all I'm doing is copying a file. Commented Feb 10, 2022 at 17:23
6

You need search permissions on the directory:

chmod 775 /var/www/testdir

If you want files created in the directory to be owned by the directory’s group, you also need sgid:

chmod 2775 /var/www/testdir

See Understanding UNIX permissions and file types for details.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .