cockpit-project / cockpit

Cockpit is a web-based graphical interface for servers.
http://www.cockpit-project.org/
GNU Lesser General Public License v2.1
10.84k stars 1.09k forks source link

Improve error message for unsupported shells #20741

Open avibrazil opened 1 month ago

avibrazil commented 1 month ago

Explain what happens

  1. Change user shell to /bin/xonsh or /usr/bin/xonsh
  2. Try to login with this user; you'll get permission denied

System logs (journalctl) shows successful login but then end of session. See below.

Xonsh is a Python-powered Unix shell and it was installed from Fedora's packages:

# rpm -qi xonsh
Name        : xonsh
Version     : 0.14.1
Release     : 2.fc40
Architecture: noarch
Install Date: Wed 26 Jun 2024 04:52:38 PM -03
Group       : Unspecified
Size        : 6356150
License     : BSD-2-Clause and MIT
Signature   : RSA/SHA256, Sat 27 Jan 2024 12:54:42 PM -03, Key ID 0727707ea15b79cc
Source RPM  : xonsh-0.14.1-2.fc40.src.rpm
Build Date  : Sat 27 Jan 2024 07:00:30 AM -03
Build Host  : buildvm-s390x-20.s390.fedoraproject.org
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : https://xon.sh
Bug URL     : https://bugz.fedoraproject.org/xonsh
Summary     : A general purpose, Python-ish shell
Description :
xonsh is a Python-powered, cross-platform, Unix-gazing shell language and
command prompt.

The language is a superset of Python 3.6+ with additional shell primitives.
xonsh (pronounced conch) is meant for the daily use of experts and novices
alike.

Version of Cockpit

320

Where is the problem in Cockpit?

None

Server operating system

Fedora

Server operating system version

40

What browsers are you using?

Firefox, Safari macOS, Safari on iPhone, Safari on iPad

System log

Jul 10 20:21:35 myhost.com systemd[1]: Started session-77.scope - Session 77 of User myuser.
Jul 10 20:21:35 myhost.com cockpit-session[25398]: pam_unix(cockpit:session): session opened for user myuser(uid=1000) by myuser(uid=0)
Jul 10 20:21:35 myhost.com systemd[1]: session-77.scope: Deactivated successfully.
Jul 10 20:21:35 myhost.com systemd-logind[1991]: Session 77 logged out. Waiting for processes to exit.
Jul 10 20:21:35 myhost.com systemd-logind[1991]: Removed session 77.
martinpitt commented 1 month ago

Cockpit makes one assumption about the login shell: exit 71 exits the shell with code 71. I take it xonsh doesn't do that?

Sorry, but Cockpit has to do some very minimal check if the user's login shell is valid (as opposed to e.g. /bin/false or /sbin/nonexisting). This means that you can't use Cockpit with a shell like that.

avibrazil commented 1 month ago

Indeed doesn’t do that, just checked.

Why cockpit has such an exquisite and picturesque requirement about the user shell? I’m ready to request xonsh to do that via a bug report, but what is the reason I should put there?

I consider xonsh an innovation in the shell space, specially in history handling, but has much more desired features. I’m getting ready to switch even the root user shell to xonsh. Seems weird to me that cockpit will impose a constraint for this movement, keeping things as they were in 1975.

Thank you in advance

avibrazil commented 1 month ago

I’d also recommend and suggest to change the error message in the UI to something like “unsupported shell” or be more verbose and specific in the logs.

It took me ages to discover that the problem is related to the default user shell, since I changed the login shell a long time ago, using it successfully, but use cockpit only occasionally for administrative tasks.

martinpitt commented 1 month ago

OK, reopening to look into improving the error message.

The problem is that it shouldn't be possible to log into Cockpit for (hand-wavy) "disabled/invalid" shells, such as system users with /bin/false or /sbin/nologin. We need some way to determine whether that's the case. Actual shell logins don't have that problem as false or nologin will just immediately exit, but cockpit isn't a shell program -- we need to start something else as session leader (cockpit-bridge). We even started that through the shell in the past, but that ran into the very same problem -- there isn't enough common ground/syntax between all possible shells to do e.g. input redirection. We also tried to read /etc/shells, but it's also too inconsistent and led to problems. So the third iteration was the exit 71 trick which gives the fewest problems overall.

This is a really tough problem unfortunately.

avibrazil commented 1 month ago

Ok, much clearer now.

Just to add that Xonsh is in /etc/shells and I think it will behave as needed by Cockpit. But not the exit 71 hack for now.

supakeen commented 1 month ago

@martinpitt Would it make sense to instead of exit 71 (which is not POSIX) use say echo 71 or one of the other POSIX required commands for shells? :)

martinpitt commented 1 month ago

@supakeen it'd be much harder, as you need to do input redirection, string allocation, etc. -- and all of that from a minimal suid root wrapper; and reading input from a program is by itself hard in C. So that doesn't fill me with joy either..