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
- What you'll build
- Step 1: the people and the group
- Step 2: the top directory
- Step 3: the shared directory
- Step 4: the handoff drop box
- Step 5: a readme only Kiran can edit
- Step 6: a policy nobody can change
- Step 7: a contractor for 30 days
- Step 8: Joel leaves
- Step 9: the final check
- What you built
- 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:
- the team can all work together in a shared directory, editing each other's files, and new files automatically belong to the team
- there's a handoff drop box where anyone can leave files for Kiran, without seeing or deleting what others left
- a readme the whole team can read but only Kiran can edit
- a policy file nobody can change, not even by accident with
sudo - outsiders can't see any of it
- a contractor who joins for 30 days loses access automatically
- when Joel leaves, his account goes but his work stays
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:
- Lock his account so he can't log in any more.
- Find every file he owns outside his home directory.
- Give those files to Kiran, keeping them in the
designgroup. - 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
| Path | Mode | Effect |
|---|---|---|
/srv/design | 750 kiran:design | The team can enter and look, outsiders can't |
shared/ | 2770 | Everyone creates and edits, files go to design |
handoff/ | 1730 | Team can drop files in, only Kiran can see them |
README.txt | 640 | Team reads, Kiran edits |
POLICY.txt | 640, immutable | Nobody changes it until chattr -i |
Take it further
- Give each team member
umask 007in their~/.bashrc, so files they create anywhere are never readable by others. - Use
setfaclandgetfacl(install theaclpackage) to give one extra person read access toshared/without adding them to the group. Access control lists go beyond the three user, group and others sets. - Write a script that onboards a new team member in one command: user, password, group, and a welcome file in
handoff/. Come back to it after lesson 29.
← Special permissions: SUID, SGID, sticky bit and umaskProcesses: ps, top and htop →