Creating Users and Groups with a Bash Script

Introduction

As part of the HNG Internship, a task was assigned to create a bash script to automate creating users and groups on a Linux system. This article will walk you through the process of writing the create_users.sh script, explaining each step, and demonstrating how to use it.

The script reads a text file containing employee usernames and group names, creates users and groups as specified, sets up home directories with appropriate permissions, generates random user passwords, and logs all actions.

Prerequisites

  • A Linux machine (preferably Ubuntu).

  • Root access to execute administrative commands.

  • Basic knowledge of shell scripting.

Script Overview

The create_users.sh script performs the following tasks:

  1. Check if the script is run as root.

  2. Reads a text file containing usernames and group names.

  3. Creates users and groups as specified in the text file.

  4. Generates random passwords for the users.

  5. Logs all actions to /var/log/user_management.log.

  6. Stores the generated passwords securely in /var/secure/user_passwords.csv.

Script Details

#!/bin/bash

# Ensure the script is run as root
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root" 
    exit 1
fi

# Check if the input file is provided
if [ -z "$1" ]; then
    echo "Usage: bash create_users.sh <name-of-text-file>"
    exit 1
fi

# Log file and secure password storage
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Create necessary directories and set permissions
mkdir -p /var/secure
chmod 700 /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
touch $LOG_FILE

# Log function
log_action() {
    echo "$(date +"%Y-%m-%d %T") - $1" >> $LOG_FILE
}

# Process the input file
while IFS=';' read -r user groups; do
    # Remove leading/trailing whitespace
    user=$(echo "$user" | xargs)
    groups=$(echo "$groups" | xargs)

    # Skip empty lines
    if [ -z "$user" ]; then
        continue
    fi

    # Check if the user already exists
    if id "$user" &>/dev/null; then
        log_action "User $user already exists"
        continue
    fi

    # Create the user's personal group
    if ! getent group "$user" &>/dev/null; then
        groupadd "$user"
        log_action "Personal group $user created"
    fi

    # Create the user and add to their personal group
    useradd -m -s /bin/bash -g "$user" "$user"
    if [ $? -eq 0 ]; then
        log_action "User $user created and added to personal group $user"
    else
        log_action "Failed to create user $user"
        continue
    fi

    # Generate a random password
    password=$(openssl rand -base64 12)
    echo "$user:$password" | chpasswd
    if [ $? -eq 0 ]; then
        log_action "Password set for user $user"
    else
        log_action "Failed to set password for user $user"
    fi

    # Add the user to specified groups
    IFS=',' read -r -a group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo "$group" | xargs)
        # Check if the group exists, create if it does not
        if [ -n "$group" ]; then
            if ! getent group "$group" &>/dev/null; then
                groupadd "$group"
                if [ $? -eq 0 ]; then
                    log_action "Group $group created"
                else
                    log_action "Failed to create group $group"
                fi
            fi
            usermod -aG "$group" "$user"
            if [ $? -eq 0 ]; then
                log_action "User $user added to group $group"
            else
                log_action "Failed to add user $user to group $group"
            fi
        fi
    done

    # Securely store the password
    echo "$user,$password" >> $PASSWORD_FILE

done < "$1"

echo "User creation process completed. Check $LOG_FILE for details."

Script Explanation

  1. Checking for Root Privileges: The script checks if it's being run as the root user. If not, it exits with a message.
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root" 
    exit 1
fi
  1. Checking for Input File: The script checks if the input file is provided as an argument. If not, it exits with usage instructions.
if [ -z "$1" ]; then
    echo "Usage: bash create_users.sh <name-of-text-file>"
    exit 1
fi
  1. Setting Up Log and Password Files: The script sets up directories and files for logging and storing passwords securely.
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

mkdir -p /var/secure
chmod 700 /var/secure
touch $PASSWORD_FILE
chmod 600 $PASSWORD_FILE
touch $LOG_FILE
  1. Logging Function: A function to log actions to the log file.
log_action() {
    echo "$(date +"%Y-%m-%d %T") - $1" >> $LOG_FILE
}
  1. Processing the Input File: The script reads the input file line by line, creating users and adding them to groups as specified.
while IFS=';' read -r user groups; do
    user=$(echo "$user" | xargs)
    groups=$(echo "$groups" | xargs)

    if [ -z "$user" ]; then
        continue
    fi

    if id "$user" &>/dev/null; then
        log_action "User $user already exists"
        continue
    fi

    if ! getent group "$user" &>/dev/null; then
        groupadd "$user"
        log_action "Personal group $user created"
    fi

    useradd -m -s /bin/bash -g "$user" "$user"
    if [ $? -eq 0 ]; then
        log_action "User $user created and added to personal group $user"
    else
        log_action "Failed to create user $user"
        continue
    fi

    password=$(openssl rand -base64 12)
    echo "$user:$password" | chpasswd
    if [ $? -eq 0 ]; then
        log_action "Password set for user $user"
    else
        log_action "Failed to set password for user $user"
    fi

    IFS=',' read -r -a group_array <<< "$groups"
    for group in "${group_array[@]}"; do
        group=$(echo "$group" | xargs)
        if [ -n "$group" ]; then
            if ! getent group "$group" &>/dev/null; then
                groupadd "$group"
                if [ $? -eq 0 ]; then
                    log_action "Group $group created"
                else
                    log_action "Failed to create group $group"
                fi
            fi
            usermod -aG "$group" "$user"
            if [ $? -eq 0 ]; then
                log_action "User $user added to group $group"
            else
                log_action "Failed to add user $user to group $group"
            fi
        fi
    done

    echo "$user,$password" >> $PASSWORD_FILE

done < "$1"
  1. Completion Message: The script prints a message upon completion, directing the user to check the log file for details.
echo "User creation process completed. Check $LOG_FILE for details."

Usage

  1. Ensure the script has executable permissions:
chmod +x create_users.sh
  1. Run the script with sudo to ensure it's executed with root privileges:
sudo ./create_users.sh users.txt

Example Input File (users.txt)

Ensure that the input file users.txt is correctly formatted without any leading or trailing whitespace:

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

Conclusion

This script automates creating users and groups, setting passwords, and logging actions on a Linux system. It is an essential tool for system administrators to manage user accounts efficiently.

To learn more about the HNG Internship program, visit the HNG Internship and HNG Hire pages. These resources provide valuable insights and opportunities for aspiring developers and engineers.

This task has been an enriching experience, enhancing my skills

0
Subscribe to my newsletter

Read articles from David Yaro Gambo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

David Yaro Gambo
David Yaro Gambo