无需重新验证即可在两个打开的 X 会话之间切换

Sté*_*hon 7 xorg lightdm switch-user

需要:快速切换成对用户。

在一个系统上,有一对在某种程度上等效的用户帐户。

更具体地说,对于给定的对:

  • 这两个账户都是普通的Unix账户,只是碰巧被同一个物理用户(人)使用。
  • 同一个人几乎总是打开两个图形 X 会话,每个用户帐户一个,但一次只需要在屏幕上看到一个。
  • 这些是完全独立的帐户,具有不同的邮件配置、浏览器历史记录、文件,具有不同的安全级别。
  • 帐户之间没有共享任何内容,在同一个 X 会话中混合这些帐户是没有意义的(即使这些帐户之间的复制粘贴也是无用的)。
  • 然而,用户每天需要在它们之间切换多次。
  • 放置一个呼叫按钮很容易,dm-tool switch-to-user但实际上用户必须在每个开关上重新进行身份验证,会降低生产力。

需要允许在两个图形 X 会话之间快速切换(例如,单击面板上的按钮)而无需重新验证

系统信息和安全含义(放松本地安全应该没问题)

  • 系统是Xubuntu 16.04 Xenial。
  • X 席位、登录、锁定、切换由 lightdm 开箱即用完成。

我知道在保持其他操作安全的同时放松一对用户之间的安全性比通常的锁定和开关方法更复杂。幸运的是,在我们的案例中,由于机器位于受控场所,因此即使丢失了一些本地安全性也没关系。例如,如果一个需求的解决方案导致一些通常会自动锁定会话(如暂停+恢复)的场景不再锁定,对于这对用户,甚至系统上的每个用户,它可能是可以接受的。

不过,如果用户可以手动锁定会话,那就太好了。

此外,必须保留远程安全性(例如,对这些帐户的 SSH 访问不得受到此问题解决方案的影响)。

发帖前先搜索

方法 1:使用 lightdm 工具但以某种方式进行调整

基本上,使用dm-tool switch-to-user *username*并安排用户的会话不被锁定。

工作于 12.04

在 Ubuntu 12.04 中,我们禁用了 light-locker 以防止会话锁定,并在每个运行此命令的用户桌面上设置一个图标:

dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DisplayManager $XDG_SEAT_PATH org.freedesktop.DisplayManager.Seat.SwitchToUser string:$CALLEDUSERNAME string:somesessionname
Run Code Online (Sandbox Code Playgroud)

这有效:会话切换到提到的用户$CALLEDUSERNAME

在 16.04 中失败

这在 16.04 上并不令人满意:它切换到$CALLEDUSERNAME预选的迎宾员,但仍需要身份验证。所以,基本上结果是一样的dm-tool switch-to-user *username*。我还没有完全检查,但可能它只是与dm-tool原因完全相同的代码路径。

更多搜索

错误 #1205384“可以通过切换到控制台来绕过锁定”中寻找提示:错误:lxsession 包:Ubuntu,没有任何具体工作。

dm-toolhttp://archive.ubuntu.com/ubuntu/pool/main/l/lightdm/lightdm_1.18.1-0ubuntu1.tar.gz 上查看了源代码(来自Ubuntu 上的链接– xenial 中的 lightdm 包的详细信息) .

原理如下:

  • dm-tool可执行文件调用 dbus 将消息发送到lightdm.
  • lightdm在 中接收 dbus 事件handle_seat_call(),调用seat_switch_to_user()
  • seat_switch_to_user()调用g_signal_connect (session, SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (switch_authentication_complete_cb), seat);注册回调switch_authentication_complete_cb()
  • seat_switch_to_user()然后调用session_start()它显然创建了一个全新的 X 会话以获取身份验证(不确定细节,可能运行session_child_run()它调用 PAM)
  • switch_authentication_complete_cb() 然后切换到现有会话或创建新会话

下一步

在这种情况下,我们能否以某种方式指示 PAM 允许而无需提示,但该更改不会干扰任何其他情况?理想情况下,PAM 行为只会在切换用户情况下发生变化,而不会在登录情况或解锁情况下发生变化。也许额外的 X 会话仍会启动,但不会等待用户输入密码。

方法二:只要算出VT编号,使用chvt

  • 随时获取目标用户对应的VT(可能是因为在登录时,脚本会读取XDG_SEAT_PATH 以获取座位号,并与Xorg告诉相应的vt 号的命令行连接并将结果写入常规位置)。
  • 当需要切换到用户时,获取 vt 号并使用chvt. 可能需要一些 sudo 配置。

  • 优点:更简单,没有乱七八糟的lightdm,PAM 或其他什么,甚至没有明确的依赖lightdmso 可能在其他地方工作。

  • 缺点:找出用户和 VT 号码之间的连接的黑客方法?

结论,复述问题

  • 关于第一种方法的任何评论(通过dm-tool,PAM 调整)?
  • 关于第二种方法(通过chvt)的任何评论?

感谢您的关注。

Sté*_*hon 3

总结:已完成,可用,当前解决方案仅在协作多用户环境下可以接受,可以改进。

我编写了一个可用的概念验证补丁来lightdm完成这项工作。

它在这里满足了我们的需要!

请参阅下面的安装说明。

先决条件

  • 具有至少两个用户帐户的系统,并且用户愿意允许在图形会话之间快速切换而无需重新输入密码。
  • 每个用户都可以使用任何完全使用 的桌面环境lightdm,包括light-locker用于会话锁定。Unity 和 XFCE 应该可以工作。

使用 XFCE 进行测试。

如何使用,如何查看变化

在执行更改之前尝试此操作:

  • 让用户 A 打开图形会话
  • 让用户 B 打开另一个图形会话

现在,您可以从两个会话中的任何一个执行以下操作:

    dm-tool switch-to-user userA
Run Code Online (Sandbox Code Playgroud)

或者

    dm-tool switch-to-user userB
Run Code Online (Sandbox Code Playgroud)

变更的影响

如果不进行更改,您将看到要求输入密码的登录提示。

进行更改后,您将看到立即切换,而无需登录提示。

这里的切换非常快。比 Ubuntu 12.04 快得多,甚至在某些情况下没有闪烁。

实际使用

为了获得最大的好处,我建议在停靠/面板/码头(无论它在您的特定桌面环境中被称为什么)中的某个位置创建一个启动器图标,单击时运行:

    dm-tool switch-to-user name-of-other-user
Run Code Online (Sandbox Code Playgroud)

安全警告

应用以下命令将系统的lightdm软件包替换为修改后的版本,允许在当前登录图形会话的任意两个用户之间进行切换。这削弱了系统安全性,例如用户A以图形方式登录,锁定会话,离开,用户B登录。用户B可以解锁用户A会话并在任何时候打开它时切换到它。反之亦然(交换 A 和 B)。

sudo如果没有管理员访问权限(假设,特别是对于软件包安装),则无法应用更改。

它对我们来说工作得很好,但仍然请注意,这lightdm是一个重要的包,这可能会破坏它或引入其他微妙的错误。破坏它将会破坏所有用户使用图形登录会话的能力。您对以下命令的使用负全部责任。你被警告了。

永久性警告

变化几乎是永久性的。重新启动后它们会留下来。要恢复它们,请安装(使用aptitudesynaptic其他方式)常规lightdm*软件包来替换更改的软件包。

请注意,每当 Ubuntu 更新lightdm软件包并安装更新时,它们都会恢复更改。管理员可以再次应用它们。

可能的改进(恢复安全性)

这种概念验证可以通过巧妙地使用例如 Unix 组来完善。 lightdm仅当当前用户和目标用户列在具有常规文件名的任何组中时才允许切换,例如lightdm-quickswitch-anystringfoo. 这样的改变(可能与其他改变一起)最终可能会合并到一些官方解决方案中。

命令

我建议登录文本控制台(按 Ctrl-Alt-F1 并登录)来执行以下步骤。这允许重新启动 lig​​htdm 而不会丢失当前 shell。

将以下命令复制粘贴到 bash shell 中,它将进行调整lightdm以执行更改。

(
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*'
)
Run Code Online (Sandbox Code Playgroud)

请注意,下面的命令将立即关闭所有图形会话,而没有机会保存数据,因此所有用户都应正确关闭应用程序并首先保存所需的数据。

如果软件包确实安装良好,则可以使用以下命令立即激活更改:

    sudo service lightdm restart
Run Code Online (Sandbox Code Playgroud)

或通过重新启动。

反馈

对你起作用吗?你能想出一个变体吗?欢迎反馈。

  • 谢谢 Stéphane,终于再次实现了两次点击和超快速的用户切换!出于安全考虑,“不锁定源会话”而不是“解锁目标会话”会更好吗?这样用户仍然可以显式锁定他们的会话。顺便说一句,在 shell 脚本在全新的 16.04.1 安装上运行之前,需要将源代码库添加到sources.list。现在,如果我也可以在切换用户时继续播放音乐就好了…… (2认同)
  • 看来“systemd”提供了一些有用的原语来实现解决方案。优点:不需要修补 lightdm,不会与 lightdm 绑定,但也可以与 Gnome、KDE ​​等一起使用。我将了解如何使用 `loginctl lock-session 构建一些东西;OTHERUSERSESSION=\`some_magic_here\` ; sudo bash -c“loginctl激活$OTHERUSERSESSION;loginctl解锁会话$OTHERUSERSESSION”`。 (2认同)