// The classroom user cannot put the room to sleep. // // The second layer under the shortcut that was removed from // kglobalshortcutsrc, and the one that matters: a key can be unbound, but // anything that can reach logind can still ask for a suspend. PowerDevil // does, the logout greeter does, `systemctl suspend` from the maintenance // terminal does, and a future Plasma applet would too. They all go through // the same polkit actions, so this is the one place that answers all of // them at once. // // Answering here rather than masking sleep.target is deliberate. Masking // is machine-wide and would take suspend away from a technician's own // account as well; worse, it would be invisible to Plasma, which would go // on offering a Hibernate button that silently failed. logind is asked // whether this *user* may sleep, so a NO here is both enforcement and the // supported way to tell the desktop not to offer it: CanSuspend() and // CanHibernate() come back "no" and Plasma stops drawing the buttons. // // Scoped to the classroom user by name. Every other account — a // technician's, root's — is left entirely alone, and nothing here touches // power-off or reboot for anybody. A tech standing at the machine, or on // SSH, can still shut it down and start it up. // // To lift this for maintenance, drop a file of the same name into // /etc/polkit-1/rules.d/, which polkit reads ahead of this one. polkit.addRule(function (action, subject) { if (subject.user !== "classroom") { return polkit.Result.NOT_HANDLED; } // Every sleep state logind exposes, present and future. systemd maps // HybridSleep() and SuspendThenHibernate() onto the hibernate // actions today rather than giving them action ids of their own; the // two spellings are matched anyway so that a systemd release which // splits them out does not quietly reopen this. // // The -multiple-sessions and -ignore-inhibit variants are the same // operation asked for in different circumstances, so the prefixes are // matched rather than the exact ids. var sleeping = [ "org.freedesktop.login1.suspend", "org.freedesktop.login1.hibernate", "org.freedesktop.login1.hybrid-sleep", "org.freedesktop.login1.suspend-then-hibernate", ]; for (var i = 0; i < sleeping.length; i++) { if (action.id.indexOf(sleeping[i]) === 0) { polkit.log( "ekklesia-classroom: refusing " + action.id + " for the classroom user" ); return polkit.Result.NO; } } return polkit.Result.NOT_HANDLED; });