User Management Automation in Linux Using Bash Script

RMAG news

Scenario

As a SysOps engineer, you have been tasked to write a bash script that creates Users, Groups, and home directories with appropriate permissions for new employees in your company.

This article will walk you through writing the bash script to automate the process of creating users and groups in a Linux system.

Solution

Pre-requisites

An Ubuntu server
Basic Linux knowledge
User with sudo privileges

Script Overview

The script create_users.sh reads a text file containing usernames and group names, creates the specified users and groups, sets up home directories, generates random passwords for each user, and logs all actions. It is important to run the script with a user with sudo privileges as using your root user is not considered best practice. The script takes the input file as a command-line argument.

Breakdown of the create_users.sh script

Initial Checks

The script starts with some important checks:

# Function to check if user has sudo privileges
check_sudo() {
if sudo -n true 2>/dev/null; then
return
0
else
return
1
fi
}

# Check if user has sudo privileges
if [ ! check_sudo ]; then
echo “This script requires sudo privileges to run”
echo “Please run this script with sudo or as a user with sudo privileges”
exit 1
fi

# Check if input file is provided
if [ $# -eq 0 ]; then
echo “Please provide an input file”
echo “Usage: $0 <input-file>”
exit 1
fi

These checks ensure that the script is run with root privileges and that an input file is provided.

Directory and File Setup

input_file=$1
log_file=“/var/log/user_management.log”
password_csv=“/var/secure/user_passwords.csv”
password_file=“/var/secure/user_passwords.txt”
password_dir=“/var/secure”

#create the password directory if it doesn’t exist
if [ ! -d $password_dir ]; then
sudo mkdir $password_dir
fi

# Create log file, password csv, and password file and set permissions
sudo touch $log_file $password_csv $password_file
sudo chmod 600 $password_csv $password_file

The variables denoting the various files and directories are defined. The input_file containing the user and group names is assigned $1 denoting that it is the first command-line argument supplied.

The if statement checks whether the directory where the user passwords will be stored exists and creates the directory if it doesn’t .

The password files are given restrictive permissions (600) to ensure only the owner can read it.

Helper Functions

Two helper functions are defined:

# Function to log actions
log() {
echo $(date): $1 | sudo tee -a $log_file > /dev/null
}

# Function to generate random password
generate_password() {
openssl rand -base64 12
}

The log function appends timestamped messages to the log file, while generate_password creates a random 12-character password.

Reading the input file and Error Handling

The input file is read line-by-line using the while loop

#set line number to zero. to be used in error handling for invalid inputs
line_number=0

# Read input file line by line
while IFS=‘;’ read -r username groups; do
# Remove leading/trailing whitespace
username=$(echo $username | xargs)
groups=$(echo $groups | xargs)

#increment the line number after reading each line
line_number=$((line_number + 1))

# Check that the username and group is present
if [[ -z $username || -z $groups ]]; then
log “Error: Invalid input on line $line_number. Ensure Username and groups are provided”
echo “Error: Invalid input on line $line_number. Ensure Username and groups are provided”
continue
fi

# Check if user already exists
if id $username &>/dev/null; then
log “User $username already exists. Skipping.”
continue
fi

# Create user’s personal group
sudo groupadd $username
log “Created personal group $username

# Create user with home directory with appropriate ownership and permissions to allow only the user read, write, and execute
sudo useradd -m -g $username $username
sudo chmod 700 “/home/$username
sudo chown $username:$username “/home/$username
log “Created user $username with home directory”

# Set random password for user
password=$(generate_password)
echo $username:$password | sudo chpasswd
echo $username,$password | sudo tee -a $password_csv > /dev/null
echo $username,$password | sudo tee -a $password_file > /dev/null
log “Set password for user $username

# Add user to additional groups
IFS=‘,’ read -ra group_array <<< $groups
for group in ${group_array[@]}; do
group=$(echo $group | xargs)
# Create group if it doesn’t exist
if ! getent group $group &>/dev/null; then
sudo groupadd $group
log “Created group $group
fi
sudo usermod -a -G $group $username
log “Added user $username to group $group
done

done < $input_file

Before the loop, a variable called line_number is defined as 0. This variable will be used as a form of error handling to note any lines in the input file that does not have a username or a group defined.

IFS=’;’ sets the field separator to semicolon because the user and group names are separated by a semicolon. read -r username groups reads a line, splitting it into username and groups variables. Leading and trailing whitespaces are removed from username and groups using xargs.

line_number=$((line_number + 1)) increases by 1 at the start of each iteration in order to reference the current line number in the error logs and notifications.

The script then goes on to check if the username or groupname is present in the file and sends an error message to the log file and also notifies you on the command line about which line has the error. The script then goes on to the next line to run the script. It also checks whether or not a user has already been created and skips that user to the next.

After that it creates the user’s personal group, creates the user with a home directory and permissions set to 700 to only allow the owner access to it, and sets a random password for the user.

The script also handles multiple group assignments in the instance where a user is to join multiple groups. This is separated in the input file by a comma delimiter. The script loops through the array of groups and creates the groups if they don’t exist and adds the user to each specified group.

Usage

To use the script, run:

sudo chmod +x create_users.sh
./create_users.sh input_file.txt

Where input_file.txt contains lines in the format

username;group1,group2,group3

Security Considerations

The user running the script must have sudo privileges
Passwords are stored in a file with restricted permissions.
Random passwords are generated using OpenSSL for better security.

Conclusion

This bash script provides a powerful and flexible way to automate user and group creation in Linux systems. By handling various scenarios and providing detailed logging, it simplifies the process of managing multiple user accounts, making it an invaluable tool for system administrators.

This is a practical example of the skills developed at HNG, where participants learn to create efficient, scalable solutions for real-world problems.
Register for the HNG internship to develop these skills.