Three people share a folder and none of them can work in it. It is tempting to see one fault — “the
permissions are wrong” — and one fix, chmod -R 777. There are really four separate questions, and
each has its own answer in a different place: who is in the group (/etc/group), what the files
that already exist allow (their owner, group and mode bits), what files created tomorrow will
allow (the directory’s setgid bit, the author’s umask, default ACLs), and what everyone else can
reach (the “other” bits — on the directory as much as on the files).
The lab’s folder gets every one of them wrong, and a previous admin’s hardening makes the third worse:
every login runs umask 077, so anything anyone writes is private to its author the moment it is
saved. Fixing today’s files with chmod without touching the third question gives a folder that
works this afternoon and is broken again tomorrow morning.
chgrp -R and chmod -R g+rwX,o-rwx, and say what the
capital X is for.mask and #effective lines getfacl prints.Every file has an owner, a group and nine mode bits: rwx for the owner, rwx for the group, rwx
for everyone else. When a process opens the file, the kernel does not add these up. It picks exactly
one class and uses only its bits:
root skips the check for reading and writing. That is why the grader, and you with sudo, see
everything, and why you must look at the folder through the users’ own eyes — su - bob — to see
what bob sees.
In the broken folder, budget.csv is -rw-r--r-- bob bob. bob is its owner and may write. alice is
not bob and not in the group bob, so the other bits apply: read only. dave is in the same position
as alice — which is exactly the problem, because dave is not on the team.
On a directory the same bits mean different things:
| bit | on a file | on a directory |
|---|---|---|
r |
read the contents | list the names in it |
w |
change the contents | create, rename and delete entries in it (with x) |
x |
run it | enter it: reach anything inside by name |
Two consequences matter here. A file is reachable only if you have x on every directory on the
path to it, so taking x away from others on /srv/reports locks dave out of every file inside,
whatever those files’ own bits say. And deleting a file needs write on the directory, not on the
file: anyone with w and x on a shared folder can delete anyone else’s report. (The sticky bit,
chmod +t, restricts deletion to the file’s owner; /tmp uses it. A team that edits each other’s
files usually does not want it, but it is the answer when they should only add.)
A user’s groups are listed in /etc/group. usermod -aG reports carol appends reports to carol’s
supplementary groups; without -a, -G replaces them and silently removes every other group she
had. The change is recorded at once, but a process’s groups are fixed when it is created, so a
session that was already open keeps its old list. su - carol, a new SSH login or newgrp reports
picks up the new one. This is the most common reason a correct fix “does not work” until someone logs
out.
A program that creates a file asks for a mode — usually 0666 for files and 0777 for directories —
and the kernel removes the bits set in the process’s umask. With the usual 022, files come out
0644 and directories 0755. With 002 — Ubuntu’s default for users who have their own private
group, applied by pam_umask — they come out 0664 and 0775. With the hardening in this lab,
077, they come out 0600 and 0700: nobody but the author can do anything.
A umask is inherited by child processes, and it is set in more than one place: /etc/login.defs
(UMASK, read by pam_umask), /etc/profile and /etc/profile.d/*.sh for login shells, and a
user’s own ~/.profile or ~/.bashrc. The last one to run wins. Here it is
/etc/profile.d/00-hardening.sh.
The new file’s group is decided separately. Normally it is the creator’s primary group — alice’s
files get the group alice. If the directory has the setgid bit (chmod g+s, shown as s in the
group execute position), new entries get the directory’s group instead, and new subdirectories inherit
the setgid bit, so the rule propagates down the tree.
POSIX ACLs add entries beyond the three classes: group:reports:rwx grants that named group access
whether or not it owns the file. An ACL on a directory can also carry default entries, which are
copied onto every file and directory created inside it.
Default ACLs change how the umask applies: when the parent directory has a default ACL, the umask is
not used at all. The new file’s ACL comes from the defaults, limited only by the mode the program
asked for. So a default group:reports:rwx gives every new file group read and write even under
umask 077 — which is why the reference solution uses it.
One more entry appears whenever named entries exist: the mask. It is the maximum any named user,
named group or the owning group can get, and it is what ls -l shows in the group position. A file
created with mode 0666 gets a mask of rw-, so getfacl prints group:reports:rwx #effective:rw-:
the entry says rwx, the mask cuts it to rw-. A later chmod g-w lowers the mask, and with it every
named entry at once — a frequent surprise.
The roster names three people. The group has two:
$ cat /srv/reports/TEAM.txt
reports team: alice bob carol
$ getent group reports
reports:x:1001:alice,bob
$ id carol ; id dave
uid=1003(carol) gid=1004(carol) groups=1004(carol)
uid=1004(dave) gid=1005(dave) groups=1005(dave)
1. Look at the folder as a listing, then as the people who use it.
$ ls -la /srv/reports /srv/reports/drafts
/srv/reports:
drwxr-xr-x 3 alice alice 4096 Sep 14 09:57 .
-rw------- 1 alice alice 31 Sep 14 09:57 2026-q3-summary.txt
-rw-r--r-- 1 alice root 30 Sep 14 09:57 TEAM.txt
-rw-r--r-- 1 bob bob 38 Sep 14 09:57 budget.csv
drwxr-xr-x 2 bob bob 4096 Sep 14 09:57 drafts
/srv/reports/drafts:
-rw------- 1 bob bob 21 Sep 14 09:57 q4-outline.txt
$ sudo su - bob -c 'cat /srv/reports/2026-q3-summary.txt'
cat: /srv/reports/2026-q3-summary.txt: Permission denied
$ sudo su - dave -c 'cat /srv/reports/budget.csv'
item,amount
servers,1200
licences,300
Every file belongs to its author’s private group, so the group bits never apply to a teammate, and the
folder is 755 — open to everyone for reading.
2. Find out what tomorrow’s files will look like.
$ sudo su - alice -c 'umask; touch /srv/reports/scratch.txt; ls -l /srv/reports/scratch.txt'
0077
-rw------- 1 alice alice 0 Sep 14 09:57 /srv/reports/scratch.txt
$ grep -rn umask /etc/profile /etc/profile.d/ /etc/login.defs /etc/pam.d/common-session | grep -v ':#'
/etc/profile.d/00-hardening.sh:2:umask 077
/etc/pam.d/common-session:23:session optional pam_umask.so
pam_umask would give 002; the profile snippet runs later and wins.
3. Fix the group, then the existing tree.
$ sudo usermod -aG reports carol
$ id carol
uid=1003(carol) gid=1004(carol) groups=1004(carol),1001(reports)
$ sudo chgrp -R reports /srv/reports
$ sudo chmod -R g+rwX,o-rwx /srv/reports
$ sudo find /srv/reports -type d -exec chmod g+s {} +
$ ls -ld /srv/reports ; sudo ls -la /srv/reports
drwxrws--- 3 alice reports 4096 Sep 14 09:57 /srv/reports
drwxrws--- 3 alice reports 4096 Sep 14 09:57 .
-rw-rw---- 1 alice reports 31 Sep 14 09:57 2026-q3-summary.txt
-rw-rw---- 1 alice reports 30 Sep 14 09:57 TEAM.txt
-rw-rw---- 1 bob reports 38 Sep 14 09:57 budget.csv
drwxrws--- 2 bob reports 4096 Sep 14 09:57 drafts
g+rwX gives the group read and write, and execute only where it makes sense: on directories, and on
files that were already executable for someone. A lowercase x would have marked every report as a
program. Note that the plain ls of the folder, as learner, would now be refused: you are not on the
team either.
4. Check tomorrow, not just today. The setgid bit got the group right; the umask still wins:
$ sudo su - alice -c 'echo "first draft" > /srv/reports/q4-plan.txt'
$ sudo ls -l /srv/reports/q4-plan.txt
-rw------- 1 alice reports 12 Sep 14 09:57 /srv/reports/q4-plan.txt
$ sudo su - bob -c 'echo "bob was here" >> /srv/reports/q4-plan.txt'
-bash: line 1: /srv/reports/q4-plan.txt: Permission denied
5. Give the group a default ACL. -m sets the entry on what exists; -d -m sets the default for
what will be created:
$ sudo setfacl -R -m g:reports:rwX /srv/reports
$ sudo setfacl -R -d -m g:reports:rwX /srv/reports
$ getfacl -p /srv/reports
# file: /srv/reports
# owner: alice
# group: reports
# flags: -s-
user::rwx
group::rwx
group:reports:rwx
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:reports:rwx
default:mask::rwx
default:other::---
$ sudo su - alice -c 'echo "second draft" > /srv/reports/q4-plan-v2.txt'
$ sudo getfacl -p /srv/reports/q4-plan-v2.txt
# file: /srv/reports/q4-plan-v2.txt
# owner: alice
# group: reports
user::rw-
group::rwx #effective:rw-
group:reports:rwx #effective:rw-
mask::rw-
other::---
$ sudo su - bob -c 'echo "bob was here" >> /srv/reports/q4-plan-v2.txt && tail -1 /srv/reports/q4-plan-v2.txt'
bob was here
$ sudo su - carol -c 'mkdir /srv/reports/carol-notes && ls -ld /srv/reports/carol-notes'
drwxrws---+ 2 carol reports 4096 Sep 14 09:57 /srv/reports/carol-notes
$ sudo su - dave -c 'ls /srv/reports'
ls: cannot open directory '/srv/reports': Permission denied
The + after the mode is ls saying “there is an ACL; the nine bits are not the whole story”.
carol’s new directory is group reports, setgid, and carries the defaults on. With the test files
removed, the grader passed all four checks.
The same result is available without ACLs: keep the setgid directories and give the team a umask that
keeps group write (umask 007) where their logins set it. That depends on every program the team uses
honouring a login umask — an editor started from a desktop session or a file copied in by a service
may not — which is the argument for the ACL.
chmod -R 777. Everyone can do everything, including dave, including deleting the whole folder.
It also stops working tomorrow: new files are still created under umask 077.
usermod -G reports carol. Without -a, carol loses every other supplementary group she had —
sudo, perhaps. Always -aG, or gpasswd -a carol reports.
Testing as yourself with sudo. root is not subject to the permission check for reading and
writing, so everything “works”. Test as the people concerned: su - bob -c '…'.
Testing in a session that was already open. Group membership is read when a process starts. A
shell opened before usermod still does not have the group; log in again, or use su -.
Fixing the files and not the directories. Without x on drafts, nobody reaches the files in
it however open they are. And without w on a directory, nobody can create or rename anything in it.
chmod -R g+x instead of g+X. Every report becomes executable. Harmless until someone runs one.
Removing the hardening snippet. It works in this folder, and it also makes every file every user creates anywhere group-readable. The hardening had a purpose; the team folder needed an exception, not the removal of the rule.
Setting only access ACLs (setfacl -m) without defaults (-d -m). Today’s files work, tomorrow’s
do not — the same trap as chmod, with more typing.
chmod g-w on an ACL’d file to “tidy up”. It lowers the mask, and every named entry loses write
with it; getfacl shows #effective:r-- and bob is locked out again.
Copying files in with cp -p or rsync -a from elsewhere. Preserving modes and groups preserves
the old private ones. Copy without preserving, or fix the group afterwards.
# who, and in which groups
id alice ; id -nG alice # groups by name
getent group reports # the group's members
sudo usermod -aG reports carol # append (-a!) a supplementary group
sudo gpasswd -a carol reports # the same; gpasswd -d removes
newgrp reports # a shell with the new group, without logging out
# what is there
ls -la /srv/reports ; stat -c '%A %U:%G %n' /srv/reports/*
namei -l /srv/reports/drafts/q4-outline.txt # every directory on the path, with its bits
sudo su - bob -c 'test -w /srv/reports/budget.csv && echo writable'
# existing files
sudo chgrp -R reports /srv/reports
sudo chmod -R g+rwX,o-rwx /srv/reports # X: execute only for dirs (and already-executables)
sudo find /srv/reports -type d -exec chmod g+s {} + # setgid: new entries get the dir's group
chmod +t /srv/drop # sticky: only the owner may delete their file
# new files
umask # 0022 → 644/755, 0002 → 664/775, 0077 → 600/700
grep -rn umask /etc/profile /etc/profile.d /etc/login.defs ~/.profile ~/.bashrc
# default ACLs ignore the umask:
sudo setfacl -R -m g:reports:rwX /srv/reports # what exists
sudo setfacl -R -d -m g:reports:rwX /srv/reports # what will be created
getfacl -p /srv/reports # mask:: caps named entries; #effective: shows the result
sudo setfacl -R -b /srv/reports # remove all ACL entries
# ls -l shows '+' when a file has an ACL; the group bits it shows are the mask
Where this lab’s hints send you for reading, beyond this journal. In the TUI, h shows a
hint’s reading and l opens a journal section; the lab’s page on the site lists the same.
hello) — How the kernel picks a triadManual pages: man 1 id, man 1 getent, man 1 chmod, man 5 login.defs, man 5 acl.
alice owns plan.txt, mode 0460 (r--rw----), group reports, and alice is in reports. Can
alice write to it?
No. The owner class is chosen first and only its bits count:
r--. Being in the group does not add the group’srw-. The kernel picks one class, it does not combine them.
budget.csv is -rw-rw-rw- but dave cannot read it. What could stop him?
A directory on the path. Reaching a file needs execute on every directory leading to it; with
/srv/reportsatdrwxrws---, dave, as “other”, cannot enter it, so the file’s own bits are never consulted.
After sudo usermod -aG reports carol, carol’s already-open terminal still cannot write to the
folder. Why, and what are two ways to get the group without a reboot?
A process’s groups are set when it starts; the shell that was open before the change keeps its old list. A new login (
su - carol, a new SSH session) reads the new membership;newgrp reportsstarts a shell with it.
With umask 077, a program creates a file asking for mode 0666 in a directory that has no ACL.
What mode does the file get, and which group?
0600: the umask removes group and other bits. The group is the creator’s primary group — unless the directory is setgid, in which case it is the directory’s group.
What does the setgid bit do on a directory, and what does it not do?
New files and subdirectories get the directory’s group instead of the creator’s primary group, and new subdirectories inherit setgid. It does not change any permission bits: under a
077umask the file has the right group and still no group access.
Why does a default ACL entry group:reports:rwx give group write to new files even under
umask 077?
When the parent directory has a default ACL, the umask is not applied. The new file’s ACL is copied from the defaults and limited only by the mode the program requested (
0666for a file), so the named group getsrw-.
getfacl shows group:reports:rwx #effective:r--. What is limiting the group, and what command
typically causes it?
The mask entry, which caps named users, named groups and the owning group; here it is
r--. Achmod g-w(or any chmod of the group bits) on a file with an ACL sets the mask.
Why is chmod -R g+rwX better than chmod -R g+rwx for a folder of documents?
Capital
Xadds execute only to directories, which need it to be entered, and to files that are already executable for someone. Lowercasexmarks every document as a program.