Control File Access in Red Hat Enterprise Linux

Red Hat Enterprise LinuxBeginner
Practice Now

Introduction

In this lab, you will gain a comprehensive understanding of managing Linux file system permissions, a critical skill for any RHEL administrator. You will learn to interpret file permissions using ls -l, modify them with chmod in both symbolic and octal modes, and change file ownership using chown. Furthermore, you will explore and apply special permissions like SUID, SGID, and the Sticky Bit, and configure default permissions effectively with umask. This hands-on experience will equip you with the necessary knowledge to secure and control access to files and directories in a Linux environment.

Interpret Linux File System Permissions with ls -l

In this step, you will learn how to interpret Linux file system permissions using the ls -l command. Understanding file permissions is crucial for managing access to files and directories in a Linux environment.

Every file and directory in Linux has associated permissions that determine who can read, write, or execute it. These permissions are divided into three categories:

  • User (owner): The permissions for the file's owner.
  • Group: The permissions for users who are members of the file's group.
  • Others: The permissions for all other users on the system.

Each category can have three types of permissions:

  • Read (r): Allows viewing the contents of a file or listing the contents of a directory.
  • Write (w): Allows modifying the contents of a file or creating/deleting files within a directory.
  • Execute (x): Allows running an executable file or entering a directory.

Let's start by creating a new directory and a file within your ~/project directory to observe their default permissions.

First, create a directory named my_files:

mkdir ~/project/my_files

Next, create an empty file named document.txt inside the my_files directory:

touch ~/project/my_files/document.txt

Now, use the ls -l command to view the detailed permissions of the document.txt file. The ls -l command provides a long listing format, including file permissions, owner, group, size, and modification date.

ls -l ~/project/my_files/document.txt

You should see output similar to this:

-rw-rw-r-- 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

Let's break down the first part of the output, -rw-rw-r--.:

  • The first character (-) indicates the file type.
    • - means it's a regular file.
    • d means it's a directory.
    • l means it's a symbolic link.
  • The next nine characters are divided into three sets of three:
    • rw-: Permissions for the owner (labex). r (read), w (write), - (no execute).
    • rw-: Permissions for the group (labex). r (read), w (write), - (no execute).
    • r--: Permissions for others. r (read), - (no write), - (no execute).

This means the labex user (owner) and users in the labex group can read and write to document.txt, while all other users can only read it.

Now, let's examine the permissions of the my_files directory itself. When using ls -l on a directory, it lists the contents of the directory. To view the permissions of the directory itself, you need to use the -d option with ls -l.

ls -ld ~/project/my_files

You should see output similar to this:

drwxrwxr-x 2 labex labex 4096 Jun  6 17:36 /home/labex/project/my_files

Let's interpret the permissions drwxrwxr-x.:

  • The first character (d) indicates it's a directory.
  • rwx: Permissions for the owner (labex). r (read), w (write), x (execute).
  • rwx: Permissions for the group (labex). r (read), w (write), x (execute).
  • r-x: Permissions for others. r (read), - (no write), x (execute).

For directories:

  • r (read) allows listing the contents of the directory.
  • w (write) allows creating, deleting, or renaming files within the directory.
  • x (execute) allows entering the directory (using cd) and accessing its files and subdirectories.

This means the labex user and users in the labex group can list, create/delete files, and enter the my_files directory. Other users can list and enter the directory, but cannot create or delete files within it.

Change File Permissions with chmod (Symbolic Mode)

In this step, you will learn how to change file permissions using the chmod command in symbolic mode. Symbolic mode uses letters and symbols to represent permission changes, making it intuitive to add, remove, or set specific permissions.

The chmod command in symbolic mode follows the syntax: chmod WHO OPERATION PERMISSIONS FILE.

  • WHO: Specifies who the permission change applies to.
    • u: user (owner)
    • g: group
    • o: others
    • a: all (user, group, and others)
  • OPERATION: Specifies how to modify the permissions.
    • +: Add a permission.
    • -: Remove a permission.
    • =: Set permissions exactly as specified, overriding existing ones.
  • PERMISSIONS: Specifies the permission type.
    • r: read
    • w: write
    • x: execute

Let's continue working with the ~/project/my_files/document.txt file and ~/project/my_files directory created in the previous step.

First, let's remove write permission for the group and others from document.txt. Recall that its current permissions are -rw-rw-r--.

chmod go-w ~/project/my_files/document.txt

Now, verify the change using ls -l:

ls -l ~/project/my_files/document.txt

The output should now show:

-rw-r--r-- 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

Notice that the w (write) permission for the group and others has been removed.

Next, let's add execute permission for the owner (u) to document.txt. This is often done for scripts to make them executable.

chmod u+x ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now be:

-rwxr--r-- 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

The owner now has execute permission (x).

Now, let's practice with the ~/project/my_files directory. Its current permissions are drwxrwxr-x. Let's remove write permission for others (o) from the directory.

chmod o-w ~/project/my_files

Verify the change:

ls -ld ~/project/my_files

The output should now show:

drwxr-xr-x 2 labex labex 4096 Jun  6 17:36 /home/labex/project/my_files

Wait, why did the o-w not change the output? This is because the o (others) already did not have write permission. The r-x for others means read and execute, but no write. This demonstrates that chmod only applies changes if they are different from the current state.

Let's try setting permissions exactly. We will set the permissions for document.txt to rw-r--r-- for all (owner, group, others). This means owner gets read/write, group gets read, and others get read.

chmod a=rw,g=r,o=r ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now be:

-rw-r--r-- 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

This command a=rw,g=r,o=r is a bit redundant as a=rw would apply rw to all, then g=r would set group to r (overriding the w from a=rw), and o=r would set others to r (overriding the w from a=rw). A simpler way to achieve rw-r--r-- would be chmod u=rw,go=r. Let's try that.

chmod u=rw,go=r ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should still be:

-rw-r--r-- 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

Finally, let's make document.txt executable for everyone.

chmod a+x ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now be:

-rwxr-xr-x 1 labex labex 0 Jun  6 17:36 /home/labex/project/my_files/document.txt

Change File Permissions with chmod (Octal Mode)

In this step, you will learn how to change file permissions using the chmod command in octal (numeric) mode. Octal mode is a concise way to represent permissions, where each permission (read, write, execute) is assigned a numerical value.

The numerical values for permissions are:

  • Read (r): 4
  • Write (w): 2
  • Execute (x): 1
  • No permission (-): 0

To determine the octal value for a set of permissions (user, group, or others), you sum the values of the permissions granted.

For example:

  • rwx (read, write, execute) = 4 + 2 + 1 = 7
  • rw- (read, write, no execute) = 4 + 2 + 0 = 6
  • r-x (read, no write, execute) = 4 + 0 + 1 = 5
  • r-- (read, no write, no execute) = 4 + 0 + 0 = 4
  • --- (no permissions) = 0 + 0 + 0 = 0

The chmod command in octal mode uses a three-digit number, where each digit represents the permissions for the owner, group, and others, respectively. The syntax is: chmod OGO FILE.

  • O: Octal value for owner permissions.
  • G: Octal value for group permissions.
  • O: Octal value for others permissions.

Let's continue working with ~/project/my_files/document.txt and ~/project/my_files.

First, let's set the permissions of document.txt to rw-r--r--.

  • Owner: rw- = 6
  • Group: r-- = 4
  • Others: r-- = 4

So, the octal value will be 644.

chmod 644 ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now be:

-rw-r--r-- 1 labex labex 0 Jun  6 00:48 /home/labex/project/my_files/document.txt

Next, let's make document.txt executable only by the owner, while keeping read/write for owner, and read-only for group and others. This means the owner will have rwx (7), group r-- (4), and others r-- (4). The octal value will be 744.

chmod 744 ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now be:

-rwxr--r-- 1 labex labex 0 Jun  6 00:48 /home/labex/project/my_files/document.txt

Now, let's change the permissions of the ~/project/my_files directory. Its current permissions are drwxr-xr-x. Let's set its permissions to rwxr-x---.

  • Owner: rwx = 7
  • Group: r-x = 5
  • Others: --- = 0

So, the octal value will be 750.

chmod 750 ~/project/my_files

Verify the change:

ls -ld ~/project/my_files

The output should now show:

drwxr-x--- 2 labex labex 26 Jun  6 00:48 /home/labex/project/my_files

This means the owner (labex) has full permissions (read, write, execute), the group (labex) can read and execute (enter) the directory, and others have no permissions at all.

Finally, let's create a new executable script file to demonstrate setting execute permissions directly.

echo '#!/bin/bash' > ~/project/my_script.sh
echo 'echo "Hello from my script!"' >> ~/project/my_script.sh

By default, new files are not executable. Let's check its permissions:

ls -l ~/project/my_script.sh

You will likely see permissions like -rw-r--r--. To make it executable for the owner and group, but not others, we want rwxrwx---.

  • Owner: rwx = 7
  • Group: rwx = 7
  • Others: --- = 0

So, the octal value will be 770.

chmod 770 ~/project/my_script.sh

Verify the change:

ls -l ~/project/my_script.sh

The output should now be:

-rwxrwx--- 1 labex labex 41 Jun  6 00:52 /home/labex/project/my_script.sh

Now you can execute the script:

~/project/my_script.sh

You should see the output:

Hello from my script!

Change File Ownership with chown

In this step, you will learn how to change the owner and group of files and directories using the chown command. This is a crucial administrative task, as only the root user can change the owner of a file. The labex user has sudo privileges, which will allow you to perform these actions.

The basic syntax for chown is: chown [OPTIONS] NEW_OWNER[:NEW_GROUP] FILE(s).

Let's start by creating a new user and group that we can use to demonstrate ownership changes. Since this environment is container-based, we will create a simple user and group for demonstration purposes.

First, create a new group named devs:

sudo groupadd devs

Next, create a new user named developer and add them to the devs group. We will create a system user without a home directory or login shell for this demonstration.

sudo useradd -r -g devs -s /sbin/nologin developer

Now, let's change the owner of ~/project/my_files/document.txt from labex to developer.

sudo chown developer ~/project/my_files/document.txt

Verify the change using ls -l:

ls -l ~/project/my_files/document.txt

The output should now show developer as the owner:

-rwxr--r-- 1 developer labex 0 Jun  6 00:48 /home/labex/project/my_files/document.txt

Notice that the group ownership (labex) remained unchanged.

You can also change both the owner and the group simultaneously using the owner:group syntax. Let's change the owner of document.txt back to labex and its group to devs.

sudo chown labex:devs ~/project/my_files/document.txt

Verify the change:

ls -l ~/project/my_files/document.txt

The output should now show labex as the owner and devs as the group:

-rwxr--r-- 1 labex devs 0 Jun  6 00:48 /home/labex/project/my_files/document.txt

The chown command also supports the -R (recursive) option, which allows you to change the ownership of an entire directory tree. Let's change the owner of the ~/project/my_files directory and all its contents to developer, and the group to devs.

sudo chown -R developer:devs ~/project/my_files

Verify the change for the directory:

ls -ld ~/project/my_files

The output should reflect the new ownership:

drwxr-x--- 2 developer devs 26 Jun  6 00:48 /home/labex/project/my_files

Note that after changing the directory ownership to developer:devs, the labex user can no longer access the file inside the directory because the directory permissions are drwxr-x--- (owner and group have access, but others don't), and labex is neither the owner (developer) nor a member of the group (devs). If you try to list the file now:

ls -l ~/project/my_files/document.txt

You will get a "Permission denied" error. This demonstrates how ownership and permissions work together to control access.

You can also change only the group ownership using chown :NEW_GROUP FILE(s). This is equivalent to using the chgrp command. Let's change the group of ~/project/my_script.sh to devs.

sudo chown :devs ~/project/my_script.sh

Verify the change:

ls -l ~/project/my_script.sh

The output should show devs as the group owner, while labex remains the file owner:

-rwxrwx--- 1 labex devs 41 Jun  6 00:52 /home/labex/project/my_script.sh

Finally, let's clean up by changing the ownership back to labex:labex and then removing the developer user and devs group.

sudo chown -R labex:labex ~/project/my_files
sudo userdel developer
sudo groupdel devs

Understand and Apply Special Permissions (SUID, SGID, Sticky Bit)

In this step, you will explore special permissions in Linux: SUID (Set User ID), SGID (Set Group ID), and the Sticky Bit. These permissions provide enhanced control over file execution and directory behavior.

Special permissions are represented by an additional digit in the octal permission mode, placed before the standard three digits (owner, group, others).

  • SUID (Set User ID):
    • Octal value: 4
    • Effect on files: When an executable file with SUID is run, it executes with the permissions of the file's owner, not the user who ran it. This is commonly used for programs that need elevated privileges to perform certain tasks, like the passwd command (which needs to write to /etc/shadow, a file owned by root).
    • In ls -l output: An s appears in place of the owner's x (execute) permission. If the owner does not have execute permission, an uppercase S appears.
  • SGID (Set Group ID):
    • Octal value: 2
    • Effect on files: Similar to SUID, but the executable runs with the permissions of the file's group owner.
    • Effect on directories: Files and subdirectories created within an SGID-enabled directory inherit the group ownership of that directory, rather than the primary group of the user who created them. This is very useful for shared directories where all files should belong to a specific group.
    • In ls -l output: An s appears in place of the group's x (execute) permission. If the group does not have execute permission, an uppercase S appears.
  • Sticky Bit:
    • Octal value: 1
    • Effect on files: No effect.
    • Effect on directories: Users can create files in the directory, but they can only delete or rename files that they own. This prevents users from deleting or moving other users' files in a shared directory (e.g., /tmp).
    • In ls -l output: A t appears in place of others' x (execute) permission. If others do not have execute permission, an uppercase T appears.

Let's demonstrate these special permissions.

SUID Example

We'll create a simple C program that attempts to read a restricted file.

First, create a file that only root can read:

sudo touch ~/project/secret_data.txt
sudo chmod 600 ~/project/secret_data.txt
sudo chown root:root ~/project/secret_data.txt

Verify its permissions:

ls -l ~/project/secret_data.txt

Output:

-rw------- 1 root root 0 Jun  6 17:36 /home/labex/project/secret_data.txt

Now, create a C program read_secret.c that tries to read this file:

nano ~/project/read_secret.c

Paste the following code into read_secret.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    FILE *fp;
    char buffer[256];

    printf("Attempting to read /home/labex/project/secret_data.txt...\n");

    fp = fopen("/home/labex/project/secret_data.txt", "r");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%s", buffer);
    }

    fclose(fp);
    printf("Successfully read file.\n");
    return 0;
}

Save and exit nano (Ctrl+S, Ctrl+X).

Compile the program:

gcc ~/project/read_secret.c -o ~/project/read_secret

Now, try to run it as labex:

~/project/read_secret

You should see an "Error opening file: Permission denied" message, as labex does not have read access to secret_data.txt.

Now, let's make read_secret owned by root and set the SUID bit.

sudo chown root:root ~/project/read_secret
sudo chmod u+s ~/project/read_secret

Verify the permissions:

ls -l ~/project/read_secret

Output:

-rwsr-xr-x 1 root root 17704 Jun  6 01:02 /home/labex/project/read_secret

Notice the s in the owner's permission set. Now, run the program again as labex:

~/project/read_secret

This time, it should successfully read the file (though it's empty, so no content will be printed, but the "Successfully read file." message indicates success). This is because the SUID bit made the program run with root's permissions.

SGID Example (on Directory)

Let's create a shared directory and a new group.

sudo groupadd shared_group
sudo mkdir ~/project/shared_dir
sudo chown labex:shared_group ~/project/shared_dir
sudo chmod 770 ~/project/shared_dir

Now, set the SGID bit on shared_dir:

sudo chmod g+s ~/project/shared_dir

Verify the permissions:

ls -ld ~/project/shared_dir

Output:

drwxrws--- 2 labex shared_group 6 Jun  6 01:02 /home/labex/project/shared_dir

Notice the s in the group's permission set.

Now, create a file inside shared_dir:

touch ~/project/shared_dir/new_file.txt

Check the ownership of new_file.txt:

ls -l ~/project/shared_dir/new_file.txt

Output:

-rw-r--r-- 1 labex shared_group 0 Jun  6 01:02 /home/labex/project/shared_dir/new_file.txt

Even though labex's primary group is labex, the new_file.txt inherited the shared_group group ownership from shared_dir due to the SGID bit.

Sticky Bit Example

The /tmp directory is a classic example of a directory with the sticky bit set. Let's create a similar directory.

sudo mkdir ~/project/public_upload
sudo chmod 1777 ~/project/public_upload

The 1 in 1777 is the octal value for the sticky bit. 777 grants full permissions to owner, group, and others.

Verify the permissions:

ls -ld ~/project/public_upload

Output:

drwxrwxrwt 2 root root 6 Jun  6 01:02 /home/labex/project/public_upload

Notice the t in others' permission set.

Now, let's simulate another user creating a file in this directory. Since we only have labex user, we'll create a file as labex and then try to delete it after changing its ownership to root (simulating another user).

Create a file as labex:

touch ~/project/public_upload/labex_file.txt

Change its ownership to root:

sudo chown root:root ~/project/public_upload/labex_file.txt

Now, try to delete labex_file.txt as labex:

rm ~/project/public_upload/labex_file.txt

You will see a prompt asking if you want to remove the write-protected file, and after confirming with y, you'll get an "Operation not permitted" error. This is because the sticky bit prevents users from deleting files they don't own within that directory, even though labex has write permission on the public_upload directory. Only root or the owner of labex_file.txt (root in this case) can delete it.

To clean up, you'll need sudo to remove labex_file.txt:

sudo rm ~/project/public_upload/labex_file.txt

Cleaning Up

Remove the created files and directories, and the user/group:

sudo rm -f ~/project/secret_data.txt ~/project/read_secret.c ~/project/read_secret
sudo rm -rf ~/project/shared_dir ~/project/public_upload
sudo groupdel shared_group

Configure Default Permissions with umask

In this final step, you will learn about umask, which controls the default permissions assigned to newly created files and directories. The umask (user file-creation mode mask) is a bitmask that removes permissions from the maximum possible permissions.

The maximum permissions for a new file are 666 (rw-rw-rw-), meaning read and write for everyone. New files typically do not get execute permissions by default for security reasons.
The maximum permissions for a new directory are 777 (rwxrwxrwx), meaning read, write, and execute for everyone.

The umask value is subtracted from these maximum permissions to determine the actual default permissions.

To view your current umask value, simply type umask:

umask

You will likely see 0002 or 0022. In this environment, it's 0022 for labex user.

A umask of 0022 means:

  • The first 0 is for special permissions (SUID, SGID, Sticky Bit), which are not affected by umask by default.
  • The second 0 means no permissions are removed from the owner.
  • The third 2 means the write permission (value 2) is removed from the group.
  • The fourth 2 means the write permission (value 2) is removed from others.

Let's calculate the default permissions with a umask of 0022:

  • For files (max 666):

    • Owner: 6 - 0 = 6 (rw-)
    • Group: 6 - 2 = 4 (r--)
    • Others: 6 - 2 = 4 (r--)
    • Resulting file permissions: 644 (rw-r--r--)
  • For directories (max 777):

    • Owner: 7 - 0 = 7 (rwx)
    • Group: 7 - 2 = 5 (r-x)
    • Others: 7 - 2 = 5 (r-x)
    • Resulting directory permissions: 755 (rwxr-xr-x)

Let's test this. Create a new file and directory:

touch ~/project/new_file_umask.txt
mkdir ~/project/new_dir_umask

Check their permissions:

ls -l ~/project/new_file_umask.txt
ls -ld ~/project/new_dir_umask

You should see permissions like -rw-r--r-- for the file and drwxr-xr-x for the directory, confirming the 0022 umask effect.

Now, let's change the umask to 0077. This umask will remove all group and others permissions.

umask 0077

Verify the umask has changed:

umask

Output:

0077

Now, let's calculate the default permissions with a umask of 0077:

  • For files (max 666):

    • Owner: 6 - 0 = 6 (rw-)
    • Group: 6 - 7 = -1 (effectively 0, ---)
    • Others: 6 - 7 = -1 (effectively 0, ---)
    • Resulting file permissions: 600 (rw-------)
  • For directories (max 777):

    • Owner: 7 - 0 = 7 (rwx)
    • Group: 7 - 7 = 0 (---)
    • Others: 7 - 7 = 0 (---)
    • Resulting directory permissions: 700 (rwx------)

Let's test this new umask. Create another new file and directory:

touch ~/project/restricted_file.txt
mkdir ~/project/restricted_dir

Check their permissions:

ls -l ~/project/restricted_file.txt
ls -ld ~/project/restricted_dir

You should now see permissions like -rw------- for the file and drwx------ for the directory.

The umask setting is typically configured in shell initialization files (like ~/.bashrc or /etc/profile) to apply automatically when a user logs in. For this lab, the umask change is temporary and only applies to the current terminal session.

To revert the umask to its default for the labex user, you can simply set it back to 0022:

umask 0022

Finally, clean up the files and directories created in this step:

rm ~/project/new_file_umask.txt ~/project/restricted_file.txt
rmdir ~/project/new_dir_umask ~/project/restricted_dir

Summary

In this lab, we delved into the fundamental aspects of managing Linux file system permissions. We began by mastering the ls -l command to interpret file and directory permissions, understanding the significance of user, group, and others categories, and the read, write, and execute permissions. This foundational knowledge was then applied to modify permissions using chmod in both symbolic and octal modes, providing flexibility in setting access rights.

Furthermore, we learned how to change file ownership with the chown command, which is crucial for assigning administrative control. The lab also covered the understanding and application of special permissions (SUID, SGID, and Sticky Bit), which offer advanced control over execution and file creation behaviors. Finally, we explored how to configure default permissions for newly created files and directories using umask, ensuring consistent permission settings across the system.