Skip to content

Conversation

@norfluxX
Copy link

@norfluxX norfluxX commented Sep 10, 2025

Hi Shubham,

As mentioned in the project #1, Shell Script for User Management and Backup in Linux. I have completed the same.

File name is - pam-main.sh under day02

It consists of:

  1. Add user
  2. Delete user
  3. Modify user - Add user to multiple groups
  4. Modify user - Changing Login Shell
  5. Modify user - Disable Login
  6. Modify user - Enable Login
  7. Modify user - Add user to sudo group
  8. Add group
  9. Backup directories

Also added comments wherever possible to give appropriate explanation. please review and let me know if any changes.

Summary by CodeRabbit

  • New Features

    • Interactive, colorized menu for Linux user/group management: add/delete users, modify users (add to groups, toggle shells, disable/enable login), grant sudo/wheel, create groups, and make timestamped directory backups. New users receive a generated temporary password and are forced to change it on first login.
  • Chores

    • Requires root privileges to run.
  • Bug Fixes

    • Known issue: may enter an unintended continuous loop when executed as root.

@coderabbitai
Copy link

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds a new interactive Bash script day02/pam-main.sh implementing a 10-option, ANSI-colored CLI for Linux user/group management and directory backups; includes UID>=1000 filtering, random temp password generation, system command usage, a malformed shebang, enforces root execution via an initial check, and runs a perpetual menu loop.

Changes

Cohort / File(s) Summary
New script
day02/pam-main.sh
Adds a single interactive Bash script implementing a 10-option CLI: add user (derive username from full name, random temp password via openssl or /dev/urandom, expire password), delete user (UID>=1000 filtering, confirmation, protects current user), modify users (add to groups, toggle/change shell, enable/disable login, add to sudo/wheel), add group, backup absolute directories to /opt/dir_backups as timestamped tar.gz. Uses useradd/userdel/usermod/chsh/chpasswd/groupadd/tar/getent/awk, defines ANSI color vars, unsets vars after operations, contains malformed shebang (#/bin/bash) and enforces root via an initial check before entering a perpetual menu loop.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Admin as Admin (interactive)
    participant Script as pam-main.sh
    participant Sys as System (user/group/tar)

    Admin->>Script: Run script / select option
    alt Not root
        Script->>Admin: "Must run as root" and exit
    else Root (initial check passes)
        Admin->>Script: Choose option (1..10)
        alt 1: Add user
            Script->>Admin: Prompt for full name
            Admin->>Script: Provide name
            Script->>Sys: useradd -m -s /bin/bash
            Script->>Sys: generate password -> chpasswd -> passwd -e
            Sys-->>Script: OK/ERR
            Script-->>Admin: Result
        else 2: Delete user
            Script->>Sys: getent passwd (UID>=1000) -> list
            Admin->>Script: Select & confirm username
            Script->>Sys: userdel -r
            Sys-->>Script: OK/ERR
            Script-->>Admin: Result
        else 3..7: Modify user (groups/shell/disable/enable/sudo)
            Script->>Sys: usermod / chsh / group modifications
            Sys-->>Script: OK/ERR
            Script-->>Admin: Result
        else 8: Add group
            Script->>Sys: groupadd (if not exists)
            Sys-->>Script: OK/ERR
            Script-->>Admin: Result
        else 9: Backup directories
            Script->>Admin: Prompt absolute path
            Admin->>Script: Provide path
            Script->>Sys: tar -> /opt/dir_backups/<user>-<ts>.tar.gz
            Sys-->>Script: OK/ERR
            Script-->>Admin: Result
        else 10: Exit
            Script-->>Admin: Exit loop and terminate
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks (2 passed, 1 inconclusive)

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The current title "shell scripting project #1" is too generic and does not clearly summarize the primary change in this PR (adding day02/pam-main.sh, an interactive Linux user/group management and backup script), so it does not convey enough information for reviewers scanning the history. Rename the PR to a concise, specific title that highlights the main change, for example: "Add interactive user/group management and backup script (day02/pam-main.sh)" or "Add pam-main.sh: interactive user/group management & backups" to make the intent clear to reviewers.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

"I hop with keys and gentle cheer,
I make new names and keep them near,
Shells flip, groups gather, backups hum,
Passwords tumble, users come and run,
A tiny rabbit's sysadmin drum. 🐇"

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
day02/pam-main.sh (1)

1-154: Fix shebang and quoting issues

  • day02/pam-main.sh line 1: replace #/bin/bash with a valid shebang (e.g. #!/usr/bin/env bash).
  • Quote every variable expansion (SC2086), e.g. use "${username}", "${grpname}", "${dirback}".
  • Replace legacy backticks with $(…) command substitutions (SC2006).
  • Add -r to all read invocations to prevent backslash mangling (SC2162).
  • Use [[ … ]] for conditional tests instead of […] where recommended (SC2292).
  • Remove or utilize the unused WHITE color constant (SC2034).
🧹 Nitpick comments (3)
day02/pam-main.sh (3)

10-10: Remove unused color constant WHITE

Not used anywhere; drop it or use consistently for output.

-WHITE='\033[1;37m'

73-81: Prefer usermod -s for shell changes; handle unsupported shells

  • chsh may fail if shell not in /etc/shells; check errors.
  • Quote variables and add a default else branch.
-if [ "$curr_shell" = "/bin/sh" ]; then
-      chsh -s /bin/bash "$username"
+if [[ "$curr_shell" == "/bin/sh" ]]; then
+      usermod -s /bin/bash "$username" && \
       echo "$username's shell is successfully changed to bash"
       echo "-------------------------------------------------"
-elif [ "$curr_shell" = "/bin/bash" ]; then
-      chsh -s /bin/sh "$username"
+elif [[ "$curr_shell" == "/bin/bash" ]]; then
+      usermod -s /bin/sh "$username" && \
       echo "$username's shell is successfully changed to sh"
       echo "-----------------------------------------------"
+else
+      echo "Unsupported current shell '$curr_shell'; no change made."
 fi

107-114: Mirror portability for enabling login

Use usermod -s and check success.

-echo "Changing $username shell to /bin/bash"
-chsh -s /bin/bash "$username"
+echo "Changing $username shell to /bin/bash"
+usermod -s /bin/bash "$username"
 echo "$username's shell is successfully activated to bash"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 140e9d1 and bd99c61.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 10-10: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (1)
day02/pam-main.sh (1)

1-154: Target distro and commands: confirm Debian/Ubuntu vs RHEL/CentOS

You mix Debian-only tools (deluser, addgroup) with portable ones. Confirm target(s) and adjust accordingly, or branch by detection.

Would you confirm the Linux distributions you want to support? If multi-distro, I can add a small helper that maps commands per OS (ID from /etc/os-release) and detects sudo/wheel, nologin path, etc.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
day02/pam-main.sh (2)

1-1: Malformed shebang; enable strict mode early

Current line prevents execution under Bash and misses safe options.

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

74-86: Group selection mismatch: list source ≠ pick source

You list groups via getent (all groups) but pick via /etc/group filtered by GID>=1000, so indices don’t match. Result: wrong group may be chosen.

-echo "------------------Group List-------------------------"
-getent group | awk -F: '{print $1}' | nl -w1 -s". "
+echo "------------------Group List-------------------------"
+getent group | awk -F: '{print $1}' | nl -w1 -s". "
 read -p "Select the existing user NUMBER: " choice
 read -p "Select the group NUMBER to be added: " gchoice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")"
 if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
🧹 Nitpick comments (5)
day02/pam-main.sh (5)

94-107: Prompt mismatch and prefer usermod -s over chsh

Prompt asks for username but expects a number. Use usermod -s for consistency.

-read -p "Select the existing username: " choice
+read -p "Select the existing user NUMBER: " choice
 username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
 curr_shell=$(getent passwd "$username" | cut -d: -f7)
 if [ "$curr_shell" = "/bin/sh" ]; then
-		    chsh -s /bin/bash "$username"
+		    usermod -s /bin/bash "$username"
 		    echo "$username's shell is successfully changed to bash"
 		    echo "-------------------------------------------------"
 elif [ "$curr_shell" = "/bin/bash" ]; then
-		    chsh -s /bin/sh "$username"
+		    usermod -s /bin/sh "$username"
 		    echo "$username's shell is successfully changed to sh"
 		    echo "-----------------------------------------------"
 fi

113-122: Consistent prompts and enable using usermod -s

Align prompt with numbered list and prefer usermod -s.

-read -p "Select the existing username: " choice
+read -p "Select the existing user NUMBER: " choice
@@
-                echo "Changing $username shell to /bin/bash"
-                chsh -s /bin/bash "$username"
+                echo "Changing $username shell to /bin/bash"
+                usermod -s /bin/bash "$username"
                 echo "$username's shell is successfully activated to bash"

Also applies to: 130-139


147-153: Prompt mismatch for sudo group selection

Menu uses numbers; prompt says “Enter the existing username”. Fix text.

-read -p "Enter the existing username: " choice
+read -p "Select the existing user NUMBER: " choice

169-179: Backup: verify selected user and absolute path; handle empty username

Minor guardrails to avoid creating “_timestamp.tar.gz”.

 username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
-read -r -p "Specify the absolute path of the directory to be backed up: " dirback
-if [[ -d "$dirback" ]]; then
+[[ -n "${username:-}" ]] || { echo "Invalid user selection."; break; }
+read -r -p "Specify the absolute path of the directory to be backed up: " dirback
+if [[ "$dirback" = /* && -d "$dirback" ]]; then
   ts="$(date +%F_%H-%M-%S)"
   tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
     echo "Backup completed successfully" || echo "Backup failed"
 else
   echo "Directory '$dirback' not found."
 fi

188-190: Exit cleanly

Using break relies on loop structure; exit 0 is clearer.

-	break;
+	exit 0
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd99c61 and 89b33c2.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[error] 16-16: Couldn't parse this while loop. Fix to allow more checks.

(SC1073)


[error] 16-16: Couldn't find 'done' for this 'do'.

(SC1061)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (7)
day02/pam-main.sh (7)

1-1: Fix malformed shebang and enable safe Bash options early

Use a valid shebang and fail fast with safe defaults.

Apply:

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

16-20: Remove tight no-op loop that busy-spins before the menu

This while-loop repeatedly re-checks EUID and does nothing when root.

-while true; do
-if [[ $EUID -ne 0 ]]; then
-  echo "This script must be run as root (sudo)."; exit 1
-fi
-done

21-21: Run the root check once before entering the menu loop

Place EUID check above the main loop.

+if [[ $EUID -ne 0 ]]; then
+  echo "This script must be run as root (sudo)." >&2
+  exit 1
+fi
 while true; do

82-90: Align prompts with number selection, validate inputs, and pick group from the same list

Fix prompt text, add numeric checks, and use getent group for selection (list and pick source should match).

-read -p "Select the existing user NUMBER: " choice
-read -p "Select the group NUMBER to be added: " gchoice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
-if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
-  usermod -aG "$grpname" "$username" && echo "$username added to group $grpname"
-else
-  echo "Invalid selection."
-fi
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid user selection."; continue; }
+read -r -p "Select the group NUMBER to be added: " gchoice
+[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid group selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")"
+if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
+  usermod -aG "$grpname" "$username" && echo "$username added to group $grpname"
+else
+  echo "Invalid selection."
+fi

100-111: Prompt/selection mismatch; add validation before toggling shell

Prompt says “username” but expects a number; also guard empty picks.

-	read -p "Select the existing username: " choice
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+	read -r -p "Select the existing user NUMBER: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }
-	curr_shell=$(getent passwd "$username" | cut -d: -f7)
-	if [ "$curr_shell" = "/bin/sh" ]; then
+	curr_shell=$(getent passwd "$username" | cut -d: -f7)
+	if [[ "$curr_shell" == "/bin/sh" ]]; then
 		    chsh -s /bin/bash "$username"
 		    echo "$username's shell is successfully changed to bash"
 		    echo "-------------------------------------------------"
-	elif [ "$curr_shell" = "/bin/bash" ]; then
+	elif [[ "$curr_shell" == "/bin/bash" ]]; then
 		    chsh -s /bin/sh "$username"
 		    echo "$username's shell is successfully changed to sh"
 		    echo "-----------------------------------------------"
 	fi

153-157: Prompt/selection mismatch and missing validation for sudo-group add

Switch to number-based prompt and validate.

-	read -p "Enter the existing username: " choice
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+	read -r -p "Select the existing user NUMBER: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }

176-185: Harden backup input handling and filename

Validate selection, guard empty username, and avoid empty prefix in archive name.

-	read -r -p "Select the user NUMBER to associate with the backup: " choice
-	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
-	read -r -p "Specify the absolute path of the directory to be backed up: " dirback
-	if [[ -d "$dirback" ]]; then
-	  ts="$(date +%F_%H-%M-%S)"
-	  tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
+	read -r -p "Select the user NUMBER to associate with the backup: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	[[ -n "${username:-}" ]] || { echo "Invalid user selection."; continue; }
+	read -r -p "Specify the absolute path of the directory to be backed up: " dirback
+	if [[ -d "$dirback" ]]; then
+	  ts="$(date +%F_%H-%M-%S)"
+	  tar -czf "/opt/dir_backups/${username:-unknown}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
 	    echo "Backup completed successfully" || echo "Backup failed"
🧹 Nitpick comments (2)
day02/pam-main.sh (2)

44-50: Avoid printing plaintext temporary passwords to the terminal

Store in a root-only log instead of echoing the secret.

-	  echo "$username created. Temporary password: $randpass (will be forced to change on first login)"
+	  log="/root/pam-main-passwords.log"
+	  { umask 077; printf '%s:%s\n' "$username" "$randpass" >> "$log"; }
+	  echo "$username created. Temporary password saved to $log (will be forced to change on first login)"

9-9: Remove unused color variable (ShellCheck SC2034)

WHITE is defined but not used.

-WHITE='\033[1;37m'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89b33c2 and 8a74275.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (1)
day02/pam-main.sh (1)

121-126: Good portability on login disable

Detecting nologin dynamically and using usermod -s is portable and correct. LGTM.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (6)
day02/pam-main.sh (6)

1-1: Fix malformed shebang and enable safe Bash options

Script won’t run under Bash as written; add strict mode early.

Apply:

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

16-20: Remove infinite pre-loop; perform root check once before the menu

This while-true block busy-loops forever for root users.

Apply:

-while true; do
-if [[ $EUID -ne 0 ]]; then
-  echo "This script must be run as root (sudo)."; exit 1
-fi
-done
+if [[ $EUID -ne 0 ]]; then
+  echo "This script must be run as root (sudo)." >&2
+  exit 1
+fi

38-38: Don’t exit the menu when the user already exists; continue instead

break exits the whole menu loop.

-  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue

81-86: Fix group selection source mismatch (list via getent, select via /etc/group)

You list groups with getent but index into /etc/group (different orders) → wrong group.

-read -p "Select the existing user NUMBER: " choice
-read -p "Select the group NUMBER to be added: " gchoice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid user selection."; continue; }
+read -r -p "Select the group NUMBER to be added: " gchoice
+[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid group selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")"

118-126: Validate numeric selection for “Disable Login”

Match prompt style and guard empty username.

-read -p "Select the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-if getent passwd "$username" > /dev/null; then
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then

151-158: Add sudo: use NUMBER prompt + validation and guard empty username

Prevents accidental empty add.

-read -p "Enter the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
 admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
-usermod -aG "$admin_group" "$username"
-echo "$username added to $admin_group group."
+if [[ -n "${username:-}" ]]; then
+  usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group."
+else
+  echo "Invalid selection."
+fi
🧹 Nitpick comments (2)
day02/pam-main.sh (2)

176-183: Backups: validate selected user and show archive path

Minor UX hardening.

-username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }
 read -r -p "Specify the absolute path of the directory to be backed up: " dirback
 if [[ -d "$dirback" ]]; then
   ts="$(date +%F_%H-%M-%S)"
-  tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
-    echo "Backup completed successfully" || echo "Backup failed"
+  archive="/opt/dir_backups/${username}_$ts.tar.gz"
+  tar -czf "$archive" -C "$dirback" . >/dev/null 2>&1 && \
+    echo "Backup completed: $archive" || echo "Backup failed"

9-9: Remove unused color variable WHITE

Clean up per ShellCheck SC2034.

-WHITE='\033[1;37m'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a74275 and 115dd6a.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (2)
day02/pam-main.sh (2)

121-125: Good: portable nologin detection and consistent usermod usage

This improves distro compatibility.


54-67: Good: safer delete flow with validation and self-delete guard

Numeric validation, confirmation, and userdel -r are appropriate.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (5)
day02/pam-main.sh (5)

1-1: Fix shebang and enable strict mode early
Use a valid shebang and safe bash options at the top.

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

16-21: Remove infinite pre-loop; run root check once, then enter menu
Current while/do around the EUID check spins forever (no body/break) and prevents reaching the menu.

-while true; do
-if [[ $EUID -ne 0 ]]; then
-  echo "This script must be run as root (sudo)."; exit 1
-fi
-done
-while true; do
+if [[ $EUID -ne 0 ]]; then
+  echo "This script must be run as root (sudo)." >&2
+  exit 1
+fi
+while true; do

35-39: Don’t exit the menu when user exists; continue instead
Using break exits the whole menu loop.

-  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+  echo "User '$username' already exists."
+  echo "-----------------------------------------------"
+  unset username
+  continue

155-166: Add-to-sudo: prompt mismatch and missing validation
Input expects a NUMBER but prompt asks for username; also validate selection and handle empty username.

-read -p "Enter the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+if [[ -z "${username:-}" ]]; then echo "Invalid selection."; continue; fi
 admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
 usermod -aG "$admin_group" "$username"
 echo "$username added to $admin_group group."

121-129: Prompt/validation mismatch for ‘Disable Login’
Prompt says “username” but expects a NUMBER; also missing numeric validation. Align prompt and validate.

-read -p "Select the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
-if getent passwd "$username" > /dev/null; then
+if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
🧹 Nitpick comments (4)
day02/pam-main.sh (4)

139-147: Minor: make prompt consistent with NUMBER input
Message says “user” but you require a number; adjust for clarity.

-read -rp "Select the existing user: " choice
+read -rp "Select the existing user NUMBER: " choice

Also applies to: 141-141


178-187: Backup: validate selection and guard empty username
Add NUMBER validation and ensure username is non-empty before naming the archive.

-read -r -p "Select the user NUMBER to associate with the backup: " choice
-username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+read -r -p "Select the user NUMBER to associate with the backup: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
@@
-  ts="$(date +%F_%H-%M-%S)"
-  tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
+  ts="$(date +%F_%H-%M-%S)"
+  name="${username:-unknown}"
+  tar -czf "/opt/dir_backups/${name}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \

Also applies to: 180-186


9-9: Remove unused color or use it
WHITE is defined but unused.

-WHITE='\033[1;37m'
+# WHITE='\033[1;37m' # unused

22-33: Optional: factor repeated listing/selection into helpers
You duplicate “list users”, “validate number”, and “map selection” in several cases. Extract small functions to reduce mistakes and drift.

Happy to propose a minimal helper set (list_users, select_from_list, list_groups) if you want.

Also applies to: 199-203

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 115dd6a and 1c2c1e9.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (6)
day02/pam-main.sh (6)

38-38: Don’t exit menu when user exists; continue instead

Keeps UX consistent with other invalid selections.

-	  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+	  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue

1-1: Fix malformed shebang and enable strict mode early

Script won’t run under Bash as-is; also add safe options.

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

81-89: Fix group selection: validate gchoice and resolve from same list source

Currently validates $choice twice and indexes /etc/group (GID>=1000) while listing via getent; indexes can mismatch.

-        getent group | awk -F: '{print $1}' | nl -w1 -s". "
+        getent group | awk -F: '{print $1}' | nl -w1 -s". "
@@
-	read -p "Select the group NUMBER to be added: " gchoice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	read -p "Select the group NUMBER to be added: " gchoice
+    [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
@@
-	grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
-    if [[ -n "${username}" && -n "${grpname}" ]]; then
+	grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")"
+    if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
 	  usermod -aG "$grpname" "$username" && echo "$username added to group $grpname"

125-135: Option 5 (Disable login): prompt/validation mismatch; guard selection

Prompt asks for username but expects a number; add numeric validation and consistent flow.

-	read -p "Select the existing username: " choice
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-	if getent passwd "$username" > /dev/null; then
+	read -r -p "Select the existing user NUMBER: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
 		nologin_path="$(command -v nologin || echo /sbin/nologin)"
 		echo "Changing $username shell to $nologin_path"
 		usermod -s "$nologin_path" "$username"
 		echo "$username's login disabled."
 		echo "-------------------------------"
 	else
-		echo "User $username not found!"
+		echo "Invalid selection."
 	fi

159-163: Option 7 (Add to sudo/wheel): prompt/validation mismatch; add checks

Reads NUMBER but prompts for username; add validation and skip on invalid.

-	read -p "Enter the existing username: " choice
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-	admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
-	usermod -aG "$admin_group" "$username"
-	echo "$username added to $admin_group group."
+	read -r -p "Select the existing user NUMBER: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	if [[ -n "${username:-}" ]]; then
+	  admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
+	  usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group."
+	else
+	  echo "Invalid selection."
+	fi

16-21: Remove infinite root-check loop; check once before menu

Current while/do loop spins forever when EUID==0 and never reaches the menu.

-while true; do
-if [[ $EUID -ne 0 ]]; then
-  echo "This script must be run as root (sudo)."; exit 1
-fi
-done
+if [[ $EUID -ne 0 ]]; then
+  echo "This script must be run as root (sudo)." >&2; exit 1
+fi
🧹 Nitpick comments (2)
day02/pam-main.sh (2)

182-189: Option 9 (Backup): validate selection; handle empty username; safer filename

Avoid empty username and ensure numeric selection. Optionally keep “unknown” prefix.

-	read -r -p "Select the user NUMBER to associate with the backup: " choice
-	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	read -r -p "Select the user NUMBER to associate with the backup: " choice
+	[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
@@
-	  tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
+	  tar -czf "/opt/dir_backups/${username:-unknown}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \
 	    echo "Backup completed successfully" || echo "Backup failed"

9-9: Remove unused WHITE color var (SC2034)

Silences ShellCheck warning.

-WHITE='\033[1;37m'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c2c1e9 and 373a869.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (5)
day02/pam-main.sh (5)

1-1: Fix shebang and enable strict mode early

Use a valid shebang and turn on safe Bash options to fail fast.

Apply:

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

33-38: Don’t exit the menu when user already exists; use continue

break exits the main loop; you want to return to the menu.

-  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+  echo "User '$username' already exists."
+  echo "-----------------------------------------------"
+  unset username
+  continue

76-87: Group selection: validate group number and resolve from the same list source

You validate choice, but not gchoice; also you list groups via getent yet resolve via /etc/group, which can index-mismatch.

 getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". "
-read -p "Select the existing user NUMBER: " choice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
-read -p "Select the group NUMBER to be added: " gchoice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+read -r -p "Select the group NUMBER to be added: " gchoice
+[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+grpname="$(getent group | awk -F: '$3 >= 1000 {print $1}' | sed -n "${gchoice}p")"
-if [[ -n "${username}" && -n "${grpname}" ]]; then
+if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then

155-163: Prompt/selection mismatch and missing validation

Asks for username but uses numeric index; add validation and ensure username resolved.

-read -p "Enter the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }
 admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
 usermod -aG "$admin_group" "$username"

121-129: Prompt/selection mismatch: expects NUMBER but asks for username; add validation

Currently asks for “username” but uses sed index; this will break on non-numeric input.

-read -p "Select the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
-if getent passwd "$username" > /dev/null; then
+if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
🧹 Nitpick comments (7)
day02/pam-main.sh (7)

6-12: Remove unused color or use it

WHITE is defined but not used; drop it or use it to keep things tidy. ShellCheck SC2034.

-WHITE='\033[1;37m'

16-19: Root check LGTM

Runs once before the loop and exits non-root. Consider sending message to stderr, but OK as-is.

-  echo "This script must be run as root (sudo)."
+  echo "This script must be run as root (sudo)." >&2

31-31: Read without backslash escapes

Use -r to avoid interpreting backslashes in input.

-read -p "Select the option: " choice
+read -r -p "Select the option: " choice

39-46: Avoid printing passwords to the console; store securely or prompt to set

Echoing the temporary password is risky (shoulder-surfing/logging). Prefer saving to a root-readable file or forcing the admin to set it interactively.

-  printf '%s:%s\n' "$username" "$randpass" | chpasswd
+  printf '%s:%s\n' "$username" "$randpass" | chpasswd
   passwd --expire "$username" >/dev/null
-  echo "$username created. Temporary password: $randpass (will be forced to change on first login)"
+  passfile="/root/user_temp_passwords.csv"
+  umask 077
+  printf '%s,%s\n' "$username" "$randpass" >> "$passfile"
+  echo "$username created. Temporary password stored at $passfile (will be forced to change on first login)"

51-70: User deletion flow looks solid; consider terminating active sessions

Optionally terminate processes/sessions before deletion to avoid leftover processes.

-      if userdel -r "$username" >/dev/null 2>&1; then
+      loginctl terminate-user "$username" >/dev/null 2>&1 || pkill -KILL -u "$username" >/dev/null 2>&1 || true
+      if userdel -r "$username" >/dev/null 2>&1; then
         echo "$username deleted."

98-120: Shell toggle: optionally restrict to valid shells

Consider checking against /etc/shells before toggling, and handle usermod failures explicitly.

-  if [[ "$curr_shell" == "/bin/sh" ]]; then
+  if ! grep -qxF "/bin/bash" /etc/shells || ! grep -qxF "/bin/sh" /etc/shells; then
+    echo "Warning: /etc/shells does not include expected shells."
+  fi
+  if [[ "$curr_shell" == "/bin/sh" ]]; then
     usermod -s /bin/bash "$username" && echo "$username's shell changed to bash"

139-146: Align prompt with numeric selection

The input is validated as a number; update the prompt to match.

-read -rp "Select the existing user: " choice
+read -rp "Select the existing user NUMBER: " choice
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 373a869 and 70d4b4c.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (1)
day02/pam-main.sh (1)

200-204: Default branch OK

Invalid options handled and loop continues. Good.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
day02/pam-main.sh (4)

1-1: Fix shebang and enable strict mode early

Current shebang is malformed; add a valid one and harden execution.

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

34-38: Don’t exit the menu when user exists

Using break here exits the main loop. Use continue so the menu keeps running.

-  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+  echo "User '$username' already exists."
+  echo "-----------------------------------------------"
+  unset username
+  continue

80-87: Fix group selection validation and source mismatch

  • Validation checks $choice twice; second should validate $gchoice.
  • You list groups via getent but resolve from /etc/group; indexes can diverge. Resolve from the same list you printed.
-        getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". "
-	read -p "Select the existing user NUMBER: " choice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
-	read -p "Select the group NUMBER to be added: " gchoice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-	grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
+        groups_list="$(getent group | awk -F: '{print $1}')"
+        echo "$groups_list" | nl -w1 -s". "
+	read -r -p "Select the existing user NUMBER: " choice
+        [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	read -r -p "Select the group NUMBER to be added: " gchoice
+        [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+	grpname="$(printf '%s\n' "$groups_list" | sed -n "${gchoice}p")"

156-163: Add sudo/wheel: prompt/validation and empty-username guard

Add numeric validation and ensure a valid username before usermod.

-	read -p "Enter the existing username: " choice
-	username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-	admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
-	usermod -aG "$admin_group" "$username"
-	echo "$username added to $admin_group group."
+	read -r -p "Select the existing user NUMBER: " choice
+        [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+	username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+        if [[ -n "${username:-}" ]]; then
+	  admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
+	  usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group."
+        else
+          echo "Invalid selection."
+        fi
🧹 Nitpick comments (3)
day02/pam-main.sh (3)

9-9: Remove unused color variable WHITE

It’s defined but never used. Drop it to avoid noise.

-WHITE='\033[1;37m'

142-147: Enable login: match prompt wording with behavior

Minor: the prompt should say NUMBER to align with selection style.

-        read -rp "Select the existing user: " choice
+        read -rp "Select the existing user NUMBER: " choice

52-180: Prefer NSS-aware enumeration (getent) over parsing /etc/passwd directly

If the system uses LDAP/SSSD, parsing /etc/passwd may miss users. Consider getent passwd and filtering by UID. Applies to all user lists.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70d4b4c and e2a9eec.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (5)
day02/pam-main.sh (5)

13-19: Run root check before banner and print errors to stderr

Fail fast before UI output; send the error to stderr.

-echo "------------------------------------------------------"
-echo -e "=======\033[45m Welcome to Login Management System \033[0m======="
-echo "------------------------------------------------------"
-if [[ $EUID -ne 0 ]]; then
-  echo "This script must be run as root (sudo)."
-  exit 1
-fi
+if [[ $EUID -ne 0 ]]; then
+  echo "This script must be run as root (sudo)." >&2
+  exit 1
+fi
+echo "------------------------------------------------------"
+echo -e "=======\033[45m Welcome to Login Management System \033[0m======="
+echo "------------------------------------------------------"

1-1: Fix malformed shebang and enable strict mode

Current first line won’t invoke Bash. Add a valid shebang and safe Bash options early.

Apply:

-#/bin/bash
+#!/usr/bin/env bash
+set -Eeuo pipefail
+IFS=$'\n\t'

33-51: Don’t exit the menu when user exists; use continue

Using break here quits the main loop.

-  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break
+  echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue

157-165: Fix prompt/validation for sudo group addition

Prompt asks for username but code expects a number; also missing numeric validation and empty check.

-awk -F: '$3 >= 1000 {print $1}' /etc/passwd | nl -w1 -s". " #Filtering only normal users
-read -p "Enter the existing username: " choice
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
+awk -F: '$3 >= 1000 {print $1}' /etc/passwd | nl -w1 -s". "
+read -r -p "Select the existing user NUMBER: " choice
+[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }
 admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)"
 usermod -aG "$admin_group" "$username"
 echo "$username added to $admin_group group."

81-90: Fix validation bug and unify group source

  • gchoice is never validated (copy/paste uses $choice again).
  • You list groups via getent but resolve from /etc/group; indexes can diverge.
-        getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". "
+        getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". "
 read -p "Select the existing user NUMBER: " choice
     [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
 read -p "Select the group NUMBER to be added: " gchoice
-    [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
+    [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; }
-username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")
-grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p")
+username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")"
+grpname="$(getent group | awk -F: '$3 >= 1000 {print $1}' | sed -n "${gchoice}p")"
-    if [[ -n "${username}" && -n "${grpname}" ]]; then
+    if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
🧹 Nitpick comments (3)
day02/pam-main.sh (3)

9-9: Remove unused color variable WHITE

It’s defined but never used (SC2034).

-WHITE='\033[1;37m'

129-133: Add robust nologin fallback

If nologin isn’t available, fall back to /bin/false.

-        nologin_path="$(command -v nologin || echo /sbin/nologin)"
+        nologin_path="$(command -v nologin || { [[ -x /usr/sbin/nologin ]] && echo /usr/sbin/nologin || echo /bin/false; })"

144-146: Prompt consistency: ask for NUMBER explicitly

Aligns with other menu prompts.

-        read -rp "Select the existing user: " choice
+        read -rp "Select the existing user NUMBER: " choice
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2a9eec and 0edfd17.

📒 Files selected for processing (1)
  • day02/pam-main.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh

[error] 1-1: Use #!, not just #, for the shebang.

(SC1113)


[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).

(SC2034)

🔇 Additional comments (4)
day02/pam-main.sh (4)

52-76: User deletion flow looks solid

Numeric validation, self-deletion guard with SUDO_USER fallback, confirm, and userdel -r are correct.


100-121: Shell toggle logic is consistent and safe

Good use of getent and usermod -s with clear messages.


170-179: Group creation flow looks good

Existence check + groupadd with clear messages.


180-200: Backup flow is well-hardened

Validates user selection and directory, timestamps the archive, and quotes paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant