DEV Community

Cover image for Linux Users and Groups Management using Bash Script
Mayowa Fajube
Mayowa Fajube

Posted on

Linux Users and Groups Management using Bash Script

INTRODUCTION

User and group management is a fundamental task for any Linux SysOps engineer. Handling these tasks manually can be error-prone and time-consuming, especially in larger environments. It is critical when dealing with multiple users and groups to ensure each user has the correct permissions and access within the system. To streamline this process, I have developed a Bash script, create_users.sh, which automates the creation of users and groups based on a supplied file. This script not only creates users and their corresponding home directories but also ensures they are assigned to the correct groups and generates secure random passwords for them. Additionally, the script logs all actions for auditing purposes.

Script Overview

The create_users.sh script automates the following tasks:

  • Reading user and group information from a file.
  • Creating users and their personal groups.
  • Setting up home directories with proper permissions.
  • Generating random passwords for each user.
  • Logging all actions to a log file.
  • Storing generated passwords securely in a CSV file.

Let's break down the script step by step to understand its functionality.

0. Shebang: Specifying the Interpreter

The script begins with a shebang line:
#!/bin/bash
The importance of this line is;

  • Interpreter Directive: It specifies the path to the interpreter that should be used to execute the script. In this case, #!/bin/bash tells the system to use the Bash shell to run the script. The interpreter is responsible for parsing and executing the commands within the script.
  • Executable Scripts: When the shebang is present, the script can be executed directly as a standalone program. This means the script can be run by simply typing its name, provided it has execute permissions. Without the shebang, you would need to explicitly invoke the interpreter and pass the script as an argument (e.g., bash create_users.sh).

1. Checking Script Arguments

The script starts by verifying if a file name argument is provided alongside the bash script during runtime. This file should contain the username and group information in a specific format.

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

If the argument is missing, the script exits with a usage message, ensuring the user knows how to correctly run the script.

2. Assigning user file argument supplied to a variable

USER_FILE="$1"
Enter fullscreen mode Exit fullscreen mode

USER_FILE is a variable that I defined within the script. By assigning USER_FILE="$1", I am storing the value of the first argument passed to the script in this variable which is then used throughout the script to refer to the file containing the user and group information. By assigning the argument to a variable, the script can easily reference the input file without directly using $1 multiple times, making the code more readable and maintainable.

3. Checking Input File Existence

The below command checks if the specified user file exists. If not, it exits with an error message.

if [ ! -f "$USER_FILE" ]; then
    echo "Error: File $USER_FILE does not exist."
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

This is to prevent the script from running without the necessary input data, avoiding potential errors.

4. Defining File Paths for logs and passwords

LOG_FILE="/var/log/user_management.log"
PASSWORD_DIR="/var/secure"
PASSWORD_FILE="$PASSWORD_DIR/user_passwords.csv"
Enter fullscreen mode Exit fullscreen mode

These assigned paths to variables LOG_FILE and PASSWORD_FILE help in organizing the script's output and ensuring logs and passwords are stored securely.

5. Ensuring Log and Password Files Exist

touch $LOG_FILE

if [ ! -d "$PASSWORD_DIR" ]; then
    mkdir -p "$PASSWORD_DIR"
    chmod 700 "$PASSWORD_DIR"
fi

if [ ! -f "$PASSWORD_FILE" ]; then
    echo "username,password" > $PASSWORD_FILE
fi
chmod 600 $PASSWORD_FILE
Enter fullscreen mode Exit fullscreen mode

This section of the script ensures that the log file and password directory exist, creating them if necessary. It also sets appropriate permissions for security. Creating the password directory with chmod 700 and the password file with chmod 600, ensures that only the root user can read and write these files, protecting sensitive information.

6. Logging Function

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

This simple logging function records actions with timestamps, helping in troubleshooting and auditing. It appends log entries to the log file, providing a history of all script actions.

7. Reading and Processing the Input File

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

The script reads the input file line by line at this stage, processing each entry to extract the usernames and groups. It removes any leading or trailing whitespace from the entries.This ensures that any extraneous spaces in the input file do not cause issues.

8. Checking and Creating Users and Groups

    if id -u "$username" >/dev/null 2>&1; then
        log_action "User $username already exists."
        continue
    fi
Enter fullscreen mode Exit fullscreen mode

For each user, the script checks if the user already exists. If the user exists, it logs this information and skips it to the next user. If the user does not exist, the script creates a personal group for the user.

    if ! getent group "$username" >/dev/null 2>&1; then
        groupadd "$username"
    fi
Enter fullscreen mode Exit fullscreen mode

It then creates the user with their personal group and sets up their home directory with the correct permissions.

    useradd -m -g "$username" -s /bin/bash "$username"
    chmod 700 /home/"$username"
    chown "$username:$username" /home/"$username"
Enter fullscreen mode Exit fullscreen mode

This ensures that the user's home directory is private and owned by the user.

9. Generating and Setting Passwords

    password=$(openssl rand -base64 12)
    echo "$username:$password" | chpasswd
    echo "$username,$password" >> $PASSWORD_FILE
Enter fullscreen mode Exit fullscreen mode

The script section generates a random password using openssl, sets this password for the user, and logs it securely in the password file. Using openssl rand -base64 12 generates a secure 12-character password for each user.

10. Assigning Additional Groups

    if [ -n "$groups" ]; then
        IFS=',' read -r -a group_array <<< "$groups"
        for group in "${group_array[@]}"; do
            group=$(echo "$group" | xargs)
            if ! getent group "$group" >/dev/null 2>&1; then
                groupadd "$group"
            fi
            usermod -aG "$group" "$username"
        done
    fi
Enter fullscreen mode Exit fullscreen mode

If additional groups are specified for the user, the script processes each group, ensuring it exists before adding the user to the group. This ensures that users are correctly assigned to all specified groups, creating groups if they do not already exist.

11. Logging Completion

    log_action "User $username created with groups: $username, $groups"
done < $USER_FILE

log_action "User creation process completed."
Enter fullscreen mode Exit fullscreen mode

After processing all users, the script logs the completion of the user creation process.

Thanks to the HNG team for their brilliant initiative. This technical article fulfills stage 1 to stage 2 of the HNG11 internship program. For those looking to enhance their skills, consider joining the HNG Internship program. This initiative offers valuable hands-on experience and mentorship from industry experts. Additionally, for more advanced resources and opportunities, the HNG Premium platform provides exclusive access to premium content and professional development tools.

Top comments (0)