Nandishwar Singh

Home / Learn Linux / Project 2

A shared team folder

Three users, one group and a folder they can all work in without deleting each other's files.

Project
2 of 5
Time
About 50 minutes
Uses
Lessons 13 to 15

On this page

  1. What you'll build
  2. Step 1: the people and the group
  3. Step 2: the top directory
  4. Step 3: the shared directory
  5. Step 4: the handoff drop box
  6. Step 5: a readme only Kiran can edit
  7. Step 6: a policy nobody can change
  8. Step 7: a contractor for 30 days
  9. Step 8: Joel leaves
  10. Step 9: the final check
  11. What you built
  12. Take it further

What you'll build

A small design studio is moving its files onto your Linux server. There are three people: Kiran leads the team, and Tara and Joel work with them. You'll set up /srv/design so that:

You'll use users and groups (lesson 13), permissions (lesson 14) and the special bits and attributes (lesson 15). Every step has a check, so you know it really works, not just that the command ran.

Step 1: the people and the group

Create a group called design. Create users kiran, tara and joel with home directories and Bash, give each the password Studio.2026, and add all three to design.

Hint

sudo groupadd design, then sudo adduser --disabled-password --comment "..." name for each, chpasswd can set all three passwords from three lines, and sudo usermod -aG design name.

Solution
$ sudo groupadd design
$ sudo adduser --disabled-password --comment "Kiran, team lead" kiran
$ sudo adduser --disabled-password --comment "Tara" tara
$ sudo adduser --disabled-password --comment "Joel" joel
$ printf "kiran:Studio.2026\ntara:Studio.2026\njoel:Studio.2026\n" | sudo chpasswd
$ sudo usermod -aG design kiran
$ sudo usermod -aG design tara
$ sudo usermod -aG design joel
$ getent group design
design:x:1006:kiran,tara,joel

Check

Each user should show design in their groups:

$ id kiran
uid=1003(kiran) gid=1003(kiran) groups=1003(kiran),100(users),1006(design)
$ id joel
uid=1008(joel) gid=1008(joel) groups=1008(joel),100(users),1006(design)

Step 2: the top directory

Create /srv/design, owned by kiran and the group design. Team members can enter it and list it. Everyone else gets nothing.

Solution
$ sudo mkdir /srv/design
$ sudo chown kiran:design /srv/design
$ sudo chmod 750 /srv/design
$ ls -ld /srv/design
drwxr-x--- 2 kiran design 4096 Oct 21 11:39 /srv/design

Check

Test as a real user, by logging in as them with su -, so they get exactly the settings they'd have on a normal login. ravi from lesson 13 isn't in design, so he should be locked out completely:

ubuntu@linux:~$ su - ravi
Password:
ravi@linux:~$ ls /srv/design
ls: cannot open directory '/srv/design': Permission denied
ravi@linux:~$ exit
logout

Step 3: the shared directory

Create /srv/design/shared. Every team member can create files there and edit each other's files, and new files must automatically belong to the design group.

Hint

That's lesson 15's SGID bit on a directory, plus rwxrwx---: 2770.

Solution
$ sudo mkdir /srv/design/shared
$ sudo chown kiran:design /srv/design/shared
$ sudo chmod 2770 /srv/design/shared
$ sudo ls -ld /srv/design/shared
drwxrws--- 2 kiran design 4096 Oct 21 11:39 /srv/design/shared

ubuntu isn't in design, so from here on it needs sudo even to look inside /srv/design. The admin account isn't part of the team, and that's how it should be.

Check

Tara creates a file, and it lands in design. Joel can edit it, because new files are group-writable (Ubuntu's umask of 002 from lesson 15):

ubuntu@linux:~$ su - tara
Password:
tara@linux:~$ echo "logo v1" > /srv/design/shared/logo.txt
tara@linux:~$ ls -l /srv/design/shared
total 4
-rw-rw-r-- 1 tara design 8 Oct 21 11:39 logo.txt
tara@linux:~$ exit
logout
ubuntu@linux:~$ su - joel
Password:
joel@linux:~$ echo "logo v2, with blue" >> /srv/design/shared/logo.txt
joel@linux:~$ cat /srv/design/shared/logo.txt
logo v1
logo v2, with blue
joel@linux:~$ exit
logout

Testing with sudo -u tara ... instead would give a different result here: sudo applies a stricter umask of its own, so Tara's file would come out rw-r--r-- and Joel couldn't edit it. Always test sharing as a real login.

Why not add the sticky bit here?

Lesson 15's 3770 would also stop people deleting each other's files, which sounds better. But on Ubuntu it would break exactly this check. The kernel setting fs.protected_regular = 2 refuses to let anyone open a file they don't own for writing with > or >> inside a sticky directory that the group can write to. It's there to stop a classic attack on shared directories like /tmp, and it means Joel's >> above would fail with Permission denied.

So a shared directory is a choice. Use 2770 when people work on each other's files and trust each other, and keep backups for accidents. Use 3770 when everyone only adds their own files, like the drop box in the next step.

Step 4: the handoff drop box

Create /srv/design/handoff. Team members can put files in it, but they can't see what's in there, not even the names. Only Kiran can list and read it.

Hint

To create a file in a directory you need w and x on it. To see the names you need r. Give the group wx and no r: -wx, which is 3. Add the sticky bit so nobody deletes another's handoff. That's 1730.

Solution
$ sudo mkdir /srv/design/handoff
$ sudo chown kiran:design /srv/design/handoff
$ sudo chmod 1730 /srv/design/handoff
$ sudo ls -ld /srv/design/handoff
drwx-wx--T 2 kiran design 4096 Oct 21 11:39 /srv/design/handoff

Check

ubuntu@linux:~$ su - tara
Password:
tara@linux:~$ echo "invoice draft" > /srv/design/handoff/tara-invoice.txt
tara@linux:~$ exit
logout
ubuntu@linux:~$ su - joel
Password:
joel@linux:~$ echo "brief" > /srv/design/handoff/joel-brief.txt
joel@linux:~$ ls /srv/design/handoff
ls: cannot open directory '/srv/design/handoff': Permission denied
joel@linux:~$ exit
logout
ubuntu@linux:~$ su - kiran
Password:
kiran@linux:~$ ls -l /srv/design/handoff
total 8
-rw-rw-r-- 1 joel joel  6 Oct 21 11:39 joel-brief.txt
-rw-rw-r-- 1 tara tara 14 Oct 21 11:39 tara-invoice.txt
kiran@linux:~$ exit
logout

Joel could drop his file but couldn't list the directory. Kiran sees both.

Step 5: a readme only Kiran can edit

Create /srv/design/README.txt with a line of text. The team can read it, only Kiran can change it, and it doesn't even exist for outsiders.

Solution
$ echo "Shared files go in shared/. Hand finished work to Kiran in handoff/." | sudo tee /srv/design/README.txt > /dev/null
$ sudo chown kiran:design /srv/design/README.txt
$ sudo chmod 640 /srv/design/README.txt
$ sudo ls -l /srv/design/README.txt
-rw-r----- 1 kiran design 69 Oct 21 11:39 /srv/design/README.txt

Check

ubuntu@linux:~$ su - tara
Password:
tara@linux:~$ cat /srv/design/README.txt
Shared files go in shared/. Hand finished work to Kiran in handoff/.
tara@linux:~$ echo "tara was here" >> /srv/design/README.txt
-bash: /srv/design/README.txt: Permission denied
tara@linux:~$ exit
logout

Step 6: a policy nobody can change

Create /srv/design/POLICY.txt with the studio's rules. Make it readable by the team, and impossible to change or delete for anyone, root included, until you deliberately unlock it.

Solution
$ echo "Client files never leave this server." | sudo tee /srv/design/POLICY.txt > /dev/null
$ sudo chown root:design /srv/design/POLICY.txt
$ sudo chmod 640 /srv/design/POLICY.txt
$ sudo chattr +i /srv/design/POLICY.txt
$ sudo lsattr /srv/design/POLICY.txt
----i---------e------- /srv/design/POLICY.txt

Check

$ sudo rm /srv/design/POLICY.txt
rm: cannot remove '/srv/design/POLICY.txt': Operation not permitted
$ echo "rule 2" | sudo tee -a /srv/design/POLICY.txt
/srv/design/POLICY.txt: Operation not permitted (os error 1)
rule 2
$ cat /srv/design/POLICY.txt
cat: /srv/design/POLICY.txt: Permission denied

ubuntu isn't in design, so it can't read the policy either without sudo. That's correct: the admin account isn't part of the team.

Step 7: a contractor for 30 days

Sam joins for one month. Create the account with the password Temp.Access.1, add Sam to design, and make the account expire 30 days from today, so you can't forget to remove it.

Hint

date -d "+30 days" +%F prints the date 30 days from now. Put it inside $(...) in chage -E.

Solution
$ sudo adduser --disabled-password --comment "Sam, contractor" sam
$ echo "sam:Temp.Access.1" | sudo chpasswd
$ sudo usermod -aG design sam
$ sudo chage -E $(date -d "+30 days" +%F) sam
$ sudo chage -l sam | grep "Account expires"
Account expires                                         : Nov 20, 2026
$ getent group design
design:x:1006:kiran,tara,joel,sam

Step 8: Joel leaves

Joel is leaving. Do it in a safe order:

  1. Lock his account so he can't log in any more.
  2. Find every file he owns outside his home directory.
  3. Give those files to Kiran, keeping them in the design group.
  4. Delete his account and home directory.
Hint

usermod -L, then find /srv -user joel, then find ... -exec chown kiran:design {} +. userdel -r last.

Solution
$ sudo usermod -L joel
$ sudo passwd -S joel
joel L 2026-10-21 0 99999 7 -1
$ sudo find /srv -user joel
/srv/design/handoff/joel-brief.txt
$ sudo find /srv -user joel -exec chown kiran:design {} +
$ sudo userdel -r joel
userdel: joel mail spool (/var/mail/joel) not found
$ getent group design
design:x:1006:kiran,tara,sam
$ sudo ls -l /srv/design/handoff
total 8
-rw-rw-r-- 1 kiran design  6 Oct 21 11:39 joel-brief.txt
-rw-rw-r-- 1 tara  tara   14 Oct 21 11:39 tara-invoice.txt

His brief is still there, now owned by Kiran and the team. If you'd only changed the owner (chown kiran), the file would have kept Joel's private group, and once his account was gone, ls would show a bare group number where joel used to be.

Step 9: the final check

Show the whole setup in one view: the modes in numbers and letters, owners and groups, for /srv/design and everything in it. Then confirm an outsider still can't get in.

Solution
$ sudo find /srv/design -exec stat -c "%a %A %U:%G %n" {} +
750 drwxr-x--- kiran:design /srv/design
640 -rw-r----- kiran:design /srv/design/README.txt
2770 drwxrws--- kiran:design /srv/design/shared
664 -rw-rw-r-- tara:design /srv/design/shared/logo.txt
640 -rw-r----- root:design /srv/design/POLICY.txt
1730 drwx-wx--T kiran:design /srv/design/handoff
664 -rw-rw-r-- tara:tara /srv/design/handoff/tara-invoice.txt
664 -rw-rw-r-- kiran:design /srv/design/handoff/joel-brief.txt
ubuntu@linux:~$ su - ravi
Password:
ravi@linux:~$ cat /srv/design/README.txt
cat: /srv/design/README.txt: Permission denied
ravi@linux:~$ exit
logout
$ sudo namei -l /srv/design/shared
f: /srv/design/shared
drwxr-xr-x root  root   /
drwxr-xr-x root  root   srv
drwxr-x--- kiran design design
drwxrws--- kiran design shared

namei shows each level of the path, so you can see that /srv/design (750, group design) is the gate that keeps Ravi out of everything below it.

What you built

PathModeEffect
/srv/design750 kiran:designThe team can enter and look, outsiders can't
shared/2770Everyone creates and edits, files go to design
handoff/1730Team can drop files in, only Kiran can see them
README.txt640Team reads, Kiran edits
POLICY.txt640, immutableNobody changes it until chattr -i

Take it further