File Systems, NFS and AutofsLesson 4 of 4
Diagnosing and fixing permission problems
Work out why access is denied, step by step, and fix it with ownership, modes, setgid directories and ACLs.
nameiidls -ldchownchgrpchmodchmod g+ssetfaclgetfaclls -Zmount -o ro
After this lesson you can
- Follow a fixed checklist from identity to path to mode to everything else, and find the cause of an access denied error.
- Build a shared directory where a team can create and edit each other's files, using setgid and umask or default ACLs.
- Grant one extra user or group access with an ACL, and tell apart permission, mount and SELinux denials.
The idea
“Permission denied” is an answer, not a diagnosis. Work through the same checklist every time and the cause appears quickly.
- Who am I?
idshows the user, primary group and supplementary groups the process really has. A group added withusermod -aGtakes effect only at the next login. - Can I reach the file? You need
xon every directory in the path.namei -l /full/pathprints each component’s owner and mode, so the broken one stands out. - Is the mode right for what I’m doing? Reading a file needs
r; writing needsw; running needsx; listing a directory needsron it; creating or deleting entries in a directory needswandxon the directory. - Who owns it?
ls -ld. Fix withchown user:grouporchgrp. - Is there an ACL? A
+after the mode inls -lmeans extra rules:getfacl FILE. - Is something other than permissions involved? Mount options (
ro,noexec,nosuid), SELinux (ls -Z,ausearch -m avc), file attributes (lsattr), or, on NFS, the server.
Shared directories: setgid
For a team that edits each other’s files, three things must be true:
| Need | Mechanism |
|---|---|
| Only the team may enter | Directory owned root:developers, mode 770 |
| New files get the team’s group, not the creator’s | setgid bit on the directory (chmod g+s, or 2770) |
| Team members can modify each other’s files | New files are group-writable: umask 002, or a default ACL |
The setgid bit on a directory makes new files and subdirectories inherit its group, and new subdirectories inherit setgid too. But the mode of a new file is the creator’s umask applied to 666, and the usual umask 022 removes group write, so inherited group alone does not let teammates edit. On RHEL, regular users whose primary group matches their name get umask 002 from /etc/profile.d//etc/bashrc, but you should not rely on that.
A default ACL on the directory is the robust fix: setfacl -d -m g:developers:rwx /srv/projects gives every new entry that group’s access regardless of umask.
ACLs in two commands
setfacl -m u:erin:r file # give erin read access
setfacl -m g:auditors:rx dir # give a group read and enter
setfacl -x u:erin file # remove one entry
setfacl -b file # remove all ACL entries
getfacl file # list owner, group, ACL entries and the mask
The mask entry caps the permissions of named users and groups; getfacl shows the effective rights when the mask is narrower. If an ACL does not seem to work, check the mask.
The sticky bit
On a shared directory like /tmp (mode 1777, shown as drwxrwxrwt), the sticky bit means only a file’s owner (or root) can delete or rename it, even though everyone can write there. Use it when many users must add files to one place but not remove each other’s.
Try it
sudo mkdir -p /srv/lab/a/b && echo hello | sudo tee /srv/lab/a/b/file.txt
sudo chmod 700 /srv/lab/a
sudo -u alex cat /srv/lab/a/b/file.txt
namei -l /srv/lab/a/b/file.txt
cat: /srv/lab/a/b/file.txt: Permission denied
f: /srv/lab/a/b/file.txt
dr-xr-xr-x root root /
drwxr-xr-x root root srv
drwxr-xr-x root root lab
drwx------ root root a
drwxr-xr-x root root b
-rw-r--r-- root root file.txt
The file is world-readable, yet denied: directory a is drwx------. namei -l shows it at a glance.
A shared project directory
sudo groupadd developers
sudo usermod -aG developers alex
sudo usermod -aG developers dana
sudo mkdir -p /srv/projects
sudo chown root:developers /srv/projects
sudo chmod 2770 /srv/projects
sudo -u alex touch /srv/projects/plan.txt
ls -ld /srv/projects
ls -l /srv/projects
drwxrws---. 2 root developers 22 Nov 3 12:41 /srv/projects
total 0
-rw-r--r--. 1 alex developers 0 Nov 3 12:41 plan.txt
The s in the group triplet is setgid. The file’s group is developers (inherited), but it is -rw-r--r--: dana can read it and not edit. Now the default ACL:
sudo setfacl -d -m g:developers:rwx /srv/projects
sudo -u alex touch /srv/projects/new.txt
getfacl /srv/projects
ls -l /srv/projects/new.txt
# file: srv/projects
# owner: root
# group: developers
# flags: -s-
user::rwx
group::rwx
other::---
default:user::rwx
default:group::rwx
default:group:developers:rwx
default:mask::rwx
default:other::---
-rw-rw----+ 1 alex developers 0 Nov 3 12:44 new.txt
Note the + and -rw-rw----: the new file has group write and no access for others.
One extra reader
sudo setfacl -m u:erin:r /srv/projects/plan.txt
getfacl -c /srv/projects/plan.txt
user::rw-
user:erin:r--
group::r--
mask::r--
other::---
Beyond mode bits
| Symptom | Layer | Check |
|---|---|---|
Read-only file system | Mount | findmnt -no OPTIONS -T FILE shows ro |
Script with x bit says Permission denied | Mount | noexec in the options |
| Modes right, service still denied | SELinux | ls -Z, sudo ausearch -m avc -ts recent |
Operation not permitted even as root | Attribute | lsattr FILE shows i (immutable): chattr -i |
| Fine locally, denied over NFS | Server | UID mismatch, export options, root squash |
Going further
chmod -R with a capital X (chmod -R g+rX dir) adds execute only to directories and already-executable files, which is what you want for recursive fixes. find /srv -nouser -o -nogroup finds files whose owner no longer exists, typically after deleting a user. restorecon -Rv repairs SELinux labels after moving files; moved files keep their old label, copied files get the destination’s. getfacl -R src | setfacl --restore=- copies ACLs, and cp -a preserves them. stat FILE shows mode in octal, owner, timestamps and context in one view.
Practice
0 of 5 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
Which part of the path blocks me?
As root create
/srv/lab/a/b/file.txt, set directory/srv/lab/ato mode700(owned by root), and then try to read the file asalex. Usenamei -lto see the whole path with owners and modes, and name the directory that blocks him.Check your result
catas alex fails withPermission denied.namei -l /srv/lab/a/b/file.txtshowsdrwx------ root root a: alex lacksxona.Hint
To reach a file you need
x(search) on every directory in its path, plusron the file itself.Solution
sudo mkdir -p /srv/lab/a/b && echo hello | sudo tee /srv/lab/a/b/file.txt sudo chmod 700 /srv/lab/a sudo -u alex cat /srv/lab/a/b/file.txt namei -l /srv/lab/a/b/file.txt - Practice
A directory where a team can collaborate
Create the group
developerswith membersalexanddana. Create/srv/projectsowned byroot:developers, readable and writable by the group only, and arranged so that new files and directories automatically belong todevelopers. Verify by creating a file as alex and reading and editing it as dana. Others must have no access.Check your result
ls -ld /srv/projectsshowsdrwxrws---and groupdevelopers. A file created by alex has groupdevelopers. dana can append to it only if it is group-writable (see the next exercise).Hint
Mode
2770: the leading2is the setgid bit, which makes new entries inherit the directory's group.Solution
sudo groupadd developers sudo usermod -aG developers alex sudo usermod -aG developers dana sudo mkdir -p /srv/projects sudo chown root:developers /srv/projects sudo chmod 2770 /srv/projects ls -ld /srv/projects sudo -u alex touch /srv/projects/plan.txt ls -l /srv/projects - Practice
My colleague can see my file but not edit it
In the shared directory, alex's new file is
-rw-r--r--and dana getsPermission deniedwhen appending. Explain the cause and fix it two ways: (1) by setting the group's write access on existing files and changing alex's umask, and (2) by a default ACL on the directory that works regardless of anybody's umask.Check your result
After fix 1 new files are
-rw-rw-r--. After fix 2getfacl /srv/projectsshowsdefault:group:developers:rwxand new files are group-writable (themaskentry matters).Hint
The file mode is the creator's umask applied to 666. umask 022 removes group write.
setfacl -d -m g:developers:rwx DIRsets the default for new entries.Solution
sudo chmod g+w /srv/projects/plan.txt umask # 0022 in alex's shell: group write removed # fix 1: umask 002 for alex (shell profile) # fix 2: default ACL on the directory sudo setfacl -d -m g:developers:rwx /srv/projects getfacl /srv/projects sudo -u alex touch /srv/projects/new.txt ls -l /srv/projects/new.txt - Practice
One extra user, without changing the group
User
erinis not indevelopersbut must be able to read/srv/projects/plan.txtand nothing else there. Grant that with an ACL, show it withgetfacl, and explain howls -lreveals that an ACL exists. Remove the entry afterwards.Check your result
getfacllistsuser:erin:r--.ls -lshows a+after the mode bits. As erin,cat plan.txtworks but listing/srv/projectsis still denied.Hint
setfacl -m u:erin:r file, remove withsetfacl -x u:erin file. The directory'sxis a separate issue: erin needs a way to reach the file.Solution
sudo setfacl -m u:erin:r /srv/projects/plan.txt sudo setfacl -m u:erin:x /srv/projects getfacl /srv/projects/plan.txt ls -l /srv/projects/plan.txt sudo -u erin cat /srv/projects/plan.txt sudo setfacl -x u:erin /srv/projects/plan.txt /srv/projects - Challenge
It is not always mode bits
For each symptom say which layer you check next and which command shows it: (a)
touch: cannot touch 'x': Read-only file system; (b) a script with mode755fails withPermission deniedwhen run, but works withbash script; (c) mode and ownership are right, yet the web server cannot read/srv/web/index.html; (d)Operation not permittedonchattr-protected file.Check your result
(a) mount options:
findmnt -no OPTIONS; (b)noexecmount option; (c) SELinux label:ls -Zandausearch -m avc; (d) file attributes:lsattr.Hint
After ownership and mode, the remaining layers are: mount options, SELinux, file attributes and, for network shares, the server side.
Solution
findmnt -no OPTIONS -T /path/to/file # (a) ro? (b) noexec? ls -Z /srv/web/index.html # (c) SELinux type sudo ausearch -m avc -ts recent | tail -3 lsattr /path/to/file # (d) i = immutable