DEV Community

Cover image for Changing the Login Shell with Security and Interactivity
Rafael Mori
Rafael Mori

Posted on

Changing the Login Shell with Security and Interactivity

Changing a user's login shell can be a simple task, but it involves several considerations to ensure security and convenience. This article presents a Bash script that exemplifies how to perform this change interactively and securely, using the dialog tool for user interaction and detailed validations to prevent errors or unsafe configurations.

Overview of the Script

The script changes the login shell in multiple steps, ensuring each action is validated before being applied. Among the main features of the script are:

  1. Permission verification: The script requires the user to be in the sudo group, ensuring that only users with administrative privileges can make changes.
  2. Interactivity with dialog: The dialog tool is used to display interactive menus, making it easy for the user to choose the new shell.
  3. Validation of available and safe shells: The script checks if the chosen shell is listed in /etc/shells and is considered safe.
  4. Shell change: Multiple methods are implemented to perform the shell change, with checks at each step.
  5. Confirmation and feedback: The user is informed about the success or failure of the operation and instructed to restart the session if necessary.

Script Components and Functionality

1. Dependency Check

Before starting, the script checks if the user belongs to the sudo group and if the dialog command is installed:

if ! groups | grep -q '\bsudo\b'; then
    printf "The user is not in the sudo group.\n"
    exit 1
fi

if ! command -v dialog &> /dev/null; then
    printf "The dialog command is not available. Do you want to install it? (y/n) "
    read -r response
    if [[ ! "$response" =~ ^[Yy]$ ]]; then
      printf "Dialog installation canceled.\nPackage required to continue.\n"
      exit 0
    fi
    if ! sudo apt-get install -y dialog; then
        echo "Could not install dialog."
        exit 1
    fi
fi
Enter fullscreen mode Exit fullscreen mode

This initial validation prevents the script from running without the necessary prerequisites, reducing the likelihood of failures.

2. Listing Available Shells

The script uses the /etc/shells file to retrieve the list of available shells and display them to the user in an interactive menu:

_AVAILABLE_SHELLS=$(grep -v '^#' "/etc/shells" | tr '\n' ' ')
_SHELL=$(dialog --menu "Choose the shell you want to use:" 15 50 10 $_AVAILABLE_SHELLS 3>&1 1>&2 2>&3)
Enter fullscreen mode Exit fullscreen mode

This method ensures that only valid shells can be selected.

3. Safe Shell Validation

Before performing the change, the script checks if the chosen shell is safe by comparing it with a predefined list of allowed shells:

check_shell_safe() {
    local shell=$1
    local allowed_shells=(
      "/bin/sh" "/usr/bin/sh"
      "/bin/bash" "/usr/bin/bash"
      "/bin/zsh" "/usr/bin/zsh"
      # Other allowed shells
    )
    local forbidden_shells=("/bin/false" "/usr/sbin/nologin")
    [[ " ${allowed_shells[*]} " == *" $shell "* ]] && [[ -x $shell ]] && [[ $shell == /* ]] && [[ ! " ${forbidden_shells[*]} " == *" $shell "* ]]
}
Enter fullscreen mode Exit fullscreen mode

This validation prevents unsafe or non-functional shells from being set as default.

4. Changing the Shell

The script implements three methods to change the user's shell:

  1. Using the chsh command:
   chsh -s "$SHELL"
Enter fullscreen mode Exit fullscreen mode
  1. Using the usermod command:
   sudo usermod --shell "$SHELL" "$(id -un)"
Enter fullscreen mode Exit fullscreen mode
  1. Directly editing the /etc/passwd file:
   sudo sed -i "s|$_OLD_LINE|$_NEW_LINE|" "/etc/passwd"
Enter fullscreen mode Exit fullscreen mode

These methods are applied in sequence, ensuring redundancy if one of them fails.

5. Verification and Feedback

After changing the shell, the script verifies whether the change was applied successfully and informs the user:

if verify_shell_change "$SHELL"; then
    dialog --msgbox "Shell successfully changed to $SHELL." 10 50
else
    dialog --msgbox "Could not change the shell." 10 50
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Importance of Validations

The validations implemented in the script ensure that only valid and safe shells are configured. This prevents issues such as:

  • Setting a nonexistent or invalid shell, making it impossible for the user to log in.
  • Using unsafe or disabled shells by default (e.g., /bin/false or /usr/sbin/nologin).

Conclusion

This script demonstrates how to automate and simplify the process of changing login shells with security and interactivity. It can be adapted to meet the specific needs of an environment, but best practices for validation and user feedback should be maintained to ensure its reliability and usability.

If you have questions or want to customize the script for your system, feel free to adjust the lists of allowed and forbidden shells or add new validation methods!

For more details, check out the script on GitHub: View the Gist. Feel free to follow me on GitHub, leave a comment, or contribute to the discussion!

Top comments (0)