Linux File Permissions & User Management: Solve Permission Denied Errors
This guide explains the Linux permission model (user/group/other with read/write/execute), how to read ls -l output, practical chmod/chown/umask usage, user and group management commands, sudo configuration with visudo, and a five-step troubleshooting workflow for Permission denied errors.
Permission Model: Three User Classes × Three Permissions
Every file has three sets of permissions for three user classes:
Owner (u) – the file's creator
Group (g) – users in the file's group
Others (o) – everyone else
All (a) – shorthand for u+g+o
Each class gets three permission bits with different meanings for files and directories: r (read): on files – view contents; on directories – list entries w (write): on files – modify contents; on directories – create/delete files inside x (execute): on files – run as program; on directories – enter directory ( cd)
Key insight: A directory's execute bit is often overlooked. Without x , you cannot cd into it even if you have r , and you cannot access any files inside.
Reading ls -l Output
Example:
$ ls -l deploy.sh
-rwxr-xr-- 1 deploy deploy 872 Sep 26 10:00 deploy.sh
- rwx r-x r--
①type ②owner ③group ④othersPosition 1: file type ( - regular, d directory, l symlink)
Positions 2‑4: owner permissions ( rwx = full)
Positions 5‑7: group permissions ( r-x = read + execute)
Positions 8‑10: others permissions ( r-- = read only)
Special permissions (mentioned for awareness):
SUID – process gains file owner's privileges (e.g., passwd)
SGID – new files in a directory inherit the directory's group
Sticky Bit – only the file's owner can delete it (e.g., /tmp)
chmod, chown, and umask
Numeric (octal) mode
Each digit = sum of r=4, w=2, x=1 for owner, group, others.
Octal Permission String Typical Use
755 rwxr-xr-x Scripts, executables, directories
644 rw-r--r-- Config files, regular files
600 rw------- Private keys, password files chmod 755 deploy.sh # rwxr-xr-x
chmod 644 app.log # rw-r--r--
chmod 600 id_rsa # rw------- (private key must be 600)Warning: chmod 777 opens access to everyone – acceptable only for temporary debugging, never in production.
Tip: Script fails with Permission denied ? Nine times out of ten it's missing execute bit: chmod +x script.sh .
Symbolic mode
Better for incremental changes:
chmod u+x deploy.sh # add execute for owner
chmod g-w app.log # remove write for group
chmod a+r readme.md # add read for all
chmod -R 755 /opt/app # recursive on directory treechown – change ownership
chown deploy app.log # change owner only
chown deploy:deploy app.log # change owner and group
chown -R deploy:deploy /opt/app # recursiveNote: chown requires root; prefix with sudo as a regular user.
umask – default permissions for new files
Formula: base permission − umask .
Default base: directories 777, files 666 Typical umask 022 → directories 755, files 644 Temporary change: umask 027 Permanent: add umask 027 to
~/.bashrcUser and Group Management
useradd -m -s /bin/bash deploy # create user with home dir
passwd deploy # set password
usermod -aG docker deploy # append to docker group (note -a)
id deploy # show uid, gid, groups
su - deploy # switch user with login environment
groupadd devs # create group
gpasswd -a deploy devs # add user to groupCritical: usermod -G without -a replaces all supplementary groups. Always use -aG to append.
One-liner for Docker access: sudo usermod -aG docker deploy – re-login to take effect.
sudo Configuration and Permission Denied Troubleshooting
Editing sudoers safely
Use visudo (validates syntax). Example: allow user deploy to restart nginx without password:
sudo visudo
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginxSecurity rule: Never write NOPASSWD: ALL – that hands out full root. Grant only the specific commands needed.
Five-step Permission denied diagnosis
Identify the user from the error – is it your login user or a service user (e.g., nginx, gunicorn)?
Check target permissions with ls -l on the file/directory.
Walk the path – every directory in the path must have x for the accessing user.
Apply targeted fix :
Missing execute → chmod +x Cannot write → chmod g+w or adjust ownership
Service user blocked → chown -R www-data:www-data /opt/app Check SELinux if still failing: getenforce, temporarily setenforce 0 to test.
Universal test command: sudo -u www-data cat /opt/app/config.yaml – run the exact access attempt as the service user to see if it succeeds.
Core principle: Least privilege – give each entity exactly the permissions it needs, no more. Slight inconvenience now prevents security incidents later.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Farmer Manor Chronicle
A heart like drifting clouds, ever at ease; a mind like flowing water, free to roam.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
