feat: close the chord that let a teacher hibernate the room
Ctrl+Alt+Delete opened Plasma's session screen and a teacher hibernated a classroom computer from it. A hibernated room cannot be recovered by anybody standing in front of it, which on a Sunday morning is everybody. logout=false was already set and did not stop it. That restriction governs Plasma's own actions — what plasmashell draws in a menu or an applet. The chord is a KGlobalAccel shortcut registered by ksmserver and it asks D-Bus for the greeter without consulting a Plasma action at all. A restriction on a menu cannot see a key. Three layers, because each one alone has a way past it. The key. kglobalshortcutsrc unbinds every ksmserver session action and PowerDevil's Sleep, Hibernate, PowerDown and PowerOff, each entry marked immutable. It is deliberately not in the xdg directory with the other settings: kglobalacceld opens that file as a SimpleConfig, so it reads one file in the teacher's home and no system directory at all. Measured — with it in the cascade, kreadconfig6 reported the chord unbound while the shortcut server went on answering Ctrl+Alt+Del. classroom-desktop-reset copies the package's copy into place before the shortcut server starts, the same way the panel is copied out of the package at every login. The policy. A polkit rule refuses login1.suspend* and .hibernate* for the classroom user and for nobody else. This is the layer that matters: a key can be unbound and anything reaching logind can still ask. Refusing here rather than masking sleep.target keeps a technician's own account working, and is also what tells Plasma to stop drawing the button — CanSuspend and CanHibernate come back no. Hybrid sleep and suspend-then-hibernate have no action of their own in systemd 257; both are authorised through hibernate, so denying it denies all three. The greeter. Its D-Bus activation is shadowed with /bin/false, the same mechanism already used for the old notification daemon. Layer one removes the caller, this removes the callee. Measured in the lab, from the package, after a reboot: the escape reproduced first with the shadow removed — the greeter really does start — and then refused, exited 1, with it back. The chord reports nothing bound. systemctl suspend as the classroom user is denied. The maintenance chord and the display chord both still answer, by key code, after the shortcut file is replaced wholesale. A root process may still suspend, hibernate, reboot and power off. 182 checks pass across a logout and back. Screen locking stays disabled, the power button still does nothing, and reboot and shut down are not newly denied to anybody. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8db5e8dd9f
commit
23dff0b7b4
@@ -0,0 +1,86 @@
|
||||
# The keys that end a classroom session, taken away.
|
||||
#
|
||||
# A teacher pressed Ctrl+Alt+Delete, got Plasma's session screen with
|
||||
# Hibernate on it, and hibernated the room. This file is what closes that,
|
||||
# and it is worth being precise about why the lockdown already in
|
||||
# kdeglobals did not.
|
||||
#
|
||||
# [KDE Action Restrictions] logout=false stops *Plasma's own* logout
|
||||
# actions — the ones plasmashell draws in a menu or an applet. The
|
||||
# Ctrl+Alt+Delete chord is not one of those. It is a KGlobalAccel
|
||||
# shortcut registered by ksmserver, and pressing it calls the logout
|
||||
# greeter over D-Bus without ever asking a Plasma action whether it is
|
||||
# allowed. A restriction on a menu cannot see a key.
|
||||
#
|
||||
# WHY THIS FILE IS NOT IN THE XDG DIRECTORY WITH THE OTHERS.
|
||||
#
|
||||
# Every other classroom setting is installed into
|
||||
# /etc/ekklesia-classroom/xdg and reaches Plasma through KConfig's
|
||||
# cascade. That was tried here first and it does not work, which was
|
||||
# measured rather than reasoned about: with this file in the cascade,
|
||||
# kreadconfig6 reported the chord as "none" while kglobalacceld went on
|
||||
# answering Ctrl+Alt+Del. kglobalacceld opens kglobalshortcutsrc as a
|
||||
# SimpleConfig — no cascade, no system directories, no immutability from
|
||||
# anywhere but the file itself — so it reads exactly one file,
|
||||
# ~/.config/kglobalshortcutsrc, and nothing else.
|
||||
#
|
||||
# So this is installed to /etc/ekklesia-classroom/kglobalshortcutsrc and
|
||||
# classroom-desktop-reset copies it into the teacher's home before the
|
||||
# session's shortcut server starts. That is the same thing the classroom
|
||||
# already does with the panel: the file in the home directory is not
|
||||
# state, it is a copy of the package, replaced at every login so that an
|
||||
# update can always reach a room.
|
||||
#
|
||||
# KGlobalAccel stores every shortcut as
|
||||
#
|
||||
# Name=active,default,friendly name
|
||||
#
|
||||
# and repopulates whatever is missing from each component's registered
|
||||
# defaults when that component starts — which is why replacing the whole
|
||||
# file costs nothing: everything not named below comes straight back.
|
||||
# Measured in the lab, including the maintenance chord, which is
|
||||
# registered from its desktop entry and is bound again after the replace.
|
||||
#
|
||||
# Each key is marked [$i] — immutable — and that is what makes the
|
||||
# replacement stick: KGlobalAccel writes this file constantly, and
|
||||
# without the marker it would put the chord back the moment ksmserver
|
||||
# registered its actions again.
|
||||
#
|
||||
# Per key rather than per group, deliberately. Marking
|
||||
# [org_kde_powerdevil] immutable as a whole would also freeze the
|
||||
# brightness and keyboard backlight keys, which a classroom has no reason
|
||||
# to take away.
|
||||
#
|
||||
# The default column is set to none as well as the active one, so that
|
||||
# "reset to default" is not a way back to the chord.
|
||||
#
|
||||
# This is one of three layers. The other two are the polkit rule that
|
||||
# makes the sleep states unavailable to the classroom user at all, and the
|
||||
# D-Bus service file that leaves the greeter itself with nothing to start.
|
||||
|
||||
[ksmserver]
|
||||
# The chord itself.
|
||||
Log Out[$i]=none,none,Show Logout Screen
|
||||
# And every other way ksmserver offers to end the session. All of these
|
||||
# ship unbound; they are written out so that a future Plasma release
|
||||
# cannot introduce a default binding into a room without this file being
|
||||
# updated too.
|
||||
Log Out Without Confirmation[$i]=none,none,Log Out Without Confirmation
|
||||
LogOut[$i]=none,none,Log Out
|
||||
Halt Without Confirmation[$i]=none,none,Shut Down Without Confirmation
|
||||
Reboot[$i]=none,none,Reboot
|
||||
Reboot Without Confirmation[$i]=none,none,Reboot Without Confirmation
|
||||
Shut Down[$i]=none,none,Shut Down
|
||||
|
||||
[org_kde_powerdevil]
|
||||
# Sleep and Hibernate are bound by default to the XF86Sleep and
|
||||
# XF86Hibernate keys, which a classroom keyboard may well have. PowerDown
|
||||
# and PowerOff are the same story for XF86PowerDown and XF86PowerOff.
|
||||
#
|
||||
# The power *button* is already ignored at two layers; these are the
|
||||
# keyboard keys of the same name, which are a different path and were
|
||||
# never covered.
|
||||
Sleep[$i]=none,none,Suspend
|
||||
Hibernate[$i]=none,none,Hibernate
|
||||
PowerDown[$i]=none,none,Power Down
|
||||
PowerOff[$i]=none,none,Power Off
|
||||
Reference in New Issue
Block a user