One of the more curious problems of running Linux on desktops is handling the local device access. The idea is usually quite simple: local users should have access to devices such as removable media (floppies, pendrives), scanners, speakers, webcams and ability to power off or reboot the computer. At the same time, remote users should have that access restricted.
Why? I think the main rationale behind this is that those users have physical access to those functions (yes, you could say that they have physical hard drive access too). They can insert the floppies, plug the pendrive, press the power button or just pull out the plug. They usually suffer the speaker noises and scare in front of the webcam.
At the same time, remote (or inactive users) shouldn’t be given the right to shut down the system unexpectedly, shout into the speakers, stream the user’s webcam or install Windows to his pendrive. I think that doesn’t need explaining.
I would like to shortly describe a few attempts to solve the problem and the issues with them.
The no-solution of unlimited access
The simplest solution is to give users unlimited access to the listed resources. However, this only satisfies one of the goals and therefore can work only in pure single-user environment.
The plugdev group solution
This solution is based on standard *nix access management. The relevant devices are owned by a dedicated group or groups (like
video…) and therefore can only be used by users belonging to those groups.
Sadly, this solution has more disadvantages than advantages. The access assignments are basically static. Each user needs be given access explicitly, and retains it throughout local and remote sessions.
In fact, this is an acceptable solution for a single-local-user system. Assuming that all other users are remote users, we can safely grant full access to the only user that is supposed to be able to use the machine locally (he’s most likely got root access too).
Dynamic groups via pam_group
What if we could dynamically add users to the
plugdev group (and similar) whenever they log in locally? This is basically the solution which can be achieved with the help of
In this case, the access to the relevant groups is given for local logins in form of supplementary groups for the process (session). That is, the user who logged in locally implicitly belongs to the groups and the same user logged in remotely doesn’t have access to the devices — even if both sessions are active simultaneously.
While this seems near to perfect, it has two disadvantages. First of them is spelled out on top of the manpage and configuration file: if user can create a setgid executable, he can use it to acquire a persistent access to the groups independent of the location. Therefore, the solution is only beneficial when users are restricted from running their own executables.
The other problem is that multiple local sessions are given equal access to the devices. That is, if one user locks out his session and the other logs in, the locked session can still use (and block) all the devices.
Dynamic permissions via ConsoleKit and logind
The basic idea is that there is a daemon that tracks user logins (seats). The daemon is responsible for complete control of device permissions and action access based on logged in users and the active session.
That said, the solution is the most flexible and secure one. With the use of ACLs on devices and abstraction over power actions, the users can be given minimal permissions necessary. You could say that it can solve all the problems. Plus achieve even more, like blocking shutdown actions while writing CDs.
However, there’s one simple problem. They are not really well documented. The former is supposedly unmaintained, the latter is tightly bound to systemd and far from being portable. Upstream seems to be focusing on telling others how to write different kinds of applications rather than documented what they have written.
Therefore, most of the information in this section is either discovered or guessed. I haven’t seen a comparison of ConsoleKit with logind either.
Honestly? I have no idea what the future would look like. Some developers are working on running logind without systemd — but that looks like tilting at windmills to me. It may help for a while but the number of issues will grow over time, and it still won’t help on systems which are not modern GNU/Linux.
The other solution is to revive ConsoleKit. However, it will need to grow a logind-compatible interface or otherwise it won’t be useful for systemd purists like GNOME, and possibly a more modern Linux backend utilizing cgroups.
Curious enough, the «tiny daemon» of logind has a similar amount of code as the whole ConsoleKit, even though ConsoleKit supports larger number of platforms and logind heavily relies on other components of systemd doing the right thing™.