DEV Community

Cover image for Automating User Management with Advanced Bashscript
Omolara Adeboye
Omolara Adeboye

Posted on

Automating User Management with Advanced Bashscript

As part of the requirements of my DevOps internship with HNG, I am required to create a bash script to automate user management.
Managing users in a Linux environment can be a repetitive and error-prone task if done manually, especially when dealing with a large number of users. To simplify this process, you can use a bash script to automate user creation, group assignment, and password management. Let's walk through a comprehensive bash script designed to streamline user management. This script reads a list of usernames and groups from a text file, creates users and groups accordingly, sets up home directories, generates random passwords, and logs all actions for audit purposes. You can find the complete script on my GitHub repository.

This bash script performs several key tasks:

  1. Ensures root privileges: The script checks if it is run as root.
  2. Logs actions: Logs important actions and errors for audit and debugging.
  3. Validates inputs: Ensures usernames and group names are valid.
  4. Creates users and groups: Adds new users and groups as specified in an input file.
  5. Sets passwords: Generates and sets random passwords for new users.
  6. Configures home directories: Sets appropriate permissions for user home directories.

Detailed Explanation of script.

  • Script Header and Logging The script begins by defining a logging function to record actions and errors to a log file.
#!/usr/bin/bash

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
Enter fullscreen mode Exit fullscreen mode
  • Password Generation A function to generate random passwords is defined, which uses /dev/urandom for secure random number generation.
generate_password() {
    local password_length=12
    tr -dc A-Za-z0-9 </dev/urandom | head -c $password_length
}
Enter fullscreen mode Exit fullscreen mode
  • Ensuring Root Privileges The script checks if it is run with root privileges. If not, it logs an error and exits. Root users have user id 0.
if [ "$(id -u)" -ne 0 ]; then
    echo "This script must be run as root or with sudo privileges" >&2
    log "Script not run as root or with sudo privileges"
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode
  • File Paths and Initial Checks The script sets file paths for the user input file, log file, and password storage. It also verifies the existence of these files.
USER_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"

if [ -z "$USER_FILE" ]; then
    echo "Usage: $0 <name-of-text-file>"
    log "No user file provided. Usage: $0 <name-of-text-file>"
    exit 1
fi

if [ ! -f "$USER_FILE" ]; then
    echo "Input file not found"
    log "Input file '$USER_FILE' not found"
    exit 1
fi

if [ ! -f "$LOG_FILE" ]; then
    touch "$LOG_FILE"
    chmod 0600 "$LOG_FILE"
    log "Log file created: $LOG_FILE"
fi

if [ ! -f "$PASSWORD_FILE" ]; then
    mkdir -p /var/secure
    touch "$PASSWORD_FILE"
    chmod 0600 "$PASSWORD_FILE"
    log "Password file created: $PASSWORD_FILE"
fi
Enter fullscreen mode Exit fullscreen mode
  • Input Validation The script validates the usernames and group names using regular expressions to ensure they contain only alphanumeric characters, hyphens, and underscores.
validate_username() {
    if [[ ! "$1" =~ ^[a-zA-Z0-9_-]+$ ]]; then
        return 1
    fi
    return 0
}

validate_groups() {
    IFS=',' read -ra group_list <<< "$1"
    for group in "${group_list[@]}"; do
        if [[ ! "$group" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            return 1
        fi
    done
    return 0
}

Enter fullscreen mode Exit fullscreen mode
  • User and Group Creation The script reads the user file line by line, creating users and their groups as necessary. It also ensures that each user has a personal group and sets up the home directory with appropriate permissions.
while IFS=';' read -r username groups; do
    username=$(echo "$username" | xargs)
    groups=$(echo "$groups" | xargs)

    if [ -z "$username" ] || [ -z "$groups" ]; then
        log "Invalid line format in user file: '$username;$groups'"
        user_creation_failed=true
        continue
    fi

    if ! validate_username "$username"; then
        log "Invalid username format: '$username'"
        user_creation_failed=true
        continue
    fi

    if ! validate_groups "$groups"; then
        log "Invalid group format: '$groups'"
        group_creation_failed=true
        continue
    fi

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

    all_users_exist=false

    if ! getent group "$username" > /dev/null; then
        if groupadd "$username"; then
            log "Group $username created."
        else
            log "Failed to create group $username."
            group_creation_failed=true
            continue
        fi
    fi

    IFS=',' read -ra group_list <<< "$groups"
    for group in "${group_list[@]}"; do
        if ! getent group "$group" > /dev/null; then
            if groupadd "$group"; then
                log "Group $group created."
            else
                log "Failed to create group $group."
                group_creation_failed=true
            fi
        fi
    done
    unset IFS

    if useradd -m -g "$username" -G "$groups" "$username"; then
        log "User $username created and added to groups $groups"
        users_created=true
        any_users_created=true
    else
        log "Failed to create user $username"
        user_creation_failed=true
        continue
    fi

    password=$(generate_password)
    log "Generated password for $username"

    if echo "$username:$password" | chpasswd; then
        echo "$username,$password" >> "$PASSWORD_FILE"
        log "Password set for $username and stored securely"
    else
        log "Failed to set password for $username"
        password_setting_failed=true
        continue
    fi

    if chown "$username:$username" "/home/$username" && chmod 700 "/home/$username"; then
        log "Home directory for $username set up with appropriate permissions."
    else
        log "Failed to set up home directory for $username"
        home_directory_setup_failed=true
    fi

done < "$USER_FILE"
Enter fullscreen mode Exit fullscreen mode
  • Summary and Exit After processing all lines, the script logs a summary of the actions taken and exits.
log "User creation script run completed."

if [ "$any_users_created" = true ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - User creation script completed successfully."
elif [ "$all_users_exist" = true ]; then
    echo "Users already exist. Nothing left to do"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - No users were created successfully. Check log file."
    log "No users were created successfully. Please check the input file format: username;group1,group2,group3."
fi

[ "$user_creation_failed" = true ] && echo "Users creation incomplete." && log "Some users were not created due to errors. Check file format"
[ "$password_setting_failed" = true ] && echo "Users' passwords creation incomplete." && log "Some users' passwords were not set due to errors. Check file format"
[ "$group_creation_failed" = true ] && echo "Groups creation incomplete." && log "Some groups were not created due to errors. Check file format"
[ "$home_directory_setup_failed" = true ] && echo "Home directories creation incomplete." && log "Some home directories were not set up due to errors."

exit 0

Enter fullscreen mode Exit fullscreen mode

Conclusion
This script offers a reliable way to automate processes related to user management, lowering the possibility of mistakes and saving important administrative time. System administrators can create user accounts in a consistent and safe manner with this script, which also manages passwords and group assignments. Detailed logs are kept for accountability and debugging purposes. To get real-time internship experience, sign up with HNG

Top comments (0)