Changing the shell (using chsh) via the command line in a script

In a startup script that sets up a machine, I want to run

chsh -s /bin/zsh

However, this asks for the user's password. How do I pass in the password as a parameter? Or if I have sudo power, can I somehow bypass that step? Or alternatively, is there another way to change the default startup shell?


Solution 1:

The following prevents locked-down accounts from changing their shells, and selectively lets people use chsh themselves WITHOUT sudo or su:

Simple setup that is still secure:

  1. Add this very top of /etc/pam.d/chsh:

    # This allows users of group chsh to change their shells without a password.
    #
    # Per: http://serverfault.com/questions/202468/changing-the-shell-using-chsh-via-the-command-line-in-a-script
    #
    auth       sufficient   pam_wheel.so trust group=chsh
    
  2. Create the chsh group:

    groupadd chsh
    

For any user allowed to change their shell:

    usermod -a -G chsh username

Money shot:

user@host:~$ getent passwd $USER
user:x:1000:1001::/home/user:/bin/bash
user@host:~$ chsh -s `which zsh`
user@host:~$ getent passwd $USER
user:x:1000:1001::/home/user:/usr/bin/zsh
user@host:~$ 

Solution 2:

chsh actually changes the line pertaining to a user in /etc/passwd, though a user can only change his/her own 'line' in /etc/passwd. Hence, if you want to change shell for another user, you need his / her passwd.

If you really want to do it (given the concerns in Lorenzo's post, and possible security concerns) here's how one can do this:

#visudo

This requires root privileges.

Say you're currently running as "alice" and want to change "bob's" shell without password;

Add to the file:

Cmnd_Alias     SHELL = /usr/bin/chsh
Runas_Alias    SH    = Bob
alice          ALL   = (SH) NOPASSWD: SHELL

This makes sure 'alice' can run on all hosts as the users in the group SH without a password the group of commands in SHELL.

Probably a bit far fetched to do it this way, but it is possible.

Be sure to read "man sudoers" before changing the sudores file with 'visudo', especially the messages related to security!

Solution 3:

You need to pass the username; doing this via sudo (or by root) will allow you to set a user's password/shell without being asked the old password. Please check man chsh for further information.

Now my question is: why would you want to do that? If it's a set-up script, shouldn't you just change the users' shell at creation time (i.e. when launching adduser)? If you're cloning a system remotely, shouldn't you change it in /etc/passwd first? I see no reasons for doing it via a script, unless you automated the whole installation process and the selection of shells to be installed comes after the creation of the first user.