4 of 4

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.

  • namei
  • id
  • ls -ld
  • chown
  • chgrp
  • chmod
  • chmod g+s
  • setfacl
  • getfacl
  • ls -Z
  • mount -o ro

50 min5 exercises

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.

  1. Who am I? id shows the user, primary group and supplementary groups the process really has. A group added with usermod -aG takes effect only at the next login.
  2. Can I reach the file? You need x on every directory in the path. namei -l /full/path prints each component’s owner and mode, so the broken one stands out.
  3. Is the mode right for what I’m doing? Reading a file needs r; writing needs w; running needs x; listing a directory needs r on it; creating or deleting entries in a directory needs w and x on the directory.
  4. Who owns it? ls -ld. Fix with chown user:group or chgrp.
  5. Is there an ACL? A + after the mode in ls -l means extra rules: getfacl FILE.
  6. 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:

NeedMechanism
Only the team may enterDirectory owned root:developers, mode 770
New files get the team’s group, not the creator’ssetgid bit on the directory (chmod g+s, or 2770)
Team members can modify each other’s filesNew 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

SymptomLayerCheck
Read-only file systemMountfindmnt -no OPTIONS -T FILE shows ro
Script with x bit says Permission deniedMountnoexec in the options
Modes right, service still deniedSELinuxls -Z, sudo ausearch -m avc -ts recent
Operation not permitted even as rootAttributelsattr FILE shows i (immutable): chattr -i
Fine locally, denied over NFSServerUID 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.

  1. Warm-up

    Which part of the path blocks me?

    As root create /srv/lab/a/b/file.txt, set directory /srv/lab/a to mode 700 (owned by root), and then try to read the file as alex. Use namei -l to see the whole path with owners and modes, and name the directory that blocks him.

    Check your result

    cat as alex fails with Permission denied. namei -l /srv/lab/a/b/file.txt shows drwx------ root root a: alex lacks x on a.

    Hint

    To reach a file you need x (search) on every directory in its path, plus r on 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
  2. Practice

    A directory where a team can collaborate

    Create the group developers with members alex and dana. Create /srv/projects owned by root:developers, readable and writable by the group only, and arranged so that new files and directories automatically belong to developers. 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/projects shows drwxrws--- and group developers. A file created by alex has group developers. dana can append to it only if it is group-writable (see the next exercise).

    Hint

    Mode 2770: the leading 2 is 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
  3. 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 gets Permission denied when 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 2 getfacl /srv/projects shows default:group:developers:rwx and new files are group-writable (the mask entry matters).

    Hint

    The file mode is the creator's umask applied to 666. umask 022 removes group write. setfacl -d -m g:developers:rwx DIR sets 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
  4. Practice

    One extra user, without changing the group

    User erin is not in developers but must be able to read /srv/projects/plan.txt and nothing else there. Grant that with an ACL, show it with getfacl, and explain how ls -l reveals that an ACL exists. Remove the entry afterwards.

    Check your result

    getfacl lists user:erin:r--. ls -l shows a + after the mode bits. As erin, cat plan.txt works but listing /srv/projects is still denied.

    Hint

    setfacl -m u:erin:r file, remove with setfacl -x u:erin file. The directory's x is 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
  5. 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 mode 755 fails with Permission denied when run, but works with bash script; (c) mode and ownership are right, yet the web server cannot read /srv/web/index.html; (d) Operation not permitted on chattr-protected file.

    Check your result

    (a) mount options: findmnt -no OPTIONS; (b) noexec mount option; (c) SELinux label: ls -Z and ausearch -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