But, no, one cannot just "exec /my/shell" if the shell in the password file is a program that doesn't offer such a command.
Being able to assign a login shell to an account is an important security feature. It's not simply a user preference mechanism. It can be used to bind an account to a "restricted shell":
When people use remote execution tools like (historically) rsh or ssh, the remote account's login shell is used.
You can replace an account's login shell with a program that parses the commands and allows only very limited access.
Here is an example such a script which I used for an account that accepted SSH tunnel connections for a remote desktop. (The remote Windows machine contained a "service" that called back to this machine via SSH, setting up a tunnel for accessing that Windows machine in the reverse direction.)
#!/bin/bash
if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
echo interactive login not permitted
echo "$@" >> ~/.log
exit 1
fi
case "$2" in
rdp )
while true ; do sleep 3600 ; done
;;
* )
echo that command is not allowed
exit 1
;;
esac
The only command allowed is "rdp", and what it does is put this "shell" to sleep, to keep the connection open. It's implemented as a built-in, right in the above case statement.
If this script exits, the login session or remote command is terminated.
The reason I did this is that the Windows machine held an unprotected SSH private key to be able to perform a password-less login to that Linux box. (This ran as a service, so even if the Windows machine were power-cycled, it would reconnect.)
If someone got into the Windows box and discovered and understood the setup, and the Linux account were not protected by this script, they would be able to use the unprotected private key to ssh into it, or run ssh commands, or scp files, etc.
This sort of thing has other applications; for instance, it could be used to give people real SSH git access, without shell access.
Being able to assign a login shell to an account is an important security feature. It's not simply a user preference mechanism. It can be used to bind an account to a "restricted shell":
https://en.wikipedia.org/wiki/Restricted_shell
When people use remote execution tools like (historically) rsh or ssh, the remote account's login shell is used.
You can replace an account's login shell with a program that parses the commands and allows only very limited access.
Here is an example such a script which I used for an account that accepted SSH tunnel connections for a remote desktop. (The remote Windows machine contained a "service" that called back to this machine via SSH, setting up a tunnel for accessing that Windows machine in the reverse direction.)
The only command allowed is "rdp", and what it does is put this "shell" to sleep, to keep the connection open. It's implemented as a built-in, right in the above case statement.If this script exits, the login session or remote command is terminated.
The reason I did this is that the Windows machine held an unprotected SSH private key to be able to perform a password-less login to that Linux box. (This ran as a service, so even if the Windows machine were power-cycled, it would reconnect.)
If someone got into the Windows box and discovered and understood the setup, and the Linux account were not protected by this script, they would be able to use the unprotected private key to ssh into it, or run ssh commands, or scp files, etc.
This sort of thing has other applications; for instance, it could be used to give people real SSH git access, without shell access.