Chapter 4 ⏱️ 50 min read 📚 Intermediate

Control Access to Files

Master Linux file permissions and ownership. Learn to use chmod, chown, umask, and Access Control Lists (ACLs) to secure files and implement granular access control policies.

🎯 Introduction

File permissions are the foundation of Linux security. Every file and directory has an owner, a group, and a set of permissions that determine who can read, write, or execute it. Understanding and managing these permissions is critical for maintaining system security and proper access control.

In this chapter, you'll learn to:

  • Interpret and modify file permissions using symbolic and octal notation
  • Change file and directory ownership with chown and chgrp
  • Apply special permissions (SUID, SGID, sticky bit) for advanced scenarios
  • Set default permissions using umask
  • Implement fine-grained access control with Access Control Lists (ACLs)
  • Troubleshoot permission-related issues
📘 Note

File permissions work in conjunction with SELinux on RHEL systems. Both must be correctly configured for proper access control.

🔒 File Permissions

Understanding Permission Types

Linux uses three types of permissions applied to three categories of users:

Permission Symbol Octal On Files On Directories
Read r 4 View file contents List directory contents
Write w 2 Modify file contents Create/delete files in directory
Execute x 1 Run file as program Enter directory (cd)

Reading Permission Strings

When you run ls -l, you see permission information:

-rwxr-xr--. 1 student developers 1234 Nov 14 10:30 script.sh
│││││││││││
│││││││││└└─ Other permissions (r--)
││││││└┴┴─── Group permissions (r-x)
│││└┴┴───── Owner permissions (rwx)
│└───────── File type indicator
└────────── SELinux context present (dot)

File Type Indicators

  • - Regular file
  • d Directory
  • l Symbolic link
  • c Character device
  • b Block device
  • s Socket
  • p Named pipe (FIFO)

chmod - Change Mode (Permissions)

Symbolic Method

Use letters to modify permissions:

# Add execute permission for owner (user)
chmod u+x file.sh

# Remove write permission for group
chmod g-w file.txt

# Set exact permissions for others
chmod o=r file.txt

# Add read permission for all (user, group, other)
chmod a+r file.txt

# Multiple changes at once
chmod u+x,g-w,o-r file.sh

# Recursive change
chmod -R u+w directory/

Symbolic notation syntax:

  • Who: u (user/owner), g (group), o (others), a (all)
  • Operator: + (add), - (remove), = (set exactly)
  • Permission: r (read), w (write), x (execute)

Octal (Numeric) Method

Use three-digit numbers where each digit represents owner, group, and others:

# Common permission sets
chmod 755 script.sh    # rwxr-xr-x (owner: full, group/others: read+execute)
chmod 644 file.txt     # rw-r--r-- (owner: read+write, others: read-only)
chmod 600 secret.txt   # rw------- (owner: read+write, others: no access)
chmod 777 public/      # rwxrwxrwx (all permissions for everyone - DANGEROUS!)
chmod 700 private/     # rwx------ (owner: full access, others: no access)
chmod 640 config.conf  # rw-r----- (owner: read+write, group: read, others: none)

Calculating Octal Values

# Each permission has a value:
# r (read)    = 4
# w (write)   = 2
# x (execute) = 1

# Add them together for each user category:
# rwx = 4+2+1 = 7
# rw- = 4+2+0 = 6
# r-x = 4+0+1 = 5
# r-- = 4+0+0 = 4
# -wx = 0+2+1 = 3
# -w- = 0+2+0 = 2
# --x = 0+0+1 = 1
# --- = 0+0+0 = 0
💡 Tip

Use symbolic notation when making incremental changes (chmod g+w). Use octal notation when setting complete permission sets (chmod 644).

Common Permission Scenarios

Octal Symbolic Use Case
755 rwxr-xr-x Executable scripts, directories
644 rw-r--r-- Regular files, text files
600 rw------- Private files, SSH keys
700 rwx------ Private scripts, .ssh directory
775 rwxrwxr-x Shared team directories

👤 File Ownership

Every file and directory has two types of owners:

  • User (Owner): The user who owns the file
  • Group: The group that owns the file

chown - Change Owner

# Change owner only
sudo chown john file.txt

# Change owner and group
sudo chown john:developers file.txt

# Change group only (using colon)
sudo chown :developers file.txt

# Recursive ownership change
sudo chown -R john:developers directory/

# Use reference file for ownership
sudo chown --reference=template.txt newfile.txt

# Verbose output
sudo chown -v john file.txt

# Change from specific owner to new owner
sudo chown --from=alice:users john:developers file.txt
⚠️ Warning

Only root can change file ownership. Regular users cannot give away their files to other users. This prevents security issues and quota circumvention.

chgrp - Change Group

# Change group
sudo chgrp developers file.txt

# Recursive group change
sudo chgrp -R developers project/

# Verbose output
sudo chgrp -v developers *.txt

# Use reference file
sudo chgrp --reference=template.txt newfile.txt

Procedure: Setting Up a Shared Project Directory

  1. Create the directory:
    sudo mkdir /shared/projects
  2. Create a group for the team:
    sudo groupadd developers
  3. Add users to the group:
    sudo usermod -aG developers alice
    sudo usermod -aG developers bob
    sudo usermod -aG developers charlie
  4. Set group ownership:
    sudo chgrp developers /shared/projects
  5. Set appropriate permissions:
    sudo chmod 2775 /shared/projects
  6. Verify the configuration:
    ls -ld /shared/projects
    # Should show: drwxrwsr-x. 2 root developers ...

⭐ Special Permissions

Beyond basic read, write, and execute permissions, Linux supports three special permission bits:

1. SUID (Set User ID) - Bit 4

When set on an executable file, the program runs with the privileges of the file's owner, not the user who executes it.

# Set SUID using symbolic notation
sudo chmod u+s /usr/local/bin/program

# Set SUID using octal notation (4 prefix)
sudo chmod 4755 /usr/local/bin/program

# Example: passwd command uses SUID
ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 /usr/bin/passwd
#   ↑ Notice the 's' instead of 'x'

Use cases:

  • passwd - Allows users to change their password (requires root to modify /etc/shadow)
  • ping - Requires root privileges to create raw network sockets
  • sudo - Executes commands as root
⚠️ Security Warning

SUID on executables owned by root is a significant security risk if the program is vulnerable. Regularly audit SUID files:

sudo find / -perm -4000 -type f -ls 2>/dev/null

2. SGID (Set Group ID) - Bit 2

On executable files: Process runs with the group privileges of the file's group.

On directories: New files inherit the directory's group ownership (not the creator's primary group).

# Set SGID on directory (most common use)
sudo chmod g+s /shared/projects
sudo chmod 2775 /shared/projects

# Set SGID on executable
sudo chmod g+s /usr/local/bin/tool

# Verify SGID on directory
ls -ld /shared/projects
drwxrwsr-x. 2 root developers 4096 /shared/projects
#      ↑ Notice the 's' in group execute position

Why use SGID on directories:

  • Ensures all files in shared directory have consistent group ownership
  • Team members can collaborate without permission issues
  • New files automatically belong to the project group

3. Sticky Bit - Bit 1

When set on a directory, only the file owner, directory owner, or root can delete or rename files within that directory.

# Set sticky bit using symbolic notation
sudo chmod o+t /shared/public

# Set sticky bit using octal notation (1 prefix)
sudo chmod 1777 /shared/public

# Example: /tmp directory uses sticky bit
ls -ld /tmp
drwxrwxrwt. 15 root root 4096 /tmp
#        ↑ Notice the 't' in other execute position

Use cases:

  • /tmp - Users can create files but cannot delete others' files
  • /var/tmp - Same protection as /tmp
  • Shared upload directories where users should not delete each other's files

Special Permissions Summary

Permission Symbolic Octal Display Effect
SUID u+s 4 s or S in owner execute Run as file owner
SGID g+s 2 s or S in group execute Run as file group / inherit group
Sticky o+t 1 t or T in other execute Restrict deletion
📘 Note on Uppercase vs Lowercase

Lowercase (s, t): Special permission + execute permission is set
Uppercase (S, T): Special permission set but execute permission is NOT set

-rwSr--r--  # SUID set, but owner has no execute permission (unusual)
drwxrwsrwx  # SGID set with execute permission (normal)

🎭 Default Permissions with umask

The umask (user file-creation mode mask) determines the default permissions for newly created files and directories. It works by subtracting permissions from the system's default maximum permissions.

How umask Works

# System default maximum permissions:
# Files:       666 (rw-rw-rw-)  - no execute by default
# Directories: 777 (rwxrwxrwx)  - full permissions

# With umask 0022:
# Files:       666 - 022 = 644 (rw-r--r--)
# Directories: 777 - 022 = 755 (rwxr-xr-x)

Viewing and Setting umask

# View current umask (octal)
umask
0022

# View current umask (symbolic)
umask -S
u=rwx,g=rx,o=rx

# Set umask temporarily (current session only)
umask 0027

# Set umask using symbolic notation
umask u=rwx,g=rx,o=

Common umask Values

umask Files Created Directories Created Use Case
0022 644 (rw-r--r--) 755 (rwxr-xr-x) Default for most users
0002 664 (rw-rw-r--) 775 (rwxrwxr-x) Group collaboration
0077 600 (rw-------) 700 (rwx------) Maximum privacy
0027 640 (rw-r-----) 750 (rwxr-x---) Secure group sharing

Making umask Permanent

To make umask settings permanent, add them to shell configuration files:

# For individual user (add to ~/.bashrc or ~/.bash_profile)
echo "umask 0027" >> ~/.bashrc

# For all users (add to /etc/bashrc or /etc/profile)
sudo vi /etc/bashrc
# Add: umask 0027

# Reload configuration
source ~/.bashrc
💡 Tip

Root typically has a more restrictive umask (0022 or 0027) than regular users to enhance security.

🎯 Access Control Lists (ACLs)

Access Control Lists (ACLs) provide fine-grained access control beyond the traditional user/group/other permission model. ACLs allow you to grant permissions to specific users or groups without changing the file's owner or group.

When to Use ACLs

  • Need to give specific users access without adding them to groups
  • Multiple groups need different levels of access to the same file
  • Complex permission scenarios beyond owner/group/other
  • Temporary access grants to specific users

Viewing ACLs - getfacl

# View ACLs on a file
getfacl file.txt

# Sample output:
# file: file.txt
# owner: student
# group: developers
user::rw-              # Owner permissions
user:john:r--          # Specific user 'john' has read
user:alice:rw-         # Specific user 'alice' has read+write
group::r--             # Owning group permissions
group:managers:r--     # Specific group 'managers' has read
mask::rw-              # Maximum effective permissions
other::---             # Other users permissions

# View ACLs for directory and contents
getfacl -R /project

# View only files with ACLs
ls -la
-rw-r--r--+ 1 student developers 1234 Nov 14 10:30 file.txt
#        ↑ Plus sign indicates ACL is set

Setting ACLs - setfacl

Grant Permissions

# Give user 'john' read access
setfacl -m u:john:r file.txt

# Give user 'alice' read+write access
setfacl -m u:alice:rw file.txt

# Give group 'managers' read+execute on directory
setfacl -m g:managers:rx /project

# Multiple ACL entries at once
setfacl -m u:john:rw,u:jane:r,g:team:rx file.txt

# Recursive ACL application
setfacl -R -m u:john:rx /project

Remove Permissions

# Remove specific user ACL
setfacl -x u:john file.txt

# Remove specific group ACL
setfacl -x g:managers file.txt

# Remove all ACLs (restore to basic permissions)
setfacl -b file.txt

# Remove all ACLs recursively
setfacl -R -b /project

Default ACLs

Default ACLs apply to directories and are inherited by newly created files and subdirectories:

# Set default ACL for new files in directory
setfacl -d -m g:developers:rwx /project

# Set default ACL for specific user
setfacl -d -m u:john:rx /project

# View default ACLs
getfacl /project
# Will show entries like: default:user:john:r-x

# Set both current and default ACLs
setfacl -m d:g:developers:rwx,g:developers:rwx /project

ACL Mask

The mask defines the maximum effective permissions for named users and groups:

# Set mask to limit permissions
setfacl -m m::rx file.txt

# Even if a user has rwx in their ACL entry,
# the mask limits them to r-x maximum

# View effective permissions
getfacl file.txt
user:john:rwx      #effective:r-x
#         ↑ ACL     ↑ Limited by mask

# Recalculate mask automatically
setfacl -m m::rwx file.txt

Copying and Backing Up ACLs

# Copy ACLs from one file to another
getfacl file1.txt | setfacl --set-file=- file2.txt

# Backup ACLs to file
getfacl -R /project > project_acls.txt

# Restore ACLs from backup
setfacl --restore=project_acls.txt

# Preserve ACLs when copying files
cp -a --preserve=all source.txt dest.txt
# or
cp --preserve=mode,ownership,timestamps,xattr source.txt dest.txt

Procedure: Implementing ACLs for Project Directory

  1. Create project directory:
    sudo mkdir /project/webapp
    sudo chown root:developers /project/webapp
    sudo chmod 750 /project/webapp
  2. Add specific user access:
    # Give manager read access
    sudo setfacl -m u:manager:rx /project/webapp
    
    # Give auditor read-only access
    sudo setfacl -m u:auditor:r /project/webapp
  3. Add specific group access:
    # Give QA team read+execute
    sudo setfacl -m g:qa_team:rx /project/webapp
  4. Set default ACLs for new files:
    # Developers get full access on new files
    sudo setfacl -d -m g:developers:rwx /project/webapp
    
    # Manager gets read on new files
    sudo setfacl -d -m u:manager:rx /project/webapp
  5. Verify configuration:
    getfacl /project/webapp
    
    # Expected output shows both current and default ACLs
  6. Test by creating a new file:
    sudo -u developer touch /project/webapp/test.txt
    getfacl /project/webapp/test.txt
    # Should show inherited ACLs from parent directory

ACL Examples for Common Scenarios

# Scenario 1: Give temp contractor access for 1 month
setfacl -m u:contractor:rx /data
# (Remove after project: setfacl -x u:contractor /data)

# Scenario 2: Multiple teams need different access
setfacl -m g:dev_team:rwx,g:qa_team:rx,g:managers:r /project

# Scenario 3: Shared directory where everyone can write but not delete others' files
chmod 1777 /shared/dropbox
setfacl -m d:u::rwx,d:g::rwx,d:o::rwx /shared/dropbox

# Scenario 4: Log directory readable by specific users
setfacl -m u:alice:r,u:bob:r /var/log/application.log
⚠️ Important Considerations
  • ACLs are stored as extended attributes - ensure filesystem supports them (most modern filesystems do)
  • Backup tools must preserve ACLs (use tar --acls or rsync -A)
  • The + sign in ls -l output indicates ACLs are present
  • ACLs work in addition to SELinux, not instead of it

📝 Practice Questions

Question 1: What permissions does chmod 755 set?

  • A) rwxr-xr-x (owner: full, group: r-x, other: r-x)
  • B) rw-r--r-- (owner: rw, group: r, other: r)
  • C) rwxrwxrwx (full access for all)
  • D) r-xr-xr-x (read+execute for all)
Answer: A) rwxr-xr-x
7=rwx (4+2+1), 5=r-x (4+0+1), 5=r-x (4+0+1). Owner has full control (read, write, execute), while group and others can read and execute but cannot write.

Question 2: What does the sticky bit do on a directory?

  • A) Makes files read-only
  • B) Only file owners can delete their own files
  • C) Prevents directory from being deleted
  • D) Makes all files executable
Answer: B) Only file owners can delete their own files
The sticky bit prevents users from deleting or renaming files they don't own, even if they have write permission on the directory. This is why /tmp uses the sticky bit (1777).

Question 3: How do you give user 'john' read access to a file using ACLs?

  • A) chmod u+r:john file.txt
  • B) setfacl -m u:john:r file.txt
  • C) chown john:r file.txt
  • D) acl john read file.txt
Answer: B) setfacl -m u:john:r file.txt
setfacl with -m (modify) is the correct command for setting ACL permissions. The syntax is: setfacl -m u:username:permissions file

Question 4: What is the effect of umask 0027?

  • A) New files: 640, Directories: 750
  • B) New files: 644, Directories: 755
  • C) New files: 600, Directories: 700
  • D) New files: 666, Directories: 777
Answer: A) New files: 640, Directories: 750
With umask 0027: Files are created as 666-027=640 (rw-r-----), Directories as 777-027=750 (rwxr-x---). This provides good security while allowing group read access.

Question 5: What does SGID on a directory do?

  • A) Makes directory executable
  • B) New files inherit the directory's group ownership
  • C) Only root can access the directory
  • D) Encrypts all files in the directory
Answer: B) New files inherit the directory's group ownership
SGID on directories ensures that new files are created with the directory's group ownership rather than the creator's primary group. This is essential for shared project directories where team members need consistent group ownership (chmod 2775 /shared/project).