DEV Community

Faruq2991
Faruq2991

Posted on

Automating User and Group Management with a Bash Script

I recently got accepted into the famous(https://hng.tech/hire). It is a very intense hands-on 8 week program where your skills will be tested and legends are made. As a requirement for proceeding to the next stage, interns on every track are given tasks they are expected to execute, document and write an article to pass. this blog post is such.
I would recommend anyone willing to upskill and gain employable skill to enroll into the program. (https://hng.tech/premium) https://hng.tech/internship

Hey there, fellow Sysadmin! We can all agree that managing users and groups is a bit difficult and time consuming. Trust me, I've been there. Picture this: it's 2 AM, you're knee-deep in energy drink cans, trying to add the 50th user to your system. Your eyes are crossing, and you're pretty sure you just gave someone access to critical codes by mistake. We've all been there, right? Well, chin up, because I'm about to introduce you to your new best friend: a Bash script that'll make user management a breeze!

Script Breakdown

   declare -a users
   declare -a groups
Enter fullscreen mode Exit fullscreen mode

The script starts with a shebang (#!/bin/bash) to specify the interpreter. It then declares two arrays, users and groups, to hold user and group data.

  1. Argument Check
   if [[ $# -ne 1 ]]; then
     echo "Usage: $0 <input_file>"
     exit 1
   fi

   input_file="$1"
   echo "Reading input file: $input_file"
Enter fullscreen mode Exit fullscreen mode

The script checks and confirm that the script is run is run with exactly one argument (the input file). Otherwise, the exit code 1 is triggered which which indicates failure. The input file is then assigned to the variable input_file.

  1. Reading the Input File
   function read_input() {
     local file="$1"

     if [[ ! -f "$file" ]]; then
       echo "File not found!"
       return 1
     fi

     while IFS= read -r line; 
     do
       user=$(echo "$line" | cut -d';' -f1)
       groups_list=$(echo "$line" | cut -d';' -f2 | tr -d '[:space:]')
       users+=("$user")
       groups+=("$groups_list")
     done < "$file"
   }

   read_input "$input_file"
Enter fullscreen mode Exit fullscreen mode

The read_input function reads the input file line by line. Each line read is expected to contain a username and a comma-separated(delimiter) list of groups, separated by a semicolon. The function splits each line into a user and their groups, then adds these to the respective arrays.

  1. Verification of Data
   echo "Users: ${users[@]}"
   echo "Groups: ${groups[@]}"
Enter fullscreen mode Exit fullscreen mode

The script prints the users and groups arrays to verify the data read from the input file.

  1. Log and Password Files Setup
   log_file="/var/log/user_management.log"
   password_file="/var/secure/user_passwords.txt"

   touch $log_file
   mkdir -p $(dirname $password_file)
   touch $password_file

Enter fullscreen mode Exit fullscreen mode

The script sets up paths for a log file and a password file. It creates these files and their parent directories if they do not exist.

  1. User and Group Management
   for (( i = 0; i < ${#users[@]}; i++ )); do
     user="${users[$i]}"
     user_groups="${groups[$i]}"
     if id "$user" &>/dev/null; then
       echo "User $user already exists, Skipped" | tee -a "$log_file"
     else
       # Create user
       useradd -m -s /bin/bash "$user"
       if [[ $? -ne 0 ]]; then
         echo "Failed to create user $user" | tee -a "$log_file"
         exit 1
       fi
       echo "User $user created" | tee -a "$log_file"

       password=$(openssl rand -base64 50 | tr -dc 'A-Za-z0-9!?%=' | head -c 10)
       echo "$user:$password" | chpasswd
       if [[ $? -ne 0 ]]; then
         echo "Failed to set password for $user" | tee -a "$log_file"
         exit 1
       fi
       echo "Password for $user set" | tee -a "$log_file"
       echo "$user:$password" >> "$password_file"

       if grep -q "^$user:" /etc/group; then
         echo "Personal group $user already exists" | tee -a "$log_file"
       else
         echo "Personal group $user does not exist, creating $user" | tee -a "$log_file"
         groupadd "$user"
         if [[ $? -ne 0 ]]; then
           echo "Failed to create personal group $user" | tee -a "$log_file"
           exit 1
         fi
       fi

       usermod -aG "$user" "$user"
       if [[ $? -ne 0 ]]; then
         echo "Failed to add $user to $user group" | tee -a "$log_file"
         exit 1
       fi
       echo "Added $user to $user group" | tee -a "$log_file"

       for group in $(echo "$user_groups" | tr ',' '\n'); do
         if grep -q "^$group:" /etc/group; then
           echo "Group $group already exists" | tee -a "$log_file"
         else
           echo "Group $group does not exist, creating $group" | tee -a "$log_file"
           groupadd "$group"
           if [[ $? -ne 0 ]]; then
             echo "Failed to create group $group" | tee -a "$log_file"
             exit 1
           fi
         fi

         usermod -aG "$group" "$user"
         if [[ $? -ne 0 ]]; then
           echo "Failed to add $user to $group group" | tee -a "$log_file"
           exit 1
         fi
         echo "Added $user to $group group" | tee -a "$log_file"
       done
     fi
   done
Enter fullscreen mode Exit fullscreen mode

The main loop iterates over the users and groups arrays. For each user:

  • If the user already exists, it logs and skips to the next user.
  • If the user does not exist, it creates the user, sets a password, logs the details, and creates a personal group if it does not exist.
  • The user is added to their personal group and any additional groups specified.

This script provides a comprehensive solution for automating the management of users and groups, ensuring consistent and secure setups based on predefined input data.

Top comments (1)

Collapse
 
hacker_haii profile image
DEEP SHAH

Interesting @faruq2991