Commit graph

256 commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 2841493927 Use a dash-truncated drop-in for user-%j.slice configuration
This removes the UserTasksMax= setting in logind.conf. Instead, the generic
TasksMax= setting on the slice should be used. Instead of a transient unit we
use a drop-in to tweak the default definition of a .slice. It's better to use
the normal unit mechanisms instead of creating units on the fly. This will also
make it easier to start user@.service independently of logind, or set
additional settings like MemoryMax= for user slices.

The setting in logind is removed, because otherwise we would have two sources
of "truth": the slice on disk and the logind config. Instead of trying to
coordinate those two sources of configuration (and maintainer overrides to
both), let's just convert to the new one fully.

Right now now automatic transition mechanism is provided. logind will emit a
hint when it encounters the setting, but otherwise it will be ignored.

Fixes #2556.
2018-04-25 16:18:45 +02:00
Jan Synacek 22f9331412 logind: enable limiting of user session scopes using pam context objects (#8397) 2018-04-17 16:42:44 +02:00
Lennart Poettering b667d50d34
Merge pull request #8700 from keszybz/hibernation
Various improvements related to hibernation
2018-04-11 10:26:27 +02:00
Zbigniew Jędrzejewski-Szmek b71c9758d1 shared/sleep-config: return a custom message when not enough swap for hibernation
$ sudo swapoff -av
swapoff /dev/vda4
$ sudo systemctl hibernate
Failed to hibernate system via logind: Not enough swap space for hibernation

Fixes #6729.
2018-04-11 09:26:14 +02:00
Zbigniew Jędrzejewski-Szmek c8c8ee85af logind: refuse operations if the target unit is masked or unavailable
If hibernate.target is masked, and systemctl hibernate is invoked, havoc ensues.
logind starts the hibernation operation, but then doesn't go through with it;
gnome-shell segfaults. Let's be nice to the user and refuse doing anything in
that case.

$ sudo systemctl mask hibernate.target
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "no"
$ sudo systemctl hibernate
Failed to hibernate system via logind: Access denied
Failed to start hibernate.target: Unit hibernate.target is masked.

https://bugzilla.redhat.com/show_bug.cgi?id=1468003#c4
2018-04-10 21:31:59 +02:00
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00
Yu Watanabe c75436067f tree-wide: remove unused variables (#8612) 2018-03-29 12:50:50 +02:00
Mario Limonciello e68c79db91 Rename suspend-to-hibernate to suspend-then-hibernate
Per some discussion with Gnome folks, they would prefer this name
as it's more descriptive of what's happening.
2018-03-28 15:11:10 -05:00
Lennart Poettering 959071cac2
Merge pull request #8552 from keszybz/test-improvements
Test and diagnostics improvements
2018-03-23 15:26:54 +01:00
Zbigniew Jędrzejewski-Szmek 37c1d5e97d tree-wide: warn when a directory path already exists but has bad mode/owner/type
When we are attempting to create directory somewhere in the bowels of /var/lib
and get an error that it already exists, it can be quite hard to diagnose what
is wrong (especially for a user who is not aware that the directory must have
the specified owner, and permissions not looser than what was requested). Let's
print a warning in most cases. A warning is appropriate, because such state is
usually a sign of borked installation and needs to be resolved by the adminstrator.

$ build/test-fs-util

Path "/tmp/test-readlink_and_make_absolute" already exists and is not a directory, refusing.
   (or)
Directory "/tmp/test-readlink_and_make_absolute" already exists, but has mode 0775 that is too permissive (0755 was requested), refusing.
   (or)
Directory "/tmp/test-readlink_and_make_absolute" already exists, but is owned by 1001:1000 (1000:1000 was requested), refusing.

Assertion 'mkdir_safe(tempdir, 0755, getuid(), getgid(), MKDIR_WARN_MODE) >= 0' failed at ../src/test/test-fs-util.c:320, function test_readlink_and_make_absolute(). Aborting.

No functional change except for the new log lines.
2018-03-23 10:26:38 +01:00
Zbigniew Jędrzejewski-Szmek d50b5839b0 basic/mkdir: convert bool flag to enum
In preparation for subsequent changes...
2018-03-22 15:57:56 +01:00
Lennart Poettering e743bca2a6 logind: drop obsolete comment
The code matching this comment was removed in
a50df72b37 in 2014, let's drop the comment
too.
2018-03-21 20:01:20 +01:00
Lennart Poettering bc2b6332a2 logind: use manager_get_user_by_pid() where appropriate
The current code reimplemented something like the
manager_get_user_by_pid() logic on its own, manually. Let's unify this.
2018-03-21 20:01:20 +01:00
Mario Limonciello c58493c00a Introduce suspend-to-hibernate (#8274)
Suspend to Hibernate is a new sleep method that invokes suspend
for a predefined period of time before automatically waking up
and hibernating the system.

It's similar to HybridSleep however there isn't a performance
impact on every suspend cycle.

It's intended to use with systems that may have a higher power
drain in their supported suspend states to prevent battery and
data loss over an extended suspend cycle.

Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
2018-03-08 14:17:33 +01:00
Alan Jenkins e8a3144ec4 login: fix user@.service case, so we don't allow nested sessions (#8051)
> logind sessions are mostly bound to the audit session concept, and audit
> sessions remain unaffected by "su", in fact they are defined to be
> "sealed off", i.e. in a way that if a process entered a session once, it
> will always stay with it, and so will its children, i.e. the only way to
> get a new session is by forking off something off PID 1 (or something
> similar) that never has been part of a session.

The code had a gap.  user@.service is a special case PAM session which does
not create a logind session.  Let's remember to check for it.

Fixes #8021
2018-02-22 21:38:44 +01:00
Lennart Poettering 6e11e7e67d nologin: extend the /run/nologin descriptions a bit (#8244)
This is an attempt to improve #8228 a bit, by extending the /run/nologin
a bit, but still keeping it somewhat brief.

On purpose I used the vague wording "unprivileged user" rather than
"non-root user" so that pam_nologin can be updated to disable its
behaviour for members of the "wheel" group one day, and our messages
would still make sense.

See #8228.
2018-02-22 14:21:30 +01:00
Zbigniew Jędrzejewski-Szmek af229d7a5b login,user-sessions: always warn when we fail to remove nologin file
This usually is very annoying to users who then cannot log in, so
make sure we always warn if that happens (selinux, or whatever other reason).

This reverts a790812cb3.
2018-02-16 10:44:22 +01:00
Simon Fowler e25937a3ed Suspend on lid close based on power status. (#8016)
This change adds support for controlling the suspend-on-lid-close
behaviour based on the power status as well as whether the machine is
docked or has an external monitor. For backwards compatibility the new
configuration file variable is ignored completely by default, and must
be set explicitly before being considered in any decisions.
2018-02-09 17:37:39 +01:00
Lennart Poettering ddd59d0c7f logind: fix sysfs change trigger code
We can't create files in sysfs, hence don't bother. Also if we ignore
the return value, do so explicitly by casting to void.
2017-11-29 12:32:57 +01:00
Lennart Poettering 401e33ed56 logind: make sure we don't acces m->action_what if it's not initialized (#7475)
Fixes: #7466
2017-11-27 08:15:07 +01:00
Lennart Poettering 6f302ce676 logind: don't propagate firmware misbehaviours to bus clients
If for some reason we can't query the firmware state, don't propagate
that to clients, but instead log about it, and claim that
reboot-to-firmware is not available (which is the right answer, since it
is not working).

Let's log about this though, as this is certainly relevant to know, even
though not for the client.
2017-11-24 11:57:23 +01:00
Zbigniew Jędrzejewski-Szmek 53e1b68390 Add SPDX license identifiers to source files under the LGPL
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
2017-11-19 19:08:15 +01:00
Alan Jenkins 34160d9195 logind: fix SetLinger to authorize by client's effective User ID
SetLinger is authorized by the PolicyKit action "set-self-linger", if it is
not passed an explicit UID.

According to comments we were determining the default UID from the client's
session.  However, user processes e.g. which are run from a terminal
emulator do not necessarily belong to a session scope unit.  They may
equally be started from the systemd user manager [1][2].  Actually the
comment was wrong, and it would also have worked for processes
started from the systemd user manager.

Nevertheless it seems to involve fetching "augmented credentials" i.e.
it's using a racy method, so we shouldn't have been authenticating based
on it.

We could change the default UID, but that raises issues especially for
consistency between the methods.  Instead we can just use the clients
effective UID for authorization.

This commit also fixes `loginctl enable-linger $USER` to match the docs
that say it was equivalent to `loginctl enable-linger` (given that $USER
matches the callers user and owner_uid).  Previously, the former would not
have suceeded for unpriviliged users in the default configuration.

[1] It seems the main meaning of per-session scopes is tracking the PAM
login process.  Killing that provokes logind to revoke device access.  Less
circularly, killing it provokes getty to hangup the TTY.

[2] User units may be started with an environment which includes
XDG_SESSION_ID (presuambly GNOME does this?).  Or not.
2017-11-14 18:15:33 +00:00
Alan Jenkins 7b33c6228f logind: comment use of *_get_session()
The manpages tell that such calls have quite limited meaning.  logind has
a few in the implementation of what remains of the session concept.

At the same time, logind basically exposes sd_pid_get_session() as public
API.  This is absolutely required, to retain compatability e.g. with Xorg.
But client code will work in more situations if it avoids assuming that it
runs in a session itself.

Its use inside the login session could be replaced with $XDG_SESSION_ID
(which pam_systemd sets).  I don't know whether it would be useful to
change Xorg at this point or not.  But if you were building something new,
you would think about whether you want to support running it in a systemd
service.

Comment these logind API features, acknowledging the reason they exist is
based in history.  I.e. help readers avoid drawing implications from their
existence which apply to history, but not the current general case.

Finally, searching these revealed a call to sd_pid_get_session() in
implementing some types of logind inhibitors.  So these inhibitors don't
work as intended when taken from inside a systemd user service :(.  Comment
this as well, deferring it as ticket #6852.
2017-11-14 18:15:33 +00:00
Alan Jenkins 095b8833d6 logind: more specific error message for unknown users
If you try to run `loginctl user-status` on a non-logged in user to see
whether "Linger" is enabled, it doesn't work.

If you're already an expert in logind, the fact that the user is considered
unknown actually tells you the user is not lingering.  So, probably they
they do not have lingering enabled.  I think we can point towards this
without being misleading.

I also reword it because I thought it was slightly confusing to run
`loginctl user-status root` and get an error back about "User 0".  Try to
be more specific, that it is "User ID 0".
2017-11-14 18:15:33 +00:00
Alan Jenkins aeb075704b logind: remove an obscure dbus error from GetSessionByPID(0) and friends
GetSessionByPID(0) can fail with NO_SESSION_FOR_PID.  More obscurely, if
the session is abandoned, it can return NO_SUCH_SESSION.  It is not clear
that the latter was intended.  The message associated with the former,
hints that this was overlooked.

We don't have a document enumerating the errors.  Any specific
error-handling in client code, e.g. translated messages, would also be
liable to overlook the more obscure error code.

I can't see any equivalent condition for GetUserByPID(0).  On the other
hand, the code did not return NO_USER_FOR_PID where it probably should.
The relevant code is right next to that for GetSessionByPID(0), so it will
be simpler to understand if both follow the same pattern.
2017-11-14 18:12:42 +00:00
Yu Watanabe c31ad02403 mkdir: introduce follow_symlink flag to mkdir_safe{,_label}() 2017-10-06 16:03:33 +09:00
Zbigniew Jędrzejewski-Szmek c9905d4dd2 Merge pull request #6944 from poettering/suspend-fix
systemctl reboot/suspend tweaks
2017-10-05 11:26:44 +02:00
Lennart Poettering d13f5e164e logind: don's change dry-run boolean before we actually enqueue the operation
Let's not affect change before the PK check.
2017-10-04 20:56:24 +02:00
Lennart Poettering 15e99a4392 logind: reorder things a bit
Let's keep the three sleep method implementations close to each other.
2017-10-04 20:56:24 +02:00
Lennart Poettering 36b69c3131 logind: add Halt() and CanHalt() APIs
This adds new method calls Halt() and CanHalt() to the logind bus APIs.
They aren't overly useful (as the whole concept of halting isn't really
too useful), however they clean up one major asymmetry: currently, using
the "shutdown" legacy commands it is possibly to enqueue a "halt"
operation through logind, while logind officially doesn't actually
support this. Moreover, the path through "shutdown" currently ultimately
fails, since the referenced "halt" action isn't actually defined in
PolicyKit.

Finally, the current logic results in an unexpected asymmetry in
systemctl: "systemctl poweroff", "systemctl reboot" are currently
asynchronous (due to the logind involvement) while "systemctl halt"
isnt. Let's clean this up, and make all three APIs implemented by
logind natively, and all three hence asynchronous in "systemctl".

Moreover, let's add the missing PK action.

Fixes: #6957
2017-10-04 20:56:24 +02:00
Alan Jenkins 07b38ba51e Revert "tree-wide: use pid_is_valid() at more places"
This reverts commit ee043777be.

It broke almost everywhere it touched.  The places that
handn't been converted, were mostly followed by special
handling for the invalid PID `0`.  That explains why they
tested for `pid < 0` instead of `pid <= 0`.

I think that one was the first commit I reviewed, heh.
2017-10-03 12:43:24 +01:00
Lennart Poettering ee043777be tree-wide: use pid_is_valid() at more places 2017-08-31 15:45:04 +02:00
Alan Jenkins b61fa4e001 logind: tighten assertion in execute_shutdown_or_sleep()
Following commit b498d6ea, I belated realized we should tighten the
assertions as well, to make sure that we're setting `m->action_what` to
represent an action in progress.  (The check for an action in progress is
to compare `m->action_what` to zero)
2017-08-24 15:21:21 +01:00
Alan Jenkins 6d7f7fd49f logind: add missing resume signal when we fail to initiate sleep/shutdown
This fixed https://bugzilla.redhat.com/show_bug.cgi?id=1476313
as much as I was able to reproduce it in a VM, at least.

E.g. this signal might wake the screen back up, providing a more visible
indicator of suspend failure.  In my VM testing, it was also required in
order to unblock keyboard input in gnome-shell after the failed suspend.

At the same time, fix the error handling for scheduled shutdowns.  This now
mirrors the behaviour of when you use `shutdown -k` - it sends all the
scary messages about shutting down, "but you'll have to do it [shut down
the system] yourself".  It also avoids the risk of locking out the admin
(nologin file), in case they logged out for some reason (and they use
`sudo` instead of root).

Not that I have any idea why you'd want to use `shutdown -k`, but the code
is easier to analyze if it rolls back on error (in the absence of any code
comment as to why that's not wanted).
2017-08-24 14:52:22 +01:00
Alan Jenkins df75a1a8aa logind: respect "delay" inhibitors in scheduled shutdowns
There is no justification not to wait an extra (default) 5 seconds, for
a more graceful shutdown of user programs.  Again, you don't get to ignore
delay inhibitors for unscheduled shutdowns, short of
`systemctl poweroff -f`.

It is simplest if we move the test for `m->shutdown_dry_run` into
manager_scheduled_shutdown_handler().

However we need to not add such delays during a "dry run".  Otherwise, we
would still have to be considered "in progress" for some seconds after our
admin has seen the final wall message.  If they go to `poweroff`, we would
have blocked them with a misleading error message.  Note this `poweroff`
will still process delay inhibitors as needed.  If the admin planned to
use a more forceful method... eh.  It's their responsibility to assess
whether that's safe.

There is an argument that the alternative behaviour could be used (racily!)
to kludge around them not being able to shutdown to "single user mode".  If
we cared about that case, we would have easily preserved non-racy support
for it in `shutdown`.

Additionally, though I think this code does read more easily by reducing
inconsistencies, we didn't come up with any use case for delay inhibitors
v.s. shutdown.[1]  The SIGTERM v.s. SIGKILL delay is more general, and we
allow a whole 90 seconds for it, not just 5.  So I don't think keeping this
approach bears a risk of significant damage.

[1] https://www.freedesktop.org/wiki/Software/systemd/inhibit/
2017-08-24 12:42:54 +01:00
Alan Jenkins b498d6ea9f logind: add missing check for conflicting operation v.s. scheduled shutdown
> We don't want to shutdown while a suspend is running, and vice versa.
> This would be confusing and could lead to data loss in the worst case.

https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1441253/comments/4

According to the above comment, if the conflicting operation is hung,
we don't want to force things when the admin has not passed a force option.

Similarly if you're not an admin, you probably shouldn't get to sneak
around this check by using a scheduled shutdown instead of an unscheduled
one.  (And no-one so far thought it necessary to add such a permission in
PolKit).

Note that if the conflicting operation was _not_ hung, and we lost the
race with suspend, the system might not have shut down at the scheduled
time anyway.  Which is no good if you were scheduling a power outage.
And scheduling a shutdown for an arbitrary time when the system is resumed,
does not seem a very useful semantic.  More likely, scheduled shutdowns are
useful on systems which do not use suspend, such as multi-user servers.
(In which case even PolKit defaults likely don't let the users trigger
suspend).
2017-08-24 12:42:17 +01:00
Alan Jenkins f8169e62df logind: method_schedule_shutdown() already rejects empty type
Don't test for an empty `type` afterwards.  This is not how you cancel
scheduled shutdowns - there's a separate method for that.
2017-08-24 12:42:17 +01:00
Alan Jenkins cbc373502f logind: remember to remove '/run/systemd/shutdown/scheduled' 2017-08-24 12:42:10 +01:00
Lennart Poettering cad93f2996 core, sd-bus, logind: make use of uid_is_valid() in more places 2017-07-31 18:01:42 +02:00
Lennart Poettering 3a87a86e33 audit: introduce audit_session_is_valid() and make use of it everywhere
Let's add a proper validation function, since validation isn't entirely
trivial. Make use of it where applicable. Also make use of
AUDIT_SESSION_INVALID where we need a marker for an invalid audit
session.
2017-07-31 18:01:42 +02:00
Zbigniew Jędrzejewski-Szmek cf82fda94e logind: nicer error message when we cannot guess the caller's session
Partial fix for #6032.
2017-05-31 22:10:15 -04:00
Zbigniew Jędrzejewski-Szmek 2b0445262a tree-wide: add SD_ID128_MAKE_STR, remove LOG_MESSAGE_ID
Embedding sd_id128_t's in constant strings was rather cumbersome. We had
SD_ID128_CONST_STR which returned a const char[], but it had two problems:
- it wasn't possible to statically concatanate this array with a normal string
- gcc wasn't really able to optimize this, and generated code to perform the
  "conversion" at runtime.
Because of this, even our own code in coredumpctl wasn't using
SD_ID128_CONST_STR.

Add a new macro to generate a constant string: SD_ID128_MAKE_STR.
It is not as elegant as SD_ID128_CONST_STR, because it requires a repetition
of the numbers, but in practice it is more convenient to use, and allows gcc
to generate smarter code:

$ size .libs/systemd{,-logind,-journald}{.old,}
   text	   data	    bss	    dec	    hex	filename
1265204	 149564	   4808	1419576	 15a938	.libs/systemd.old
1260268	 149564	   4808	1414640	 1595f0	.libs/systemd
 246805	  13852	    209	 260866	  3fb02	.libs/systemd-logind.old
 240973	  13852	    209	 255034	  3e43a	.libs/systemd-logind
 146839	   4984	     34	 151857	  25131	.libs/systemd-journald.old
 146391	   4984	     34	 151409	  24f71	.libs/systemd-journald

It is also much easier to check if a certain binary uses a certain MESSAGE_ID:

$ strings .libs/systemd.old|grep MESSAGE_ID
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x

$ strings .libs/systemd|grep MESSAGE_ID
MESSAGE_ID=c7a787079b354eaaa9e77b371893cd27
MESSAGE_ID=b07a249cd024414a82dd00cd181378ff
MESSAGE_ID=641257651c1b4ec9a8624d7a40a9e1e7
MESSAGE_ID=de5b426a63be47a7b6ac3eaac82e2f6f
MESSAGE_ID=d34d037fff1847e6ae669a370e694725
MESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5
MESSAGE_ID=1dee0369c7fc4736b7099b38ecb46ee7
MESSAGE_ID=39f53479d3a045ac8e11786248231fbf
MESSAGE_ID=be02cf6855d2428ba40df7e9d022f03d
MESSAGE_ID=7b05ebc668384222baa8881179cfda54
MESSAGE_ID=9d1aaa27d60140bd96365438aad20286
2017-02-15 00:45:12 -05:00
Zbigniew Jędrzejewski-Szmek 28a9ec4443 logind: trivial simplification
free_and_strdup() handles NULL arg, so make use of that.
2017-01-31 00:47:07 -05:00
Reverend Homer 8fb3f00997 tree-wide: replace all readdir cycles with FOREACH_DIRENT{,_ALL} (#4853) 2016-12-09 10:04:30 +01:00
Zbigniew Jędrzejewski-Szmek f97b34a629 Rename formats-util.h to format-util.h
We don't have plural in the name of any other -util files and this
inconsistency trips me up every time I try to type this file name
from memory. "formats-util" is even hard to pronounce.
2016-11-07 10:15:08 -05:00
Lennart Poettering c5a11ae268 logind: enforce a limit on inhibitors we hand out
For similar reasons as the recent addition of a limit on sessions.

Note that we don't enforce a limit on inhibitors per-user currently, but
there's an implicit one, since each inhibitor takes up one fd, and fds are
limited via RLIMIT_NOFILE, and the limit on the number of processes per user.
2016-05-05 22:50:09 +02:00
Lennart Poettering 6d97d3c648 logind: expose more configuration settings as bus properties 2016-05-05 22:50:09 +02:00
Lennart Poettering 183e073842 logind: enforce a limit on current user sessions
We really should put limits on all resources we manage, hence add one to the
number of concurrent sessions, too. This was previously unbounded, hence set a
relatively high limit of 8K by default.

Note that most PAM setups will actually invoke pam_systemd prefixed with "-",
so that the return code of pam_systemd is ignored, and the login attempt
succeeds anyway. On systems like this the session will be created but is not
tracked by systemd.
2016-05-05 22:50:09 +02:00
Zbigniew Jędrzejewski-Szmek 152199f2d7 logind: allow any user to request lingering
We enable lingering for anyone who wants this. It is still disabled by
default to avoid keeping long-running processes accidentally.
Admins might want to customize this policy on multi-user sites.
2016-04-21 00:21:33 -04:00