Skip to content

Add pidfd parameter to CheckAuthorization()

Luca Boccassi requested to merge bluca/polkit:check_auth_pidfd into master

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;
    }

Merge request reports