run: split out polkit ops into separate .c file (#43047)
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ executables += [
|
||||
executable_template + {
|
||||
'name' : 'systemd-run',
|
||||
'public' : true,
|
||||
'sources' : files('run.c'),
|
||||
'sources' : files('run.c', 'run-polkit.c'),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "bus-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "pidfd-util.h"
|
||||
#include "process-util.h"
|
||||
#include "run-polkit.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int polkit_check_authorization(sd_bus *bus, PolkitFlags flags, char **ret_tmpauthz_id) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
pid_t pid;
|
||||
_cleanup_close_ int pidfd = -EBADF;
|
||||
_cleanup_free_ char *tmpauthz_id = NULL;
|
||||
int is_authorized, is_challenge;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"CheckAuthorization");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
pid = getpid_cached();
|
||||
|
||||
/* Polkit requires pidfd to honor temporary authorizations */
|
||||
pidfd = pidfd_open(pid, 0);
|
||||
if (pidfd < 0)
|
||||
return log_debug_errno(errno, "pidfd_open failed: %m");
|
||||
|
||||
r = sd_bus_message_append(m, "(sa{sv})s", "unix-process", 4, "pid", "u", (uint32_t) pid,
|
||||
"start-time", "t", UINT64_C(0), "uid", "i", (uint32_t) geteuid(), "pidfd", "h", pidfd,
|
||||
"org.freedesktop.systemd1.manage-units");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "a{ss}us", /* details = */ 0, (uint32_t) flags, /* cancel_id = */ NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check authorization: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read(reply, "bb", &is_authorized, &is_challenge);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "{ss}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *key, *value;
|
||||
r = sd_bus_message_enter_container(reply, 'e', "ss");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(reply, "ss", &key, &value);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(key, "polkit.temporary_authorization_id")) {
|
||||
r = free_and_strdup(&tmpauthz_id, value);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply); /* a{ss} */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply); /* (bba{ss}) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (ret_tmpauthz_id && is_authorized)
|
||||
*ret_tmpauthz_id = TAKE_PTR(tmpauthz_id);
|
||||
|
||||
return is_authorized;
|
||||
}
|
||||
|
||||
int polkit_revoke_temporary_authorization_by_id(sd_bus *bus, const char *id) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(id);
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"RevokeTemporaryAuthorizationById");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "s", id);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
log_debug("Revoking temporary authorization %s", id);
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, /* ret_reply= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to revoke temporary authorization %s: %s",
|
||||
id, bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_polkit_subject_for_uid(sd_bus_message *m) {
|
||||
const char *kind = NULL;
|
||||
uid_t uid = UID_INVALID;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'r', "sa{sv}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read(m, "s", &kind);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'a', "{sv}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *key, *contents;
|
||||
char type;
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'e', "sv");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(m, "s", &key);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_peek_type(m, &type, &contents);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(key, "pid")) {
|
||||
if (*contents != SD_BUS_TYPE_UINT32)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "start-time")) {
|
||||
if (*contents != SD_BUS_TYPE_UINT64)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "uid")) {
|
||||
if (*contents != SD_BUS_TYPE_INT32)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_read(m, "v", "i", &uid);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "pidfd")) {
|
||||
if (*contents != SD_BUS_TYPE_UNIX_FD)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else {
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(m); /* a(sa{sv}) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(m); /* (a(sa{sv})) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
return uid_is_valid(uid) && uid == geteuid();
|
||||
}
|
||||
|
||||
int polkit_revoke_temporary_authorizations(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
const char *session_id = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
session_id = getenv("XDG_SESSION_ID");
|
||||
if (!session_id)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "XDG_SESSION_ID is not set");
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"EnumerateTemporaryAuthorizations");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "(sa{sv})", "unix-session", 1, "session-id", "s", session_id);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate temporary authorizations: %s",
|
||||
bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "(ss(sa{sv})tt)");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *id = NULL, *action_id = NULL;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'r', "ss(sa{sv})tt");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(reply, "ss", &id, &action_id);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(action_id, "org.freedesktop.systemd1.manage-units")) {
|
||||
r = check_polkit_subject_for_uid(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
r = polkit_revoke_temporary_authorization_by_id(bus, id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
r = sd_bus_message_skip(reply, "(sa{sv})");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_skip(reply, "tt");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "forward.h"
|
||||
|
||||
int polkit_check_authorization(sd_bus *bus, PolkitFlags flags, char **ret_tmpauthz_id);
|
||||
int polkit_revoke_temporary_authorization_by_id(sd_bus *bus, const char *id);
|
||||
int polkit_revoke_temporary_authorizations(sd_bus *bus);
|
||||
+25
-307
@@ -4,7 +4,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/pidfd.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -57,6 +56,7 @@
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "ptyfwd.h"
|
||||
#include "run-polkit.h"
|
||||
#include "runtime-scope.h"
|
||||
#include "signal-util.h"
|
||||
#include "special.h"
|
||||
@@ -110,7 +110,6 @@ static int arg_pty_late = -1; /* tristate */
|
||||
static char **arg_path_property = NULL;
|
||||
static char **arg_socket_property = NULL;
|
||||
static char **arg_timer_property = NULL;
|
||||
static bool arg_with_timer = false;
|
||||
static bool arg_quiet = false;
|
||||
static bool arg_verbose = false;
|
||||
static OutputMode arg_output = _OUTPUT_MODE_INVALID;
|
||||
@@ -513,7 +512,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-boot", "SECONDS", "Run SECONDS after machine was booted up"):
|
||||
@@ -521,7 +519,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-startup", "SECONDS", "Run SECONDS after systemd activation"):
|
||||
@@ -529,7 +526,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-unit-active", "SECONDS", "Run SECONDS after the last activation"):
|
||||
@@ -537,7 +533,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-unit-inactive", "SECONDS",
|
||||
@@ -546,7 +541,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-calendar", "SPEC", "Realtime timer"): {
|
||||
@@ -576,7 +570,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -585,7 +578,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("on-clock-change", NULL, "Run when the realtime clock jumps"):
|
||||
@@ -593,23 +585,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_with_timer = true;
|
||||
break;
|
||||
|
||||
OPTION_LONG("timer-property", "NAME=VALUE", "Set timer unit property"):
|
||||
if (strv_extend(&arg_timer_property, opts.arg) < 0)
|
||||
return log_oom();
|
||||
|
||||
arg_with_timer = arg_with_timer ||
|
||||
STARTSWITH_SET(opts.arg,
|
||||
"OnActiveSec=",
|
||||
"OnBootSec=",
|
||||
"OnStartupSec=",
|
||||
"OnUnitActiveSec=",
|
||||
"OnUnitInactiveSec=",
|
||||
"OnCalendar=",
|
||||
"OnClockChange=",
|
||||
"OnTimezoneChange=");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -617,10 +598,27 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (arg_runtime_scope == RUNTIME_SCOPE_USER)
|
||||
arg_ask_password = false;
|
||||
|
||||
with_trigger = !!arg_path_property || !!arg_socket_property || arg_with_timer;
|
||||
size_t n_timer_triggers = 0, n_other_timer_properties = 0;
|
||||
STRV_FOREACH(i, arg_timer_property)
|
||||
if (STARTSWITH_SET(*i,
|
||||
"OnActiveSec=",
|
||||
"OnBootSec=",
|
||||
"OnStartupSec=",
|
||||
"OnUnitActiveSec=",
|
||||
"OnUnitInactiveSec=",
|
||||
"OnCalendar=",
|
||||
"OnClockChange=",
|
||||
"OnTimezoneChange="))
|
||||
n_timer_triggers++;
|
||||
else
|
||||
n_other_timer_properties++;
|
||||
if (n_other_timer_properties > 0 && n_timer_triggers == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--timer-property= set without any timer trigger expression (i.e. On*= setting), refusing.");
|
||||
|
||||
with_trigger = arg_path_property || arg_socket_property || arg_timer_property;
|
||||
|
||||
/* currently, only single trigger (path, socket, timer) unit can be created simultaneously */
|
||||
if (!!arg_path_property + !!arg_socket_property + (int) arg_with_timer > 1)
|
||||
if (!!arg_path_property + !!arg_socket_property + !!arg_timer_property > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Only single trigger (path, socket, timer) unit can be created.");
|
||||
|
||||
@@ -749,10 +747,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
"--json= is not compatible with path, socket or timer operations.");
|
||||
}
|
||||
|
||||
if (arg_timer_property && !arg_with_timer)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"--timer-property= has no effect without any other timer options.");
|
||||
|
||||
if (arg_wait) {
|
||||
if (arg_no_block)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
@@ -873,11 +867,11 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
arg_slice_inherit = true;
|
||||
break;
|
||||
|
||||
OPTION('k', "reset-timestamp", NULL, "Revoke temporary authorization"):
|
||||
OPTION('k', "reset-timestamp", NULL, "Revoke temporary authorization in polkit"):
|
||||
arg_reset_timestamp = true;
|
||||
break;
|
||||
|
||||
OPTION('K', "remove-timestamp", NULL, "Revoke all temporary authorizations for this user session"):
|
||||
OPTION('K', "remove-timestamp", NULL, "Revoke all temporary authorizations for this user session in polkit"):
|
||||
arg_remove_timestamp = true;
|
||||
break;
|
||||
|
||||
@@ -2975,282 +2969,6 @@ static bool shall_make_executable_absolute(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int polkit_check_authorization(sd_bus *bus, PolkitFlags flags, char **ret_tmpauthz_id) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
pid_t pid;
|
||||
_cleanup_close_ int pidfd = -EBADF;
|
||||
_cleanup_free_ char *tmpauthz_id = NULL;
|
||||
int is_authorized, is_challenge;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"CheckAuthorization");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
pid = getpid_cached();
|
||||
|
||||
/* Polkit requires pidfd to honor temporary authorizations */
|
||||
pidfd = pidfd_open(pid, 0);
|
||||
if (pidfd < 0)
|
||||
return log_debug_errno(errno, "pidfd_open failed: %m");
|
||||
|
||||
r = sd_bus_message_append(m, "(sa{sv})s", "unix-process", 4, "pid", "u", (uint32_t) pid,
|
||||
"start-time", "t", UINT64_C(0), "uid", "i", (uint32_t) geteuid(), "pidfd", "h", pidfd,
|
||||
"org.freedesktop.systemd1.manage-units");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "a{ss}us", /* details = */ 0, (uint32_t) flags, /* cancel_id = */ NULL);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check authorization: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read(reply, "bb", &is_authorized, &is_challenge);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "{ss}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *key, *value;
|
||||
r = sd_bus_message_enter_container(reply, 'e', "ss");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(reply, "ss", &key, &value);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(key, "polkit.temporary_authorization_id")) {
|
||||
r = free_and_strdup(&tmpauthz_id, value);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply); /* a{ss} */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply); /* (bba{ss}) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (ret_tmpauthz_id && is_authorized)
|
||||
*ret_tmpauthz_id = TAKE_PTR(tmpauthz_id);
|
||||
|
||||
return is_authorized;
|
||||
}
|
||||
|
||||
static int revoke_temporary_authorization_by_id(sd_bus *bus, const char *id) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(id);
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"RevokeTemporaryAuthorizationById");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "s", id);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
log_debug("Revoking temporary authorization %s", id);
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, /* ret_reply= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to revoke temporary authorization %s: %s",
|
||||
id, bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_polkit_subject_for_uid(sd_bus_message *m) {
|
||||
const char *kind = NULL;
|
||||
uid_t uid = UID_INVALID;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'r', "sa{sv}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read(m, "s", &kind);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'a', "{sv}");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *key, *contents;
|
||||
char type;
|
||||
|
||||
r = sd_bus_message_enter_container(m, 'e', "sv");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(m, "s", &key);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_peek_type(m, &type, &contents);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(key, "pid")) {
|
||||
if (*contents != SD_BUS_TYPE_UINT32)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "start-time")) {
|
||||
if (*contents != SD_BUS_TYPE_UINT64)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "uid")) {
|
||||
if (*contents != SD_BUS_TYPE_INT32)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_read(m, "v", "i", &uid);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else if (streq(key, "pidfd")) {
|
||||
if (*contents != SD_BUS_TYPE_UNIX_FD)
|
||||
return bus_log_parse_error(SYNTHETIC_ERRNO(EINVAL));
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
} else {
|
||||
r = sd_bus_message_skip(m, "v");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(m); /* a(sa{sv}) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(m); /* (a(sa{sv})) */
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
return uid_is_valid(uid) && uid == geteuid();
|
||||
}
|
||||
|
||||
static int revoke_temporary_authorizations(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
const char *session_id = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
session_id = getenv("XDG_SESSION_ID");
|
||||
if (!session_id)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "XDG_SESSION_ID is not set");
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &m,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"EnumerateTemporaryAuthorizations");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "(sa{sv})", "unix-session", 1, "session-id", "s", session_id);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_call(bus, m, /* usec = */ 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate temporary authorizations: %s",
|
||||
bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "(ss(sa{sv})tt)");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
for (;;) {
|
||||
const char *id = NULL, *action_id = NULL;
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'r', "ss(sa{sv})tt");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = sd_bus_message_read(reply, "ss", &id, &action_id);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (streq(action_id, "org.freedesktop.systemd1.manage-units")) {
|
||||
r = check_polkit_subject_for_uid(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
r = revoke_temporary_authorization_by_id(bus, id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
r = sd_bus_message_skip(reply, "(sa{sv})");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_skip(reply, "tt");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int polkit_validate(sd_bus *bus) {
|
||||
PolkitFlags flags = POLKIT_ALWAYS_QUERY;
|
||||
int r;
|
||||
@@ -3333,7 +3051,7 @@ static int run(int argc, char* argv[]) {
|
||||
return r;
|
||||
|
||||
if (arg_remove_timestamp) {
|
||||
r = revoke_temporary_authorizations(bus);
|
||||
r = polkit_revoke_temporary_authorizations(bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (arg_validate)
|
||||
@@ -3347,7 +3065,7 @@ static int run(int argc, char* argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0 && tmpauthz_id) {
|
||||
r = revoke_temporary_authorization_by_id(bus, tmpauthz_id);
|
||||
r = polkit_revoke_temporary_authorization_by_id(bus, tmpauthz_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -3365,7 +3083,7 @@ static int run(int argc, char* argv[]) {
|
||||
return start_transient_trigger(bus, ".path");
|
||||
if (arg_socket_property)
|
||||
return start_transient_trigger(bus, ".socket");
|
||||
if (arg_with_timer)
|
||||
if (arg_timer_property)
|
||||
return start_transient_trigger(bus, ".timer");
|
||||
return start_transient_service(bus);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef enum OutputFlags OutputFlags;
|
||||
typedef enum OutputMode OutputMode;
|
||||
typedef enum PagerFlags PagerFlags;
|
||||
typedef enum PatternCompileCase PatternCompileCase;
|
||||
typedef enum PolkitFlags PolkitFlags;
|
||||
typedef enum RemoveFlags RemoveFlags;
|
||||
typedef enum ResolveSupport ResolveSupport;
|
||||
typedef enum TPM2Flags TPM2Flags;
|
||||
|
||||
Reference in New Issue
Block a user