Switching between two opened X sessions without reauthenticating
Need: quick switch between pairs of users.
On a system there is a pair of user accounts that are somehow equivalent.
More concretely, for a given pair:
- Both account are regular Unix accounts, they just happened to be used by the same physical user (person).
- The same person has nearly always two graphical X sessions opened, one for each user account, but only needs to see one at a time on the screen.
- These are completely separate accounts with different mail configurations, browser histories, files, with different levels of security.
- Nothing is shared between the accounts, there would be no point in mixing those accounts on same X session (even a copy-paste between those would be useless).
- Yet the user needs to switch between them many times a day.
- It is easy to put a button that calls
dm-tool switch-to-user
but practically the user then has to re-authenticate on every switch and that is a productivity loss.
The need is to allow quick switch between the two graphical X sessions (e.g. at the click on a button on a panel) without having to reauthenticate.
System info and security implication (relaxing local security should be okay)
- System is Xubuntu 16.04 Xenial.
- X seats, login, locking, switching is done by lightdm out-of-the-box.
I am aware that relaxing security between pair of users while keeping other operations secure is more complicated than the usual lock-and-switch approach. Fortunately, in our case it's okay if some local security is lost since the machine is in controlled premises. For example, if a solution to the need causes some scenario that would normally automatically lock session (like suspend+resume) to no longer lock, for this pair of users, or even every user on the system, it may be acceptable.
Still, it's good if the user can manually lock the session.
Also, remote security must be preserved (for example SSH access to those accounts must not be affected by a solution to this problem).
Search before you post
Approach 1: use lightdm tools but adjust somehow
Basically, use dm-tool switch-to-user *username*
and arrange for the user's session to not get locked.
Worked in 12.04
In Ubuntu 12.04 we disabled light-locker to prevent session locking, plus set an icon on each user's desktop that ran this command:
dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DisplayManager $XDG_SEAT_PATH org.freedesktop.DisplayManager.Seat.SwitchToUser string:$CALLEDUSERNAME string:somesessionname
This worked: session switched to the user mentioned as $CALLEDUSERNAME
.
Fails in 16.04
This is unsatisfactory on 16.04: it switches to a greeter with $CALLEDUSERNAME
pre-selected but authentication is still needed. So, basically the result is the same as dm-tool switch-to-user *username*
. I haven't checked fully but probably it's just going exactly the same code paths as what dm-tool
causes.
More search
Looked for hints in Bug #1205384 “Lock can be circumvented by switching to console” : Bugs : lxsession package : Ubuntu, nothing concretely working.
I've looked at dm-tool
source code at http://archive.ubuntu.com/ubuntu/pool/main/l/lightdm/lightdm_1.18.1-0ubuntu1.tar.gz (from link on Ubuntu – Details of package lightdm in xenial).
Principle looks like this:
-
dm-tool
executable calls dbus to send message tolightdm
. -
lightdm
receives dbus event inhandle_seat_call()
, callsseat_switch_to_user()
-
seat_switch_to_user()
callsg_signal_connect (session, SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (switch_authentication_complete_cb), seat);
to register callbackswitch_authentication_complete_cb()
. -
seat_switch_to_user()
then callssession_start()
which apparently creates a whole new X session to get authentication (not sure about the details, perhaps runssession_child_run()
which calls PAM) -
switch_authentication_complete_cb()
then switches to existing session or create new one
Next step
Can we somehow instruct PAM to just allow without prompting in this case, but without that change disturbing any other case? Ideally PAM behavior would change only in the switch-user case, not in the login case or the unlock case. Maybe the extra X session would still be started but not waiting for the user to type a password.
Approach 2: just figure out the VT number and use chvt
- Get at any time which VT corresponds to target user (perhaps because at login time, a script would read XDG_SEAT_PATH to get seat number, join with
Xorg
command line which tells the corresponding vt number and write the result into a conventional place). When needing to switch to user, get the vt number and use
chvt
. Probably some sudo config will be needed.Advantage: simpler, no mess with
lightdm
, PAM or whatever, not even an explicit dependency onlightdm
so might work elsewhere.- Drawback: hackish way to figure out the join between user and VT number?
Conclusion, retell question
- Any comment about the first approach (via
dm-tool
, PAM adjust)? - Any comment about the second approach (via
chvt
)?
Thank you for your attention.
Solution 1:
Summary: done, usable, current solution is acceptable only in a cooperative multi-user environment, can be improved.
I wrote a usable-proof-of-concept patch to lightdm
that does the job.
It does what we need here!
See below for installation instructions.
Prerequisites
- A system with at least two user accounts and users willing to allow quick switch between graphical sessions without retyping passwords.
- Each user can use any desktop environment that fully uses
lightdm
, including usinglight-locker
for session locking. Unity and XFCE should work.
Tested with XFCE.
How to use, how to see the changes
Try this before performing the changes:
- have user A open a graphical session
- have user B open another graphical session
Now from any of the two session you can do :
dm-tool switch-to-user userA
or
dm-tool switch-to-user userB
Effect of the changes
Without the change you will see a login prompt requiring to type a password.
With the change you will see an immediate switch without login prompt.
Here the switch is really quick. Much quicker than in Ubuntu 12.04 and even without flickering in some cases.
Practical use
For maximum benefit, I recommend to create a launcher icon somewhere in a dock/panel/wharf (whatever it is called in your particular desktop environment) that when clicked runs:
dm-tool switch-to-user name-of-other-user
SECURITY WARNING
Applying the commands below replaces system's lightdm
packages with modified versions that allow switching between any two users currently being logged in a graphical session. This weakens system security, for example user A logs in graphically, locks session, walks away, user B logs in. User B can unlock user A session and switch to it any time it is opened. And the other way round (swap A and B).
The changes cannot be applied without administrator access (sudo
is assumed, especially for package install).
It works fine for us, but still, note that lightdm
is an important package and this might break it or introduce other subtle bugs. Breaking it will break ability to use graphical login sessions for all users. You are fully responsible for the use of the commands below. You have been warned.
Permanence warning
Changes are near-permanent. They stay after rebooting.
To revert them, install (using aptitude
, synaptic
or whatever) the regular lightdm*
packages which will replace the changed ones.
Notice that any time Ubuntu updates lightdm
packages, and the updates are installed, they will revert the changes. Administrator can apply them again.
Possible refinement (restore security)
This proof-of-concept could be refined by a clever use of e.g. Unix groups. lightdm
would only allow the switch if current and target users are listed in any group with a conventional filename, like lightdm-quickswitch-anystringfoo
.
Such a change (possible along with others) could be eventually merged into some official solution.
Commands
I suggest to login on a text console (press Ctrl-Alt-F1 and login) to do the steps below. This allows to restart lightdm without losing the current shell.
Copy-paste the commands below in a bash shell and it will adjust lightdm
to perform the changes.
(
set -euxv
echo Making sure system has necessary packages.
echo Installing packages will be done only once but might be long as it may fetch around 40Mbytes of data from the Internet.
sudo apt-get --assume-yes install devscripts
echo Enabling source packages in apt.
sudo sed -i '/^#\sdeb-src /s/^# *//' "/etc/apt/sources.list"
sudo apt-get update
sudo apt-get --assume-yes --no-install-recommends build-dep lightdm
THETEMPDIR=$( mktemp -d )
cd $THETEMPDIR
echo Getting package source
apt-get source lightdm
cd */
pwd
if [ -d .pc ]
then
quilt push -a || echo "Quilt returned an error code, we ignore it because we saw it was sometimes irrelevant."
quilt new allow_switch_between_logged_users_without_authentication
quilt add src/seat.c
fi
patch -p0 <<EOF
--- src/seat.c 2016-07-29 05:19:45.000000000 +0200
+++ src/seat.c 2016-08-15 19:37:11.693364683 +0200
@@ -1578,6 +1578,20 @@
l_debug (seat, "Switching to user %s", username);
+ if (session)
+ {
+ l_debug (seat, "WIP quick switch: found inactive existing user session, switching to it: %s. For details, see https://askubuntu.com/questions/811953/switching-between-two-opened-x-sessions-without-reauthenticating", username);
+
+ session_unlock (session);
+ seat_set_active_session (seat, session);
+
+ l_debug (seat, "WIP quick switch to user complete: %s. For details, see https://askubuntu.com/questions/811953/switching-between-two-opened-x-sessions-without-reauthenticating", username);
+ return TRUE;
+ }
+
+ l_debug (seat, "WIP quick switch: no session for user, switching to greeter: %s. For details, see https://askubuntu.com/questions/811953/switching-between-two-opened-x-sessions-without-reauthenticating", username);
+
+
/* Attempt to authenticate them */
session = create_user_session (seat, username, FALSE);
g_signal_connect (session, SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (switch_authentication_complete_cb), seat);
EOF
if [ -d .pc ]
then
quilt refresh
ls -al debian/patches/allow_switch_between_logged_users_without_authentication
cat debian/patches/allow_switch_between_logged_users_without_authentication
fi
echo Building modified packages.
dch -lquickswitch "Allow dm-tool switch-to-user username to switch without authentication if user session is already opened. WARNING: this negates local security. For details, see https://askubuntu.com/questions/811953/switching-between-two-opened-x-sessions-without-reauthenticating"
head debian/changelog
time dpkg-buildpackage -rfakeroot -uc -b
echo Installing modified packages.
cd ..
PACKAGESTOINSTALL=$( for DEBNAME in *.deb ; do PACKAGENAME="$( echo "$DEBNAME" | cut -f 1 -d _ )" ; if dpkg -l $PACKAGENAME | grep -q ^ii ; then echo $DEBNAME ; fi ; done ) ; sudo dpkg --install ${PACKAGESTOINSTALL}
dpkg -l '*lightdm*'
)
Notice that the command below will close immediately all graphical sessions without a chance to save data, so all users should close applications properly and save needed data first.
If packages did install well, the change can be activated immediately with :
sudo service lightdm restart
or by rebooting.
Feedback
Does it work for you? Can you think of a variant? Feedback welcome.