Skip to content

Commit b80120c

Browse files
author
David Herrmann
committed
logind: fail on CreateSession if already in session
Right now, if you're already in a session and call CreateSession, we return information about the current session of yours. This is highy confusing and a nasty hack. Avoid that, and instead return a commonly known error, so the caller can detect that. This has the side-effect, that we no longer override XDG_VTNR and XDG_SEAT in pam_systemd, if you're already in a session. But this sounds like the right thing to do, anyway.
1 parent 586cd08 commit b80120c

File tree

4 files changed

+28
-56
lines changed

4 files changed

+28
-56
lines changed

src/libsystemd/sd-bus/bus-common-errors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#define BUS_ERROR_DEVICE_NOT_TAKEN "org.freedesktop.login1.DeviceNotTaken"
5959
#define BUS_ERROR_OPERATION_IN_PROGRESS "org.freedesktop.login1.OperationInProgress"
6060
#define BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED "org.freedesktop.login1.SleepVerbNotSupported"
61+
#define BUS_ERROR_SESSION_BUSY "org.freedesktop.login1.SessionBusy"
6162

6263
#define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled"
6364

src/login/logind-core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
317317
int r;
318318

319319
assert(m);
320-
assert(session);
321320

322321
if (pid < 1)
323322
return -EINVAL;
@@ -330,7 +329,8 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
330329
if (!s)
331330
return 0;
332331

333-
*session = s;
332+
if (session)
333+
*session = s;
334334
return 1;
335335
}
336336

src/login/logind-dbus.c

Lines changed: 17 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -689,58 +689,23 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
689689
return r;
690690
}
691691

692-
manager_get_session_by_pid(m, leader, &session);
693-
if (!session && vtnr > 0 && vtnr < m->seat0->position_count) {
694-
session = m->seat0->positions[vtnr];
695-
/*
696-
* Old gdm and lightdm start the user-session on the same VT as
697-
* the greeter session. But they destroy the greeter session
698-
* after the user-session and want the user-session to take
699-
* over the VT. We need to support this for
700-
* backwards-compatibility, so make sure we allow new sessions
701-
* on a VT that a greeter is running on.
702-
*/
703-
if (session && session->class == SESSION_GREETER)
704-
session = NULL;
705-
}
706-
if (session) {
707-
_cleanup_free_ char *path = NULL;
708-
_cleanup_close_ int fifo_fd = -1;
709-
710-
/* Session already exists, client is probably
711-
* something like "su" which changes uid but is still
712-
* the same session */
713-
714-
fifo_fd = session_create_fifo(session);
715-
if (fifo_fd < 0)
716-
return fifo_fd;
717-
718-
path = session_bus_path(session);
719-
if (!path)
720-
return -ENOMEM;
721-
722-
log_debug("Sending reply about an existing session: "
723-
"id=%s object_path=%s uid=%u runtime_path=%s "
724-
"session_fd=%d seat=%s vtnr=%u",
725-
session->id,
726-
path,
727-
(uint32_t) session->user->uid,
728-
session->user->runtime_path,
729-
fifo_fd,
730-
session->seat ? session->seat->id : "",
731-
(uint32_t) session->vtnr);
732-
733-
return sd_bus_reply_method_return(
734-
message, "soshusub",
735-
session->id,
736-
path,
737-
session->user->runtime_path,
738-
fifo_fd,
739-
(uint32_t) session->user->uid,
740-
session->seat ? session->seat->id : "",
741-
(uint32_t) session->vtnr,
742-
true);
743-
}
692+
r = manager_get_session_by_pid(m, leader, NULL);
693+
if (r > 0)
694+
return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
695+
696+
/*
697+
* Old gdm and lightdm start the user-session on the same VT as
698+
* the greeter session. But they destroy the greeter session
699+
* after the user-session and want the user-session to take
700+
* over the VT. We need to support this for
701+
* backwards-compatibility, so make sure we allow new sessions
702+
* on a VT that a greeter is running on.
703+
*/
704+
if (vtnr > 0 &&
705+
vtnr < m->seat0->position_count &&
706+
m->seat0->positions[vtnr] &&
707+
m->seat0->positions[vtnr]->class != SESSION_GREETER)
708+
return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session");
744709

745710
audit_session_from_pid(leader, &audit_id);
746711
if (audit_id > 0) {

src/login/pam_systemd.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <security/pam_ext.h>
3232
#include <security/pam_misc.h>
3333

34+
#include "bus-common-errors.h"
3435
#include "util.h"
3536
#include "audit.h"
3637
#include "macro.h"
@@ -399,8 +400,13 @@ _public_ PAM_EXTERN int pam_sm_open_session(
399400
remote_host,
400401
0);
401402
if (r < 0) {
402-
pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r));
403-
return PAM_SYSTEM_ERR;
403+
if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) {
404+
pam_syslog(handle, LOG_DEBUG, "Cannot create session: %s", bus_error_message(&error, r));
405+
return PAM_SUCCESS;
406+
} else {
407+
pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r));
408+
return PAM_SYSTEM_ERR;
409+
}
404410
}
405411

406412
r = sd_bus_message_read(reply,

0 commit comments

Comments
 (0)