Bug 65409

Summary: logind sessions don't follow nested audit sessions
Product: systemd Reporter: Marius Vollmer <marius.vollmer>
Component: generalAssignee: systemd-bugs
Status: NEW --- QA Contact: systemd-bugs
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Marius Vollmer 2013-06-05 10:37:21 UTC
My understanding is that XDG_SESSION_ID and /proc/self/sessionid should be the same, if possible.  This isn't true when a new audit session is started with pam_loginuid from within an already existing logind session.

To reproduce, run sshd explicitly from a session and then connect to it:

  $ ssh root@f18
  # cat /proc/self/sessionid; echo
  4
  # echo $XDG_SESSION_ID
  4
  # firewall-cmd --add-port 2222/tcp      (if needed)
  # /sbin/sshd -D -p 2222

Then from somewhere else:

  $ ssh -p 2222 root@f18
  # cat /proc/self/sessionid; echo
  5                                       (as expected)
  # echo $XDG_SESSION_ID
  4

Logging in via ssh on port 2222 has created a new audit session, as expected, but systemd-logind doesn't create a new session for it since sshd is already part of a session.

I think this should be made consistent, by having systemd-logind only reuse existing sessions when they match /proc/self/sessionid.


Here is a hackish patch that implements this idea:

diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index aa212d1..3632555 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -307,6 +307,13 @@ static int bus_manager_append_preparing(DBusMessageIter *i, const char *property
         return 0;
 }
 
+static int session_has_id (Session *session, uint32_t id)
+{
+        char *end;
+        uint32_t sid = strtoul (session->id, &end, 10);
+        return sid == id && *end == '\0';
+}
+
 static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) {
         const char *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *service;
         uint32_t uid, leader, audit_id = 0;
@@ -493,7 +500,10 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         if (r < 0)
                 goto fail;
 
-        if (session) {
+        audit_session_from_pid(leader, &audit_id);
+
+        if (session &&
+            (audit_id == 0 || session_has_id (session, audit_id))) {
                 fifo_fd = session_create_fifo(session);
                 if (fifo_fd < 0) {
                         r = fifo_fd;
@@ -541,7 +551,6 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                 return 0;
         }
 
-        audit_session_from_pid(leader, &audit_id);
         if (audit_id > 0) {
                 /* Keep our session IDs and the audit session IDs in sync */
Comment 1 Lennart Poettering 2013-06-06 05:07:42 UTC
In newer fedora the session ID is actually sealed off, so this wouldn't work anymore.

Also, the way we see it we initialize from the audit ID when we can, but we wouldn't always gurantee its equal.
Comment 2 Marius Vollmer 2013-06-06 06:05:36 UTC
(In reply to comment #1)
> In newer fedora the session ID is actually sealed off, so this wouldn't work
> anymore.

Hmm, what is "this" here?  Running sshd from within an already existing session?  What would fail?  pam_loginuid?

> Also, the way we see it we initialize from the audit ID when we can, but we
> wouldn't always gurantee its equal.

I'd say that as long as a process has /proc/self/sessionid at all, the logind session if should be guaranteed to follow it.  As far as I can see, this should always be possible, by creating a new session if necessary.  If you don't want nested sessions, that probably needs to be blocked in pam_loginuid, no?

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.