DEV Community

Bright Bassey
Bright Bassey

Posted on

Writing a User Creation Script in Linux Bash

If you've never written a bash script before, today you'll be seeing how to write one.

Bash scripts are used to automate linux processes. Knowing how to write and implement them will serve you well in your devops journey.

In this article, I'll be showing you how I wrote a bash script that automates the process of creating users, assigning groups, setting up home directories, and managing passwords on a Unix-like system. The script also logs actions and handles errors efficiently.

Overview of the Script

Prerequisites

  1. You must have a functional ubuntu terminal that you can test the script(create_users.sh) from.

  2. The script must be run with root privileges to perform administrative tasks.

  3. The input file must contain usernames and groups in the format: username;group1,group2.

#!/bin/bash

# Check if the script is run as root, if not re-execute it with sudo
if [ "$EUID" -ne 0 ]; then
    echo "This script must be run as root. Re-executing with sudo..."
    sudo bash "$0" "$@"
    exit $?
fi


# Define paths to log and password file 
LOGGER="var/log/user_management.log"
PASSWORD_FILE="var/secure/user_passwords.txt"


# Ensure directories and files exist with necessary permissions
sudo mkdir -p var/log
sudo mkdir -p var/secure
sudo chmod 700 /var/secure
sudo touch $LOGGER
sudo chmod 600 /var/secure/user_passwords.txt
sudo chown root:root /var/secure/user_passwords.txt
sudo touch $PASSWORD_FILE

# Function for generating logs
logging_function(){
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> $LOGGER
}

# Function for generating random passwords
password_generator(){
    tr -dc A-Za-z0-9 </dev/urandom | head -c 12
}

# Check if a user text file was provided
if [ -z "$1" ];then 
  echo "Usage: $0 <user_file>"
  exit 1
fi

# Read the file line by line and loop through
while IFS=';' read -r user groups || [ -n "$user" ]; do
  # Trimming whitespace
  user=$(echo "$user" | xargs)
  groups=$(echo "$groups" | xargs)

  # Skip empty lines
  [ -z "$user" ] && continue

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

  # Create user and generate password
  password=$(password_generator)
  sudo useradd -m -s /bin/bash "$user"
    if [ $? -ne 0 ]; then
        log_action "Failed to create user $user"
        continue
    fi
  echo "$user:password" | chpasswd

  logging_function "User $user created with home directory"

  # Create personal group and assign to user
  sudo usermod -aG "$user" "$user"

  # Assign additional groups to user
  IFS=',' read -ra group_array <<< "$groups"
  for group in "${group_array[@]}"; do
    group=$(echo $group | xargs)
    if [ -n "$group" ]; then
        if ! getent group "$group" > /dev/null 2>&1; then
            groupadd "$group"
            logging_function "Group $group created"
        fi
        usermod -aG "$group" "$user"
        logging_function "User $user added to group $group"
    fi
    done

    # Set home directory permissions
    sudo chmod 700 /home/$user
    sudo chown $user:$user /home/$user

    # Store password securely
    echo "$user, $password" >> $PASSWORD_FILE
    logging_function "password for $user stored"
done < "$1"

#Give a success response
echo "User creation complete. Check $LOGGER"

Enter fullscreen mode Exit fullscreen mode

This is the full script. I named it create_users.sh

Script Breakdown
Let's dive into the script line-by-line.

Self-Elevation Check

#!/bin/bash

Enter fullscreen mode Exit fullscreen mode

This shebang line indicates that the script should be run using the bash shell.

if [ "$EUID" -ne 0 ]; then
    echo "This script must be run as root. Re-executing with sudo..."
    sudo bash "$0" "$@"
    exit $?
fi
Enter fullscreen mode Exit fullscreen mode

This block checks if the script is being run as the root user. If not, it re-executes itself with sudo to gain root privileges and exits with the same status code as the sudo command. Cool, right?

Define Log and Password File Paths

LOGGER="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.txt"
Enter fullscreen mode Exit fullscreen mode

These lines define the paths for the log file and the password file where actions and generated passwords will be stored.

Ensure Directories and Files Exist

sudo mkdir -p /var/log
sudo mkdir -p /var/secure
sudo chmod 700 /var/secure
Enter fullscreen mode Exit fullscreen mode

This section ensures that the required directories exist and sets appropriate permissions. The -p option in mkdir creates the directory only if it doesn't exist.

sudo touch $LOGGER
sudo touch $PASSWORD_FILE
sudo chmod 600 $PASSWORD_FILE
sudo chown root:root $PASSWORD_FILE
Enter fullscreen mode Exit fullscreen mode

These commands create the log and password files if they don't exist and set their permissions to ensure only the root user can read and write them.

Logging Function

logging_function() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> $LOGGER
}
Enter fullscreen mode Exit fullscreen mode

This function logs a message to the log file with a timestamp. It appends the message ($1) to the log file.

Password Generator

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

This function generates a random 12-character password using /dev/urandom for randomness.

Check for User File

if [ -z "$1" ]; then 
    echo "Usage: $0 <user_file>"
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

This block checks if an input file was provided as an argument. If not, it displays usage information and exits.

Read File Line by Line

while IFS=';' read -r user groups || [ -n "$user" ]; do

Enter fullscreen mode Exit fullscreen mode

This while loop reads the input file line-by-line. IFS=';' sets the internal field separator to ;, and read -r user groups reads each line into the user and groups variables. The || [ -n "$user" ] part ensures the loop processes the last line even if it doesn't end with a newline.

Trim Whitespace

user=$(echo "$user" | xargs)
groups=$(echo "$groups" | xargs)

Enter fullscreen mode Exit fullscreen mode

These lines remove leading and trailing whitespace from the user and groups variables using xargs.

Skip Empty Lines

[ -z "$user" ] && continue

Enter fullscreen mode Exit fullscreen mode

This condition skips empty lines by continuing to the next iteration of the loop if user is empty.

Check if User Exists

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

This block checks if the user already exists using the id command. If the user exists, it logs the information and skips to the next iteration.

Create User and Set Password

password=$(password_generator)
sudo useradd -m -s /bin/bash "$user"
if [ $? -ne 0 ]; then
    logging_function "Failed to create user $user"
    continue
fi
echo "$user:$password" | sudo chpasswd

Enter fullscreen mode Exit fullscreen mode

Here, a random password is generated, and the useradd command creates a new user with a home directory and sets the shell to /bin/bash. If useradd fails, it logs the failure and continues to the next iteration. The chpasswd command sets the user's password.

Log User Creation

logging_function "User $user created with home directory"

Enter fullscreen mode Exit fullscreen mode

This line logs the successful creation of the user and their home directory.

Create Personal Group

sudo usermod -aG "$user" "$user"

Enter fullscreen mode Exit fullscreen mode

This command adds the user to their personal group, which is named the same as the username.

Assign Additional Groups

IFS=',' read -ra group_array <<< "$groups"
for group in "${group_array[@]}"; do
    group=$(echo $group | xargs)
    if [ -n "$group" ]; then
        if ! getent group "$group" > /dev/null 2>&1; then
            sudo groupadd "$group"
            logging_function "Group $group created"
        fi
        sudo usermod -aG "$group" "$user"
        logging_function "User $user added to group $group"
    fi
done
Enter fullscreen mode Exit fullscreen mode

This block assigns additional groups to the user. It splits the groups variable into an array using IFS=',', and then iterates over each group. If the group doesn't exist, it is created. The user is then added to each group, and the actions are logged.

Set Home Directory Permissions

sudo chmod 700 /home/$user
sudo chown $user:$user /home/$user
Enter fullscreen mode Exit fullscreen mode

These commands set the permissions and ownership of the user's home directory to ensure it's secure and owned by the user.

Store Password Securely

echo "$user, $password" >> $PASSWORD_FILE
logging_function "Password for $user stored"
Enter fullscreen mode Exit fullscreen mode

The user's password is stored in the password file, and the action is logged.

End of Script

done < "$1"

echo "User creation complete. Check $LOGGER"
Enter fullscreen mode Exit fullscreen mode

The done < "$1" line marks the end of the while loop, which reads from the input file. The final echo statement informs the user that the process is complete and advises checking the log file for details.

Conclusion
This script provides a comprehensive solution for user management in a Unix-like system. It ensures that users are created with secure passwords, assigned to appropriate groups, and have their actions logged for auditing purposes. By understanding each line of the script, administrators can modify and extend it to fit their specific needs.

Learn More
For more information on automation scripts and enhancing your technical skills, consider exploring the HNG Internship program. If you are looking to hire skilled developers, visit HNG Hire to find top talent.

Top comments (0)