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.
📋 Table of Contents
🎯 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
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 filedDirectorylSymbolic linkcCharacter devicebBlock devicesSocketpNamed 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
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
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
- Create the directory:
sudo mkdir /shared/projects - Create a group for the team:
sudo groupadd developers - Add users to the group:
sudo usermod -aG developers alice sudo usermod -aG developers bob sudo usermod -aG developers charlie - Set group ownership:
sudo chgrp developers /shared/projects - Set appropriate permissions:
sudo chmod 2775 /shared/projects - 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 socketssudo- Executes commands as root
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 |
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
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
- Create project directory:
sudo mkdir /project/webapp sudo chown root:developers /project/webapp sudo chmod 750 /project/webapp - 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 - Add specific group access:
# Give QA team read+execute sudo setfacl -m g:qa_team:rx /project/webapp - 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 - Verify configuration:
getfacl /project/webapp # Expected output shows both current and default ACLs - 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
- ACLs are stored as extended attributes - ensure filesystem supports them (most modern filesystems do)
- Backup tools must preserve ACLs (use
tar --aclsorrsync -A) - The
+sign inls -loutput indicates ACLs are present - ACLs work in addition to SELinux, not instead of it
📝 Practice Questions
Question 1: What permissions does chmod 755 set?
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?
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?
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?
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?
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).