Understanding File Permissions and chmod
Table of Contents
- Introduction
- Understanding File Permissions Basics
- Reading Permission Strings
- The chmod Command
- Numeric (Octal) Mode
- Symbolic Mode
- The chown Command
- The chgrp Command
- Special Permissions
- Understanding umask
- Real-World Permission Scenarios
- Practice Labs
- Summary
Introduction
File permissions are the foundation of Linux security. Every file and directory has a set of permissions that control who can read, write, or execute it. Understanding and managing these permissions is critical for:
- System Security: Preventing unauthorized access to sensitive files
- User Management: Controlling what users can do with files
- Application Deployment: Setting correct permissions for web servers, databases
- Collaboration: Allowing multiple users to work with shared files safely
For the LFCS exam, you must be proficient in:
- Reading and interpreting permission strings
- Using
chmodin both numeric and symbolic modes - Changing file ownership with
chownandchgrp - Understanding special permissions (setuid, setgid, sticky bit)
- Managing default permissions with
umask
This guide provides comprehensive coverage with practical examples.
Understanding File Permissions Basics
The Three Permission Types
Every file has three types of permissions:
- Read (r): Permission to view file contents or list directory contents
- Write (w): Permission to modify file contents or create/delete files in a directory
- Execute (x): Permission to run a file as a program or access a directory
The Three Permission Categories
Permissions are assigned to three categories of users:
- User (u): The file owner
- Group (g): Members of the file's group
- Other (o): Everyone else on the system
Viewing Permissions
Use ls -l to view detailed file information including permissions:
ls -l myfile.txt
Example output:
-rw-r--r-- 1 alice developers 1024 Dec 09 10:30 myfile.txt
Breaking down the output:
-rw-r--r--: Permission string1: Number of hard linksalice: Owner (user)developers: Group1024: File size in bytesDec 09 10:30: Last modification timemyfile.txt: Filename
Reading Permission Strings
The permission string has 10 characters:
-rw-r--r--
Character Breakdown
Position 1: File type
-: Regular filed: Directoryl: Symbolic linkb: Block devicec: Character devicep: Named pipes: Socket
Positions 2-4: User (owner) permissions
r: Read permissionw: Write permissionx: Execute permission-: Permission not granted
Positions 5-7: Group permissions
- Same as user permissions
Positions 8-10: Other permissions
- Same as user and group permissions
Examples
-rw-r--r--
- Regular file
- User: read, write
- Group: read only
- Other: read only
drwxr-xr-x
- Directory
- User: read, write, execute
- Group: read, execute
- Other: read, execute
-rwxrwxrwx
- Regular file
- Everyone: full permissions (read, write, execute)
-rw-------
- Regular file
- User: read, write
- Group: no permissions
- Other: no permissions
The chmod Command
The chmod (change mode) command modifies file permissions. It can be used in two modes:
- Numeric (Octal) Mode: Using numbers (e.g.,
chmod 755) - Symbolic Mode: Using letters (e.g.,
chmod u+x)
Basic Syntax
chmod [options] mode file
Common Options:
-R: Recursive (apply to directories and their contents)-v: Verbose (show files being processed)-c: Report only when changes are made
Numeric (Octal) Mode
Understanding the Numbers
Each permission has a numeric value:
- Read (r): 4
- Write (w): 2
- Execute (x): 1
- No permission: 0
Permissions are calculated by adding these values for each category.
Permission Calculation Table
| Binary | Octal | Permissions | Meaning |
|--------|-------|-------------|---------|
| 000 | 0 | --- | No permissions |
| 001 | 1 | --x | Execute only |
| 010 | 2 | -w- | Write only |
| 011 | 3 | -wx | Write and execute |
| 100 | 4 | r-- | Read only |
| 101 | 5 | r-x | Read and execute |
| 110 | 6 | rw- | Read and write |
| 111 | 7 | rwx | Read, write, and execute |
Common Permission Combinations
# 755: rwxr-xr-x (common for executables and directories)
# User: 7 (4+2+1) = rwx
# Group: 5 (4+0+1) = r-x
# Other: 5 (4+0+1) = r-x
chmod 755 script.sh
# 644: rw-r--r-- (common for regular files)
# User: 6 (4+2) = rw-
# Group: 4 (4) = r--
# Other: 4 (4) = r--
chmod 644 document.txt
# 600: rw------- (private file, only owner can read/write)
chmod 600 private.key
# 777: rwxrwxrwx (all permissions for everyone - DANGEROUS!)
chmod 777 file.txt # Generally avoid this!
# 700: rwx------ (private executable, only owner can use)
chmod 700 myscript.sh
# 664: rw-rw-r-- (group collaboration file)
chmod 664 shared.txt
Examples with Numeric Mode
# Create a test file
touch myfile.txt
ls -l myfile.txt
# Output: -rw-r--r-- 1 alice alice 0 Dec 09 10:30 myfile.txt
# Make it readable and writable by user only
chmod 600 myfile.txt
ls -l myfile.txt
# Output: -rw------- 1 alice alice 0 Dec 09 10:30 myfile.txt
# Make a script executable for user, readable for others
chmod 744 script.sh
ls -l script.sh
# Output: -rwxr--r-- 1 alice alice 0 Dec 09 10:30 script.sh
# Set full permissions for user and group, none for others
chmod 770 shared_folder
ls -ld shared_folder
# Output: drwxrwx--- 2 alice developers 4096 Dec 09 10:30 shared_folder
Recursive Permission Changes
# Change all files and subdirectories
chmod -R 755 /var/www/html
# Verbose output
chmod -Rv 644 *.txt
Symbolic Mode
Symbolic mode uses letters to modify permissions without needing to calculate numbers.
Symbolic Mode Syntax
chmod [who][operator][permissions] file
Who:
u: User (owner)g: Groupo: Othera: All (user, group, and other)
Operator:
+: Add permission-: Remove permission=: Set exact permission (removes all others)
Permissions:
r: Readw: Writex: Execute
Adding Permissions
# Add execute permission for user
chmod u+x script.sh
# Add write permission for group
chmod g+w document.txt
# Add read permission for others
chmod o+r file.txt
# Add execute permission for everyone
chmod a+x program
# Add multiple permissions at once
chmod u+rwx,g+rx,o+r file.txt
Removing Permissions
# Remove write permission from group
chmod g-w file.txt
# Remove execute permission from others
chmod o-x script.sh
# Remove all permissions from others
chmod o-rwx private.txt
# Remove write from everyone
chmod a-w readonly.txt
Setting Exact Permissions
# Set user to read/write only (removes execute if it existed)
chmod u=rw file.txt
# Set group to read-only
chmod g=r file.txt
# Set others to no permissions
chmod o= file.txt
# Set everyone to read-only
chmod a=r file.txt
Combining Operations
# Add execute for user, remove write for others
chmod u+x,o-w file.txt
# Set user to full, group to read/execute, other to none
chmod u=rwx,g=rx,o= script.sh
# Add read for all, remove write for group and others
chmod a+r,go-w file.txt
Practical Examples
# Make a script executable
chmod +x backup.sh
# Same as: chmod a+x backup.sh
# Make a file private (only owner can read/write)
chmod go-rwx private.txt
# Or: chmod 600 private.txt
# Give group write access to a shared directory
chmod g+w shared_docs/
# Remove execute permission from all files in a directory
chmod -R a-x documents/
# Make a file read-only for everyone
chmod a-w,a+r readonly.txt
The chown Command
The chown (change owner) command changes file ownership.
Basic Syntax
chown [options] user[:group] file
Note: Changing ownership typically requires root privileges.
Changing User Owner
# Change owner to bob
sudo chown bob file.txt
# Check the change
ls -l file.txt
# Output: -rw-r--r-- 1 bob alice 1024 Dec 09 10:30 file.txt
Changing User and Group
# Change owner to bob and group to developers
sudo chown bob:developers file.txt
# Check the change
ls -l file.txt
# Output: -rw-r--r-- 1 bob developers 1024 Dec 09 10:30 file.txt
Recursive Ownership Change
# Change ownership of directory and all contents
sudo chown -R alice:developers /home/alice/project
# Verbose output
sudo chown -Rv www-data:www-data /var/www/html
Using Numeric UIDs and GIDs
# Use numeric user ID and group ID
sudo chown 1000:1000 file.txt
# Find your UID and GID
id
# Output: uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo)
Practical Examples
# Transfer ownership when moving to a new user
sudo chown -R newuser:newuser /home/olduser/important_files
# Set web server ownership
sudo chown -R www-data:www-data /var/www/mysite
# Fix ownership after copying files as root
sudo cp -r /backup/files /home/alice/
sudo chown -R alice:alice /home/alice/files
The chgrp Command
The chgrp (change group) command changes a file's group ownership.
Basic Syntax
chgrp [options] group file
Changing Group
# Change group to developers
chgrp developers project.txt
# Check the change
ls -l project.txt
# Output: -rw-r--r-- 1 alice developers 1024 Dec 09 10:30 project.txt
Recursive Group Change
# Change group for directory and all contents
chgrp -R developers /opt/project
# Verbose output
chgrp -Rv www-data /var/www/html
Practical Examples
# Share files with a group
chgrp developers shared_folder
chmod g+w shared_folder
# Change multiple files at once
chgrp developers *.txt
# Change group based on reference file
chgrp --reference=template.txt *.txt
chown vs chgrp
You can use chown to change both user and group:
# Using chown to change only group (note the colon)
sudo chown :developers file.txt
# This is equivalent to:
chgrp developers file.txt
Special Permissions
Beyond read, write, and execute, Linux has three special permissions:
- Setuid (Set User ID): 4000
- Setgid (Set Group ID): 2000
- Sticky Bit: 1000
Setuid (SUID)
When set on an executable file, the program runs with the permissions of the file owner, not the user running it.
Numeric representation: Add 4 to the front (e.g., 4755)
Example: The passwd command
ls -l /usr/bin/passwd
# Output: -rwsr-xr-x 1 root root 59976 Nov 24 2022 /usr/bin/passwd
# ^
# s indicates setuid
The passwd command needs to modify /etc/shadow (owned by root). When a regular user runs passwd, the setuid bit allows it to run with root privileges.
Setting setuid:
# Numeric mode
chmod 4755 program
# Symbolic mode
chmod u+s program
# Check result
ls -l program
# Output: -rwsr-xr-x 1 alice alice 12345 Dec 09 10:30 program
# ^
# s = setuid + execute
# S = setuid without execute (unusual)
Security Warning: Setuid programs are security-sensitive. A poorly written setuid program can be exploited to gain root access.
Setgid (SGID)
On Files: When set on an executable, the program runs with the permissions of the file's group.
On Directories: New files created in the directory inherit the directory's group (instead of the creator's primary group).
Numeric representation: Add 2 to the front (e.g., 2755)
Setting setgid:
# Numeric mode
chmod 2755 shared_directory
# Symbolic mode
chmod g+s shared_directory
# Check result
ls -ld shared_directory
# Output: drwxr-sr-x 2 alice developers 4096 Dec 09 10:30 shared_directory
# ^
# s indicates setgid
Practical example for team collaboration:
# Create shared directory for developers
sudo mkdir /opt/team_project
sudo chown alice:developers /opt/team_project
sudo chmod 2775 /opt/team_project
# Now when any developer creates a file in this directory,
# it will automatically be owned by the developers group
cd /opt/team_project
touch newfile.txt
ls -l newfile.txt
# Output: -rw-r--r-- 1 alice developers 0 Dec 09 10:30 newfile.txt
# ^^^^^^^^^
# Inherited from directory
Sticky Bit
When set on a directory, only the file owner (or root) can delete or rename files in that directory, even if other users have write permission to the directory.
Numeric representation: Add 1 to the front (e.g., 1777)
Example: /tmp directory
ls -ld /tmp
# Output: drwxrwxrwt 10 root root 4096 Dec 09 10:30 /tmp
# ^
# t indicates sticky bit
Everyone can create files in /tmp, but users can only delete their own files.
Setting sticky bit:
# Numeric mode
chmod 1777 shared_directory
# Symbolic mode
chmod +t shared_directory
# Check result
ls -ld shared_directory
# Output: drwxrwxrwt 2 alice alice 4096 Dec 09 10:30 shared_directory
# ^
# t indicates sticky bit
Practical example:
# Create a shared upload directory
mkdir /opt/uploads
chmod 1777 /opt/uploads
# Now all users can create files, but only owners can delete them
Special Permissions Summary Table
| Permission | Numeric | File Effect | Directory Effect | Symbol |
|------------|---------|-------------|------------------|--------|
| Setuid | 4000 | Run as file owner | (no effect) | s in user position |
| Setgid | 2000 | Run as file group | New files inherit directory group | s in group position |
| Sticky Bit | 1000 | (no effect) | Only owner can delete files | t in other position |
Combining Special Permissions
# Setuid + standard permissions (4755)
# 4 (setuid) + 7 (user: rwx) + 5 (group: r-x) + 5 (other: r-x)
chmod 4755 program
# Result: -rwsr-xr-x
# Setgid + standard permissions (2775)
# 2 (setgid) + 7 (user: rwx) + 7 (group: rwx) + 5 (other: r-x)
chmod 2775 directory
# Result: drwxrwsr-x
# Sticky bit + standard permissions (1777)
# 1 (sticky) + 7 (user: rwx) + 7 (group: rwx) + 7 (other: rwx)
chmod 1777 shared_dir
# Result: drwxrwxrwt
# All special permissions (7755)
chmod 7755 file
# Result: -rwsr-sr-t
Understanding umask
The umask (user file-creation mode mask) sets default permissions for newly created files and directories.
How umask Works
umask uses a subtraction model:
For files:
- Maximum permissions: 666 (rw-rw-rw-)
- Subtract umask from this to get actual permissions
For directories:
- Maximum permissions: 777 (rwxrwxrwx)
- Subtract umask from this to get actual permissions
Viewing Current umask
# Symbolic notation
umask -S
# Output: u=rwx,g=rx,o=rx
# Numeric notation
umask
# Output: 0022
Common umask Values
umask 0022 (most common default):
- New files: 666 - 022 = 644 (rw-r--r--)
- New directories: 777 - 022 = 755 (rwxr-xr-x)
umask 0002 (common for group collaboration):
- New files: 666 - 002 = 664 (rw-rw-r--)
- New directories: 777 - 002 = 775 (rwxrwxr-x)
umask 0077 (very restrictive, private):
- New files: 666 - 077 = 600 (rw-------)
- New directories: 777 - 077 = 700 (rwx------)
Setting umask
# Set umask temporarily (current session only)
umask 0022
# Test it
touch newfile.txt
ls -l newfile.txt
# Output: -rw-r--r-- 1 alice alice 0 Dec 09 10:30 newfile.txt
mkdir newdir
ls -ld newdir
# Output: drwxr-xr-x 2 alice alice 4096 Dec 09 10:30 newdir
Making umask Permanent
Add to ~/.bashrc or ~/.profile:
# For personal files (restrictive)
umask 0077
# For shared environment (group writable)
umask 0002
# Standard default
umask 0022
Then reload:
source ~/.bashrc
umask Calculation Examples
Example 1: umask 0027
Files:
666 (maximum for files)
-027 (umask)
----
640 (rw-r-----)
Directories:
777 (maximum for directories)
-027 (umask)
----
750 (rwxr-x---)
Example 2: umask 0077
Files:
666
-077
----
600 (rw-------)
Directories:
777
-077
----
700 (rwx------)
Real-World Permission Scenarios
Scenario 1: Web Server Files
Requirements:
- Web server user (www-data) needs to read files
- Developer needs to modify files
- Public should not access files directly
# Set ownership
sudo chown -R developer:www-data /var/www/html
# Set permissions
sudo chmod -R 750 /var/www/html
# For uploaded files that need to be writable by web server
sudo chmod -R 770 /var/www/html/uploads
# Files: rw-r----- (640)
# Directories: rwxr-x--- (750)
sudo find /var/www/html -type f -exec chmod 640 {} \;
sudo find /var/www/html -type d -exec chmod 750 {} \;
Scenario 2: Shared Project Directory
Requirements:
- Team members can read, write, and create files
- New files should be accessible to all team members
- Others should not access the directory
# Create directory
sudo mkdir /opt/team_project
# Set ownership
sudo chown alice:developers /opt/team_project
# Set permissions with setgid
sudo chmod 2770 /opt/team_project
# Result: drwxrws--- 2 alice developers 4096 Dec 09 10:30 /opt/team_project
# Team members should set umask for group collaboration
echo "umask 0002" >> ~/.bashrc
source ~/.bashrc
Scenario 3: Backup Script
Requirements:
- Only root should be able to run the script
- Script must be protected from modification
- Script needs to access sensitive files
# Create script
sudo nano /usr/local/bin/backup.sh
# Set ownership to root
sudo chown root:root /usr/local/bin/backup.sh
# Set permissions: owner can read/write/execute, others nothing
sudo chmod 700 /usr/local/bin/backup.sh
# Verify
ls -l /usr/local/bin/backup.sh
# Output: -rwx------ 1 root root 1234 Dec 09 10:30 /usr/local/bin/backup.sh
Scenario 4: Log Files
Requirements:
- Application writes logs
- Admin group can read logs
- Logs should be append-only (not writable by app)
# Create log directory
sudo mkdir /var/log/myapp
# Set ownership
sudo chown myapp:admin /var/log/myapp
# Set directory permissions
sudo chmod 755 /var/log/myapp
# Create log file with restricted permissions
sudo touch /var/log/myapp/app.log
sudo chown myapp:admin /var/log/myapp/app.log
sudo chmod 640 /var/log/myapp/app.log
# Result: -rw-r----- 1 myapp admin 0 Dec 09 10:30 app.log
Scenario 5: SSH Private Key
Requirements:
- Only owner can read/write the private key
- SSH will refuse to use the key if permissions are too open
# Generate SSH key
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
# Set correct permissions
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh
# Verify
ls -la ~/.ssh/
# Output:
# drwx------ 2 alice alice 4096 Dec 09 10:30 .
# -rw------- 1 alice alice 3401 Dec 09 10:30 id_rsa
# -rw-r--r-- 1 alice alice 745 Dec 09 10:30 id_rsa.pub
Practice Labs
Lab 1: Basic Permission Changes
Task: Create files and practice changing permissions with numeric mode.
# Create test directory
mkdir ~/permission_practice
cd ~/permission_practice
# Create test files
touch file1.txt file2.txt file3.txt
# Check current permissions
ls -l
# Change file1.txt to 644 (rw-r--r--)
chmod 644 file1.txt
# Change file2.txt to 600 (rw-------)
chmod 600 file2.txt
# Change file3.txt to 755 (rwxr-xr-x)
chmod 755 file3.txt
# Verify changes
ls -l
# Expected output:
# -rw-r--r-- 1 alice alice 0 Dec 09 10:30 file1.txt
# -rw------- 1 alice alice 0 Dec 09 10:30 file2.txt
# -rwxr-xr-x 1 alice alice 0 Dec 09 10:30 file3.txt
Lab 2: Symbolic Mode Practice
Task: Use symbolic mode to modify permissions.
# Create test file
touch symbolic_test.txt
ls -l symbolic_test.txt
# Initial: -rw-r--r--
# Add execute for user
chmod u+x symbolic_test.txt
ls -l symbolic_test.txt
# Result: -rwxr--r--
# Remove read for others
chmod o-r symbolic_test.txt
ls -l symbolic_test.txt
# Result: -rwxr-----
# Add write for group
chmod g+w symbolic_test.txt
ls -l symbolic_test.txt
# Result: -rwxrw----
# Set exact permissions: user=rw, group=r, other=none
chmod u=rw,g=r,o= symbolic_test.txt
ls -l symbolic_test.txt
# Result: -rw-r-----
Lab 3: Creating an Executable Script
Task: Create a shell script and make it executable.
# Create script
cat > hello.sh << 'EOF'
#!/bin/bash
echo "Hello, World!"
echo "Current user: $USER"
EOF
# Check permissions
ls -l hello.sh
# Result: -rw-r--r--
# Try to execute (will fail)
./hello.sh
# Error: Permission denied
# Make executable
chmod +x hello.sh
ls -l hello.sh
# Result: -rwxr-xr-x
# Now execute
./hello.sh
# Output:
# Hello, World!
# Current user: alice
Lab 4: Ownership Changes
Task: Practice changing file ownership (requires sudo).
# Create test file
touch ownership_test.txt
ls -l ownership_test.txt
# Result: -rw-r--r-- 1 alice alice 0 Dec 09 10:30 ownership_test.txt
# Change owner to root (requires sudo)
sudo chown root ownership_test.txt
ls -l ownership_test.txt
# Result: -rw-r--r-- 1 root alice 0 Dec 09 10:30 ownership_test.txt
# Change group to root
sudo chown :root ownership_test.txt
ls -l ownership_test.txt
# Result: -rw-r--r-- 1 root root 0 Dec 09 10:30 ownership_test.txt
# Change both back to alice
sudo chown alice:alice ownership_test.txt
ls -l ownership_test.txt
# Result: -rw-r--r-- 1 alice alice 0 Dec 09 10:30 ownership_test.txt
Lab 5: Understanding umask
Task: Experiment with different umask values.
# Check current umask
umask
# Example output: 0022
# Create file with current umask
touch file_umask_022.txt
mkdir dir_umask_022
# Check permissions
ls -l file_umask_022.txt
# Expected: -rw-r--r-- (644)
ls -ld dir_umask_022
# Expected: drwxr-xr-x (755)
# Change umask to restrictive
umask 0077
# Create new file
touch file_umask_077.txt
mkdir dir_umask_077
# Check permissions
ls -l file_umask_077.txt
# Expected: -rw------- (600)
ls -ld dir_umask_077
# Expected: drwx------ (700)
# Restore umask
umask 0022
Lab 6: Setgid for Shared Directory
Task: Create a shared directory where all files inherit the group.
# Create shared directory
mkdir ~/shared_team
# Set setgid bit
chmod 2775 ~/shared_team
ls -ld ~/shared_team
# Result: drwxrwsr-x 2 alice alice 4096 Dec 09 10:30 ~/shared_team
# ^
# s indicates setgid
# Create a file in this directory
touch ~/shared_team/teamfile.txt
ls -l ~/shared_team/teamfile.txt
# The group will be the same as the directory's group (alice)
# If the directory was owned by group "developers", new files would
# automatically be in the "developers" group
Lab 7: Sticky Bit for Shared Directory
Task: Create a directory where users can only delete their own files.
# Create directory
mkdir ~/shared_sticky
# Set sticky bit with full permissions
chmod 1777 ~/shared_sticky
ls -ld ~/shared_sticky
# Result: drwxrwxrwt 2 alice alice 4096 Dec 09 10:30 ~/shared_sticky
# ^
# t indicates sticky bit
# Create files
touch ~/shared_sticky/myfile.txt
# Try to delete (as owner - will work)
rm ~/shared_sticky/myfile.txt
# If another user tried to delete your file, they would get:
# rm: cannot remove 'myfile.txt': Operation not permitted
Lab 8: Finding Files by Permission
Task: Use find to locate files with specific permissions.
# Create test files with various permissions
cd ~/permission_practice
chmod 777 file1.txt
chmod 644 file2.txt
chmod 600 file3.txt
# Find all files with 777 permissions
find . -type f -perm 0777
# Output: ./file1.txt
# Find all files readable by everyone
find . -type f -perm -444
# Find files with setuid bit set
find /usr/bin -type f -perm -4000 2>/dev/null
# Find world-writable files (potential security issue)
find /home -type f -perm -002 2>/dev/null
Lab 9: Recursive Permission Changes
Task: Change permissions for multiple files and directories.
# Create directory structure
mkdir -p ~/project/{src,docs,scripts}
touch ~/project/src/{file1.c,file2.c}
touch ~/project/docs/{readme.md,guide.md}
touch ~/project/scripts/{build.sh,deploy.sh}
# Set all directories to 755
find ~/project -type d -exec chmod 755 {} \;
# Set all regular files to 644
find ~/project -type f -exec chmod 644 {} \;
# Make all .sh files executable
chmod +x ~/project/scripts/*.sh
# Verify
ls -lR ~/project
Lab 10: Fixing Common Permission Issues
Task: Practice fixing typical permission problems.
# Scenario: Web application directory
mkdir -p ~/webapp/{public,private,uploads}
# Problem 1: Uploaded files are not readable by web server
touch ~/webapp/uploads/user_upload.jpg
# Fix: Make sure group can read
chmod 640 ~/webapp/uploads/user_upload.jpg
sudo chown alice:www-data ~/webapp/uploads/user_upload.jpg
# Problem 2: Private directory is accessible
ls -ld ~/webapp/private
# Fix: Remove permissions for others
chmod 750 ~/webapp/private
# Problem 3: Script won't execute
echo '#!/bin/bash' > ~/webapp/backup.sh
echo 'echo "Running backup..."' >> ~/webapp/backup.sh
# Fix: Add execute permission
chmod +x ~/webapp/backup.sh
# Problem 4: Group members can't collaborate
# Fix: Set setgid and appropriate permissions
chmod 2775 ~/webapp/public
Lab 11: Security Audit
Task: Audit a directory for security issues.
# Create test environment
mkdir ~/audit_test
cd ~/audit_test
touch normal.txt
chmod 777 insecure.txt
chmod 4755 setuid_file
chmod 2755 setgid_file
# Find world-writable files
echo "World-writable files:"
find . -type f -perm -002
# Find files with setuid
echo "Files with setuid:"
find . -type f -perm -4000
# Find files with setgid
echo "Files with setgid:"
find . -type f -perm -2000
# Find files with excessive permissions
echo "Files with 777 permissions:"
find . -type f -perm 0777
Lab 12: Bulk Permission Corrections
Task: Fix permissions for an entire project.
# Simulate messy project
mkdir -p ~/messy_project/{src,bin,conf}
touch ~/messy_project/src/{main.c,utils.c}
touch ~/messy_project/bin/program
touch ~/messy_project/conf/settings.conf
# Set random wrong permissions
chmod -R 777 ~/messy_project
# Fix all at once:
# Directories: 755 (rwxr-xr-x)
find ~/messy_project -type d -exec chmod 755 {} \;
# Regular files: 644 (rw-r--r--)
find ~/messy_project -type f -exec chmod 644 {} \;
# Executables in bin: 755 (rwxr-xr-x)
chmod 755 ~/messy_project/bin/*
# Config files: 640 (rw-r-----)
chmod 640 ~/messy_project/conf/*
# Verify
ls -lR ~/messy_project
Lab 13: Permission Troubleshooting
Task: Diagnose and fix permission-related errors.
# Scenario 1: Can't cd into directory
mkdir test_dir
chmod 644 test_dir # No execute permission
cd test_dir # Error: Permission denied
# Fix:
chmod 755 test_dir
cd test_dir # Success
# Scenario 2: Can't list directory contents
mkdir test_dir2
chmod 311 test_dir2 # Execute but no read
ls test_dir2 # Error: Permission denied
# Fix:
chmod 755 test_dir2
ls test_dir2 # Success
# Scenario 3: SSH key rejected
cp ~/.ssh/id_rsa ~/test_key
chmod 644 ~/test_key
ssh -i ~/test_key user@host # Error: permissions are too open
# Fix:
chmod 600 ~/test_key
ssh -i ~/test_key user@host # Success
Lab 14: Advanced Scenario - Application Deployment
Task: Set up proper permissions for a web application.
# Create application structure
sudo mkdir -p /var/www/myapp/{public,private,storage,logs}
# Set ownership
sudo chown -R deploy:www-data /var/www/myapp
# Set base permissions
sudo chmod -R 755 /var/www/myapp
# Public files: read by everyone
sudo chmod -R 755 /var/www/myapp/public
# Private files: only app can access
sudo chmod -R 750 /var/www/myapp/private
# Storage: app needs to write, setgid for new files
sudo chmod 2775 /var/www/myapp/storage
# Logs: app writes, admins read
sudo chmod 2775 /var/www/myapp/logs
# Verify
ls -la /var/www/myapp
Lab 15: Creating a Secure User Environment
Task: Set up a new user with proper permissions.
# Create user (requires root)
sudo useradd -m -s /bin/bash newuser
# Set password
sudo passwd newuser
# Check home directory permissions
ls -ld /home/newuser
# Should be: drwxr-x--- (750) or drwx------ (700)
# If not, fix:
sudo chmod 750 /home/newuser
# Create standard directories
sudo -u newuser mkdir /home/newuser/{Documents,Downloads,bin}
# Set umask for user
sudo bash -c 'echo "umask 0027" >> /home/newuser/.bashrc'
# Create private SSH directory
sudo -u newuser mkdir /home/newuser/.ssh
sudo chmod 700 /home/newuser/.ssh
# Verify everything
sudo ls -la /home/newuser
Lab 16: Understanding Permission Precedence
Task: Understand how user, group, and other permissions interact.
# Create test file
touch precedence_test.txt
# Set specific permissions
chmod 421 precedence_test.txt
ls -l precedence_test.txt
# Result: -r---w---x 1 alice alice 0 Dec 09 10:30 precedence_test.txt
# r w x
# user group other
# As the owner (user), you can READ
cat precedence_test.txt # Works (user has r)
# But you can't write (user doesn't have w)
echo "test" >> precedence_test.txt # Permission denied
# Group members can WRITE but not read
# Others can EXECUTE (if it were a script)
# Key insight: User permissions are checked FIRST
# If you're the owner, group and other permissions don't apply to you
Lab 17: Special Permissions Combination
Task: Practice using all special permissions.
# Create directory structure
mkdir ~/special_perms
cd ~/special_perms
# Create setuid file (would need to be owned by root for real effect)
touch setuid_example
chmod 4755 setuid_example
ls -l setuid_example
# Result: -rwsr-xr-x
# Create setgid directory
mkdir setgid_dir
chmod 2755 setgid_dir
ls -ld setgid_dir
# Result: drwxr-sr-x
# Create sticky bit directory
mkdir sticky_dir
chmod 1777 sticky_dir
ls -ld sticky_dir
# Result: drwxrwxrwt
# Combine all special bits (unusual but possible)
touch all_special
chmod 7755 all_special
ls -l all_special
# Result: -rwsr-sr-t
Lab 18: Numeric to Symbolic Conversion
Task: Practice converting between numeric and symbolic notation.
# Create test file
touch convert_test.txt
# Challenge: Set to 754
chmod 754 convert_test.txt
ls -l convert_test.txt
# Result: -rwxr-xr--
# Now do the same with symbolic mode
chmod 644 convert_test.txt # Reset
chmod u=rwx,g=rx,o=r convert_test.txt
ls -l convert_test.txt
# Result: -rwxr-xr--
# Practice:
# 644 -> u=rw,g=r,o=r
# 755 -> u=rwx,g=rx,o=rx
# 600 -> u=rw,g=,o=
# 777 -> u=rwx,g=rwx,o=rwx
Lab 19: Permission Inheritance
Task: Understand how permissions affect file creation.
# Create parent directory with setgid
mkdir ~/parent_dir
chmod 2775 ~/parent_dir
ls -ld ~/parent_dir
# Result: drwxrwsr-x
# Set umask for group collaboration
umask 0002
# Create file in parent
touch ~/parent_dir/child_file.txt
ls -l ~/parent_dir/child_file.txt
# File permissions: -rw-rw-r-- (664, based on umask)
# Group: inherited from parent directory (due to setgid)
# Create subdirectory
mkdir ~/parent_dir/child_dir
ls -ld ~/parent_dir/child_dir
# Directory permissions: drwxrwxr-x (775, based on umask)
# Also has setgid bit: drwxrwsr-x (inherited)
Lab 20: Complete Permission Audit
Task: Perform a comprehensive security audit of your home directory.
# Find all world-writable files (security risk)
echo "=== World-writable files ==="
find ~ -type f -perm -002 ! -path "*/.*" 2>/dev/null
# Find all world-writable directories
echo "=== World-writable directories ==="
find ~ -type d -perm -002 ! -path "*/.*" 2>/dev/null
# Find files with no owner (orphaned files)
echo "=== Files with no owner ==="
find ~ -nouser 2>/dev/null
# Find files with no group
echo "=== Files with no group ==="
find ~ -nogroup 2>/dev/null
# Find setuid files (uncommon in home directory)
echo "=== Setuid files ==="
find ~ -type f -perm -4000 2>/dev/null
# Find setgid files
echo "=== Setgid files ==="
find ~ -type f -perm -2000 2>/dev/null
# Check for overly permissive SSH files
echo "=== SSH directory permissions ==="
ls -la ~/.ssh/ 2>/dev/null
# Summary of recommendations
echo "=== Recommended fixes ==="
echo "1. Remove world-write from all files: find ~ -type f -perm -002 -exec chmod o-w {} \;"
echo "2. Secure SSH: chmod 700 ~/.ssh; chmod 600 ~/.ssh/id_*; chmod 644 ~/.ssh/*.pub"
echo "3. Check ownership: sudo chown -R $USER:$USER ~"
Summary
Key Concepts Covered
-
File Permission Basics
- Three permission types: read (r), write (w), execute (x)
- Three categories: user (u), group (g), other (o)
- Reading permission strings (10-character format)
-
The chmod Command
- Numeric mode: 755, 644, 600, etc.
- Symbolic mode: u+x, g-w, o=r, etc.
- Recursive changes with -R
-
The chown and chgrp Commands
- Changing file ownership
- Changing group ownership
- Recursive changes
-
Special Permissions
- Setuid (4000): Run as file owner
- Setgid (2000): Run as file group / inherit directory group
- Sticky bit (1000): Only owner can delete files
-
umask
- Sets default permissions for new files
- Subtraction model: 666-umask for files, 777-umask for directories
- Common values: 0022, 0002, 0077
-
Real-World Scenarios
- Web server file permissions
- Shared project directories
- Secure script execution
- Log file management
- SSH key protection
Permission Quick Reference
Common File Permissions:
644(rw-r--r--): Regular files, readable by all600(rw-------): Private files, owner only755(rwxr-xr-x): Executable files and directories700(rwx------): Private executables
Common Directory Permissions:
755(rwxr-xr-x): Standard directory775(rwxrwxr-x): Shared directory with group write700(rwx------): Private directory1777(rwxrwxrwt): Public shared directory with sticky bit
Special Permissions:
4755: Setuid executable2775: Setgid directory for team collaboration1777: Sticky bit directory (like /tmp)
chmod Quick Reference
Numeric Mode:
chmod 644 file.txt # rw-r--r--
chmod 755 script.sh # rwxr-xr-x
chmod 600 private.key # rw-------
chmod 2775 shared_dir # rwxrwsr-x (with setgid)
Symbolic Mode:
chmod u+x file # Add execute for user
chmod g-w file # Remove write for group
chmod o=r file # Set other to read only
chmod a+r file # Add read for all
chmod u=rwx,g=rx,o= file # Set exact permissions
Security Best Practices
-
Principle of Least Privilege
- Give only the minimum permissions necessary
- Avoid 777 permissions (everyone can do everything)
-
Protect Sensitive Files
- Private keys: 600
- Config files with passwords: 600 or 640
- User home directories: 750 or 700
-
Careful with Special Permissions
- Setuid programs can be security risks
- Only use setuid when absolutely necessary
- Regularly audit for setuid/setgid files
-
Use umask Appropriately
- Personal system: umask 0077 (restrictive)
- Shared system: umask 0022 (moderate)
- Team collaboration: umask 0002 (group friendly)
-
Regular Audits
- Check for world-writable files
- Review setuid/setgid programs
- Ensure proper ownership
For the LFCS Exam
Be prepared to:
- Explain the meaning of any permission string
- Convert between numeric and symbolic notation
- Use chmod in both modes confidently
- Change ownership with chown and chgrp
- Explain and set special permissions
- Calculate and set umask values
- Troubleshoot permission-related issues
- Apply appropriate permissions for real-world scenarios
Common exam scenarios:
- Make a script executable
- Set up shared directory for team collaboration
- Fix permission issues preventing file access
- Secure sensitive files (SSH keys, config files)
- Set up web server permissions
- Understand and explain special permissions
Next Steps
In the next post, we'll cover:
- Advanced File Operations: Hard links, symbolic links, and file attributes
- ACLs (Access Control Lists): More granular permission control beyond user/group/other
- File System Attributes: Using chattr and lsattr for additional protection
Continue practicing with the labs in this guide to build muscle memory for permission management. Understanding file permissions is fundamental to Linux system administration and critical for the LFCS certification.
Related LFCS Posts:
- LFCS Phase 1 Part 21: Wildcards and File Management
- LFCS Phase 1 Part 32: Text Processing with cut, sort, and uniq
- LFCS Phase 1 Part 33: Advanced Text Processing with awk and sed
Practice consistently, and good luck with your LFCS preparation!

