User creation script using bash shell.
Published: 2024-07-02 23:57:05

In this article, I will demonstrate how a sysop administrator employs bash shell scripting to create multiple users and assign them unique passwords to different groups. 

Well, who's a sysOps admin?

A SysOps (System Operations) Administrator, also known as a Systems Administrator or SysAdmin is a professional responsible for managing, maintaining, and ensuring the smooth operation of an organization's IT infrastructure. It involves a wide range of tasks to keep the organization's systems running efficiently, securely, and reliably. Among the list of key responsibilities handled by a SysOp Admin, one of the most important tasks is user management. In an infrastructure where Linux OS is the main choice of all systems, the bash shell scripting language can be used by SysAdmin to manage and maintain user accessibility. Here, I will be explaining how a SysAdmin makes use of shell scripting to manage user, groups, and password creation with ease.

```
#!/bin/bash

# Check if the input file is provided
if [ -z "$1" ]; then
  echo "Usage: $0 <input_file>"
  exit 1
fi

INPUT_FILE="$1"

```
The above code starts with a shebang statement which defines the type of shell to run this script, in this situation, it's a bash shell script. The other lines check if an input file is given while running the script, this explanation will come in later after the whole script is prepared.

```
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Ensure the log file exists
touch "$LOG_FILE"

# Ensure the secure directory and password file exist with correct permissions
mkdir -p /var/secure
touch "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"

```
While creating the users, we will need to log every action and step taken during the creation of users, passwords, and groups for future reference. The above code ensures that the log file is created and assigned appropriate permissions.

```
# Function to generate a random password
generate_password() {
  tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}

```
The next step is to generate random passwords for our users, it simply generates a 12-character password.

```
# Read the input file line by line
while IFS=";" read -r user groups; do
  # Remove leading/trailing whitespace from user and groups
  user=$(echo "$user" | xargs)
  groups=$(echo "$groups" | xargs)

```
In the input file that contains the users and groups mentioned earlier, this code reads it line by line to create matching usernames and groups specified in the file. The input file can might contain details like this:

`Luffy; straw-hats`

The code also trims whitespace if there's any.

```
  # Create a personal group with the same name as the user
  if ! getent group "$user" &>/dev/null; then
    groupadd "$user"
    echo "$(date +'%Y-%m-%d %H:%M:%S') - Created personal group $user" | tee -a "$LOG_FILE"
  fi

```
The next step checks if the group written in the input file exists and adds the user, if it doesn't, the group is created using `groupadd` and this action is logged into the log file.

```
  if id "$user" &>/dev/null; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - User $user already exists. Skipping..." | tee -a "$LOG_FILE"
    continue
  fi

  # Create the user with the personal group
  useradd -m -s /bin/bash -g "$user" "$user"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Created user $user with personal group $user" | tee -a "$LOG_FILE"

```
This step checks for the existence of a user and logs the response, if the user doesn't exist, it creates the user and assigns the user's home directory to /bin/bash and personal group specified in the input file.

```
  # Set the home directory permissions
  chmod 700 "/home/$user"
  chown "$user:$user" "/home/$user"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Set permissions for /home/$user" | tee -a "$LOG_FILE"

```
This action simply sets the permission for the home directory of the user to 700 and logs the action.

```
  # Generate a random password and set it
  password=$(generate_password)
  echo "$user:$password" | chpasswd
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Set password for $user" | tee -a "$LOG_FILE"

  # Securely store the password
  echo "$user,$password" >> "$PASSWORD_FILE"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Stored password for $user in $PASSWORD_FILE" | tee -a "$LOG_FILE"

```
A password is generated for the user, stores the username and password in the password file, and logs the action in the log file.

```
  # Add user to specified groups
  IFS="," read -r -a group_array <<< "$groups"
  for group in "${group_array[@]}"; do
    group=$(echo "$group" | xargs)  # Remove leading/trailing whitespace
    if ! getent group "$group" &>/dev/null; then
      groupadd "$group"
      echo "$(date +'%Y-%m-%d %H:%M:%S') - Created group $group" | tee -a "$LOG_FILE"
    fi
    usermod -aG "$group" "$user"
    echo "$(date +'%Y-%m-%d %H:%M:%S') - Added user $user to group $group" | tee -a "$LOG_FILE"
  done

done < "$INPUT_FILE"

```
Here, groups are checked for their existence and created if they are not, users are added to their specified groups using other `usermod`. Every action here is then logged to the log file.

`echo "$(date +'%Y-%m-%d %H:%M:%S') - User creation process completed." | tee -a "$LOG_FILE"
`
Finally, a message concluding the creation process and logs to the log file.

To use this script, you will need to create an input file with the `.txt` extension. Before you run the file, ensure you change the file permissions of the script using the `chmod +x script.sh` command. 
Here is an example of what the input file should look like:

```
coby;navy
luffy;straw-hats
edward-newgate;whitebeard
shanks;red-hair
```
coby,luffy,edward-newgate, and shanks are usernames while the navy,straw-hats,whitebeard, and red hair are the personal groups of the users. To run the script:

`sudo ./script.sh input.txt`

Conclusion:
Using the bash script simply makes user management seamless for system admins. This is a task given by the HNG internship. To find out about this internship visit: https://hng.tech/internship or https://hng.tech/hire to also participate. Thank you for your time. Here is the full script:

```
#!/bin/bash

# Check if the input file is provided
if [ -z "$1" ]; then
  echo "Usage: $0 <input_file>"
  exit 1
fi

INPUT_FILE="$1"
LOG_FILE="/var/log/user_management.log"
PASSWORD_FILE="/var/secure/user_passwords.csv"

# Ensure the log file exists
touch "$LOG_FILE"

# Ensure the secure directory and password file exist with correct permissions
mkdir -p /var/secure
touch "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"

# Function to generate a random password
generate_password() {
  tr -dc A-Za-z0-9 </dev/urandom | head -c 12 ; echo ''
}

# Read the input file line by line
while IFS=";" read -r user groups; do
  # Remove leading/trailing whitespace from user and groups
  user=$(echo "$user" | xargs)
  groups=$(echo "$groups" | xargs)

  # Create a personal group with the same name as the user
  if ! getent group "$user" &>/dev/null; then
    groupadd "$user"
    echo "$(date +'%Y-%m-%d %H:%M:%S') - Created personal group $user" | tee -a "$LOG_FILE"
  fi

  if id "$user" &>/dev/null; then
    echo "$(date +'%Y-%m-%d %H:%M:%S') - User $user already exists. Skipping..." | tee -a "$LOG_FILE"
    continue
  fi

  # Create the user with the personal group
  useradd -m -s /bin/bash -g "$user" "$user"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Created user $user with personal group $user" | tee -a "$LOG_FILE"

  # Set the home directory permissions
  chmod 700 "/home/$user"
  chown "$user:$user" "/home/$user"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Set permissions for /home/$user" | tee -a "$LOG_FILE"

  # Generate a random password and set it
  password=$(generate_password)
  echo "$user:$password" | chpasswd
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Set password for $user" | tee -a "$LOG_FILE"

  # Securely store the password
  echo "$user,$password" >> "$PASSWORD_FILE"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - Stored password for $user in $PASSWORD_FILE" | tee -a "$LOG_FILE"

  # Add user to specified groups
  IFS="," read -r -a group_array <<< "$groups"
  for group in "${group_array[@]}"; do
    group=$(echo "$group" | xargs)  # Remove leading/trailing whitespace
    if ! getent group "$group" &>/dev/null; then
      groupadd "$group"
      echo "$(date +'%Y-%m-%d %H:%M:%S') - Created group $group" | tee -a "$LOG_FILE"
    fi
    usermod -aG "$group" "$user"
    echo "$(date +'%Y-%m-%d %H:%M:%S') - Added user $user to group $group" | tee -a "$LOG_FILE"
  done

done < "$INPUT_FILE"

echo "$(date +'%Y-%m-%d %H:%M:%S') - User creation process completed." | tee -a "$LOG_FILE"
```