GNU/Linux filesystem permissions and rights are the basis of the system’s security, and one of it’s principles is the clear separation of rights to files and folders. In a heavily multiuser environment, such as a school’s server, file rights prevent a user by default to accidentally delete or overwrite another’s documents. However, there are use cases where multiple users need to access (read, write, and even delete) other user’s files – such may be the case in the above mentioned school server, where students work on the same project. In this section of RHCSA exam preparation we will learn how to create an environment for such collaboration, using the setgid (set groupID) technique. Note that while we perform these steps on a recent operating system, the setgid isn’t a new thing, and you will find it in any and all distributions.
In this tutorial you will learn:
- How to add users to a supplementary group
- How to use set-GID on a directory
- How to check proper ownership within the set-GID directory
- How to use the special directory as a member of the group
Software Requirements and Conventions Used
|Category||Requirements, Conventions or Software Version Used|
|System||Red Hat Enterprise Linux 8|
|Software||GNU Coreutils 8.30|
|Other||Privileged access to your Linux system as root or via the
# – requires given linux commands to be executed with root privileges either directly as a root user or by use of
$ – requires given linux commands to be executed as a regular non-privileged user
The use case
To demonstrate the usage of the setgid, we have a virtual server, and on it we need to create a group of users, add members, and setup a directory that they have both access. So far this is only a
matter of permission settings. The trick will be to add the setgid to the directory, so the files created inside the directory will have the owner group of the parent directory. Since the group will have read and write permissions within the directory, any members of the group can read and write the files, without the need of the original user setting group membership explicitly.
First we create the objects needed. Let’s create the project directory:
# mkdir -p /student_projects/rocket_science
And our two users,
john, using the useradd command:
# useradd john # useradd sarah
We also need to create a user group that will allow collaboration between it’s members:
# groupadd rocketengineers
Next we set this group as the owner of the project directory, recursively:
# chown -R :rocketengineers /student_projects/rocket_science
Next, we add our users to the
# usermod -a -G rocketengineers john # usermod -a -G rocketengineers sarah
We added the group as secondary group. For details about groups, see the group membership tutorial.
To finish the basic setup, we need to add full permission to the group on the directory:
# chmod 770 /student_projects/rocket_science
And with this, our basic setup is complete. Both users can write to the directory, and created files will be owned by the user, and owning group will be the user’s primary group. We can check the
permissions we set with
# stat /student_projects/rocket_science File: /student_projects/rocket_science Size: 6 Blocks: 0 IO Block: 4096 directory Device: fd00h/64768d Inode: 17789698 Links: 2 Access: (0770/drwxrwx---) Uid: ( 0/ root) Gid: ( 1003/rocketengineers) Context: unconfined_u:object_r:default_t:s0 Access: 2020-10-04 18:29:57.500453785 +0200 Modify: 2020-10-04 18:29:47.650278956 +0200 Change: 2020-10-04 18:30:34.809115974 +0200 Birth: -
Identifiers will most likely differ. We can see that the owner of the directory is
root, while the group ownership belongs to the
rocketengineers group. This allows both members
of the group to read and write from and to the directory.
Collaboration without setgid
Let’s say the two users would like to share some notes with this setup.
sarah got a text file with important data in her home directory:
$ id uid=1002(sarah) gid=1002(sarah) groups=1002(sarah),1003(rocketengineers) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ cat general_project.notes text
To share it with
john, she copies the file to the shared directory (so there is still a backup in her home directory, just in case):
$ cp general_project.notes /student_projects/rocket_science/
By checking ownerships, we can see that the owner is indeed
sarah, and the group owning the file is also
sarah, the user’s primary group:
$ stat /student_projects/rocket_science/general_project.notes File: /student_projects/rocket_science/general_project.notes Size: 5 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 18019570 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1002/ sarah) Gid: ( 1002/ sarah) Context: unconfined_u:object_r:default_t:s0 Access: 2020-10-04 18:31:30.229099624 +0200 Modify: 2020-10-04 18:31:30.229099624 +0200 Change: 2020-10-04 18:31:30.229099624 +0200 Birth: -
Let’s switch to
john. He also has some findings on the project, and would like to share them.
$ id uid=1001(john) gid=1001(john) groups=1001(john),1003(rocketengineers) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ echo "mytext" > rocket.txt $ cp rocket.txt /student_projects/rocket_science/
Same permissions apply, the newly copied file will be owned by
$ stat /student_projects/rocket_science/rocket.txt File: /student_projects/rocket_science/rocket.txt Size: 7 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 18356857 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1001/ john) Gid: ( 1001/ john) Context: unconfined_u:object_r:default_t:s0 Access: 2020-10-04 18:32:24.433075710 +0200 Modify: 2020-10-04 18:32:24.433075710 +0200 Change: 2020-10-04 18:32:24.433075710 +0200 Birth: -
Since both of them are members of the
rocketengineers group, they can read the contents of the directory, and since both of their notes are world-readable, they can both read each other’s
$ cat /student_projects/rocket_science/general_project.notes text
The problem arises when
john would like to add some notes on
sarah‘s important data file:
$ echo "some comments" >> /student_projects/rocket_science/general_project.notes -bash: /student_projects/rocket_science/general_project.notes: Permission denied
In effect, they can’t work on each other’s files, only read them. Now
sarah could set the group ownership of her file to their common group, thus solving the issue. But why would she need
that with every file, if we got the setgid to help us?
Setting the setgid flag
To set the setgid flag, we use
# chmod g+s /student_projects/rocket_science
Notice the “s” flag at grop permissions (set as bold for the sake of clarity):
# stat /student_projects/rocket_science File: /student_projects/rocket_science Size: 53 Blocks: 0 IO Block: 4096 directory Device: fd00h/64768d Inode: 17789698 Links: 2 Access: (2770/drwxrws---) Uid: ( 0/ root) Gid: ( 1003/rocketengineers) Context: unconfined_u:object_r:default_t:s0 Access: 2020-10-04 18:32:29.389167450 +0200 Modify: 2020-10-04 18:32:24.433075710 +0200 Change: 2020-10-04 18:34:04.449927062 +0200 Birth: -
Testing and verifying the results
sarah can share her new research notes:
$ cat findings.txt rocket needs wings $ cp findings.txt /student_projects/rocket_science/ $ stat /student_projects/rocket_science/findings.txt File: /student_projects/rocket_science/findings.txt Size: 19 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 18999000 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1002/ sarah) Gid: ( 1003/rocketengineers) Context: unconfined_u:object_r:default_t:s0 Access: 2020-10-04 18:35:15.195236593 +0200 Modify: 2020-10-04 18:35:15.195236593 +0200 Change: 2020-10-04 18:35:15.195236593 +0200 Birth: -
The group ownership is set to the parent directory’s group because of the
setgid in place. That will cause
john to be able to comment on the new research notes:
$ echo "verified!" >> /student_projects/rocket_science/findings.txt $ cat /student_projects/rocket_science/findings.txt rocket needs wings verified!
And with that we completed our goal of setting up a collaboration directory for a group of users. We could do so for other groups with the above method, separating different project’s data by
permissions, so a member of one group can’t accidentally delete data of another project.
# Video Title: Working in a setgid directory
# Video Description: Editing other user’s files in a setgid directory
# Video file name: rhcsa_setgid.webm
Under GNU/Linux strict permissions and ownership rights,
setgid is a simple way to allow users of the system to interact with each other’s files in a secure way, enabling group work
without the use of some heavy external solution, or messing up the user’s initial groups and permissions. In the above example, we did not need to touch the user home directories, or their system-wide
permissions, we just set up a special place where they can share what they need to.
- Create multiple project directories with different groups. Check if one project’s members can read other project’s files.
- Create a cross-project directory, where any project member have access to.
- Create a cross-project read only directory, where only one project (project management) members can write, but members of all projects can read.