Linux User Group and File Permissions

LinuxBeginner
Practice Now

Introduction

Linux is a multi-user operating system. Every process and file belongs to a user, and every user has a primary group plus optional supplementary groups. Together, identity, ownership, and permission bits determine who can read, change, execute, or enter a resource.

In this lab, you will build a small team environment using dedicated practice accounts. You will create a user, manage group membership, secure a file, inspect an account lock, control default permissions with umask, and configure sticky-bit and setgid directories. All work stays inside the lab environment and leaves the default labex login path unchanged.

Inspect Identities and Create a Practice User

In this step, you will inspect your current identity and create a separate account for permission exercises. Linux represents a user with a username and numeric user ID (UID). It also records a primary group ID (GID) and any supplementary groups.

First, confirm the identity of the current shell:

whoami

The output should be labex. Now display the UID, primary group, and supplementary groups associated with this account:

id

The exact numeric IDs can vary, but the output labels them as uid, gid, and groups.

Creating an account changes system files, so it requires administrative privileges. sudo means “superuser do”: it runs the following command with elevated authority after checking that the current account is allowed to do so. Use it only for the command that needs administration, and read the complete command before pressing Enter.

The useradd command below uses three options:

  • -m creates the home directory.
  • -U creates a same-named primary group.
  • -s /bin/bash selects Bash as the account's login shell.

Create a practice user named jack:

sudo useradd -m -U -s /bin/bash jack

Inspect the new account and its home directory:

id jack
ls -ld /home/jack

The id output should show jack as both the user and primary group. The directory listing should show that /home/jack exists and belongs to jack:jack.

Manage Supplementary Groups

In this step, you will create a team group and add users to supplementary groups. A user's primary group normally becomes the group owner of newly created files. Supplementary groups grant access to additional shared resources.

Create a group named developers:

sudo groupadd developers

The usermod -aG options mean "append to supplementary groups." The -a is important: without it, -G can replace existing supplementary memberships. Add jack to both developers and sudo:

sudo usermod -aG developers,sudo jack

Also register labex as a member of developers. The current shell will not immediately gain the new group identity; you will refresh it safely in the final step.

sudo usermod -aG developers labex

Inspect both accounts:

groups jack
groups labex

The first output should include jack, developers, and sudo. The second should include developers. Membership in sudo allows an authenticated account to request elevated privileges; it should be granted only to trusted administrators.

Control File Ownership and Permissions

In this step, you will secure a team report with a specific owner, group, and permission mode. A long listing displays the file type first, followed by three permission triplets for the owner, group, and others.

Create an empty report in the project directory:

touch /home/labex/project/secure-report.txt

Change both owners with the user:group form of chown:

sudo chown jack:developers /home/labex/project/secure-report.txt

Set mode 640:

sudo chmod 640 /home/labex/project/secure-report.txt

In numeric notation, read is 4, write is 2, and execute is 1. Therefore:

  • Owner 6 means read and write (4 + 2).
  • Group 4 means read only.
  • Others 0 means no access.

Inspect the result:

ls -l /home/labex/project/secure-report.txt
stat -c 'owner=%U group=%G mode=%a' /home/labex/project/secure-report.txt

The stable stat fields should report owner=jack group=developers mode=640.

Inspect and Change an Account Lock

In this step, you will practice temporarily locking and unlocking a dedicated account. Linux stores password hashes and account status in /etc/shadow. A leading ! in the password field marks password authentication as locked.

The setup created a practice account named contractor. Display only the first character of its password field so that the hash itself is never printed. Read the pipeline from left to right: getent shadow contractor retrieves the account's shadow record; the first cut uses : as a delimiter and selects field 2; the second cut keeps character 1 of that field:

sudo getent shadow contractor | cut -d: -f2 | cut -c1

The initial character should normally be $, which is the beginning of a modern password-hash format. Lock the account with usermod -L:

sudo usermod -L contractor

Inspect the first character again:

sudo getent shadow contractor | cut -d: -f2 | cut -c1

It should now be !. Unlock the account with usermod -U and confirm that the ! disappears:

sudo usermod -U contractor
sudo getent shadow contractor | cut -d: -f2 | cut -c1

For this scenario, the contractor has now left the team. Lock the account one final time while preserving its files:

sudo usermod -L contractor

Locking password authentication does not delete the account, remove its home directory, or necessarily terminate existing sessions. It is different from deleting a user and is useful when files must be retained for review.

Control Default Permissions with Umask

In this step, you will use umask to control the permission bits removed when the shell creates new files and directories. Programs usually start with a maximum mode of 666 for regular files and 777 for directories. A mask of 027 removes write permission from the group and all permissions from others.

Create a workspace for the experiment:

mkdir -p /home/labex/project/umask-demo

Save the current mask so that you can restore it later. The syntax $(command) is called command substitution: the shell runs the command inside the parentheses and replaces the entire expression with its output. The assignment stores that result in original_umask; as with other shell assignments, there are no spaces around =.

original_umask=$(umask)

Apply mask 027, then create a file and directory:

umask 027
touch /home/labex/project/umask-demo/private-note.txt
mkdir /home/labex/project/umask-demo/private-dir

Inspect the resulting numeric modes:

stat -c '%a %n' /home/labex/project/umask-demo/private-note.txt /home/labex/project/umask-demo/private-dir

The file should have mode 640, while the directory should have mode 750. Files do not receive execute bits automatically. Restore the shell's original mask:

umask "$original_umask"

Changing umask affects objects created afterward; it does not rewrite permissions on existing objects.

Protect a Shared Directory with the Sticky Bit

In this step, you will configure a public drop box where everyone can create files but users cannot delete files owned by someone else. Ordinary mode 777 grants all users full directory access. Adding the sticky bit changes deletion rules inside the directory.

Create the shared directory and set mode 1777. The leading 1 enables the sticky bit.

mkdir /tmp/shared-dropbox
chmod 1777 /tmp/shared-dropbox

Use sudo -u to create one file as each practice account:

sudo -u jack touch /tmp/shared-dropbox/jack-note.txt
sudo -u contractor touch /tmp/shared-dropbox/contractor-note.txt

Now let jack try to delete the contractor's file:

sudo -u jack rm /tmp/shared-dropbox/contractor-note.txt

This failure is intentional. You should see Operation not permitted, and the contractor's file should remain. Inspect the directory:

ls -ld /tmp/shared-dropbox

The permissions should end in a lowercase t, such as drwxrwxrwt. Lowercase t means the sticky bit and execute permission for others are both set. Uppercase T would mean the sticky bit is set without the corresponding execute bit.

Configure a Setgid Team Directory

In this step, you will prepare a private collaboration directory. On a directory, setgid causes newly created children to inherit the directory's group instead of the creator's primary group. This keeps team files associated with one shared group.

Create the directory:

mkdir /home/labex/project/team-share

Make jack the owner and developers the group owner:

sudo chown jack:developers /home/labex/project/team-share

Set mode 2770. The leading 2 enables setgid; 770 grants full access to the owner and group while denying access to others.

sudo chmod 2770 /home/labex/project/team-share

Inspect the result:

ls -ld /home/labex/project/team-share
stat -c 'owner=%U group=%G mode=%a' /home/labex/project/team-share

The long listing should show s in the group execute position, such as drwxrws---. Lowercase s means both setgid and group execute are active. Uppercase S would mean setgid is present but group execute is missing.

Setuid, represented by an s in the owner execute position, is another special bit commonly found on carefully controlled system executables. Recognize it when reading permissions, but do not add it to arbitrary programs.

Refresh Group Membership and Verify Inheritance

In this step, you will activate the developers membership in a child shell and prove that setgid controls the group of a new file. Adding a user to /etc/group does not rewrite the supplementary groups of an already running shell.

Start a child shell with developers as its active group:

newgrp developers

The prompt may refresh. You are still the labex user, but the child shell now has developers as its effective group. Confirm both identities:

id

Create a file in the setgid directory:

touch /home/labex/project/team-share/labex-note.txt

Inspect the new file:

stat -c 'owner=%U group=%G mode=%a' /home/labex/project/team-share/labex-note.txt

The owner should be labex, while the group should be developers. Setgid inherits the group owner; the file's read and write bits still depend on the creating process and its umask.

Exit the child shell and return to the original terminal session:

exit

The file remains in place after the child shell closes.

Summary

You practiced the core identity and access model used by Linux systems. You created a user and team group, managed supplementary memberships, assigned ownership, and translated numeric permission modes into practical access rules. You also inspected an account lock without exposing its password hash.

You then moved beyond ordinary permissions: umask controlled defaults, the sticky bit protected files in a public directory, and setgid preserved team group ownership in a private collaboration directory. Finally, you used newgrp to refresh group membership and verified the inherited group on a real file.