Unix permissions determine who can do what with files and directories. Understanding them is fundamental to system security and avoiding “Permission denied” errors.

The Permission Model

Every file has three permission types for three user classes:

Permission Types:

  • r (read) = 4
  • w (write) = 2
  • x (execute) = 1

User Classes:

  • u (user/owner)
  • g (group)
  • o (others)

Reading Permissions

1
2
ls -l file.txt
# -rw-r--r-- 1 user group 1234 Feb 25 12:00 file.txt

Breaking down -rw-r--r--:

Friwl-eOtwynpree-r-:Grre=oarudf-pi-:+leOrw,terhaidedtre=so:ndliryreeacdtoornyl,yl=link)

Numeric (Octal) Mode

Add the values: r=4, w=2, x=1

rrrrww--x-x-=====44440+++++22000+++++10100=====76540

Common permission sets:

1
2
3
4
5
chmod 755 file  # rwxr-xr-x (executable, everyone can run)
chmod 644 file  # rw-r--r-- (readable by all, writable by owner)
chmod 700 file  # rwx------ (owner only)
chmod 600 file  # rw------- (owner read/write only)
chmod 777 file  # rwxrwxrwx (everyone can do everything - avoid!)

Symbolic Mode

Format: [who][operation][permissions]

Who: u (user), g (group), o (others), a (all) Operation: + (add), - (remove), = (set exactly) Permissions: r, w, x

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Add execute for owner
chmod u+x script.sh

# Remove write for group and others
chmod go-w file.txt

# Set exact permissions
chmod u=rwx,g=rx,o=r file.txt

# Add execute for everyone
chmod a+x script.sh
chmod +x script.sh  # Same thing

Directory Permissions

For directories, permissions mean something different:

  • r = Can list contents (ls)
  • w = Can create/delete files inside
  • x = Can enter directory (cd) and access files
1
2
3
4
# Typical directory permissions
chmod 755 mydir  # Others can enter and list
chmod 700 mydir  # Private directory
chmod 750 mydir  # Group can enter and list

Common Permission Patterns

Scripts and Executables

1
2
chmod 755 script.sh   # Anyone can run
chmod 700 script.sh   # Only owner can run

Config Files (Sensitive)

1
2
chmod 600 config.yml  # Owner read/write only
chmod 400 secrets.key # Owner read only

Web Files

1
2
chmod 644 index.html  # Readable by web server
chmod 755 uploads/    # Web server can list/write

SSH Keys

1
2
3
4
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys

Recursive Changes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Change all files in directory
chmod -R 644 /path/to/dir

# Change only directories
find /path -type d -exec chmod 755 {} \;

# Change only files
find /path -type f -exec chmod 644 {} \;

# Combined approach
chmod -R u=rwX,g=rX,o=rX /path
# Capital X = execute only if directory or already executable

Special Permissions

Setuid (4xxx)

Executes as the file owner, not the user running it:

1
2
chmod 4755 program    # -rwsr-xr-x
chmod u+s program     # Same thing

Example: /usr/bin/passwd runs as root to modify /etc/shadow.

Setgid (2xxx)

Executes as the file’s group. For directories, new files inherit the directory’s group:

1
2
chmod 2755 directory  # drwxr-sr-x
chmod g+s directory   # Same thing

Useful for shared directories where all files should belong to a common group.

Sticky Bit (1xxx)

Only file owner can delete files in directory:

1
2
chmod 1755 directory  # drwxr-xr-t
chmod +t directory    # Same thing

Example: /tmp has sticky bit so users can’t delete each other’s files.

Combined Special Permissions

1
2
3
4
chmod 4755 program    # Setuid
chmod 2755 directory  # Setgid  
chmod 1755 directory  # Sticky
chmod 6755 program    # Setuid + Setgid

chown and chgrp

Change ownership:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Change owner
chown user file.txt

# Change owner and group
chown user:group file.txt

# Change group only
chgrp group file.txt
chown :group file.txt

# Recursive
chown -R user:group /path/to/dir

Default Permissions (umask)

umask sets the default permissions for new files:

1
2
3
4
5
6
7
8
9
# Check current umask
umask
# 0022

# New file permissions: 666 - 022 = 644 (rw-r--r--)
# New directory permissions: 777 - 022 = 755 (rwxr-xr-x)

# Set restrictive umask
umask 077  # New files: 600, new dirs: 700

Add to ~/.bashrc for permanent change.

Troubleshooting

“Permission denied”

1
2
3
4
5
6
7
8
# Check current permissions
ls -la file.txt

# Check if you're the owner
stat file.txt

# Check directory permissions (need x to access files inside)
ls -ld /path/to/directory

Script Won’t Execute

1
2
3
4
5
6
7
8
9
# Check for execute permission
ls -l script.sh

# Add it
chmod +x script.sh

# Or run with interpreter
bash script.sh
python script.py

SSH Key Issues

1
2
3
4
5
# SSH is strict about permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/config

Web Server Can’t Read Files

1
2
3
4
5
6
7
8
9
# Check file ownership
ls -la /var/www/html/

# Fix ownership
sudo chown -R www-data:www-data /var/www/html/

# Fix permissions
find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;

Quick Reference

NumericSymbolicMeaning
755rwxr-xr-xExecutable by all
644rw-r–r–Readable by all
700rwx——Owner only
600rw——-Owner read/write
777rwxrwxrwxEveryone everything (avoid)
400r——–Owner read only
SpecialBitEffect
Setuid4xxxRun as owner
Setgid2xxxRun as group / inherit group
Sticky1xxxOnly owner can delete

Permissions seem complex but follow a simple pattern: three classes (user, group, others), three permissions (read, write, execute), represented as either letters (rwx) or numbers (4+2+1=7). Start with the common patterns (755, 644, 600), and you’ll handle 90% of permission tasks.