THis not only mkaes a lot of code shorter, but also safer, as we pin the
clients via a pidfd.
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-log-control-api.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-log-control-api.h"
#include "chase.h"
#include "confidential-virt.h"
#include "data-fd-util.h"
#include "chase.h"
#include "confidential-virt.h"
#include "data-fd-util.h"
* its sleeve: if the name is specified empty we use the client's unit. */
if (isempty(name)) {
* its sleeve: if the name is specified empty we use the client's unit. */
if (isempty(name)) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t pid;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
+ r = bus_query_sender_pidref(message, &pidref);
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r < 0)
- return r;
-
- u = manager_get_unit_by_pid(m, pid);
+ u = manager_get_unit_by_pidref(m, &pidref);
if (!u)
return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
} else {
if (!u)
return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
} else {
static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = ASSERT_PTR(userdata);
static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = ASSERT_PTR(userdata);
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
/* Anyone can call this method */
/* Anyone can call this method */
- r = sd_bus_message_read(message, "u", &pid);
+ r = sd_bus_message_read(message, "u", &pidref.pid);
- if (pid < 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
-
- if (pid == 0) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
+ if (pidref.pid < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pidref.pid);
+ if (pidref.pid == 0) {
+ r = bus_query_sender_pidref(message, &pidref);
- u = manager_get_unit_by_pid(m, pid);
+ u = manager_get_unit_by_pidref(m, &pidref);
- return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
+ return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pidref.pid);
return reply_unit_path(u, message, error);
}
return reply_unit_path(u, message, error);
}
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
if (sd_id128_is_null(id)) {
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
if (sd_id128_is_null(id)) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t pid;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- r = sd_bus_creds_get_pid(creds, &pid);
+ r = bus_query_sender_pidref(message, &pidref);
- u = manager_get_unit_by_pid(m, pid);
+ u = manager_get_unit_by_pidref(m, &pidref);
if (!u)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
if (!u)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
- "Client " PID_FMT " not member of any unit.", pid);
+ "Client " PID_FMT " not member of any unit.", pidref.pid);
} else {
u = hashmap_get(m->units_by_invocation_id, &id);
if (!u)
} else {
u = hashmap_get(m->units_by_invocation_id, &id);
if (!u)
}
static int aux_scope_from_message(Manager *m, sd_bus_message *message, Unit **ret_scope, sd_bus_error *error) {
}
static int aux_scope_from_message(Manager *m, sd_bus_message *message, Unit **ret_scope, sd_bus_error *error) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_(pidref_done) PidRef sender_pidref = PIDREF_NULL;
_cleanup_free_ PidRef *pidrefs = NULL;
const char *name;
Unit *from, *scope;
_cleanup_free_ PidRef *pidrefs = NULL;
const char *name;
Unit *from, *scope;
CGroupContext *cc;
size_t n_pids = 0;
uint64_t flags;
CGroupContext *cc;
size_t n_pids = 0;
uint64_t flags;
int r;
assert(ret_scope);
int r;
assert(ret_scope);
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
+ r = bus_query_sender_pidref(message, &sender_pidref);
- from = manager_get_unit_by_pid(m, pid);
+ from = manager_get_unit_by_pidref(m, &sender_pidref);
if (!from)
return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
if (!from)
return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "dbus-cgroup.h"
#include "dbus-kill.h"
#include "dbus-manager.h"
#include "dbus-cgroup.h"
#include "dbus-kill.h"
#include "dbus-manager.h"
return bus_set_transient_oom_policy(u, name, &s->oom_policy, message, flags, error);
if (streq(name, "PIDs")) {
return bus_set_transient_oom_policy(u, name, &s->oom_policy, message, flags, error);
if (streq(name, "PIDs")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_(pidref_done) PidRef sender_pidref = PIDREF_NULL;
unsigned n = 0;
r = sd_bus_message_enter_container(message, 'a', "u");
unsigned n = 0;
r = sd_bus_message_enter_container(message, 'a', "u");
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
uint32_t upid;
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
uint32_t upid;
r = sd_bus_message_read(message, "u", &upid);
if (r < 0)
r = sd_bus_message_read(message, "u", &upid);
if (r < 0)
- if (!creds) {
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
+ if (!pidref_is_set(&sender_pidref)) {
+ r = bus_query_sender_pidref(message, &sender_pidref);
- r = sd_bus_creds_get_pid(creds, &pid);
+ p = &sender_pidref;
+ } else {
+ r = pidref_set_pid(&pidref, upid);
- } else
- pid = (uid_t) upid;
- r = pidref_set_pid(&pidref, pid);
- if (r < 0)
- return r;
- r = unit_pid_attachable(u, &pidref, error);
+ r = unit_pid_attachable(u, p, error);
if (r < 0)
return r;
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
if (r < 0)
return r;
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
- r = unit_watch_pidref(u, &pidref, /* exclusive= */ false);
+ r = unit_watch_pidref(u, p, /* exclusive= */ false);
if (r < 0 && r != -EEXIST)
return r;
}
if (r < 0 && r != -EEXIST)
return r;
}
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-polkit.h"
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "condition.h"
#include "dbus-job.h"
#include "cgroup-util.h"
#include "condition.h"
#include "dbus-job.h"
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD, &creds);
_cleanup_(pidref_freep) PidRef *pidref = NULL;
uid_t process_uid, sender_uid;
uint32_t upid;
_cleanup_(pidref_freep) PidRef *pidref = NULL;
uid_t process_uid, sender_uid;
uint32_t upid;
r = sd_bus_message_read(message, "u", &upid);
if (r < 0)
r = sd_bus_message_read(message, "u", &upid);
if (r < 0)
- r = sd_bus_creds_get_pid(creds, &pid);
+ _cleanup_(pidref_done) PidRef p = PIDREF_NULL;
+ r = bus_creds_get_pidref(creds, &p);
- } else
- pid = (uid_t) upid;
- r = pidref_new_from_pid(pid, &pidref);
+ r = pidref_dup(&p, &pidref);
+ } else
+ r = pidref_new_from_pid(upid, &pidref);
return sd_bus_error_set_errnof(error, r, "Failed to retrieve process UID: %m");
if (process_uid != sender_uid)
return sd_bus_error_set_errnof(error, r, "Failed to retrieve process UID: %m");
if (process_uid != sender_uid)
- return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pid);
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pidref->pid);
if (process_uid != u->ref_uid)
if (process_uid != u->ref_uid)
- return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by target unit's UID. Refusing.", pid);
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by target unit's UID. Refusing.", pidref->pid);
}
r = set_ensure_consume(&pids, &pidref_hash_ops_free, TAKE_PTR(pidref));
}
r = set_ensure_consume(&pids, &pidref_hash_ops_free, TAKE_PTR(pidref));
return 0;
path = sd_bus_message_get_path(message);
return 0;
path = sd_bus_message_get_path(message);
if (object_path_startswith("/org/freedesktop/systemd1", path)) {
r = mac_selinux_access_check(message, verb, error);
if (object_path_startswith("/org/freedesktop/systemd1", path)) {
r = mac_selinux_access_check(message, verb, error);
- if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t pid;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return 0;
+ if (streq(path, "/org/freedesktop/systemd1/unit/self")) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
- r = sd_bus_creds_get_pid(creds, &pid);
+ r = bus_query_sender_pidref(message, &pidref);
- u = manager_get_unit_by_pid(m, pid);
+ u = manager_get_unit_by_pidref(m, &pidref);
} else {
r = manager_get_job_from_dbus_path(m, path, &j);
if (r >= 0)
u = j->unit;
else
} else {
r = manager_get_job_from_dbus_path(m, path, &j);
if (r >= 0)
u = j->unit;
else
- manager_load_unit_from_dbus_path(m, path, NULL, &u);
+ (void) manager_load_unit_from_dbus_path(m, path, NULL, &u);
assert(bus);
assert(path);
assert(bus);
assert(path);
- if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ if (streq(path, "/org/freedesktop/systemd1/unit/self")) {
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &pid);
+ r = bus_query_sender_pidref(message, &pidref);
- u = manager_get_unit_by_pid(m, pid);
+ u = manager_get_unit_by_pidref(m, &pidref);
if (!u)
return 0;
} else {
if (!u)
return 0;
} else {
- sd_bus_creds_get_cmdline(creds, &cmdline);
+ (void) sd_bus_creds_get_cmdline(creds, &cmdline);
cl = strv_join(cmdline, " ");
struct audit_info audit_info = {
cl = strv_join(cmdline, " ");
struct audit_info audit_info = {
void *userdata,
sd_bus_error *error,
uid_t uid,
void *userdata,
sd_bus_error *error,
uid_t uid,
- pid_t pid,
- int pidfd,
+ pid_t leader_pid,
+ int leader_pidfd,
const char *service,
const char *type,
const char *class,
const char *service,
const char *type,
const char *class,
if (flags != 0)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Flags must be zero.");
if (flags != 0)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Flags must be zero.");
- if (pidfd >= 0) {
- r = pidref_set_pidfd(&leader, pidfd);
- if (r < 0)
- return r;
- } else if (pid == 0) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t p;
-
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
- if (r < 0)
- return r;
-
- r = sd_bus_creds_get_pid(creds, &p);
- if (r < 0)
- return r;
-
- r = pidref_set_pid(&leader, p);
- if (r < 0)
- return r;
- } else {
- assert(pid > 0);
+ if (leader_pidfd >= 0)
+ r = pidref_set_pidfd(&leader, leader_pidfd);
+ else if (leader_pid == 0)
+ r = bus_query_sender_pidref(message, &leader);
+ else {
+ if (leader_pid < 0)
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Leader PID is not valid");
- r = pidref_set_pid(&leader, pid);
- if (r < 0)
- return r;
+ r = pidref_set_pid(&leader, leader_pid);
if (leader.pid == 1 || leader.pid == getpid_cached())
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
if (leader.pid == 1 || leader.pid == getpid_cached())
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
+ pid_t leader_pid;
+ uint32_t vtnr;
- int remote;
- uint32_t vtnr = 0;
- int r;
assert(message);
assert_cc(sizeof(pid_t) == sizeof(uint32_t));
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
assert(message);
assert_cc(sizeof(pid_t) == sizeof(uint32_t));
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
- r = sd_bus_message_read(message,
- "uusssssussbss",
- &uid,
- &leader,
- &service,
- &type,
- &class,
- &desktop,
- &cseat,
- &vtnr,
- &tty,
- &display,
- &remote,
- &remote_user,
- &remote_host);
+ r = sd_bus_message_read(
+ message,
+ "uusssssussbss",
+ &uid,
+ &leader_pid,
+ &service,
+ &type,
+ &class,
+ &desktop,
+ &cseat,
+ &vtnr,
+ &tty,
+ &display,
+ &remote,
+ &remote_user,
+ &remote_host);
/* pidfd = */ -EBADF,
service,
type,
/* pidfd = */ -EBADF,
service,
type,
static int method_create_session_pidfd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
static int method_create_session_pidfd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
- int leaderfd = -EBADF;
- uid_t uid;
- int remote;
- uint32_t vtnr = 0;
+ uint32_t vtnr;
+ uid_t uid;
+ int leader_fd = -EBADF, remote, r;
- r = sd_bus_message_read(message,
- "uhsssssussbsst",
- &uid,
- &leaderfd,
- &service,
- &type,
- &class,
- &desktop,
- &cseat,
- &vtnr,
- &tty,
- &display,
- &remote,
- &remote_user,
- &remote_host,
- &flags);
+ r = sd_bus_message_read(
+ message,
+ "uhsssssussbsst",
+ &uid,
+ &leader_fd,
+ &service,
+ &type,
+ &class,
+ &desktop,
+ &cseat,
+ &vtnr,
+ &tty,
+ &display,
+ &remote,
+ &remote_user,
+ &remote_host,
+ &flags);
- /* pid = */ 0,
- leaderfd,
+ /* leader_pid = */ 0,
+ leader_fd,
Manager *m = ASSERT_PTR(userdata);
InhibitMode mm;
InhibitWhat w;
Manager *m = ASSERT_PTR(userdata);
InhibitMode mm;
InhibitWhat w;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD, &creds);
- r = sd_bus_creds_get_pid(creds, &pid);
+ r = bus_creds_get_pidref(creds, &pidref);
- r = pidref_set_pid(&pidref, pid);
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed pin source process "PID_FMT": %m", pid);
-
if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
"Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.",
if (hashmap_size(m->inhibitors) >= m->inhibitors_max)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED,
"Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.",