3.5. Lab: Permissions Management#

Practice setting up secure projects and managing permissions. All exercises use your home directory, so no sudo required.

3.5.1. Part 1: Understanding Permissions#

3.5.1.1. Exercise 1.1: Reading ls -l Output#

# Create test files
$ mkdir ~/lab/permissions
$ cd ~/lab/permissions
$ touch document.txt script.sh config.ini secret.key

# List with details
$ ls -l
total 0
-rw-r--r-- 1 user user 0 Jan 15 config.ini
-rw-r--r-- 1 user user 0 Jan 15 document.txt
-rw-r--r-- 1 user user 0 Jan 15 script.sh
-rw-r--r-- 1 user user 0 Jan 15 secret.key

# For each file, determine:
# 1. Who owns it?
# 2. What group does it belong to?
# 3. Can the owner write to it?
# 4. Can others read it?
# 5. What would 644 be in symbols?

3.5.1.2. Exercise 1.2: Octal Notation Conversion#

Convert between symbols and octal:

# Symbol to octal
# rwxr-xr-x = ?     (answer: 755)
# rw-r--r-- = ?     (answer: 644)
# rw------- = ?     (answer: 600)
# rwxrwxrwx = ?     (answer: 777)

# Octal to symbol
# 700 = ?           (answer: rwx------)
# 640 = ?           (answer: rw-r-----)
# 444 = ?           (answer: r--r--r--)
# 755 = ?           (answer: rwxr-xr-x)

3.5.2. Part 2: Modifying Permissions#

3.5.2.1. Exercise 2.1: chmod with Octal Notation#

# Make a file private (owner read/write only)
$ chmod 600 secret.key
$ ls -l secret.key
-rw------- 1 user user 0 Jan 15 secret.key

# Make a script executable by owner and group
$ chmod 750 script.sh
$ ls -l script.sh
-rwxr-x--- 1 user user 0 Jan 15 script.sh

# Make a document world-readable but not writable
$ chmod 644 document.txt
$ ls -l document.txt
-rw-r--r-- 1 user user 0 Jan 15 document.txt

# Challenge: How would you set config.ini to rw-rw-r--?
# Answer: chmod 664 config.ini

3.5.2.2. Exercise 2.2: chmod with Symbolic Notation#

# Add execute permission for owner
$ chmod u+x script.sh
$ ls -l script.sh
-rwxr--r-- 1 user user 0 Jan 15 script.sh

# Remove all permissions, then add read for all
$ chmod a-rwx,a+r document.txt
$ ls -l document.txt
-r--r--r-- 1 user user 0 Jan 15 document.txt

# Add write for group
$ chmod g+w config.ini
$ ls -l config.ini
-rw-rw-r-- 1 user user 0 Jan 15 config.ini

# Remove read permission for others
$ chmod o-r secret.key
$ ls -l secret.key
-rw------- 1 user user 0 Jan 15 secret.key (already was)

3.5.2.3. Exercise 2.3: Recursive Permissions#

# Create a directory structure
$ mkdir -p project/{src,docs,data}
$ touch project/src/{main.sh,lib.sh}
$ touch project/docs/{README.txt,INSTALL.txt}
$ ls -lR project

# Set permissions recursively
$ chmod 755 project
$ chmod 644 project/docs/*
$ chmod 644 project/src/*.sh

# Challenge: Give group write permission to all files in 'data' directory
# Answer: chmod g+w project/data

3.5.3. Part 3: Understanding Umask#

3.5.3.1. Exercise 3.1: Exploring Default Umask#

# Check current umask
$ umask
0022

# Create files and directories to see default permissions
$ cd ~/lab/umask
$ touch newfile.txt
$ mkdir newdir
$ ls -ld newdir
drwxr-xr-x 2 user user 4096 Jan 15 newdir
$ ls -l newfile.txt
-rw-r--r-- 1 user user 0 Jan 15 newfile.txt

# Calculate what happened:
# File: 666 - 022 = 644 ✓
# Directory: 777 - 022 = 755 ✓

3.5.3.2. Exercise 3.2: Changing Umask Temporarily#

# Change to restrictive umask
$ umask 0077
$ umask
0077

# Create new files
$ touch private_file.txt
$ mkdir private_dir
$ ls -l private_file.txt
-rw------- 1 user user 0 Jan 15 private_file.txt
$ ls -ld private_dir
drwx------ 2 user user 4096 Jan 15 private_dir

# Calculation:
# File: 666 - 077 = 600 ✓
# Directory: 777 - 077 = 700 ✓

# Reset umask
$ umask 0022

3.5.3.3. Exercise 3.3: Umask for Team Collaboration#

# Set team-friendly umask
$ umask 0002
$ touch shared_file.txt
$ mkdir shared_dir
$ ls -l shared_file.txt
-rw-rw-r-- 1 user user 0 Jan 15 shared_file.txt
$ ls -ld shared_dir
drwxrwxr-x 2 user user 4096 Jan 15 shared_dir

# Results:
# File: 666 - 002 = 664 (owner and group can write)
# Directory: 777 - 002 = 775 (owner and group can write/enter)

# Challenge: What umask gives directories rwxr-xr-x and files rw-r--r--?
# Answer: umask 0022

3.5.4. Part 4: Special Permissions#

3.5.4.1. Exercise 4.1: Understanding setuid#

# Compare regular vs setuid program
$ ls -l /bin/passwd /bin/cat
-rwxr-xr-x 1 root root 42136 Jan 1 /bin/cat
-rwsr-xr-x 1 root root 68208 Jan 1 /bin/passwd
                ^
                Notice the 's' instead of 'x' in owner execute

# The setuid bit allows passwd to run as root even when you execute it
$ whoami
user
$ passwd user
# This actually modifies /etc/shadow, which requires root!
# Because passwd has the setuid bit and is owned by root

# Demonstrate with a simple example:
$ cd ~/lab/special
$ cat > myscript.sh << 'EOF'
#!/bin/bash
echo "Running as: $(whoami)"
EOF
$ chmod 755 myscript.sh
$ ./myscript.sh
Running as: user

# Set setuid (you'd need root for this, so just show the concept)
# sudo chmod u+s myscript.sh
# ./myscript.sh would then say "Running as: root"

3.5.4.2. Exercise 4.2: Understanding setgid and Sticky Bit#

# Check setgid on directories
$ ls -ld /var/tmp
drwxrwxrwt 10 root root 4096 Jan 15 /var/tmp
         ^^
         sticky bit (t) and setgid (s)

# Create a group-shared directory with setgid
$ mkdir team_project
$ chmod g+s team_project    # Set setgid
$ chmod 2770 team_project   # Alternative: octal notation
$ ls -ld team_project
drwxrws--- 2 user user 4096 Jan 15 team_project
        ^
        's' means setgid

# Any files created in this directory inherit the group
$ cd team_project
$ touch file1.txt
$ ls -l file1.txt
-rw-r--r-- 1 user user 0 Jan 15 file1.txt
# file1.txt will have the group of team_project, not user's default group!

3.5.4.3. Exercise 4.3: Sticky Bit Protection#

# In /tmp directory, anyone can create files but only delete their own
$ ls -ld /tmp
drwxrwxrwt 10 root root 4096 Jan 15 /tmp
         ^
         sticky bit (t)

# Set sticky bit on a directory
$ chmod 1777 shared_dir    # Octal notation
# or
$ chmod +t shared_dir      # Symbolic notation

# Result: Users can create files but can't delete others' files
$ ls -ld shared_dir
drwxrwxrwt 2 user user 4096 Jan 15 shared_dir

# Challenge: What permissions would you set to:
# - Give owner rwx, group rwx, others just enter?
# - Make files created in it inherit the group?
# Answer: chmod 2770 dirname

3.5.5. Part 5: Real-World Project Setup Scenario#

3.5.5.1. Scenario: Setting Up a Secure Web Development Project#

Your team (user, alice, bob) is starting a PHP web project that needs:

  1. Source code (developers should read/modify, web server reads)

  2. Configuration files (secrets - developers only)

  3. Uploads directory (web server writes, developers read)

  4. Logs directory (web server writes, developers read)

3.5.5.2. Exercise 5.1: Create the Structure#

# Create project directory
$ cd ~/lab
$ mkdir -p webproject/{src,config,uploads,logs}
$ cd webproject
$ tree
webproject/
├── config/
├── logs/
├── src/
└── uploads/

# Create some sample files
$ echo "<?php echo 'Hello'; ?>" > src/index.php
$ echo "DB_USER=app\nDB_PASS=secret123" > config/db.conf
$ touch logs/access.log
$ chmod 775 uploads  # Web server needs write access

3.5.5.3. Exercise 5.2: Set Secure Permissions#

# 1. Set directory permissions
$ chmod 755 .                  # Project root: rwxr-xr-x
$ chmod 755 src               # Source: readable by all
$ chmod 750 config            # Config: developers only (no read for web server)
$ chmod 755 logs              # Logs: readable by all
$ chmod 755 uploads           # Uploads: web server can write

# 2. Set file permissions
$ chmod 644 src/*.php         # Source files: readable by all, writable by owner
$ chmod 640 config/*          # Config: readable by group (developers), not by web
$ chmod 644 logs/*.log        # Logs: readable by all

# Verify
$ ls -lR

3.5.5.4. Exercise 5.3: Set Up Group Ownership#

# Assume 'www-data' is the web server user and 'webteam' is the developer group

# Set group ownership
$ chgrp webteam config        # Developers can read config
$ chgrp www-data logs         # Web server owns logs
$ chgrp www-data uploads      # Web server owns uploads

# Set group read/write where needed
$ chmod 750 config            # webteam group can read
$ chmod 755 logs              # Web server (www-data) can write via sticky bit
$ chmod 775 uploads           # Web server can write

# For logs and uploads to work with setgid:
$ chmod 2755 logs             # Files created inherit www-data group
$ chmod 2775 uploads          # Files created inherit www-data group

3.5.5.5. Exercise 5.4: Security Verification Checklist#

# Run these commands to verify security:

# 1. Check no world-writable directories
$ find . -type d -perm -002
# Should show nothing or only expected temp directories

# 2. Verify config files aren't world-readable
$ ls -l config/
-rw-r----- 1 user webteam 35 Jan 15 db.conf
# Permission should be 640 or 600 (not 644)

# 3. Check source code permissions
$ ls -l src/
-rw-r--r-- 1 user user 25 Jan 15 index.php
# Should be readable (644) but not writable by group/others

# 4. Verify upload/log directories are writable by process
$ ls -ld uploads logs
drwxrwxr-x 2 user www-data 4096 Jan 15 logs
drwxrwxr-x 2 user www-data 4096 Jan 15 uploads
# Should be writable by the group that owns them

# 5. Test file creation with setgid
$ touch uploads/test.txt
$ ls -l uploads/test.txt
-rw-r--r-- 1 user www-data 0 Jan 15 uploads/test.txt
# Should show www-data as group (inherited from directory)

3.5.5.6. Reflection Questions#

  1. Why did we make config/ less readable (750) than src/ (755)?

  2. What would happen if you set uploads/ to 755 without setgid?

  3. Why is the sticky bit (t) useful on the logs/ directory?

  4. How would you allow only specific developers to modify config files?

  5. What are the risks of making config files world-readable (644)?

3.5.5.7. Challenge: Enhanced Security#

Modify the setup so that:

  • Only the admin user (not all developers) can read/modify config

  • Developers can still read production logs

  • Web server can create both logs and uploads

  • No sensitive files are world-readable

Hint: Use umask, file-level permissions, and group membership strategically.

3.5.6. Summary: Key Takeaways#

3.5.6.1. Permissions Hierarchy#

Owner (u) > Group (g) > Others (o)

3.5.6.2. Quick Reference Table#

Task

Command

Notes

View permissions

ls -l file

Shows rwx permissions

Change permissions (octal)

chmod 755 file

u=7, g=5, o=5

Change permissions (symbolic)

chmod u+x file

Add execute to owner

Change ownership

chown user:group file

Changes both owner and group

Change group

chgrp group file

Changes group only

View umask

umask

Shows current umask

Change umask

umask 022

Affects new file/directory creation

Set setuid

chmod u+s file

File runs as owner

Set setgid

chmod g+s dir

New files inherit group

Set sticky bit

chmod +t dir

Only owner can delete their files

3.5.6.3. Common Permission Patterns#

Pattern

Octal

Use Case

Owner full, others none

700

Private files/directories

Owner rw, others r

644

Source code, documentation

Owner rwx, others rx

755

Executable scripts, directories

Owner/group rw, others none

660

Shared team files

Owner/group rwx, others none

770

Shared team directory

All full

777

Temporary files (dangerous!)

3.5.6.4. Umask Calculation#

For Files: Final permission = 666 - umask

  • umask 022 → files get 644 (rw-r–r–)

  • umask 077 → files get 600 (rw——-)

For Directories: Final permission = 777 - umask

  • umask 022 → dirs get 755 (rwxr-xr-x)

  • umask 077 → dirs get 700 (rwx——)

3.5.6.5. Security Principles#

  1. Principle of Least Privilege: Users should have minimum permissions needed

  2. Sensitive First: Config files, secrets → 600 or 640

  3. Group Collaboration: Use groups and setgid for team projects

  4. Audit Regularly: Check ls -l and find for permission issues

  5. Document Permissions: Explain why files have specific permissions

  6. Test From User Perspective: Don’t just test as root/owner

3.5.6.6. Common Mistakes to Avoid#

  • ❌ Making config files world-readable (644) when they contain secrets

  • ❌ Using 777 for anything except temp directories

  • ❌ Forgetting to set group ownership in team projects

  • ❌ Not considering who needs to write (often requires group permissions)

  • ❌ Setting setuid on user scripts (security risk)

  • ❌ Changing permissions without understanding the impact