Merge pull request #6866 from sourcejedi/set-linger2

logind: fix `loginctl enable-linger`
This commit is contained in:
Lennart Poettering 2017-11-15 11:15:15 +01:00 committed by GitHub
commit 0986658d51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 190 additions and 161 deletions

View file

@ -280,11 +280,10 @@
one or more logged in users, followed by the most recent log
data from the journal. Takes one or more user names or numeric
user IDs as parameters. If no parameters are passed, the status
of the caller's user is shown. This function is intended to
generate human-readable output. If you are looking for
computer-parsable output, use <command>show-user</command>
instead. Users may be specified by their usernames or numeric
user IDs. </para></listitem>
is shown for the user of the session of the caller. This
function is intended to generate human-readable output. If you
are looking for computer-parsable output, use
<command>show-user</command> instead.</para></listitem>
</varlistentry>
<varlistentry>

View file

@ -441,7 +441,7 @@ manpages = [
'3',
['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf'],
''],
['sd_pid_get_session',
['sd_pid_get_owner_uid',
'3',
['sd_peer_get_cgroup',
'sd_peer_get_machine_name',
@ -453,7 +453,7 @@ manpages = [
'sd_peer_get_user_unit',
'sd_pid_get_cgroup',
'sd_pid_get_machine_name',
'sd_pid_get_owner_uid',
'sd_pid_get_session',
'sd_pid_get_slice',
'sd_pid_get_unit',
'sd_pid_get_user_slice',

View file

@ -394,16 +394,19 @@
<para><function>sd_bus_creds_get_session()</function> will
retrieve the identifier of the login session that the process is
a part of. See
<citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. For
processes that are not part of a session, returns -ENXIO.
</para>
a part of. Please note the login session may be limited to a stub
process or two. User processes may instead be started from their
systemd user manager, e.g. GUI applications started using DBus
activation, as well as service processes which are shared between
multiple logins of the same user. For processes that are not part
of a session, returns -ENXIO.</para>
<para><function>sd_bus_creds_get_owner_uid()</function> will
retrieve the numeric UID (user identifier) of the user who owns
the login session that the process is a part of. See
the user unit or login session that the process is a part of. See
<citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
For processes that are not part of a session, returns -ENXIO.
For processes that are not part of a user unit or session, returns
-ENXIO.
</para>
<para><function>sd_bus_creds_has_effective_cap()</function> will check whether the capability specified by
@ -500,15 +503,16 @@
<listitem><para>The given field is not specified for the described
process or peer. This will be returned by
<function>sd_bus_get_unit()</function>,
<function>sd_bus_get_slice()</function>,
<function>sd_bus_get_user_unit()</function>,
<function>sd_bus_get_user_slice()</function>,
<function>sd_bus_get_session()</function>, and
<function>sd_bus_get_owner_uid()</function> if the process is
<function>sd_bus_creds_get_unit()</function>,
<function>sd_bus_creds_get_slice()</function>,
<function>sd_bus_creds_get_user_unit()</function>,
<function>sd_bus_creds_get_user_slice()</function>, and
<function>sd_bus_creds_get_session()</function> if the process is
not part of a systemd system unit, systemd user unit, systemd
slice, or logind session. It will also be returned by
<function>sd_bus_creds_get_exe()</function> and
slice, or logind session. It will be returned by
<function>sd_bus_creds_get_owner_uid()</function> if the process is
not part of a systemd user unit or logind session. It will also be
returned by <function>sd_bus_creds_get_exe()</function> and
<function>sd_bus_creds_get_cmdline()</function> for kernel
threads (since these are not started from an executable binary,
nor have a command line), and by

View file

@ -21,10 +21,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
<refentry id="sd_pid_get_session" conditional='HAVE_PAM'>
<refentry id="sd_pid_get_owner_uid" conditional='HAVE_PAM'>
<refentryinfo>
<title>sd_pid_get_session</title>
<title>sd_pid_get_owner_uid</title>
<productname>systemd</productname>
<authorgroup>
@ -38,30 +38,30 @@
</refentryinfo>
<refmeta>
<refentrytitle>sd_pid_get_session</refentrytitle>
<refentrytitle>sd_pid_get_owner_uid</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_pid_get_session</refname>
<refname>sd_pid_get_unit</refname>
<refname>sd_pid_get_user_unit</refname>
<refname>sd_pid_get_owner_uid</refname>
<refname>sd_pid_get_session</refname>
<refname>sd_pid_get_user_unit</refname>
<refname>sd_pid_get_unit</refname>
<refname>sd_pid_get_machine_name</refname>
<refname>sd_pid_get_slice</refname>
<refname>sd_pid_get_user_slice</refname>
<refname>sd_pid_get_cgroup</refname>
<refname>sd_peer_get_session</refname>
<refname>sd_peer_get_unit</refname>
<refname>sd_peer_get_user_unit</refname>
<refname>sd_peer_get_owner_uid</refname>
<refname>sd_peer_get_session</refname>
<refname>sd_peer_get_user_unit</refname>
<refname>sd_peer_get_unit</refname>
<refname>sd_peer_get_machine_name</refname>
<refname>sd_peer_get_slice</refname>
<refname>sd_peer_get_user_slice</refname>
<refname>sd_peer_get_cgroup</refname>
<refpurpose>Determine session, unit, owner of a session,
container/VM or slice of a specific PID or socket
peer</refpurpose>
<refpurpose>Determine the owner uid of the user unit or session,
or the session, user unit, system unit, container/VM or slice that
a specific PID or socket peer belongs to.</refpurpose>
</refnamediv>
<refsynopsisdiv>
@ -69,15 +69,15 @@
<funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_pid_get_session</function></funcdef>
<funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
<paramdef>pid_t <parameter>pid</parameter></paramdef>
<paramdef>char **<parameter>session</parameter></paramdef>
<paramdef>uid_t *<parameter>uid</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_pid_get_unit</function></funcdef>
<funcdef>int <function>sd_pid_get_session</function></funcdef>
<paramdef>pid_t <parameter>pid</parameter></paramdef>
<paramdef>char **<parameter>unit</parameter></paramdef>
<paramdef>char **<parameter>session</parameter></paramdef>
</funcprototype>
<funcprototype>
@ -87,9 +87,9 @@
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
<funcdef>int <function>sd_pid_get_unit</function></funcdef>
<paramdef>pid_t <parameter>pid</parameter></paramdef>
<paramdef>uid_t *<parameter>uid</parameter></paramdef>
<paramdef>char **<parameter>unit</parameter></paramdef>
</funcprototype>
<funcprototype>
@ -117,15 +117,15 @@
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_peer_get_session</function></funcdef>
<funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>char **<parameter>session</parameter></paramdef>
<paramdef>uid_t *<parameter>uid</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_peer_get_unit</function></funcdef>
<funcdef>int <function>sd_peer_get_session</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>char **<parameter>unit</parameter></paramdef>
<paramdef>char **<parameter>session</parameter></paramdef>
</funcprototype>
<funcprototype>
@ -135,9 +135,9 @@
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
<funcdef>int <function>sd_peer_get_unit</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>uid_t *<parameter>uid</parameter></paramdef>
<paramdef>char **<parameter>unit</parameter></paramdef>
</funcprototype>
<funcprototype>
@ -169,16 +169,34 @@
<refsect1>
<title>Description</title>
<para><function>sd_pid_get_owner_uid()</function> may be used to
determine the Unix UID (user identifier) which owns the login
session or systemd user unit of a process identified by the
specified PID. For processes which are not part of a login session
and not managed by a user manager, this function will fail with
<constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_session()</function> may be used to
determine the login session identifier of a process identified by
the specified process identifier. The session identifier is a
short string, suitable for usage in file system paths. Note that
not all processes are part of a login session (e.g. system service
processes, user processes that are shared between multiple
sessions of the same user, or kernel threads). For processes not
being part of a login session, this function will fail with
<constant>-ENODATA</constant>. The returned string needs to be freed with the libc
<citerefentry
short string, suitable for usage in file system paths. Please
note the login session may be limited to a stub process or two.
User processes may instead be started from their systemd user
manager, e.g. GUI applications started using DBus activation, as
well as service processes which are shared between multiple logins
of the same user. For processes which are not part of a login
session, this function will fail with <constant>-ENODATA</constant>.
The returned string needs to be freed with the libc <citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
<para><function>sd_pid_get_user_unit()</function> may be used to
determine the systemd user unit (i.e. user service or scope unit)
identifier of a process identified by the specified PID. The
unit name is a short string, suitable for usage in file system
paths. For processes which are not managed by a user manager, this
function will fail with <constant>-ENODATA</constant>. The
returned string needs to be freed with the libc <citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
@ -186,37 +204,21 @@
determine the systemd system unit (i.e. system service or scope
unit) identifier of a process identified by the specified PID. The
unit name is a short string, suitable for usage in file system
paths. Note that not all processes are part of a system
unit/service (e.g. user processes, or kernel threads). For
processes not being part of a systemd system unit, this function
will fail with <constant>-ENODATA</constant>. (More specifically, this call will not
work for kernel threads.) The returned string needs to be freed
with the libc <citerefentry
paths. Note that not all processes are part of a system
unit/service. For processes not being part of a systemd system
unit, this function will fail with <constant>-ENODATA</constant>.
(More specifically, this call will not work for kernel threads.)
The returned string needs to be freed with the libc <citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
<para><function>sd_pid_get_user_unit()</function> may be used to
determine the systemd user unit (i.e. user service or scope unit)
identifier of a process identified by the specified PID. This is
similar to <function>sd_pid_get_unit()</function>, but applies to
user units instead of system units.</para>
<para><function>sd_pid_get_owner_uid()</function> may be used to
determine the Unix UID (user identifier) of the owner of the
session of a process identified the specified PID. Note that this
function will succeed for user processes which are shared between
multiple login sessions of the same user, whereas
<function>sd_pid_get_session()</function> will fail. For processes
not being part of a login session and not being a shared process
of a user, this function will fail with <constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_machine_name()</function> may be used
to determine the name of the VM or container is a member of. The
machine name is a short string, suitable for usage in file system
paths. The returned string needs to be freed with the libc
<citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use. For processes not part of a VM or containers, this
call after use. For processes not part of a VM or container, this
function fails with <constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_slice()</function> may be used to
@ -246,10 +248,10 @@
functions is passed as 0, the operation is executed for the
calling process.</para>
<para>The <function>sd_peer_get_session()</function>,
<function>sd_peer_get_unit()</function>,
<para>The <function>sd_peer_get_owner_uid()</function>,
<function>sd_peer_get_session()</function>,
<function>sd_peer_get_user_unit()</function>,
<function>sd_peer_get_owner_uid()</function>,
<function>sd_peer_get_unit()</function>,
<function>sd_peer_get_machine_name()</function>,
<function>sd_peer_get_slice()</function>,
<function>sd_peer_get_user_slice()</function> and

View file

@ -193,18 +193,19 @@
<varlistentry>
<term><varname>_SYSTEMD_CGROUP=</varname></term>
<term><varname>_SYSTEMD_SESSION=</varname></term>
<term><varname>_SYSTEMD_SLICE=</varname></term>
<term><varname>_SYSTEMD_UNIT=</varname></term>
<term><varname>_SYSTEMD_USER_UNIT=</varname></term>
<term><varname>_SYSTEMD_SESSION=</varname></term>
<term><varname>_SYSTEMD_OWNER_UID=</varname></term>
<term><varname>_SYSTEMD_SLICE=</varname></term>
<listitem>
<para>The control group path in the systemd hierarchy, the
systemd session ID (if any), the systemd unit name (if any),
the systemd user session unit name (if any), the owner UID
of the systemd session (if any) and the systemd slice unit
of the process the journal entry originates from.</para>
the systemd slice unit name, the systemd unit name, the
unit name in the systemd user manager (if any), the systemd
session ID (if any), and the owner UID of the systemd user
unit or systemd session (if any) of the process the journal
entry originates from.</para>
</listitem>
</varlistentry>

View file

@ -1151,11 +1151,11 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
b = streq(argv[0], "enable-linger");
if (argc < 2) {
/* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
* session name, in which case logind will try to guess our session. */
/* No argument? Let's use an empty user name,
* then logind will use our user. */
short_argv[0] = argv[0];
short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[1] = (char*) "";
short_argv[2] = NULL;
argv = short_argv;
argc = 2;

View file

@ -50,27 +50,47 @@
#include "user-util.h"
#include "utmp-wtmp.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
const char *name;
Session *session;
int r;
/* Get client login session. This is not what you are looking for these days,
* as apps may instead belong to a user service unit. This includes terminal
* emulators and hence command-line apps. */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_session(creds, &name);
if (r == -ENXIO)
goto err_no_session;
if (r < 0)
return r;
session = hashmap_get(m->sessions, name);
if (!session)
goto err_no_session;
*ret = session;
return 0;
err_no_session:
return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
"Caller does not belong to any known session");
}
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
Session *session;
assert(m);
assert(message);
assert(ret);
if (isempty(name)) {
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_session(creds, &name);
if (r == -ENXIO)
return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
"Caller does not belong to any known session");
if (r < 0)
return r;
}
if (isempty(name))
return get_sender_session(m, message, error, ret);
session = hashmap_get(m->sessions, name);
if (!session)
@ -80,30 +100,48 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch
return 0;
}
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
uid_t uid;
User *user;
int r;
/* Note that we get the owner UID of the session, not the actual client UID here! */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r == -ENXIO)
goto err_no_user;
if (r < 0)
return r;
user = hashmap_get(m->users, UID_TO_PTR(uid));
if (!user)
goto err_no_user;
*ret = user;
return 0;
err_no_user:
return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "Caller does not belong to any logged in user or lingering user");
}
int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
User *user;
assert(m);
assert(message);
assert(ret);
if (!uid_is_valid(uid)) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
/* Note that we get the owner UID of the session, not the actual client UID here! */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r < 0)
return r;
}
if (!uid_is_valid(uid))
return get_sender_user(m, message, error, ret);
user = hashmap_get(m->users, UID_TO_PTR(uid));
if (!user)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "User ID "UID_FMT" is not logged in or lingering", uid);
*ret = user;
return 0;
@ -329,6 +367,9 @@ static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_er
return sd_bus_reply_method_return(message, "o", p);
}
/* Get login session of a process. This is not what you are looking for these days,
* as apps may instead belong to a user service unit. This includes terminal
* emulators and hence command-line apps. */
static int method_get_session_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Session *session = NULL;
@ -419,7 +460,9 @@ static int method_get_user_by_pid(sd_bus_message *message, void *userdata, sd_bu
if (r < 0)
return r;
if (!user)
return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID,
"PID "PID_FMT" does not belong to any logged in user or lingering user",
pid);
}
p = user_bus_path(user);
@ -1117,13 +1160,13 @@ static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus
}
static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
_cleanup_free_ char *cc = NULL;
Manager *m = userdata;
int r, b, interactive;
struct passwd *pw;
const char *path;
uint32_t uid;
bool self = false;
uint32_t uid, auth_uid;
assert(message);
assert(m);
@ -1132,22 +1175,23 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
if (r < 0)
return r;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID |
SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
if (!uid_is_valid(uid)) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
/* Note that we get the owner UID of the session, not the actual client UID here! */
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r < 0)
return r;
/* Note that we get the owner UID of the session or user unit,
* not the actual client UID here! */
r = sd_bus_creds_get_owner_uid(creds, &uid);
if (r < 0)
return r;
}
self = true;
} else if (!uid_is_valid(uid))
return -EINVAL;
/* owner_uid is racy, so for authorization we must use euid */
r = sd_bus_creds_get_euid(creds, &auth_uid);
if (r < 0)
return r;
errno = 0;
pw = getpwuid(uid);
@ -1157,7 +1201,8 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger",
uid == auth_uid ? "org.freedesktop.login1.set-self-linger" :
"org.freedesktop.login1.set-user-linger",
NULL,
interactive,
UID_INVALID,

View file

@ -357,6 +357,8 @@ static int pid_is_active(Manager *m, pid_t pid) {
Session *s;
int r;
/* Get client session. This is not what you are looking for these days.
* FIXME #6852 */
r = manager_get_session_by_pid(m, pid, &s);
if (r < 0)
return r;

View file

@ -332,28 +332,15 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
assert(m);
if (streq(path, "/org/freedesktop/login1/seat/self")) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
sd_bus_message *message;
Session *session;
const char *name;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
r = manager_get_seat_from_creds(m, message, NULL, error, &seat);
if (r < 0)
return r;
r = sd_bus_creds_get_session(creds, &name);
if (r < 0)
return r;
session = hashmap_get(m->sessions, name);
if (!session)
return 0;
seat = session->seat;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
@ -367,11 +354,10 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
return -ENOMEM;
seat = hashmap_get(m->seats, e);
if (!seat)
return 0;
}
if (!seat)
return 0;
*found = seat;
return 1;
}

View file

@ -580,23 +580,15 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
assert(m);
if (streq(path, "/org/freedesktop/login1/session/self")) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
sd_bus_message *message;
const char *name;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
r = manager_get_session_from_creds(m, message, NULL, error, &session);
if (r < 0)
return r;
r = sd_bus_creds_get_session(creds, &name);
if (r < 0)
return r;
session = hashmap_get(m->sessions, name);
} else {
_cleanup_free_ char *e = NULL;
const char *p;
@ -610,11 +602,10 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
return -ENOMEM;
session = hashmap_get(m->sessions, e);
if (!session)
return 0;
}
if (!session)
return 0;
*found = session;
return 1;
}

View file

@ -270,18 +270,15 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
assert(m);
if (streq(path, "/org/freedesktop/login1/user/self")) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
sd_bus_message *message;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
if (r < 0)
return r;
r = sd_bus_creds_get_owner_uid(creds, &uid);
} else {
const char *p;

View file

@ -1120,6 +1120,8 @@ static int parse_argv(int argc, char *argv[]) {
arg_userns_chown = true;
if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0) {
/* Save the user from accidentally registering either user-$SESSION.scope or user@.service.
* The latter is not technically a user session, but we don't need to labour the point. */
log_error("--keep-unit --register=yes may not be used when invoked from a user session.");
return -EINVAL;
}