DEV Community

ibrahim
ibrahim

Posted on

Automating User and Group Management with a Bash Script

Automating User and Group Management with a Bash Script

inspired by HNG .

As a SysOps engineer, one of your routine tasks involves managing users and groups on a server. This can be time-consuming and prone to errors, especially when dealing with many users. Automation is the key to efficiency and reliability. This article will walk you through a Bash script that automates creating users and groups, setting up home directories with appropriate permissions, generating random passwords, and logging all actions.

This project was inspired by HNG internship 11, DevOps trcak of stage one.
visit HNG WEBSITE to learn more about the program

Overview

  1. Creates users and their groups.
  2. Adds users to additional specified groups.
  3. Sets up home directories with correct permissions and ownership.
  4. Generates random passwords for users.
  5. Logs all actions to /var/log/user_management.log. Stores generated passwords securely in /var/secure/user_passwords.txt

A bash script create_users.sh will be created:

The script, create_users.sh, reads a text file containing usernames and their associated groups. Each line in the file is formatted as user;groups, where groups are delimited by commas. The script performs the following tasks:

Example Input File

light;sudo,dev,www-data
idimma;sudo
mayowa;dev,www-data

Enter fullscreen mode Exit fullscreen mode

The script
Below is the complete script

#!/bin/bash

# Define log and password files
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

# Create log and password files if they don't exist
touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE

# Function to log messages
log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# Function to generate random password
generate_password() {
    tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}

# Check if the input file is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi

# Read the input file
INPUT_FILE=$1

# Check if the input file exists
if [ ! -f $INPUT_FILE ]; then
    echo "Input file not found!"
    exit 1
fi

while IFS=';' read -r username groups; do
    # Remove leading and trailing whitespaces
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)

    if id "$username" &>/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi

    # Create a personal group for the user
    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."

    # Create user and add to personal group
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."

    # Create additional groups if they don't exist and add user to groups
    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group >/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done

    # Set up home directory permissions
    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."

    # Generate random password and store it
    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" >> $PASSWORD_FILE
    log_message "Password set for user $username."

done < "$INPUT_FILE"

log_message "User and group creation process completed."

exit 0


Enter fullscreen mode Exit fullscreen mode

Detailed Explanation

Let's break down the script line by line to understand how it works.

1. Shebang and Definitions

#!/bin/bash
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

Enter fullscreen mode Exit fullscreen mode

The shebang (#!/bin/bash) indicates that the script should be executed using the Bash shell.
LOG_FILE and PASSWORD_FILE specify the paths for the log and password files.
2. Creating Log and Password Files

touch $LOG_FILE
mkdir -p /var/secure
touch $PASSWORD_FILE
Enter fullscreen mode Exit fullscreen mode

touch $LOG_FILE creates the log file if it doesn't exist.
mkdir -p /var/secure creates the directory /var/secure if it doesn't exist.
touch $PASSWORD_FILE creates the password file if it doesn't exist.

3. Logging Function

log_message() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

Enter fullscreen mode Exit fullscreen mode

'log_message' is a function that logs messages with a timestamp to both the log file and the terminal.

4. Password Generation Function

generate_password() {
    tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}
Enter fullscreen mode Exit fullscreen mode

This function generates a random 12-character alphanumeric password.
5. Input File Check

if [ $# -ne 1 ]; then
    echo "Usage: $0 <input_file>"
    exit 1
fi
INPUT_FILE=$1
if [ ! -f $INPUT_FILE ]; then
    echo "Input file not found!"
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

The script checks if exactly one argument (the input file) is provided and if the file exists.
6. Reading the Input File

while IFS=';' read -r username groups; do
    username=$(echo $username | xargs)
    groups=$(echo $groups | xargs)
Enter fullscreen mode Exit fullscreen mode

his loop reads the input file line by line, splitting each line into username and groups using ; as the delimiter.
xargs removes leading and trailing whitespaces.

7. Checking for Existing Users

    if id "$username" &>/dev/null; then
        log_message "User $username already exists. Skipping..."
        continue
    fi
Enter fullscreen mode Exit fullscreen mode

This checks if the user already exists and logs a message if they do, then skips to the next iteration
8. Creating Personal Group and User

    groupadd $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create group $username."
        continue
    fi
    log_message "Group $username created successfully."
    useradd -m -g $username -s /bin/bash $username
    if [ $? -ne 0 ]; then
        log_message "Failed to create user $username."
        continue
    fi
    log_message "User $username created successfully."
Enter fullscreen mode Exit fullscreen mode

groupadd $username creates a personal group for the user.
useradd -m -g $username -s /bin/bash $username creates the user with the specified home directory and shell.
9. Adding User to Additional Groups

    IFS=',' read -ra group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo $group | xargs)
        if [ -z "$group" ]; then
            continue
        fi
        if ! getent group $group >/dev/null; then
            groupadd $group
            if [ $? -ne 0 ]; then
                log_message "Failed to create group $group."
                continue
            fi
            log_message "Group $group created successfully."
        fi
        usermod -aG $group $username
        log_message "User $username added to group $group."
    done
Enter fullscreen mode Exit fullscreen mode

This splits the groups string into an array and iterates over each group, creating the group if it doesn't exist and adding the user to it.
10. Setting Up Home Directory Permissions

    chmod 700 /home/$username
    chown $username:$username /home/$username
    log_message "Permissions set for home directory of $username."
Enter fullscreen mode Exit fullscreen mode

chmod 700 /home/$username sets the permissions so that only the user can access their home directory.
chown $username:$username /home/$username sets the ownership of the home directory.
11. Generating and Storing Passwords

    password=$(generate_password)
    echo "$username:$password" | chpasswd
    echo "$username:$password" >> $PASSWORD_FILE
    log_message "Password set for user $username."
Enter fullscreen mode Exit fullscreen mode

This generates a random password for the user, sets it, and securely stores it
12. Completing the Process

done < "$INPUT_FILE"
log_message "User and group creation process completed."
exit
Enter fullscreen mode Exit fullscreen mode

Top comments (0)