Automating User and Group Management with a Bash Script.
Published: 2024-07-03 23:37:38


As a SysOps engineer, one of your responsibilities is to streamline and automate the process of user management. With the recent influx of new developers at our company, managing user accounts and their group memberships efficiently is crucial. In this article, I’ll walk you through a Bash script that automates the creation of users, assigns them to groups, and sets up their home directories with proper permissions. Additionally, the script logs all actions and securely stores the generated passwords.

This task is part of the HNG Internship, a fantastic program that helps interns gain real-world experience. You can learn more about the program at the [HNG Internship website](https://hng.tech/internship) or consider hiring some of their talented interns through the [HNG Hire page](https://hng.tech/hire).

The source code can be found on my https://github.com/nthelma30/Create_User.sh.git

### The Task

We need to create a Bash script called `create_users.sh` that:
1. Reads a text file with usernames and groups.
2. Creates users and groups as specified.
3. Sets up home directories with appropriate permissions.
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`.

### Input File Format

The input file should contain lines formatted as `user;groups`, where `user` is the username, and `groups` is a comma-separated list of group names. For example:
```
light; sudo,dev,www-data
idimma; sudo
mayowa; dev,www-data
```

### The Script

Here is the `create_users.sh` script:

```bash
#!/bin/bash

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

# Ensure log and secure directories are initialized once
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Initialize log file
if [ ! -f "$LOG_FILE" ]; then
    sudo touch "$LOG_FILE"
    sudo chown root:root "$LOG_FILE"
    sudo chmod 600 "$LOG_FILE"
fi

# Initialize password file
if [ ! -f "$PASSWORD_FILE" ]; then
    sudo mkdir -p /var/secure
    sudo touch "$PASSWORD_FILE"
    sudo chown root:root "$PASSWORD_FILE"
    sudo chmod 600 "$PASSWORD_FILE"
fi

# Redirect stdout and stderr to the log file
exec > >(sudo tee -a "$LOG_FILE") 2>&1

# Function to check if user exists
user_exists() {
    id "$1" &>/dev/null
}

# Function to check if a group exists
group_exists() {
    getent group "$1" > /dev/null 2>&1
}

# Function to check if a user is in a group
user_in_group() {
    id -nG "$1" | grep -qw "$2"
}

# Read each line from the input file
while IFS=';' read -r username groups; do
    # Trim whitespace
    username=$(echo "$username" | tr -d '[:space:]')
    groups=$(echo "$groups" | tr -d '[:space:]')

    # Check if the user already exists
    if user_exists "$username"; then
        echo "User $username already exists."
    else
        # Create user
        sudo useradd -m "$username"

        # Generate random password
        password=$(openssl rand -base64 12)

        # Set password for user
        echo "$username:$password" | sudo chpasswd

        # Log actions
        echo "User $username created. Password: $password"

        # Store passwords securely
        echo "$username,$password" | sudo tee -a "$PASSWORD_FILE"
    fi

    # Ensure the user's home directory and personal group exist
    sudo mkdir -p "/home/$username"
    sudo chown "$username:$username" "/home/$username"

    # Ensure the user's personal group exists
    if ! group_exists "$username"; then
        sudo groupadd "$username"
    fi
    sudo usermod -aG "$username" "$username"

    # Split the groups string into an array
    IFS=',' read -ra group_array <<< "$groups"

    # Check each group
    for group in "${group_array[@]}"; do
        if [[ -n "$group" ]]; then
            if group_exists "$group"; then
                echo "Group $group exists."
            else
                echo "Group $group does not exist. Creating group $group."
                sudo groupadd "$group"
            fi

            if user_in_group "$username" "$group"; then
                echo "User $username is already in group $group."
            else
                echo "Adding user $username to group $group."
                sudo usermod -aG "$group" "$username"
            fi
        fi
    done
done < "$1"
```

### Explanation

1. **Input Validation**: The script starts by checking if the input file exists. If not, it exits with an error message.
2. **Log and Password Files**: It ensures that the log file (`/var/log/user_management.log`) and the password file (`/var/secure/user_passwords.csv`) are created with appropriate permissions.
3. **Functions**:
    - `user_exists()`: Checks if a user already exists.
    - `group_exists()`: Checks if a group already exists.
    - `user_in_group()`: Checks if a user is a member of a group.
4. **Processing the Input File**: The script reads each line from the input file, trims whitespace, and processes the usernames and groups.
5. **User Creation**: It creates the user if they do not already exist, generates a random password using `openssl rand -base64 12`, and sets the password.
6. **Home Directory and Personal Group**: It ensures the user's home directory and personal group (named the same as the username) exist and sets the appropriate permissions.
7. **Group Membership**: It processes each group, creating it if it doesn’t exist, and adds the user to the group.

### Conclusion

This script provides an efficient way to manage user accounts and their group memberships, ensuring that all actions are logged and passwords are stored securely. By automating these tasks, SysOps engineers can save time and reduce the risk of errors.

For more information about the HNG Internship and its benefits, visit the [HNG Internship website](https://hng.tech/internship) or consider hiring from their pool of talented interns through the [HNG Hire page](https://hng.tech/hire).

--
This article can be adapted to your specific requirements or company guidelines.

Written by Thelma Ocansey