Create and configure setgid directories for collaboration – RHCSA Objective Preparation

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

Enabling collaboration with setgid directory

Enabling collaboration with setgid directory.

Software Requirements and Conventions Used

Software Requirements and Linux Command Line Conventions
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 sudo command.
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – 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.

Basic setup

First we create the objects needed. Let’s create the project directory:

# mkdir -p /student_projects/rocket_science

And our two users, sarah and 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 rocketengineers group:

# 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:

# 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 john:

$ 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
files.

$ 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:

# 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

Now 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

Working in a setgid directory – Editing other user’s files in a setgid directory

Conclusion

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.

Exercises

  1. Create multiple project directories with different groups. Check if one project’s members can read other project’s files.
  2. Create a cross-project directory, where any project member have access to.
  3. Create a cross-project read only directory, where only one project (project management) members can write, but members of all projects can read.