Beginner 15 MIN READ

Linux File Permissions and Searching in RHEL

Master Linux file permissions in RHEL. Learn the UGO/RWX model, chmod, chown, umask, special bits (SUID, SGID, Sticky), and the find command with real lab examples. RHCSA prep included.

Linux File Permissions and Searching in RHEL

In Linux, regulating file and directory access is a fundamental administrative task. Proper permissions prevent unauthorized users from viewing or modifying sensitive data. This chapter explores the standard UGO/RWX permission model. You will learn to assign permissions to three distinct user categories using two different methods, and calculate and apply consistent permissions on new files and directories. Finally, you will learn to locate files using a wide array of criteria — name, size, time, and permissions — and how to execute actions on the results as they are found.


File and Directory Access Permissions

Linux is a multi-user operating system capable of supporting hundreds of users working concurrently. The OS has hundreds of thousands of files and directories that it must maintain securely to warrant successful system and application operation from both security and reliability standpoints.

It is imperative that you regulate file and directory access by granting users only the permissions they need to carry out their tasks — a principle known as least privilege. This control of permissions on files and directories is commonly referred to as user access rights.


Determining Access Permissions

Access permissions on files and directories allow administrative control over which users can access them and to what level. The permissions discussed in this section are referred to as standard UGO/RWX permissions.

Permission Classes

Users are categorized into three unique classes for maintaining file security through access rights:

To view the permission classes on a file, use ls -l:

bash
[root@rhel ~]# ls -l /etc/hosts
-rw-r--r--. 1 root root 158 Mar 10 10:00 /etc/hosts

Breaking down column 1:

bash
- rw- r-- r--
│  │   │   │
│  │   │   └── Other: read only
│  │   └────── Group: read only
│  └────────── User (owner): read + write
└───────────── File type: - = regular file

Permission Types

Each permission class can have three types of permissions:

| Symbol | Name | On Files | On Directories |

|--------|------|----------|----------------|

| r | Read | View file contents | List directory contents with ls |

| w | Write | Modify or delete file | Create, delete, or rename files inside |

| x | Execute | Run as a program or script | Enter directory with cd |

| - | No permission | Denied | Denied |

> Senior Engineer Note: For directories, the execute bit is often misunderstood. Without x on a directory, you cannot cd into it even if you have r. Think of x as the "enter" permission and r as the "list" permission — you need both for full directory access.

Permission Modes

Permissions are expressed in two formats:

Symbolic mode — uses letters (r, w, x) with operators (+, -, =):

bash
# Add execute for owner
chmod u+x script.sh
 
# Remove write from group and other
chmod go-w file.txt
 
# Set exact permissions: owner=rwx, group=r-x, other=r--
chmod u=rwx,g=rx,o=r file.txt

Octal (numeric) mode — uses numbers 0-7 where each digit represents a permission class:

| Octal | Binary | Permissions |

|-------|--------|-------------|

| 7 | 111 | rwx |

| 6 | 110 | rw- |

| 5 | 101 | r-x |

| 4 | 100 | r-- |

| 3 | 011 | -wx |

| 2 | 010 | -w- |

| 1 | 001 | --x |

| 0 | 000 | --- |

Real lab example:

bash
[root@rhel ~]# chmod 754 deploy.sh
[root@rhel ~]# ls -l deploy.sh
-rwxr-xr-- 1 root root 1024 Apr 13 10:00 deploy.sh
# Owner: rwx (7), Group: r-x (5), Other: r-- (4)

Modifying Access Permission Bits

chmod — Changing Permissions

The chmod (change mode) command modifies file and directory permissions. Only the file owner or root can change permissions.

bash
# Symbolic examples
[root@rhel ~]# chmod u+x script.sh          # Add execute for owner
[root@rhel ~]# chmod g-w config.conf        # Remove write from group
[root@rhel ~]# chmod o= private.key         # Remove all permissions from other
[root@rhel ~]# chmod a+r public.html        # Add read for everyone
 
# Octal examples
[root@rhel ~]# chmod 600 id_rsa             # Owner rw only (SSH key)
[root@rhel ~]# chmod 755 /usr/local/bin/app # Standard executable
[root@rhel ~]# chmod 644 /etc/myapp.conf    # Config file: owner rw, rest r
[root@rhel ~]# chmod 700 /root/scripts/     # Private directory
 
# Recursive - apply to directory and all contents
[root@rhel ~]# chmod -R 750 /opt/myapp/

chown — Changing Ownership

The chown (change owner) command changes the user and/or group ownership of a file or directory. Only root can change the owner.

bash
# Change owner only
[root@rhel ~]# chown andres file.txt
 
# Change owner and group
[root@rhel ~]# chown andres:developers file.txt
 
# Change group only (colon without user)
[root@rhel ~]# chown :developers file.txt
 
# Recursive
[root@rhel ~]# chown -R andres:developers /opt/project/
 
# Verify
[root@rhel ~]# ls -l file.txt
-rw-r--r--. 1 andres developers 1024 Apr 13 10:00 file.txt

chgrp — Changing Group Ownership

chgrp changes only the group ownership — useful when you don't want to touch the owner:

bash
[root@rhel ~]# chgrp developers /opt/project/
[root@rhel ~]# chgrp -R webadmin /var/www/html/

Special Permission Bits

Beyond the standard UGO/RWX model, Linux supports three special permission bits that modify how files and directories behave.

SUID (Set User ID) — Octal 4

When SUID is set on an executable, it runs with the permissions of the file owner instead of the user executing it. This is how passwd allows regular users to change their own password (which requires writing to /etc/shadow, owned by root).

bash
[root@rhel ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 32648 /usr/bin/passwd
#   ^
#   's' in owner execute position = SUID is set

Setting SUID:

bash
[root@rhel ~]# chmod u+s /usr/local/bin/myapp
# or
[root@rhel ~]# chmod 4755 /usr/local/bin/myapp

> Senior Engineer Warning: SUID on executables is a significant security risk. Audit all SUID files regularly:

> `bash

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

> `

SGID (Set Group ID) — Octal 2

On executables, SGID runs the file with the group of the file owner. On directories, SGID forces all new files created inside to inherit the directory's group — extremely useful for shared project directories.

bash
[root@rhel ~]# ls -l /usr/bin/write
-rwxr-sr-x. 1 root tty 19536 /usr/bin/write
#        ^
#        's' in group execute position = SGID is set
 
# Set SGID on a shared directory
[root@rhel ~]# chmod g+s /opt/shared/
[root@rhel ~]# chmod 2775 /opt/shared/
[root@rhel ~]# ls -ld /opt/shared/
drwxrwsr-x. 2 root developers 40 Apr 13 10:00 /opt/shared/

Sticky Bit — Octal 1

On directories with the sticky bit set, only the file owner, the directory owner, or root can delete or rename files inside — even if others have write permission. This is the default behavior on /tmp.

bash
[root@rhel ~]# ls -ld /tmp
drwxrwxrwt. 12 root root 4096 Apr 13 10:00 /tmp
#         ^
#         't' in other execute position = sticky bit is set
 
# Set sticky bit
[root@rhel ~]# chmod o+t /opt/shared/
# or
[root@rhel ~]# chmod 1777 /opt/shared/

Default Permissions

umask — The Default Permission Mask

When a new file or directory is created, its default permissions are determined by the umask (user file creation mask). The umask specifies which permissions to remove from the system defaults.

System defaults before umask:

The umask value is subtracted from these defaults:

bash
[root@rhel ~]# umask
0022

Calculating Default Permissions

With umask 0022:

bash
Files:       666 - 022 = 644  → rw-r--r--
Directories: 777 - 022 = 755  → rwxr-xr--

Lab verification:

bash
[root@rhel ~]# umask
0022
 
[root@rhel ~]# touch newfile.txt
[root@rhel ~]# mkdir newdir
[root@rhel ~]# ls -ld newfile.txt newdir
-rw-r--r--. 1 root root    0 Apr 13 10:00 newfile.txt
drwxr-xr-x. 2 root root 4096 Apr 13 10:00 newdir

Changing the umask

bash
# Temporary (current session only)
[root@rhel ~]# umask 027
 
# Verify new behavior
[root@rhel ~]# touch securefile.txt
[root@rhel ~]# ls -l securefile.txt
-rw-r-----. 1 root root 0 Apr 13 10:00 securefile.txt
# 666 - 027 = 640 → rw-r-----

To make it permanent, add to ~/.bashrc or /etc/profile:

bash
echo "umask 027" >> /etc/profile

> Senior Engineer Note: A umask 027 is a good security baseline for most RHEL servers. It ensures no world-readable files by default, while still allowing group read access.


File Searching

Finding files efficiently is one of the most critical skills for a Linux sysadmin. RHEL provides the find command — one of the most powerful and flexible tools in the Linux arsenal.


Using the find Command

The basic syntax is:

bash
find [path] [criteria] [action]

Search by Name

bash
# Find by exact name
[root@rhel ~]# find / -name "sshd_config"
/etc/ssh/sshd_config
 
# Case-insensitive search
[root@rhel ~]# find /etc -iname "*.conf"
 
# Find by name pattern
[root@rhel ~]# find /var/log -name "*.log"
/var/log/messages
/var/log/secure
/var/log/audit/audit.log

Search by Type

bash
# Files only
[root@rhel ~]# find /etc -type f -name "*.conf"
 
# Directories only
[root@rhel ~]# find /opt -type d
 
# Symbolic links only
[root@rhel ~]# find /usr/bin -type l
 
# Block devices
[root@rhel ~]# find /dev -type b

Search by Size

bash
# Files larger than 100MB
[root@rhel ~]# find / -size +100M -type f 2>/dev/null
 
# Files smaller than 10KB
[root@rhel ~]# find /etc -size -10k -type f
 
# Files exactly 512 bytes
[root@rhel ~]# find /tmp -size 512c
 
# Size suffixes: c=bytes, k=kilobytes, M=megabytes, G=gigabytes

Search by Time

bash
# Modified in the last 24 hours
[root@rhel ~]# find /etc -mtime -1
 
# Modified more than 30 days ago
[root@rhel ~]# find /var/log -mtime +30
 
# Accessed in the last 7 days
[root@rhel ~]# find /home -atime -7
 
# Changed (metadata) in last 2 days
[root@rhel ~]# find /etc -ctime -2
 
# Modified in the last 60 minutes
[root@rhel ~]# find /tmp -mmin -60

Search by Permissions

bash
# Files with exact permissions 777
[root@rhel ~]# find / -perm 777 -type f 2>/dev/null
 
# Files with at least these permissions (any bit matches)
[root@rhel ~]# find / -perm -644 -type f 2>/dev/null
 
# Find all SUID files (security audit)
[root@rhel ~]# find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/su
 
# Find all SGID files
[root@rhel ~]# find / -perm -2000 -type f 2>/dev/null
 
# Find world-writable files (security risk)
[root@rhel ~]# find / -perm -o+w -type f 2>/dev/null

Search by Ownership

bash
# Files owned by specific user
[root@rhel ~]# find /home -user andres
 
# Files owned by specific group
[root@rhel ~]# find /opt -group developers
 
# Files with no valid owner (orphaned files - security concern)
[root@rhel ~]# find / -nouser 2>/dev/null
 
# Files with no valid group
[root@rhel ~]# find / -nogroup 2>/dev/null

Combining Multiple Criteria

bash
# Files owned by root AND with SUID set
[root@rhel ~]# find / -user root -perm -4000 -type f 2>/dev/null
 
# Large log files modified more than 7 days ago
[root@rhel ~]# find /var/log -name "*.log" -size +50M -mtime +7
 
# Config files modified in last 24 hours (useful after changes)
[root@rhel ~]# find /etc -type f -name "*.conf" -mtime -1
 
# OR operator: find files owned by root OR group root
[root@rhel ~]# find /etc \( -user root -o -group root \) -type f

Using find with -exec and -ok Flags

The real power of find comes from combining it with actions. The -exec and -ok flags let you run a command on each result found.

-exec Flag

Executes a command on each found file automatically without prompting:

bash
# Syntax
find [path] [criteria] -exec command {} \;
# {} = placeholder for the found file
# \; = end of the command

Real examples:

bash
# Change permissions on all .conf files in /etc
[root@rhel ~]# find /etc -name "*.conf" -exec chmod 644 {} \;
 
# Change ownership of all files in /opt/project
[root@rhel ~]# find /opt/project -type f -exec chown andres:developers {} \;
 
# Delete all .tmp files older than 7 days in /tmp
[root@rhel ~]# find /tmp -name "*.tmp" -mtime +7 -exec rm {} \;
 
# Display detailed info on all SUID files
[root@rhel ~]# find / -perm -4000 -type f -exec ls -lh {} \; 2>/dev/null
 
# Compress all log files larger than 100MB
[root@rhel ~]# find /var/log -name "*.log" -size +100M -exec gzip {} \;
 
# Using + instead of \; for efficiency (runs one command with multiple args)
[root@rhel ~]# find /etc -name "*.conf" -exec chmod 644 {} +

-ok Flag

Works exactly like -exec but prompts for confirmation before each action — safer for destructive operations:

bash
# Syntax
find [path] [criteria] -ok command {} \;

Real examples:

bash
# Prompt before removing each core dump file
[root@rhel ~]# find / -name core -ok rm {} \;
< rm ... /var/crash/core > ? y
< rm ... /tmp/core > ? n
 
# Prompt before changing permissions
[root@rhel ~]# find /home -name "*.sh" -ok chmod 750 {} \;
< chmod ... /home/andres/deploy.sh > ? y
< chmod ... /home/andres/backup.sh > ? y

> Senior Engineer Tip: Always test with -print before using -exec with destructive commands:

> `bash

> # First: see what would be affected

> find /tmp -name "*.tmp" -mtime +7 -print

>

> # Then: execute when confirmed

> find /tmp -name "*.tmp" -mtime +7 -exec rm {} \;

> `

Practical Security Audit with find

As a Senior Red Hat Engineer, here is a complete security audit script using find:

bash
#!/bin/bash
echo "=== SECURITY AUDIT: $(date) ==="
 
echo -e "\n[1] SUID Files:"
find / -perm -4000 -type f 2>/dev/null
 
echo -e "\n[2] SGID Files:"
find / -perm -2000 -type f 2>/dev/null
 
echo -e "\n[3] World-Writable Files:"
find / -perm -o+w -type f -not -path "/proc/*" 2>/dev/null
 
echo -e "\n[4] Orphaned Files (no owner):"
find / -nouser -o -nogroup 2>/dev/null
 
echo -e "\n[5] Files Modified in Last 24h in /etc:"
find /etc -mtime -1 -type f 2>/dev/null
 
echo "=== END AUDIT ==="

Chapter Summary

Understanding file permissions is one of the most critical skills for any RHEL administrator. In this chapter we covered the complete permission model:

The UGO/RWX model categorizes users into three classes — user (owner), group, and other — and assigns three permission types — read, write, and execute — to each class. Permissions are displayed with ls -l and modified with chmod using either symbolic or octal notation. Ownership is managed with chown and chgrp.

The special permission bits — SUID, SGID, and Sticky — extend the standard model. SUID runs executables as the file owner, SGID on directories forces group inheritance, and the Sticky bit protects files in shared directories from deletion by non-owners.

The umask controls default permissions for newly created files and directories by subtracting from the system defaults (666 for files, 777 for directories). A umask of 022 produces 644 for files and 755 for directories.

The find command is the most powerful file search tool in Linux. It supports searching by name, type, size, time, permissions, and ownership. Combined with -exec and -ok, it can perform bulk operations on search results — from changing permissions to removing outdated files.


Review Questions — RHCSA Style

1. What would the command find / -name core -ok rm {} \; do?

2. A file has permissions rwxr-x---. What is the octal representation?

3. What umask value would result in permissions of 640 for newly created files?

4. Which special permission bit on a directory ensures that new files inherit the directory's group ownership?

5. A regular user needs to execute a script that modifies /etc/passwd. Which special permission bit on the script would allow this?

6. What does the -mtime -7 option in the find command mean?

7. What is the difference between chmod 755 and chmod u=rwx,g=rx,o=rx?

8. Which command would you use to find all world-writable files on the system?

9. The sticky bit is set on a directory /data/shared with permissions rwxrwxrwt. User alice created a file in this directory. Can user bob delete it?

10. What is the default umask for the root user on a RHEL system, and what permissions will a newly created file have?


Answers to Review Questions

1. The command find / -name core -ok rm {} \; searches the entire filesystem for files named core and prompts the administrator for confirmation (-ok) before removing each one with rm. The {} is replaced by the found filename, and \; terminates the command.

2. rwxr-x--- in octal is 750. Owner: rwx=7, Group: r-x=5, Other: ---=0.

3. A umask of 026 would produce 640 for files. Calculation: 666 - 026 = 640.

4. The SGID (Set Group ID) bit on a directory ensures all new files and subdirectories created inside inherit the directory's group ownership.

5. SUID (Set User ID) on the script would allow it to run with the permissions of the script's owner. If the owner is root, the script would execute with root privileges regardless of who runs it.

6. -mtime -7 means files that were modified less than 7 days ago. The minus sign means "less than." A plus sign (+7) would mean more than 7 days ago.

7. They produce identical results. chmod 755 uses octal notation while chmod u=rwx,g=rx,o=rx uses symbolic notation. Both set owner to rwx, group to r-x, and other to r-x.

8. find / -perm -o+w -type f 2>/dev/null — the -perm -o+w flag matches any file where the other (world) write bit is set.

9. No. The sticky bit (t) on the directory means only the file owner (alice), the directory owner, or root can delete or rename files. Bob cannot delete alice's file even though he has write permission on the directory.

10. The default umask for root is 0022. A newly created file will have permissions 644 (rw-r--r--). Calculation: 666 - 022 = 644.


Questions ? Find me on X as Stackdeploy or visit stackdeploy.dev

← Back to Articles
Written by Andres Bernal | @abernal093