User & Session Management - Part 1

Everything a File

One of the ideas of Unix and all members of the Unix family, like MacOS, but also derivatives like Linux, is that “Everything is a file.” One way to explain this concept is to say everything appears somewhere in the file system. For instance, every device you can read from and write into has a file link in the /dev directory. Another approach is to state that everything is a file, process, or device and that even processes and devices are represented by file links.

That's nice, but what is a user? One thing is sure: users are not represented just by a file. This question has been introduced previously. In the manual of an ancient Unix operating system, Multics, they propose a possible answer called the 'user-process group.' Citing this manual1: a user-process group is a collection of one or more processes dedicated to serving one logged-in user. And, of course, system resources are assigned to this group of processes.

Whatever the reason, this concept did not make it into most Unix systems, and certainly not in Linux, until recently.

Slices and Scopes

But before we go into more detail, let’s talk about slices and scopes. A concept introduced by the Linux Control Group (cgroup) system and is managed by systemd.

In systemd, a slice unit is a way to organize and manage resources for a group of processes in a structured manner. This is done by creating a new section in the cgroup system, like a process family tree. Units that handle processes, mainly 'scope' and 'service' units, can be placed into a specific slice. You can limit resources for each slice, like how much memory or CPU power it can use. These limits apply to all the processes in all the units within that slice. The slices are arranged like a family tree, with parent and child slices. This hierarchy helps in managing resources more efficiently.

Systemd scopes are units that manage a group of system processes. Unlike service units, they don't start new processes on their own. Instead, they manage processes that were created externally. The primary use of scope units is to group the worker processes of a system service. This helps keep things organized and manage the resources these processes use.

systemd-logind

Let’s introduce systemd-logind, a system service that manages user logins. The man page of this service explains it very clearly: This login manager keeps track of users, their sessions, the processes they're running, and whether they're active or idle. It does this by creating a slice unit for each user under 'user.slice,' and a scope unit under that for each session a user is currently logged into. Additionally, a per-user service manager is started as a system service instance of 'user@.service' for each user who is logged in.

In simpler terms, systemd-logind organizes and manages users and their sessions by creating a dedicated section (slice) for each user and a sub-section (scope) for each session. It also starts a service manager for each logged-in user to handle their services. What systemd is doing here is revisiting the old Unix principles by defining a user as a group of processes, like Multics in the past.

Pluggable Authentication Modules

PAM, short for Pluggable Authentication Modules, is a system in Linux and other Unix-like operating systems that handles authentication tasks. It provides a unified and flexible way to authenticate users for various services like login, su, sshd, etc.

PAM allows system administrators to choose how applications authenticate users. It's called "pluggable" because its modules can be easily inserted and replaced without affecting the application. This means you can change authentication without modifying the application's code.

PAM modules can stack, meaning a user application can be configured to go through several authentication steps before access is granted. This allows for a high level of flexibility and control over authentication processes.

systemd-pam is a PAM service module part of the systemd suite of system management components. It integrates PAM services with systemd, providing better interoperability between the two.

The main function of systemd-pam is to manage system and user sessions. When a user logs in, systemd-pam creates a new session for that user. This session is then tracked by systemd, which allows it to manage various aspects of the session, such as resource limits, job control, and more.

loginctl

A utility is available to manage these Linux user sessions: loginctl. This command-line tool serves as a window into the systemd login manager, offering system administrators and power users a robust set of features for monitoring and controlling user activity. At its core, loginctl provides a comprehensive view of the system's current login state.

With simple commands like loginctl list-sessions or loginctl list-users, administrators can quickly grasp who's logged in and from where. But its capabilities extend far beyond mere listing.

The real power of loginctl lies in its ability to manipulate sessions. Need to terminate a user's session forcibly? A single command like loginctl terminate-session [SESSION_ID] does the job. Are you curious about the details of a specific user's login? loginctl show-user [USERNAME] reveals all.

Managing Sessions

Let's start with this command without adding any parameters:

$ loginctl
SESSION  UID USER     SEAT  TTY   STATE  IDLE SINCE
      3 1000 frederik seat0 tty2  active no   -
      5 1000 frederik -     pts/2 active no   -

2 sessions listed.
  • The session id’s refers to the corresponding scope. In the example above: session-3.scope and session-5.scope.
  • The seat concept is utilized by systemd to allocate hardware to a specific seat (akin to a physical or virtual workspace). In a multi-seat system, hardware is assigned to a particular seat, enabling multiple users to utilize the same computer as their own. More about that in a later posting.
  • UID: Unique numerical value assigned to each user account
  • USER: Login name mapped to the UID
  • TTY: Allocated virtual and pseudo terminal (input/output device)

View the status of the session:

$ loginctl session-status 3

Example, truncated output:

  Since: Thu 2024-07-18 11:50:28 CEST; 19min ago
  State: active
 Leader: 1921 (sddm-helper)
   Seat: seat0; vc2
    TTY: tty2
 Remote: no
Service: sddm
   Type: x11
  Class: user
Desktop: KDE
   Idle: no
   Unit: session-3.scope
         ├─1921 /usr/libexec/sddm/sddm-helper ...
         ├─1941 /usr/bin/kwalletd6 --pam-login 13 14
         └─1942 /usr/bin/startplasma-x11

Jul 18 11:50:28 ...

This session is from a user logged into a graphical desktop environment (KDE) using a virtual machine console (hence the seat). KDE uses the Simple Desktop Display Manager (SDDM), a front-end Graphic User interface, for entering login information. It is running on top of the old Xorg X11 server. This session is from a user logged into a graphical desktop environment (KDE) using a virtual machine console (hence the seat). KDE uses the Simple Desktop Display Manager (SDDM), a front-end Graphic User interface, for to enter login information. It is running on top of the old Xorg X11 server.

Besides the session information, it shows the process tree under the scope and information collected by systemd-journald. Please notice that you can change the number of journal entries to show, using the --lines parameter.

There are several other "Session Commands", such as terminating or locking a session. For example, you are running SUSE Tumbleweed with the KDE desktop in a virtual machine and have logged into that system. At the same time, you are logged in using an SSH session. You can lock and unlock the graphical session using the following command:

$ loginct lock-session <session number>

You can only lock a session with a seat attached

Managing Users

Similar to sessions, there is a command to list the user status:

$ loginctl user-status <user id or username>

The current user is listed if you do not provide the user ID.

The output is like this:

frederik (1000)
   Since: Thu 2024-07-18 11:50:28 CEST; 42min ago
   State: active
Sessions: 5 *3
  Linger: no
    Unit: user-1000.slice
          ├─session-3.scope
          │ ├─1921 /usr/libexec/sddm/sddm-helper  ...

An asterisk marks the current session. Additionally, a process tree of the user slice is displayed.

Other user commands are available, like terminate-user to end all the sessions of one or more users and the kill-user that sends, in combination with the --signal parameter a signal to processes of a user the same way as the kill command.

An interesting option is about lingering. In systemd, "linger" is a feature that allows a user session to be kept active even after all user processes have exited. This is useful in cases where a user has started services that should continue running even when the user logs out. The pam module systemd_pam is responsible for this feature.

By default, when a user logs out, systemd will stop all services and user processes associated with that user's session. However, if a service is configured to "linger", systemd will keep the user session active even after the user logs out, allowing the service to continue running.

To enable linger for a user, you can use the loginctl enable-linger command. For example, to enable linger for the user "myuser", you would run the following:

$ loginctl enable-linger myuser

Once linger is enabled for a user, any services started by that user will continue running even after the user logs out. This is especially important if you have systemd services running under your account, or if you started processes using the systemd-run command.

You can turn off linger for a user with the =loginctl disable-linger command.

But is it a File?

Yes, we get it; users are a group of processes, but are users also a file nowadays?

$ cat /run/systemd/users/$UID

Have a look into the ​/run​/systemd​/sessions directory, concatenate one of the session numbers…

And do not forget the directory containing all the information and temporary files for the user: ​/run​/user​/$UID.

Footnotes


1

Marceau, C., J. H. Saltzer, and K. J. Martin. "Chapter: 'Identification User-process-groups, an overview'." In MULTICS SYSTEM-PROGRAMMERS' MANUAL, Section BQ.3.00, Page 1. Cambridge, MA: MIT University, 11/03/67.
https://www.multicians.org/mspm/bq-3-00.671103.user-process-groups.pdf


Recommended Courses

Title

Enterprise Linux 9 - I

Learn More
Title

Enterprise Linux 9 - II

Learn More
Title

LPIC 101

Learn More

Read All >>

Training As A Service