Re: [systemd-devel] [PATCH v2 0/7] logind: close races on user and session states

2014-02-08 Thread Djalal Harouni
On Sat, Feb 08, 2014 at 12:39:25AM +0100, Zbigniew Jędrzejewski-Szmek wrote:
 On Thu, Feb 06, 2014 at 09:37:13PM +0100, Djalal Harouni wrote:
  Summary:
  Currently logind will not clear sessions on logout. The bug is confirmed
  for getty and ssh logins. This series is preparation for next patches to
  address that bug, it does not fix it.
  However, this series also fixe real races on user and session states.
  This ensures that user_save() and session_save() functions will write the
  correct user and session state to the state files.
  
  
  The logind bug was already discussed here:
  http://lists.freedesktop.org/archives/systemd-devel/2014-January/015968.html
 
 So, I did some testing with current git (ba978d7). And this bug
 appears to be only partially gone. After my second user logs out, loginctl
 stops showing the session. But the manager *remains*.
I confirm this, I've identified the problem, please see below.

 Hm, the manager remains, but /run/user/uid/systemd/ gets nuked.
 So when the user logins in a second time, communication with user manager
 is broken.
I also confirm, I didn't have time to debug this one.

 Attaching strace to systemd --user during the orignial session close yields...
 nothing. Both systemd and (sd-pam) remain undisturbed...
Yes sd-pam and the user instance will stay alive for *another* user
after logout.

In manager_gc() the user_stop() is never called.

if (!user_check_gc(user, drop_not_started) 
 user_get_state(user) != USER_CLOSING)
user_stop(user);


Note: with the recent commits, user_stop() will set user-stopping to
say that user_stop() was called.

But currently with this logic if the user_check_gc(...) returns false,
this means that 'u-sessions' is NULL, so user_get_state(user) will for
sure return USER_CLOSING if linger is not set and if it is not open
state.

I think that we should remove that USER_CLOSING check, will just test
it.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] systemd crashes if locale.conf contains invalid utf8 string

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
On Thu, Feb 06, 2014 at 07:09:59PM +0100, Goffredo Baroncelli wrote:
 In the parse_env_file_push() and load_env_file_push() functions, there
 are two assert() call to check if the key or value parameters are utf8 valid.
 
 If the strings aren't utf8 valid, assert does abort.
 
 These function are used early by systemd to parse some files. For 
 example '/etc/locale.conf'. In my case this file contained a not utf8
 sequence, which is bad, but systemd crashed during the boot, which
 is even worse !
Applied.

Your patch motivated me to push a patch I had written previously to avoid
invalid utf-8 in log messages. After those two changes systemd should
finally behave correctly for invalid utf-8 in config files.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] cryptsetup-generator: auto add deps for device as password

2014-02-08 Thread Dave Reisner
If the password is a device file, we can add Requires/After dependencies
on the device rather than requiring the user to do so.
---
This is based on a bug filed to Arch:

https://bugs.archlinux.org/task/38842

Assuming I'm correct about the race condition, this should be an easy way
of closing it without user involvement.

 src/cryptsetup/cryptsetup-generator.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/cryptsetup/cryptsetup-generator.c 
b/src/cryptsetup/cryptsetup-generator.c
index 9c98f0b..4542757 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -130,11 +130,26 @@ static int create_disk(
 streq(password, /dev/random) ||
 streq(password, /dev/hw_random))
 fputs(After=systemd-random-seed.service\n, f);
-else if (!streq(password, -) 
- !streq(password, none))
-fprintf(f,
-RequiresMountsFor=%s\n,
-password);
+else {
+_cleanup_free_ char *uu = 
fstab_node_to_udev_node(password);
+if (uu == NULL)
+return log_oom();
+
+if (is_device_path(uu)) {
+_cleanup_free_ char *dd = 
unit_name_from_path(uu, .device);
+if (dd == NULL)
+return log_oom();
+
+fprintf(f,
+After=%s\n
+Requires=%s\n,
+dd, dd);
+} else if (!streq(password, -) 
+ !streq(password, none))
+fprintf(f,
+RequiresMountsFor=%s\n,
+password);
+}
 }
 
 if (is_device_path(u))
-- 
1.8.5.4

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: just call user_stop() if user_check_gc() returns false

2014-02-08 Thread Djalal Harouni
Currently if the user logs out, the GC may never call user_stop(),
this will not terminate the systemd user and (sd-pam) of that user.

To fix this, remove the USER_CLOSING state check that is blocking the
GC from calling user_stop(). We do not need it since with the current
logic we have:

1) if user_check_gc() returns false this means that all the sessions of
the user were removed.

2) if all the sessions were removed and if linger is not set and if it
is not open state then user_get_state() will return always USER_CLOSING.

So that check will never be satisfied for normal cases, and for linger
user_check_gc() will return true which prevents the GC from collecting
the user.
---
 src/login/logind.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/login/logind.c b/src/login/logind.c
index a6f84e8..84c5b7d 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -889,11 +889,8 @@ void manager_gc(Manager *m, bool drop_not_started) {
 LIST_REMOVE(gc_queue, m-user_gc_queue, user);
 user-in_gc_queue = false;
 
-if (!user_check_gc(user, drop_not_started) 
-user_get_state(user) != USER_CLOSING)
-user_stop(user);
-
 if (!user_check_gc(user, drop_not_started)) {
+user_stop(user);
 user_finalize(user);
 user_free(user);
 }
-- 
1.8.3.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] cryptsetup-generator: auto add deps for device as password

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
On Sat, Feb 08, 2014 at 01:12:14PM -0500, Dave Reisner wrote:
 If the password is a device file, we can add Requires/After dependencies
 on the device rather than requiring the user to do so.
 ---
 This is based on a bug filed to Arch:
 
 https://bugs.archlinux.org/task/38842
 
 Assuming I'm correct about the race condition, this should be an easy way
 of closing it without user involvement.
 
  src/cryptsetup/cryptsetup-generator.c | 25 -
  1 file changed, 20 insertions(+), 5 deletions(-)
 
 diff --git a/src/cryptsetup/cryptsetup-generator.c 
 b/src/cryptsetup/cryptsetup-generator.c
 index 9c98f0b..4542757 100644
 --- a/src/cryptsetup/cryptsetup-generator.c
 +++ b/src/cryptsetup/cryptsetup-generator.c
 @@ -130,11 +130,26 @@ static int create_disk(
  streq(password, /dev/random) ||
  streq(password, /dev/hw_random))
  fputs(After=systemd-random-seed.service\n, f);
 -else if (!streq(password, -) 
 - !streq(password, none))
 -fprintf(f,
 -RequiresMountsFor=%s\n,
 -password);
 +else {
 +_cleanup_free_ char *uu = 
 fstab_node_to_udev_node(password);
 +if (uu == NULL)
 +return log_oom();
 +
 +if (is_device_path(uu)) {
 +_cleanup_free_ char *dd = 
 unit_name_from_path(uu, .device);
 +if (dd == NULL)
 +return log_oom();
 +
 +fprintf(f,
 +After=%s\n
 +Requires=%s\n,
 +dd, dd);
 +} else if (!streq(password, -) 
 + !streq(password, none))
 +fprintf(f,
 +RequiresMountsFor=%s\n,
 +password);
 +}
Patch looks fine, but I don't really understand why you invert the order of 
conditions.
Something like this feels more natural:

else if (!streq(password, -) 
 !streq(password, none)) {

_cleanup_free_ char *uu = 
fstab_node_to_udev_node(password);
if (uu == NULL)
return log_oom();

if (is_device_path(uu)) {
_cleanup_free_ char *dd = 
unit_name_from_path(uu, .device);
if (dd == NULL)
return log_oom();

fprintf(f, After=%1$s\nRequires=%1$s\n, dd);
} else
fprintf(f, RequiresMountsFor=%s\n, password);
}

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] cryptsetup-generator: auto add deps for device as password

2014-02-08 Thread Dave Reisner
On Sat, Feb 08, 2014 at 07:31:28PM +0100, Zbigniew Jędrzejewski-Szmek wrote:
 On Sat, Feb 08, 2014 at 01:12:14PM -0500, Dave Reisner wrote:
  If the password is a device file, we can add Requires/After dependencies
  on the device rather than requiring the user to do so.
  ---
  This is based on a bug filed to Arch:
  
  https://bugs.archlinux.org/task/38842
  
  Assuming I'm correct about the race condition, this should be an easy way
  of closing it without user involvement.
  
   src/cryptsetup/cryptsetup-generator.c | 25 -
   1 file changed, 20 insertions(+), 5 deletions(-)
  
  diff --git a/src/cryptsetup/cryptsetup-generator.c 
  b/src/cryptsetup/cryptsetup-generator.c
  index 9c98f0b..4542757 100644
  --- a/src/cryptsetup/cryptsetup-generator.c
  +++ b/src/cryptsetup/cryptsetup-generator.c
  @@ -130,11 +130,26 @@ static int create_disk(
   streq(password, /dev/random) ||
   streq(password, /dev/hw_random))
   fputs(After=systemd-random-seed.service\n, f);
  -else if (!streq(password, -) 
  - !streq(password, none))
  -fprintf(f,
  -RequiresMountsFor=%s\n,
  -password);
  +else {
  +_cleanup_free_ char *uu = 
  fstab_node_to_udev_node(password);
  +if (uu == NULL)
  +return log_oom();
  +
  +if (is_device_path(uu)) {
  +_cleanup_free_ char *dd = 
  unit_name_from_path(uu, .device);
  +if (dd == NULL)
  +return log_oom();
  +
  +fprintf(f,
  +After=%s\n
  +Requires=%s\n,
  +dd, dd);
  +} else if (!streq(password, -) 
  + !streq(password, none))
  +fprintf(f,
  +RequiresMountsFor=%s\n,
  +password);
  +}
 Patch looks fine, but I don't really understand why you invert the order of 
 conditions.
 Something like this feels more natural:

Yeah, not sure what I was thinking here. Thanks for the suggestion --
will push with this change.

 else if (!streq(password, -) 
  !streq(password, none)) {
 
 _cleanup_free_ char *uu = 
 fstab_node_to_udev_node(password);
 if (uu == NULL)
 return log_oom();
 
 if (is_device_path(uu)) {
 _cleanup_free_ char *dd = 
 unit_name_from_path(uu, .device);
 if (dd == NULL)
 return log_oom();
 
 fprintf(f, After=%1$s\nRequires=%1$s\n, dd);
 } else
   fprintf(f, RequiresMountsFor=%s\n, password);
 }
 
 Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: use session_get_state() to get sessions state of the user

2014-02-08 Thread Djalal Harouni
In function user_get_state() remove the session_is_active() check, just
count on the session_get_state() function to get the correct session
state.

session_is_active() may return true before starting the session scope
and user service, this means it will return true even before the creation
of the session fifo_fd which will produce incorrect states.

So be consistent and just use session_get_state().
---
 src/login/logind-user.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index fdbf6e3..2a11bab 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -648,9 +648,11 @@ UserState user_get_state(User *u) {
 bool all_closing = true;
 
 LIST_FOREACH(sessions_by_user, i, u-sessions) {
-if (session_is_active(i))
+SessionState state = session_get_state(i);
+
+if (state == SESSION_ACTIVE)
 return USER_ACTIVE;
-if (session_get_state(i) != SESSION_CLOSING)
+else if (state != SESSION_CLOSING)
 all_closing = false;
 }
 
-- 
1.8.3.1

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] Debian Bug#618862: systemd: ignores keyscript in crypttab - a possible solution

2014-02-08 Thread David Härdeman
On Wed, Feb 05, 2014 at 12:16:00AM +0100, Lennart Poettering wrote:
On Thu, 30.01.14 10:40, David Härdeman (da...@hardeman.nu) wrote:
 This issue is fixable with minor upstream changes, e.g. by extending
 the PasswordAgent protocol to add Subsystem=cryptsetup and
 Target=diskname entries to the ask. file.

I'd be fine with adding a field Id= or so, which then is filled by an
identifier of some kind be the cryptsetup tool that is useful to
identify the device to query things on. for example:
Id=cryptsetup:/dev/sda5 or so could be one way how this could be
filled in. We wouldn't enfoce any kind of syntax on this, just suggest
some common sense so that people choose identifiers that are unlikely to
clash with other subsystems, and somewhat reasonable to read...

In the patches I sent I split it into Purpose and Target and my
thinking was more or less the same as yours...i.e. that there's no
particular syntax and that the meaning of the string is subsystem
specific.

I'd be happy to change the patch to use Id=subsystem:target if
you'd prefer.

 b) the password agent implementation in systemd doesn't seem to
 handle binary strings (i.e. strings with '\0'), as can be seen by
 calls to e.g. strlen()...
 
 Whether making it binary safe would be a major change or not is
 something I haven't researched yet but it seems like a change that
 should be generally useful upstream...

I'd be OK with this, as discussed at FOSDEM, and I see you already
posted a ptach for this.

Yes. I take it you're pretty busy with the kdbus stuff right now but a
review of those patches would be nice when you have the time.

-- 
David Härdeman
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] logind: use session_get_state() to get sessions state of the user

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
On Sat, Feb 08, 2014 at 08:51:57PM +0100, Djalal Harouni wrote:
 In function user_get_state() remove the session_is_active() check, just
 count on the session_get_state() function to get the correct session
 state.
 
 session_is_active() may return true before starting the session scope
 and user service, this means it will return true even before the creation
 of the session fifo_fd which will produce incorrect states.
 
 So be consistent and just use session_get_state().
Sooo... with your patch applied, I see: 

sshd[18756]: pam_unix(sshd:session): session closed for user user2
systemd-logind[18687]: Sent message type=method_call sender=n/a 
destination=org.freedesktop.systemd1 
object=/org/freedesktop/systemd1/unit/session_2d10_2escope 
interface=org.freedesktop.systemd1.Scope member=Abandon cookie=27 
reply_cookie=0 error=n/a

And nothing afterwards. User manager for user2 is undisturbed.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] logind: use session_get_state() to get sessions state of the user

2014-02-08 Thread Djalal Harouni
On Sat, Feb 08, 2014 at 10:01:18PM +0100, Zbigniew Jędrzejewski-Szmek wrote:
 On Sat, Feb 08, 2014 at 08:51:57PM +0100, Djalal Harouni wrote:
  In function user_get_state() remove the session_is_active() check, just
  count on the session_get_state() function to get the correct session
  state.
  
  session_is_active() may return true before starting the session scope
  and user service, this means it will return true even before the creation
  of the session fifo_fd which will produce incorrect states.
  
  So be consistent and just use session_get_state().
 Sooo... with your patch applied, I see: 
 
 sshd[18756]: pam_unix(sshd:session): session closed for user user2
 systemd-logind[18687]: Sent message type=method_call sender=n/a 
 destination=org.freedesktop.systemd1 
 object=/org/freedesktop/systemd1/unit/session_2d10_2escope 
 interface=org.freedesktop.systemd1.Scope member=Abandon cookie=27 
 reply_cookie=0 error=n/a
 
 And nothing afterwards. User manager for user2 is undisturbed.
Ah this patch fixes the user state.

The one you should apply is from the other thread:
http://lists.freedesktop.org/archives/systemd-devel/2014-February/016754.html

It should work, please give it a try!

 Zbyszek

-- 
Djalal Harouni
http://opendz.org
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH v2 0/7] logind: close races on user and session states

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
On Sat, Feb 08, 2014 at 12:39:25AM +0100, Zbigniew Jędrzejewski-Szmek wrote:
 systemd-logind[2998]: Failed to process message [type=signal sender=:1.1 
 path=/org/freedesktop/systemd1/job/3284 
 interface=org.freedesktop.DBus.Properties member=PropertiesChanged 
 signature=sa{sv}as]: Invalid argument

So, this happens because match_properties_changed() expects
path=/org/freedesktop/systemd1/unit/... but gets .../job/...

I'll push a patch to quietly ignore those.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] systemd crashes if locale.conf contains invalid utf8 string

2014-02-08 Thread Goffredo Baroncelli
On 02/08/2014 07:15 PM, Zbigniew Jędrzejewski-Szmek wrote:
 On Thu, Feb 06, 2014 at 07:09:59PM +0100, Goffredo Baroncelli wrote:
[...]
 Applied.

Great !

[...]

 Zbyszek
 


-- 
gpg @keyserver.linux.it: Goffredo Baroncelli (kreijackATinwind.it
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] logind: use session_get_state() to get sessions state of the user

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
On Sat, Feb 08, 2014 at 10:20:53PM +0100, Djalal Harouni wrote:
 On Sat, Feb 08, 2014 at 10:01:18PM +0100, Zbigniew Jędrzejewski-Szmek wrote:
  On Sat, Feb 08, 2014 at 08:51:57PM +0100, Djalal Harouni wrote:
   In function user_get_state() remove the session_is_active() check, just
   count on the session_get_state() function to get the correct session
   state.
   
   session_is_active() may return true before starting the session scope
   and user service, this means it will return true even before the creation
   of the session fifo_fd which will produce incorrect states.
   
   So be consistent and just use session_get_state().
  Sooo... with your patch applied, I see: 
  
  sshd[18756]: pam_unix(sshd:session): session closed for user user2
  systemd-logind[18687]: Sent message type=method_call sender=n/a 
  destination=org.freedesktop.systemd1 
  object=/org/freedesktop/systemd1/unit/session_2d10_2escope 
  interface=org.freedesktop.systemd1.Scope member=Abandon cookie=27 
  reply_cookie=0 error=n/a
  
  And nothing afterwards. User manager for user2 is undisturbed.
 Ah this patch fixes the user state.
 
 The one you should apply is from the other thread:
 http://lists.freedesktop.org/archives/systemd-devel/2014-February/016754.html
 
 It should work, please give it a try!
You're right, I applied the wrong patch. It really seems that with your
* logind: use session_get_state() to get sessions state of the user
* logind: just call user_stop() if user_check_gc() returns false
things actually work.

One thing that still does not work is terminate-user, even though
kill-session works. 

method_terminate_user - user_stop -* session_stop - session_stop_scope - 
manager_abandom_scope
   - user_stop_service
   - user_stop_slice

manager_stop_scope calls manager_shall_kill which returns false, so it
only calls manager_abandon_scope. There seems to be a conflation between
explicit termination of users and sessions, and automatic termination when
they log out. According to the man page:

   KillUserProcesses=
   Takes a boolean argument. Configures whether the processes
   of a user should be killed when she or he completely logs
   out (i.e. after her/his last session ended). Defaults to no.

KillUserProcesses should not apply to explicit termination. I think
session_stop_scope should be changed to unconditionally kill the
session when called from method_terminate_user.

Zbyszek
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH] logind: always kill session when termination is requested

2014-02-08 Thread Zbigniew Jędrzejewski-Szmek
KillUserProcesses=yes/no should be ignored when termination is
explicitly requested.
---
This goes on top of
* logind: use session_get_state() to get sessions state of the user 
   
* logind: just call user_stop() if user_check_gc() returns false
   

With this patch loginctl terminate-user/session work for me.

Zbyszek

 src/login/logind-dbus.c |  6 +++---
 src/login/logind-seat-dbus.c|  2 +-
 src/login/logind-seat.c |  8 
 src/login/logind-seat.h |  4 ++--
 src/login/logind-session-dbus.c |  2 +-
 src/login/logind-session.c  | 12 ++--
 src/login/logind-session.h  |  2 +-
 src/login/logind-user-dbus.c|  2 +-
 src/login/logind-user.c |  4 ++--
 src/login/logind-user.h |  2 +-
 src/login/logind.c  |  6 +++---
 11 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index d671346..bd0de33 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -939,7 +939,7 @@ static int method_terminate_session(sd_bus *bus, 
sd_bus_message *message, void *
 if (!session)
 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, No 
session '%s' known, name);
 
-r = session_stop(session);
+r = session_stop(session, true);
 if (r  0)
 return r;
 
@@ -964,7 +964,7 @@ static int method_terminate_user(sd_bus *bus, 
sd_bus_message *message, void *use
 if (!user)
 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, No 
user '%lu' known or logged in, (unsigned long) uid);
 
-r = user_stop(user);
+r = user_stop(user, true);
 if (r  0)
 return r;
 
@@ -989,7 +989,7 @@ static int method_terminate_seat(sd_bus *bus, 
sd_bus_message *message, void *use
 if (!seat)
 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, No 
seat '%s' known, name);
 
-r = seat_stop_sessions(seat);
+r = seat_stop_sessions(seat, true);
 if (r  0)
 return r;
 
diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
index 909007c..26cddfe 100644
--- a/src/login/logind-seat-dbus.c
+++ b/src/login/logind-seat-dbus.c
@@ -201,7 +201,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message 
*message, void *userdata
 assert(message);
 assert(s);
 
-r = seat_stop_sessions(s);
+r = seat_stop_sessions(s, true);
 if (r  0)
 return r;
 
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index c7f112a..631be5f 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -418,7 +418,7 @@ int seat_start(Seat *s) {
 return 0;
 }
 
-int seat_stop(Seat *s) {
+int seat_stop(Seat *s, bool force) {
 int r = 0;
 
 assert(s);
@@ -430,7 +430,7 @@ int seat_stop(Seat *s) {
MESSAGE=Removed seat %s., s-id,
NULL);
 
-seat_stop_sessions(s);
+seat_stop_sessions(s, force);
 
 unlink(s-state_file);
 seat_add_to_gc_queue(s);
@@ -443,14 +443,14 @@ int seat_stop(Seat *s) {
 return r;
 }
 
-int seat_stop_sessions(Seat *s) {
+int seat_stop_sessions(Seat *s, bool force) {
 Session *session;
 int r = 0, k;
 
 assert(s);
 
 LIST_FOREACH(sessions_by_seat, session, s-sessions) {
-k = session_stop(session);
+k = session_stop(session, force);
 if (k  0)
 r = k;
 }
diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
index 9e21e3a..9e469d4 100644
--- a/src/login/logind-seat.h
+++ b/src/login/logind-seat.h
@@ -80,8 +80,8 @@ bool seat_can_graphical(Seat *s);
 int seat_get_idle_hint(Seat *s, dual_timestamp *t);
 
 int seat_start(Seat *s);
-int seat_stop(Seat *s);
-int seat_stop_sessions(Seat *s);
+int seat_stop(Seat *s, bool force);
+int seat_stop_sessions(Seat *s, bool force);
 
 bool seat_check_gc(Seat *s, bool drop_not_started);
 void seat_add_to_gc_queue(Seat *s);
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 7ee4956..f9305dd 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -188,7 +188,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message 
*message, void *userdata
 assert(message);
 assert(s);
 
-r = session_stop(s);
+r = session_stop(s, true);
 if (r  0)
 return r;
 
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index f661cc8..d4742e1 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -565,7 +565,7 @@ int session_start(Session *s) {
 return 0;
 }
 
-static int session_stop_scope(Session *s) {
+static int session_stop_scope(Session *s, bool force) {