mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
Merge pull request #6866 from sourcejedi/set-linger2
logind: fix `loginctl enable-linger`
This commit is contained in:
commit
0986658d51
@ -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>
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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 <systemd/sd-login.h></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
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user