Automating User and Group Management with a Bash Script

RMAG news

I recently got accepted into the famous(https://hng.tech/hire). It is a very intense hands-on 8 week program where your skills will be tested and legends are made. As a requirement for proceeding to the next stage, interns on every track are given tasks they are expected to execute, document and write an article to pass. this blog post is such.
I would recommend anyone willing to upskill and gain employable skill to enroll into the program. (https://hng.tech/premium) https://hng.tech/internship

Hey there, fellow Sysadmin! We can all agree that managing users and groups is a bit difficult and time consuming. Trust me, I’ve been there. Picture this: it’s 2 AM, you’re knee-deep in energy drink cans, trying to add the 50th user to your system. Your eyes are crossing, and you’re pretty sure you just gave someone access to critical codes by mistake. We’ve all been there, right? Well, chin up, because I’m about to introduce you to your new best friend: a Bash script that’ll make user management a breeze!

Script Breakdown

declare -a users
declare -a groups

The script starts with a shebang (#!/bin/bash) to specify the interpreter. It then declares two arrays, users and groups, to hold user and group data.

Argument Check

if [[ $# -ne 1 ]]; then
echo “Usage: $0 <input_file>”
exit 1
fi

input_file=$1
echo “Reading input file: $input_file

The script checks and confirm that the script is run is run with exactly one argument (the input file). Otherwise, the exit code 1 is triggered which which indicates failure. The input file is then assigned to the variable input_file.

Reading the Input File

function read_input() {
local file=$1

if [[ ! -f $file ]]; then
echo “File not found!”
return 1
fi

while IFS= read -r line;
do
user=$(echo $line | cut -d‘;’ -f1)
groups_list=$(echo $line | cut -d‘;’ -f2 | tr -d ‘[:space:]’)
users+=($user)
groups+=($groups_list)
done < $file
}

read_input $input_file

The read_input function reads the input file line by line. Each line read is expected to contain a username and a comma-separated(delimiter) list of groups, separated by a semicolon. The function splits each line into a user and their groups, then adds these to the respective arrays.

Verification of Data

echo “Users: ${users[@]}
echo “Groups: ${groups[@]}

The script prints the users and groups arrays to verify the data read from the input file.

Log and Password Files Setup

log_file=“/var/log/user_management.log”
password_file=“/var/secure/user_passwords.txt”

touch $log_file
mkdir -p $(dirname $password_file)
touch $password_file

The script sets up paths for a log file and a password file. It creates these files and their parent directories if they do not exist.

User and Group Management

for (( i = 0; i < ${#users[@]}; i++ )); do
user=${users[$i]}
user_groups=${groups[$i]}
if id $user &>/dev/null; then
echo “User $user already exists, Skipped” | tee -a $log_file
else
# Create user
useradd -m -s /bin/bash $user
if [[ $? -ne 0 ]]; then
echo “Failed to create user $user | tee -a $log_file
exit 1
fi
echo “User $user created” | tee -a $log_file

password=$(openssl rand -base64 50 | tr -dc ‘A-Za-z0-9!?%=’ | head -c 10)
echo $user:$password | chpasswd
if [[ $? -ne 0 ]]; then
echo “Failed to set password for $user | tee -a $log_file
exit 1
fi
echo “Password for $user set” | tee -a $log_file
echo $user:$password >> $password_file

if grep -q “^$user:” /etc/group; then
echo “Personal group $user already exists” | tee -a $log_file
else
echo “Personal group $user does not exist, creating $user | tee -a $log_file
groupadd $user
if [[ $? -ne 0 ]]; then
echo “Failed to create personal group $user | tee -a $log_file
exit 1
fi
fi

usermod -aG $user $user
if [[ $? -ne 0 ]]; then
echo “Failed to add $user to $user group” | tee -a $log_file
exit 1
fi
echo “Added $user to $user group” | tee -a $log_file

for group in $(echo $user_groups | tr ‘,’ ‘n’); do
if
grep -q “^$group:” /etc/group; then
echo “Group $group already exists” | tee -a $log_file
else
echo “Group $group does not exist, creating $group | tee -a $log_file
groupadd $group
if [[ $? -ne 0 ]]; then
echo “Failed to create group $group | tee -a $log_file
exit 1
fi
fi

usermod -aG $group $user
if [[ $? -ne 0 ]]; then
echo “Failed to add $user to $group group” | tee -a $log_file
exit 1
fi
echo “Added $user to $group group” | tee -a $log_file
done
fi
done

The main loop iterates over the users and groups arrays. For each user:

If the user already exists, it logs and skips to the next user.
If the user does not exist, it creates the user, sets a password, logs the details, and creates a personal group if it does not exist.
The user is added to their personal group and any additional groups specified.

This script provides a comprehensive solution for automating the management of users and groups, ensuring consistent and secure setups based on predefined input data.