Automating User and Group Management with a Bash Script.
Thelma Ocansey
Posted on July 3, 2024
As a SysOps engineer, one of your responsibilities is to streamline and automate the process of user management. With the recent influx of new developers at our company, managing user accounts and their group memberships efficiently is crucial. In this article, I’ll walk you through a Bash script that automates the creation of users, assigns them to groups, and sets up their home directories with proper permissions. Additionally, the script logs all actions and securely stores the generated passwords.
This task is part of the HNG Internship, a fantastic program that helps interns gain real-world experience. You can learn more about the program at the HNG Internship website or consider hiring some of their talented interns through the HNG Hire page.
The source code can be found on my https://github.com/nthelma30/Create_User.sh.git
The Task
We need to create a Bash script called create_users.sh
that:
- Reads a text file with usernames and groups.
- Creates users and groups as specified.
- Sets up home directories with appropriate permissions.
- Generates random passwords for the users.
- Logs all actions to
/var/log/user_management.log
. - Stores the generated passwords securely in
/var/secure/user_passwords.csv
.
Input File Format
The input file should contain lines formatted as user;groups
, where user
is the username, and groups
is a comma-separated list of group names. For example:
light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data
The Script
Here is the create_users.sh
script:
#!/bin/bash
# Check if the input file exists
if [ ! -f "$1" ]; then
echo "Error: Input file not found."
exit 1
fi
# Ensure log and secure directories are initialized once
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"
# Initialize log file
if [ ! -f "$LOG_FILE" ]; then
sudo touch "$LOG_FILE"
sudo chown root:root "$LOG_FILE"
sudo chmod 600 "$LOG_FILE"
fi
# Initialize password file
if [ ! -f "$PASSWORD_FILE" ]; then
sudo mkdir -p /var/secure
sudo touch "$PASSWORD_FILE"
sudo chown root:root "$PASSWORD_FILE"
sudo chmod 600 "$PASSWORD_FILE"
fi
# Redirect stdout and stderr to the log file
exec > >(sudo tee -a "$LOG_FILE") 2>&1
# Function to check if user exists
user_exists() {
id "$1" &>/dev/null
}
# Function to check if a group exists
group_exists() {
getent group "$1" > /dev/null 2>&1
}
# Function to check if a user is in a group
user_in_group() {
id -nG "$1" | grep -qw "$2"
}
# Read each line from the input file
while IFS=';' read -r username groups; do
# Trim whitespace
username=$(echo "$username" | tr -d '[:space:]')
groups=$(echo "$groups" | tr -d '[:space:]')
# Check if the user already exists
if user_exists "$username"; then
echo "User $username already exists."
else
# Create user
sudo useradd -m "$username"
# Generate random password
password=$(openssl rand -base64 12)
# Set password for user
echo "$username:$password" | sudo chpasswd
# Log actions
echo "User $username created. Password: $password"
# Store passwords securely
echo "$username,$password" | sudo tee -a "$PASSWORD_FILE"
fi
# Ensure the user's home directory and personal group exist
sudo mkdir -p "/home/$username"
sudo chown "$username:$username" "/home/$username"
# Ensure the user's personal group exists
if ! group_exists "$username"; then
sudo groupadd "$username"
fi
sudo usermod -aG "$username" "$username"
# Split the groups string into an array
IFS=',' read -ra group_array <<< "$groups"
# Check each group
for group in "${group_array[@]}"; do
if [[ -n "$group" ]]; then
if group_exists "$group"; then
echo "Group $group exists."
else
echo "Group $group does not exist. Creating group $group."
sudo groupadd "$group"
fi
if user_in_group "$username" "$group"; then
echo "User $username is already in group $group."
else
echo "Adding user $username to group $group."
sudo usermod -aG "$group" "$username"
fi
fi
done
done < "$1"
Explanation
- Input Validation: The script starts by checking if the input file exists. If not, it exits with an error message.
-
Log and Password Files: It ensures that the log file (
/var/log/user_management.log
) and the password file (/var/secure/user_passwords.csv
) are created with appropriate permissions. -
Functions:
-
user_exists()
: Checks if a user already exists. -
group_exists()
: Checks if a group already exists. -
user_in_group()
: Checks if a user is a member of a group.
-
- Processing the Input File: The script reads each line from the input file, trims whitespace, and processes the usernames and groups.
-
User Creation: It creates the user if they do not already exist, generates a random password using
openssl rand -base64 12
, and sets the password. - Home Directory and Personal Group: It ensures the user's home directory and personal group (named the same as the username) exist and sets the appropriate permissions.
- Group Membership: It processes each group, creating it if it doesn’t exist, and adds the user to the group.
Conclusion
This script provides an efficient way to manage user accounts and their group memberships, ensuring that all actions are logged and passwords are stored securely. By automating these tasks, SysOps engineers can save time and reduce the risk of errors.
For more information about the HNG Internship and its benefits, visit the HNG Internship website or consider hiring from their pool of talented interns through the HNG Hire page.
--
This article can be adapted to your specific requirements or company guidelines.
Written by Thelma Ocansey
Posted on July 3, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.