it's not possible to log in again shortly after log out (#1263208)

Resolves: #1263208
This commit is contained in:
Jan Synacek 2015-10-05 14:33:04 +02:00
parent a9d2e0cabe
commit 275528dc1a
8 changed files with 503 additions and 0 deletions

View File

@ -0,0 +1,36 @@
From cc85d56245a21e458dbc955fbf94fa9b3bfb9e33 Mon Sep 17 00:00:00 2001
From: David Herrmann <dh.herrmann@gmail.com>
Date: Fri, 10 Jul 2015 14:53:08 +0200
Subject: [PATCH 033/261] logind: allow greeters to take over VTs
Make sure a greeter can forcefully spawn a session on a VT that is
in-use. A recent patch prevented this (this used to be possible for all
session types) as it is highly fragile. However, as it turns out,
greeters seem to rely on that feature. Therefore, make sure we allow it
explicitly for greeters.
---
src/login/logind-dbus.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index cd9cab7..ca435df 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -699,9 +699,12 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
* after the user-session and want the user-session to take
* over the VT. We need to support this for
* backwards-compatibility, so make sure we allow new sessions
- * on a VT that a greeter is running on.
+ * on a VT that a greeter is running on. Furthermore, to allow
+ * re-logins, we have to allow a greeter to take over a used VT for
+ * the exact same reasons.
*/
- if (vtnr > 0 &&
+ if (c != SESSION_GREETER &&
+ vtnr > 0 &&
vtnr < m->seat0->position_count &&
m->seat0->positions[vtnr] &&
m->seat0->positions[vtnr]->class != SESSION_GREETER)
--
2.4.3

View File

@ -0,0 +1,141 @@
From e6494a07cbbfa93dd83782fa1f8554aa4d2353bd Mon Sep 17 00:00:00 2001
From: David Herrmann <dh.herrmann@gmail.com>
Date: Fri, 10 Jul 2015 15:08:24 +0200
Subject: [PATCH 034/261] logind: rename 'pos' to 'position'
Spell out the proper name. Use 'pos' over 'position', and also update the
logind state file to do the same. Note that this breaks live updates.
However, we only save 'POSITION' on non-seat0, so this shouldn't bother
anyone for real. If you run multi-seat setups, you better restart a
machine on updates, anyway.
---
src/login/logind-seat.c | 18 +++++++++---------
src/login/logind-session.c | 10 +++++-----
src/login/logind-session.h | 2 +-
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index fb5d076..9d5287a 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -290,8 +290,8 @@ int seat_switch_to_next(Seat *s) {
return -EINVAL;
start = 1;
- if (s->active && s->active->pos > 0)
- start = s->active->pos;
+ if (s->active && s->active->position > 0)
+ start = s->active->position;
for (i = start + 1; i < s->position_count; ++i)
if (s->positions[i])
@@ -311,8 +311,8 @@ int seat_switch_to_previous(Seat *s) {
return -EINVAL;
start = 1;
- if (s->active && s->active->pos > 0)
- start = s->active->pos;
+ if (s->active && s->active->position > 0)
+ start = s->active->position;
for (i = start - 1; i > 0; --i)
if (s->positions[i])
@@ -472,9 +472,9 @@ int seat_stop_sessions(Seat *s, bool force) {
void seat_evict_position(Seat *s, Session *session) {
Session *iter;
- unsigned int pos = session->pos;
+ unsigned int pos = session->position;
- session->pos = 0;
+ session->position = 0;
if (pos == 0)
return;
@@ -486,7 +486,7 @@ void seat_evict_position(Seat *s, Session *session) {
* position (eg., during gdm->session transition), so let's look
* for it and set it on the free slot. */
LIST_FOREACH(sessions_by_seat, iter, s->sessions) {
- if (iter->pos == pos) {
+ if (iter->position == pos) {
s->positions[pos] = iter;
break;
}
@@ -504,7 +504,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned int pos) {
seat_evict_position(s, session);
- session->pos = pos;
+ session->position = pos;
if (pos > 0 && !s->positions[pos])
s->positions[pos] = session;
}
@@ -512,7 +512,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned int pos) {
static void seat_assign_position(Seat *s, Session *session) {
unsigned int pos;
- if (session->pos > 0)
+ if (session->position > 0)
return;
for (pos = 1; pos < s->position_count; ++pos)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 6a450b0..45f4c09 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -264,7 +264,7 @@ int session_save(Session *s) {
fprintf(f, "VTNR=%u\n", s->vtnr);
if (!s->vtnr)
- fprintf(f, "POS=%u\n", s->pos);
+ fprintf(f, "POSITION=%u\n", s->position);
if (s->leader > 0)
fprintf(f, "LEADER="PID_FMT"\n", s->leader);
@@ -302,7 +302,7 @@ int session_load(Session *s) {
*seat = NULL,
*vtnr = NULL,
*state = NULL,
- *pos = NULL,
+ *position = NULL,
*leader = NULL,
*type = NULL,
*class = NULL,
@@ -329,7 +329,7 @@ int session_load(Session *s) {
"DESKTOP", &s->desktop,
"VTNR", &vtnr,
"STATE", &state,
- "POS", &pos,
+ "POSITION", &position,
"LEADER", &leader,
"TYPE", &type,
"CLASS", &class,
@@ -388,10 +388,10 @@ int session_load(Session *s) {
if (!s->seat || !seat_has_vts(s->seat))
s->vtnr = 0;
- if (pos && s->seat) {
+ if (position && s->seat) {
unsigned int npos;
- safe_atou(pos, &npos);
+ safe_atou(position, &npos);
seat_claim_position(s->seat, s, npos);
}
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 4bf739a..b8565eb 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -70,7 +70,7 @@ struct Session {
Manager *manager;
const char *id;
- unsigned int pos;
+ unsigned int position;
SessionType type;
SessionClass class;
--
2.4.3

View File

@ -0,0 +1,164 @@
From 559b5cc2734bdd968c1c56ad1dc6fff08b8b30ba Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sat, 11 Jul 2015 17:00:26 -0300
Subject: [PATCH 043/261] logind: bring bus policy up-to-date
A while back we opened up all of logind's bus calls to unprivileged
users, via PK. However, the dbus1 policy wasn't updated accordingly.
With this change, the dbus1 policy is opened up for all bus calls that
should be available to unprivileged clients.
(also rearranges some calls in the vtable, to make more sense, and be in
line with the order in the bus policy file)
Fixes #471.
---
src/login/logind-dbus.c | 4 +-
src/login/org.freedesktop.login1.conf | 72 +++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index ca435df..049e33e 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2449,8 +2449,6 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -2458,6 +2456,8 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
index 0ad7880..d8deb7b 100644
--- a/src/login/org.freedesktop.login1.conf
+++ b/src/login/org.freedesktop.login1.conf
@@ -90,6 +90,42 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
+ send_member="LockSession"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="UnlockSession"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="LockSessions"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="UnlockSessions"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="KillSession"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="KillUser"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="TerminateSession"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="TerminateUser"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="TerminateSeat"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
send_member="PowerOff"/>
<allow send_destination="org.freedesktop.login1"
@@ -130,6 +166,14 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
+ send_member="ScheduleShutdown"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="CancelScheduledShutdown"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
send_member="CanRebootToFirmwareSetup"/>
<allow send_destination="org.freedesktop.login1"
@@ -146,6 +190,10 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Seat"
+ send_member="Terminate"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Seat"
send_member="ActivateSession"/>
<allow send_destination="org.freedesktop.login1"
@@ -162,14 +210,30 @@
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"
+ send_member="Terminate"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Session"
send_member="Activate"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"
+ send_member="Lock"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Session"
+ send_member="Unlock"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Session"
send_member="SetIdleHint"/>
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Session"
+ send_member="Kill"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Session"
send_member="TakeControl"/>
<allow send_destination="org.freedesktop.login1"
@@ -188,6 +252,14 @@
send_interface="org.freedesktop.login1.Session"
send_member="PauseDeviceComplete"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.User"
+ send_member="Terminate"/>
+
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.User"
+ send_member="Kill"/>
+
<allow receive_sender="org.freedesktop.login1"/>
</policy>
--
2.4.3

View File

@ -0,0 +1,41 @@
From 6b62bbbc7b53bee11778d27d18e9506d9b42d4ba Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sat, 11 Jul 2015 17:29:48 -0300
Subject: [PATCH 044/261] logind: some firmware implementations remove
OsIndications if it is unset
We shouldn't fall over that, and just assume it is 0 in this case.
Fixes #499.
---
src/shared/efivars.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
index 0d6ecf5..347cd30 100644
--- a/src/shared/efivars.c
+++ b/src/shared/efivars.c
@@ -125,7 +125,19 @@ static int get_os_indications(uint64_t *os_indication) {
return r;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s);
- if (r < 0)
+ if (r == -ENOENT) {
+ /* Some firmware implementations that do support
+ * OsIndications and report that with
+ * OsIndicationsSupported will remove the
+ * OsIndications variable when it is unset. Let's
+ * pretend it's 0 then, to hide this implementation
+ * detail. Note that this call will return -ENOENT
+ * then only if the support for OsIndications is
+ * missing entirely, as determined by
+ * efi_reboot_to_firmware_supported() above. */
+ *os_indication = 0;
+ return 0;
+ } else if (r < 0)
return r;
else if (s != sizeof(uint64_t))
return -EINVAL;
--
2.4.3

View File

@ -0,0 +1,41 @@
From da770c386f8cc6efd3430ebab4e0707a4bb06c16 Mon Sep 17 00:00:00 2001
From: David Herrmann <dh.herrmann@gmail.com>
Date: Thu, 16 Jul 2015 18:18:01 +0200
Subject: [PATCH 085/261] logind: prefer new sessions over older ones on VT
switches
Our seat->positions[] array keeps track of the 'preferred' session on a
VT. The only situation this is used, is to select the session to activate
when a VT is activated. In the normal case, there's only one session per
VT so the selection is trivial.
Older greeters, however, implement take-overs when they start sessions on
the same VT that the greeter ran on. We recently limited such take-overs
to VTs where a greeter is running on, to force people to never share VTs
in new code that is written.
For legacy reasons, we need to be compatible to old greeters, though.
Hence, we allow those greeters to implement take-over. In such take-overs,
however, we should really make sure that the new sessions gets preferred
over the old one under all circumstances. Hence, make sure we override
the previous preferred session with a new session.
---
src/login/logind-seat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 9d5287a..1179ce9 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -505,7 +505,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned int pos) {
seat_evict_position(s, session);
session->position = pos;
- if (pos > 0 && !s->positions[pos])
+ if (pos > 0)
s->positions[pos] = session;
}
--
2.4.3

View File

@ -0,0 +1,29 @@
From 281033284352ed7651e84d228dad780dc2ef299f Mon Sep 17 00:00:00 2001
From: David Herrmann <dh.herrmann@gmail.com>
Date: Thu, 16 Jul 2015 18:46:12 +0200
Subject: [PATCH 087/261] logind: never select closing sessions for a VT
If a session is in closing state (and already got rid of its VT), then
never re-select it for that VT. There is no reason why we should grant
something to a session that is already going away *AND* already got rid
of exactly that.
---
src/login/logind-seat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 1179ce9..495ec50 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -486,7 +486,7 @@ void seat_evict_position(Seat *s, Session *session) {
* position (eg., during gdm->session transition), so let's look
* for it and set it on the free slot. */
LIST_FOREACH(sessions_by_seat, iter, s->sessions) {
- if (iter->position == pos) {
+ if (iter->position == pos && session_get_state(iter) != SESSION_CLOSING) {
s->positions[pos] = iter;
break;
}
--
2.4.3

View File

@ -0,0 +1,42 @@
From 10189fd6be0f547d75bc857860f3ecbbdbc447a6 Mon Sep 17 00:00:00 2001
From: David Herrmann <dh.herrmann@gmail.com>
Date: Fri, 31 Jul 2015 16:52:29 +0200
Subject: [PATCH 261/261] logind: release VT-positions when closing sessions
Make sure we release VT-positions when a session is closed. Otherwise,
lingering sessions will occupy VTs and prevent next logins from
succeeding.
Note that we already release session-devices when closing a session, so
there cannot be anyone using the VT anymore.
---
src/login/logind-session.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 2537d02..9a2da79 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -636,6 +636,9 @@ int session_stop(Session *s, bool force) {
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
+ if (s->seat)
+ seat_evict_position(s->seat, s);
+
/* We are going down, don't care about FIFOs anymore */
session_remove_fifo(s);
@@ -672,6 +675,9 @@ int session_finalize(Session *s) {
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
+ if (s->seat)
+ seat_evict_position(s->seat, s);
+
/* Kill session devices */
while ((sd = hashmap_first(s->devices)))
session_device_free(sd);
--
2.4.3

View File

@ -85,6 +85,13 @@ Patch0048: 0044-units-run-ldconfig-also-when-cache-is-unpopulated.patch
Patch0049: 0045-sd-event-fix-prepare-priority-queue-comparison-funct.patch
Patch0050: 0046-Revert-core-one-step-back-again-for-nspawn-we-actual.patch
Patch0051: 0048-core-report-root-cgroup-as-over-the-bus.patch
Patch0052: 0049-logind-allow-greeters-to-take-over-VTs.patch
Patch0053: 0050-logind-rename-pos-to-position.patch
Patch0054: 0051-logind-bring-bus-policy-up-to-date.patch
Patch0055: 0052-logind-some-firmware-implementations-remove-OsIndica.patch
Patch0056: 0053-logind-prefer-new-sessions-over-older-ones-on-VT-swi.patch
Patch0057: 0054-logind-never-select-closing-sessions-for-a-VT.patch
Patch0059: 0055-logind-release-VT-positions-when-closing-sessions.patch
Patch997: 0001-Re-apply-walters-unit-patch-for-F23-systemd-v222.patch
Patch998: 0001-Revert-core-mount-add-dependencies-to-dynamically-mo-v222.patch
@ -825,6 +832,8 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd
%changelog
* Mon Oct 5 2015 Jan Synáček <jsynacek@redhat.com> - 222-7
- systemctl shows the full cgroup hierarchy when doing status of a disabled or non-existing unit (#1268601)
- it's not possible to log in again shortly after log out (#1263208)
+ related logind bugfixes
* Fri Sep 25 2015 Michal Sekletar <msekleta@redhat.com> - 222-6
- Scope units will not get killed immediately during shutdown (#1170765)