Add pidfd parameter to CheckAuthorization()
Allows to verify arbitrary processes by PIDFD, like it is already allowed for D-Bus clients.
Fixes #206 (closed)
root@localhost:~# systemd-run --unit good.service -p DynamicUser=yes sleep infinity
Running as unit: good.service; invocation ID: 21c19fb228a149e4ba0b8e5372181461
root@localhost:~# systemd-run --unit bad.service -p DynamicUser=yes sleep infinity
Running as unit: bad.service; invocation ID: 4af9bb51e19149028bb197e16c120baf
root@localhost:~# test `systemctl show -P MainPID bad`
pid 643: authorized: 0, challenge: 1
root@localhost:~# test `systemctl show -P MainPID good`
pid 641: authorized: 1, challenge: 0
test rules:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.reload-daemon" && subject.system_unit == "good.service") {
if (subject.session) {
polkit.log(subject.session);
}
if (subject.seat) {
polkit.log(subject.seat);
}
if (subject.system_unit) {
polkit.log(subject.system_unit);
} else {
polkit.log("no system_unit found");
}
if (subject.no_new_privileges) {
polkit.log("no_new_privileges set");
}
return polkit.Result.YES;
}
});
test program:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <systemd/sd-bus.h>
#define _cleanup_(f) __attribute__((cleanup(f)))
#define DESTINATION "org.freedesktop.PolicyKit1"
#define PATH "/org/freedesktop/PolicyKit1/Authority"
#define INTERFACE "org.freedesktop.PolicyKit1.Authority"
#define MEMBER "CheckAuthorization"
static int log_error(int error, const char *message) {
errno = -error;
fprintf(stderr, "%s: %m\n", message);
return error;
}
int main (int argc, char **argv) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL;
int authorized = 0, challenge = 0, pid, r;
if (argc < 2)
return log_error(-EINVAL, "Usage: <prog> <pid>");
pid = atoi(argv[1]);
r = sd_bus_open_system(&bus);
if (r < 0)
return log_error(r, "Failed to acquire bus");
r = sd_bus_message_new_method_call(bus, &m, DESTINATION, PATH, INTERFACE, MEMBER);
if (r < 0)
return log_error(r, "Failed to create bus message");
r = sd_bus_message_append(m, "(sa{sv})s", "unix-process", 1, "pidfd", "h", pidfd_open(pid, 0), "org.freedesktop.systemd1.reload-daemon");
if (r < 0)
return r;
r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
if (r < 0)
return log_error(r, "Failed to append to bus message");
r = sd_bus_message_close_container(m);
if (r < 0)
return log_error(r, "Failed to append to bus message");
r = sd_bus_message_append(m, "us", 0, NULL);
if (r < 0)
return log_error(r, "Failed to append to bus message");
r = sd_bus_call(bus, m, -1, &error, &reply);
if (r < 0)
return log_error(r, MEMBER " call failed");
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
if (r < 0)
return r;
r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
if (r < 0)
return r;
printf("pid %d: authorized: %d, challenge: %d\n", pid, authorized, challenge);
return 0;
}