Module 3: User and Permission Management
Learning Objectives
By the end of this module, you will be able to:
- Create, modify, and delete user accounts in Linux
- Organize users into appropriate groups
- Understand and implement standard file permissions
- Work with advanced access control lists (ACLs)
- Interpret and set permissions using both numeric and symbolic notation
- Configure sudo access for appropriate privilege delegation
- Implement secure permission structures in real-world scenarios
Chapter 1: User Account Administration
Understanding Linux Users
In Linux, each user is assigned a unique numerical user ID (UID) that the system uses internally to track ownership and permissions. When you see usernames in directory listings or process information, what you're actually seeing is a human‐readable mapping to these UIDs.
Under the hood, Linux stores basic user account information in the /etc/passwd
file. Let's examine its structure:
username:x:UID:GID:GECOS:home_directory:login_shell
Where:
- username: The login name
- x: Placeholder for the password (actual passwords are stored in
/etc/shadow
) - UID: User ID number
- GID: Primary group ID number
- GECOS: User information field (full name, phone, etc.)
- home_directory: Path to the user's home directory
- login_shell: Path to the user's default shell
The actual password hashes are stored in /etc/shadow
, which has stricter permissions and contains additional password policy information:
username:encrypted_password:lastchange:min:max:warn:inactive:expire:reserved
Now let's explore how to manage these user accounts:
Creating User Accounts
The primary command for creating users is useradd
, but many distributions provide the more user‐friendly adduser
wrapper.
# Basic user creation
sudo useradd jsmith
# Create user with specific parameters
sudo useradd -m -d /home/jsmith -s /bin/bash -c "John Smith" -G wheel,developers jsmith
Parameters explained:
-m
: Create the home directory-d
: Specify home directory path-s
: Set login shell-c
: Set GECOS field (user information)-G
: Add to supplementary groups
When you create a user, several actions happen behind the scenes:
- A new entry is added to
/etc/passwd
- A corresponding entry is created in
/etc/shadow
- The user's home directory is created (if specified)
- Default configuration files are copied from
/etc/skel/
to the new home directory
Setting and Managing Passwords
# Set password for a user
sudo passwd jsmith
The password is hashed using algorithms like SHA-512 and stored in /etc/shadow
, not as plaintext. The shadow file also tracks password aging information, which we can manage:
# Set password expiration policies
sudo chage -M 90 -W 7 -I 14 jsmith
This would:
-M 90
: Force password change every 90 days-W 7
: Warn 7 days before expiration-I 14
: Lock account 14 days after password expires
Modifying User Accounts
# Change username
sudo usermod -l new_username old_username
# Add user to additional groups
sudo usermod -aG wheel,docker jsmith
# Change home directory
sudo usermod -d /newhome/jsmith -m jsmith
The -aG
option is especially important – the 'a' means "append" and prevents the user from being removed from other groups.
Deleting User Accounts
# Remove user account only
sudo userdel jsmith
# Remove user and their home directory
sudo userdel -r jsmith
Caution: Before deleting, consider backing up the user's home directory and any files they own elsewhere in the system.
Exercise 1: User Account Lifecycle
Let's practice the full lifecycle of user management:
- Create a new user named
trainee
with a home directory and bash shell: - Set an initial password for this user:
- Add this user to the
sudo
group (orwheel
on some distributions): - Lock the account (as if the trainee period ended):
- Check the account's password status:
- Remove the account and home directory:
sudo useradd -m -s /bin/bash -c "Training Account" trainee
sudo passwd trainee
sudo usermod -aG sudo trainee
sudo passwd -l trainee
sudo passwd -S trainee
sudo userdel -r trainee
Chapter 2: Group Management and Organization
Understanding Linux Groups
Groups in Linux serve as collections of users with similar permission needs. Every file and directory is owned by both a user and a group, enabling permission assignment to multiple users simultaneously.
Under the hood, group information is stored in /etc/group
:
groupname:x:GID:user_list
Where:
- groupname: The name of the group
- x: Legacy password field (group passwords are rarely used now)
- GID: Group ID number
- user_list: Comma-separated list of users in the group
Every user has a primary group (specified in /etc/passwd
) and zero or more supplementary groups (listed in /etc/group
). When a user creates a file, the file's group ownership defaults to the user's primary group.
Creating and Managing Groups
# Create a new group
sudo groupadd developers
# Add existing users to the group
sudo usermod -aG developers jsmith
sudo usermod -aG developers mwilson
# Alternative: use gpasswd
sudo gpasswd -a jsmith developers
You can directly edit group membership with:
# Add multiple users to a group
sudo gpasswd -M jsmith,mwilson,agarcia developers
# Remove a user from a group
sudo gpasswd -d jsmith developers
User Private Groups
Many modern Linux distributions use a User Private Group (UPG) scheme, where each user gets their own primary group with the same name as their username. This simplifies permission management in many cases but requires understanding the difference between primary and supplementary groups.
Viewing Group Membership
# List groups for current user
groups
# List groups for specific user
groups jsmith
# Alternative with user ID information
id jsmith
Exercise 2: Setting Up Project Groups
In this exercise, we'll create a collaborative project structure with appropriate group permissions:
- Create two project groups:
- Create two users and add them to appropriate groups:
- Create project directories with proper group ownership:
- Check your work:
sudo groupadd project_alpha
sudo groupadd project_beta
sudo useradd -m dev1
sudo useradd -m dev2
# Add dev1 to both projects
sudo usermod -aG project_alpha,project_beta dev1
# Add dev2 to just project_alpha
sudo usermod -aG project_alpha dev2
sudo mkdir -p /projects/alpha /projects/beta
sudo chgrp project_alpha /projects/alpha
sudo chgrp project_beta /projects/beta
ls -la /projects
groups dev1
groups dev2
Chapter 3: File Permissions
Standard Permission Model
Linux file permissions follow a simple yet powerful model based on three permission types (read, write, execute) assigned to three different entities (owner, group, others).
For files:
- Read (r): View file contents
- Write (w): Modify file contents
- Execute (x): Run the file as a program or script
For directories:
- Read (r): List directory contents
- Write (w): Create or delete files within the directory
- Execute (x): Access the directory (cd into it)
Understanding Permission Notation
When you run ls -l
, you see permissions displayed like this:
-rwxr-xr--
This breaks down as:
- First character: File type (
-
for regular file,d
for directory) - Next three characters: Owner permissions (
rwx
) - Middle three characters: Group permissions (
r-x
) - Last three characters: Others permissions (
r--
)
Numeric (Octal) Permission Notation
Permissions can also be represented as a 3-digit octal number:
- Read (r) = 4
- Write (w) = 2
- Execute (x) = 1
By adding these values for each category, we get a single digit between 0–7:
rwx
= 4+2+1 = 7r-x
= 4+0+1 = 5r--
= 4+0+0 = 4
For example, rwxr-xr--
translates to 754:
- Owner:
rwx
= 7 - Group:
r-x
= 5 - Others:
r--
= 4
Special Permission Bits
Beyond the basic permissions, Linux supports three special permission bits:
- Setuid (4000): When set on executables, they run with the owner's permissions, not the executor's
- Setgid (2000): Files inherit the directory's group; executables run with the group's permissions
- Sticky bit (1000): On directories, prevents users from deleting files they don't own
Including these gives us a 4-digit octal representation:
# Set setuid bit on a file (runs as owner)
chmod 4755 myprogram
# Set setgid bit on a directory (new files inherit group)
chmod 2775 /shared/project
# Set sticky bit on a directory (prevent deletion by non-owners)
chmod 1777 /shared/temp
Changing Permissions
We change permissions using the chmod
command, with either symbolic or numeric notation:
# Numeric notation
chmod 644 myfile.txt
# Symbolic notation
chmod u=rw,g=r,o=r myfile.txt
chmod u+x script.sh
chmod g-w shared_doc.txt
chmod a+r public_info.txt
Symbolic notation explained:
u
: Owner (user)g
: Groupo
: Othersa
: All (equivalent to ugo)+
: Add permission-
: Remove permission=
: Set exact permissions
Changing Ownership
# Change file owner
sudo chown jsmith myfile.txt
# Change owner and group simultaneously
sudo chown jsmith:developers myfile.txt
# Change only the group
sudo chgrp developers myfile.txt
# Change recursively for directories
sudo chown -R jsmith:developers /projects/alpha
Default Permissions
The umask
setting determines default permissions for newly created files and directories:
- Base permission for files: 666 (rw-rw-rw-)
- Base permission for directories: 777 (rwxrwxrwx)
- The umask value is subtracted from these base permissions
Common umask values:
- 022: Files get 644 (rw-r--r--), directories get 755 (rwxr-xr-x)
- 027: Files get 640 (rw-r-----), directories get 750 (rwxr-x---)
# View current umask
umask
# Set umask for current session
umask 027
For permanent changes, modify .bashrc
or /etc/profile
.
Chapter 4: Advanced Access Control Lists (ACLs)
Enabling ACLs
Most modern Linux filesystems support ACLs, but they might not be enabled by default. Check if they're mounted with ACL support:
# Look for "acl" in the mount options
mount | grep acl
To enable ACLs, you may need to add the acl
option in /etc/fstab
:
UUID=xxx / ext4 defaults,acl 1 1
Viewing and Setting ACLs
The getfacl
command shows the ACL for a file:
getfacl myfile.txt
Output looks like:
# file: myfile.txt
# owner: jsmith
# group: developers
user::rw-
user:agarcia:r--
group::r--
group:project_alpha:rw-
mask::rw-
other::---
To set ACLs, use setfacl
:
# Give read access to a user
setfacl -m u:agarcia:r myfile.txt
# Give read-write access to a group
setfacl -m g:project_alpha:rw myfile.txt
# Remove specific user access
setfacl -x u:agarcia myfile.txt
# Set default ACLs on a directory (inherited by new files)
setfacl -d -m g:project_alpha:rw /projects/alpha
ACL Inheritance
Default ACLs on directories are powerful for ensuring consistent permissions across project folders:
# Set default ACLs for new files and subdirectories
setfacl -d -m u:jsmith:rwx,g:project_alpha:rx /projects/alpha
# Set and apply to all existing content
setfacl -R -m u:jsmith:rwx,g:project_alpha:rx /projects/alpha
The ACL Mask
The ACL mask defines the maximum permissions that can be granted by any ACL entry other than the owner. It's automatically calculated when you set ACLs but can be explicitly set:
setfacl -m m::r /projects/alpha/restricted.txt
This would limit all ACL permissions to read-only, regardless of what individual user or group ACLs specify.
Chapter 5: Sudo Configuration and Privilege Management
Understanding Sudo
The sudo
command allows users to execute commands with elevated privileges without needing the root password. It's more secure than sharing the root password because:
- It provides an audit trail of privileged commands
- It allows fine‐grained control over which commands users can run
- It doesn't expose the root password to users
Under the hood, sudo is configured through the /etc/sudoers
file, which defines who can run what commands as which users.
Basic Sudo Configuration
The sudoers file should only be edited with the special visudo
command, which checks syntax before saving:
sudo visudo
A typical sudoers entry looks like:
username ALL=(ALL:ALL) ALL
Breaking this down:
- username: The user this rule applies to
- First
ALL
: Applies from all hosts (ALL:ALL)
: Can run commands as any user and any group- Last
ALL
: Can run any command
Configuring Group Access
Instead of configuring sudo access for individual users, best practice is to use groups:
%sudo ALL=(ALL:ALL) ALL
%wheel ALL=(ALL:ALL) ALL
The %
prefix indicates a group. This grants all members of the sudo or wheel group full sudo privileges.
Restricting Sudo Access
You can limit which commands users can run with sudo:
# Allow user to run only specific commands
jsmith ALL=/usr/bin/apt update, /usr/bin/apt upgrade
# Allow running as specific user (not root)
dbadmin ALL=(postgres) /usr/bin/psql
# Allow certain commands without password
helpdesk ALL=NOPASSWD: /usr/bin/service apache2 restart
Sudo with Password Timeouts
By default, sudo caches the password for 15 minutes. This can be adjusted in the sudoers file:
# Set timeout to 5 minutes
Defaults timestamp_timeout=5
# Require password every time
Defaults timestamp_timeout=0
Command Aliases
For complex environments, sudoers supports command aliases to group related commands:
# Define command groupings
Cmnd_Alias SERVICES = /usr/bin/service, /bin/systemctl start, /bin/systemctl stop
Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/parted, /sbin/lvm
# Use the aliases
%operators ALL=NOPASSWD: SERVICES
%storage ALL=STORAGE
Exercise: Implementing a Secure Sudo Configuration
Let's practice creating a secure, role‐based sudo configuration:
- Create three user groups for different administrative roles:
- Create test users for each role:
- Edit the sudoers file with appropriate command restrictions:
- Test your configuration by switching to each user and attempting different commands:
sudo groupadd sysadmins
sudo groupadd webadmins
sudo groupadd dbadmins
sudo useradd -m -G sysadmins sysadmin1
sudo useradd -m -G webadmins webadmin1
sudo useradd -m -G dbadmins dbadmin1
sudo visudo
Add these lines:
# System administrators - full access
%sysadmins ALL=(ALL:ALL) ALL
# Web administrators - web service management only
Cmnd_Alias WEB_CMDS = /usr/bin/systemctl * apache2, /usr/bin/systemctl * nginx
%webadmins ALL=NOPASSWD: WEB_CMDS
# Database administrators - database service access only
Cmnd_Alias DB_CMDS = /usr/bin/systemctl * mysql, /usr/bin/systemctl * postgresql
%dbadmins ALL=NOPASSWD: DB_CMDS
sudo su - webadmin1
sudo systemctl status apache2 # Should work without password
sudo systemctl status mysql # Should be denied
Chapter 6: Common Pitfalls and Troubleshooting
Permission Denied Errors
When you encounter "Permission denied" errors, systematically check:
- File Ownership: Is the file owned by the expected user and group?
ls -l problematic_file
- Permission Bits: Does the file have the necessary permissions?
# Check if executable bit is set for scripts
chmod +x script.sh
# Check directory execute permission
chmod +x /path/to/directory
- Parent Directory Permissions: All directories in a path need execute permission:
namei -l /path/to/problematic/file
- SELinux or AppArmor: On systems with enhanced security, check if these are blocking access:
# For SELinux
ls -Z problematic_file
ausearch -m avc -ts recent
# For AppArmor
aa-status
Sticky Bit Misunderstandings
A common issue occurs in shared directories without the sticky bit, where users can delete each other's files:
# Proper configuration for shared directories
chmod 1777 /shared/directory
Inadvertent Permission Changes
Recursive permission changes can have unintended consequences:
# DANGEROUS - makes all files executable
chmod -R +x /some/directory
# BETTER - only make directories executable
find /some/directory -type d -exec chmod +x {} \;
# BETTER - only make script files executable
find /some/directory -name "*.sh" -exec chmod +x {} \;
Preserving Permissions When Copying
The cp
command by default doesn't preserve permissions:
# Preserve permissions, ownership, timestamps
cp -p source destination
# For directories, use recursive preserve
cp -rp source_dir destination_dir
Recovering from Permission Mistakes
If you accidentally change permissions system-wide:
- For system files, package managers can often help:
# Debian/Ubuntu
sudo apt-get --reinstall install package_name
# Red Hat/CentOS
sudo rpm --setperms package_name
- For user files, restore from backup if available.
Troubleshooting Special Permission Bits
Issues with setuid, setgid, or sticky bits can be hard to diagnose:
# Find setuid files (potential security issues)
find / -perm -4000 -type f -ls
# Find setgid files
find / -perm -2000 -type f -ls
Understanding umask Conflicts
If files are created with unexpected permissions, check the umask:
# View current umask in both symbolic and octal
umask
umask -S
Quick Reference Summary
User Management
# Create user
sudo useradd -m -s /bin/bash username
# Modify user
sudo usermod -aG groupname username
# Delete user
sudo userdel -r username
# Set/change password
sudo passwd username
Group Management
# Create group
sudo groupadd groupname
# Add user to group
sudo usermod -aG groupname username
sudo gpasswd -a username groupname
# Remove user from group
sudo gpasswd -d username groupname
File Permissions
# Change permissions
chmod 755 file # rwxr-xr-x
chmod u+x,go-w file # Add execute to owner, remove write from group/others
# Change ownership
chown user:group file
chgrp group file
# Special permissions
chmod 4755 file # setuid
chmod 2775 directory # setgid
chmod 1777 directory # sticky bit
ACLs
# View ACL
getfacl file
# Set ACL
setfacl -m u:user:rwx file
setfacl -m g:group:rx file
# Set default ACL (inheritance)
setfacl -d -m g:group:rwx directory
Sudo
# Edit sudoers
sudo visudo
# Run command as root
sudo command
# Run command as different user
sudo -u username command
# List sudo privileges
sudo -l
Key Files
/etc/passwd
: User account information/etc/shadow
: Encrypted passwords and aging/etc/group
: Group definitions/etc/sudoers
: Sudo configuration/etc/login.defs
: Default settings for user accounts
Conclusion
This module presented the fundamentals of Linux user and permission management, which are critical for maintaining security and proper resource access in multi-user systems. By understanding these concepts deeply, you can implement appropriate permission structures that balance security with usability in your Linux environments.