mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #28056 from dtardon/polkit-cleanup
Some bus-polkit cleanup
This commit is contained in:
commit
ab93429dea
@ -32,10 +32,7 @@ static int check_good_user(sd_bus_message *m, uid_t good_user) {
|
||||
}
|
||||
|
||||
#if ENABLE_POLKIT
|
||||
static int bus_message_append_strv_key_value(
|
||||
sd_bus_message *m,
|
||||
const char **l) {
|
||||
|
||||
static int bus_message_append_strv_key_value(sd_bus_message *m, const char **l) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -56,6 +53,51 @@ static int bus_message_append_strv_key_value(
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int bus_message_new_polkit_auth_call(
|
||||
sd_bus_message *m,
|
||||
const char *action,
|
||||
const char **details,
|
||||
bool interactive,
|
||||
sd_bus_message **ret) {
|
||||
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *c = NULL;
|
||||
const char *sender;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(action);
|
||||
assert(ret);
|
||||
|
||||
sender = sd_bus_message_get_sender(m);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
|
||||
r = sd_bus_message_new_method_call(
|
||||
ASSERT_PTR(m->bus),
|
||||
&c,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"CheckAuthorization");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(c, "(sa{sv})s", "system-bus-name", 1, "name", "s", sender, action);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_message_append_strv_key_value(c, details);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(c, "us", interactive, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(c);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int bus_test_polkit(
|
||||
@ -81,71 +123,42 @@ int bus_test_polkit(
|
||||
r = sd_bus_query_sender_privilege(call, capability);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if (r > 0)
|
||||
if (r > 0)
|
||||
return 1;
|
||||
|
||||
#if ENABLE_POLKIT
|
||||
else {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
int authorized = false, challenge = false;
|
||||
const char *sender;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL, *reply = NULL;
|
||||
int authorized = false, challenge = false;
|
||||
|
||||
sender = sd_bus_message_get_sender(call);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
r = bus_message_new_polkit_auth_call(call, action, details, /* interactive = */ false, &request);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_new_method_call(
|
||||
call->bus,
|
||||
&request,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"CheckAuthorization");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(
|
||||
request,
|
||||
"(sa{sv})s",
|
||||
"system-bus-name", 1, "name", "s", sender,
|
||||
action);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_message_append_strv_key_value(request, details);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(request, "us", 0, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_call(call->bus, request, 0, ret_error, &reply);
|
||||
if (r < 0) {
|
||||
/* Treat no PK available as access denied */
|
||||
if (bus_error_is_unknown_service(ret_error)) {
|
||||
sd_bus_error_free(ret_error);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
return r;
|
||||
r = sd_bus_call(call->bus, request, 0, ret_error, &reply);
|
||||
if (r < 0) {
|
||||
/* Treat no PK available as access denied */
|
||||
if (bus_error_is_unknown_service(ret_error)) {
|
||||
sd_bus_error_free(ret_error);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
|
||||
if (r < 0)
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (authorized)
|
||||
return 1;
|
||||
r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (_challenge) {
|
||||
*_challenge = challenge;
|
||||
return 0;
|
||||
}
|
||||
if (authorized)
|
||||
return 1;
|
||||
|
||||
if (_challenge) {
|
||||
*_challenge = challenge;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -165,9 +178,9 @@ typedef struct AsyncPolkitQuery {
|
||||
sd_event_source *defer_event_source;
|
||||
} AsyncPolkitQuery;
|
||||
|
||||
static void async_polkit_query_free(AsyncPolkitQuery *q) {
|
||||
static AsyncPolkitQuery *async_polkit_query_free(AsyncPolkitQuery *q) {
|
||||
if (!q)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
sd_bus_slot_unref(q->slot);
|
||||
|
||||
@ -181,11 +194,12 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
|
||||
strv_free(q->details);
|
||||
|
||||
sd_event_source_disable_unref(q->defer_event_source);
|
||||
free(q);
|
||||
|
||||
return mfree(q);
|
||||
}
|
||||
|
||||
static int async_polkit_defer(sd_event_source *s, void *userdata) {
|
||||
AsyncPolkitQuery *q = userdata;
|
||||
AsyncPolkitQuery *q = ASSERT_PTR(userdata);
|
||||
|
||||
assert(s);
|
||||
|
||||
@ -245,6 +259,60 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int process_polkit_response(
|
||||
AsyncPolkitQuery *q,
|
||||
sd_bus_message *call,
|
||||
const char *action,
|
||||
const char **details,
|
||||
Hashmap **registry,
|
||||
sd_bus_error *ret_error) {
|
||||
|
||||
int authorized, challenge, r;
|
||||
|
||||
assert(q);
|
||||
assert(call);
|
||||
assert(action);
|
||||
assert(registry);
|
||||
assert(ret_error);
|
||||
|
||||
assert(q->action);
|
||||
assert(q->reply);
|
||||
|
||||
/* If the operation we want to authenticate changed between the first and the second time,
|
||||
* let's not use this authentication, it might be out of date as the object and context we
|
||||
* operate on might have changed. */
|
||||
if (!streq(q->action, action) || !strv_equal(q->details, (char**) details))
|
||||
return -ESTALE;
|
||||
|
||||
if (sd_bus_message_is_method_error(q->reply, NULL)) {
|
||||
const sd_bus_error *e;
|
||||
|
||||
e = sd_bus_message_get_error(q->reply);
|
||||
|
||||
/* Treat no PK available as access denied */
|
||||
if (bus_error_is_unknown_service(e))
|
||||
return -EACCES;
|
||||
|
||||
/* Copy error from polkit reply */
|
||||
sd_bus_error_copy(ret_error, e);
|
||||
return -sd_bus_error_get_errno(e);
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
|
||||
if (r >= 0)
|
||||
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (authorized)
|
||||
return 1;
|
||||
|
||||
if (challenge)
|
||||
return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int bus_verify_polkit_async(
|
||||
@ -257,7 +325,6 @@ int bus_verify_polkit_async(
|
||||
Hashmap **registry,
|
||||
sd_bus_error *ret_error) {
|
||||
|
||||
const char *sender;
|
||||
int r;
|
||||
|
||||
assert(call);
|
||||
@ -270,60 +337,18 @@ int bus_verify_polkit_async(
|
||||
|
||||
#if ENABLE_POLKIT
|
||||
AsyncPolkitQuery *q = hashmap_get(*registry, call);
|
||||
if (q) {
|
||||
int authorized, challenge;
|
||||
|
||||
/* This is the second invocation of this function, and there's already a response from
|
||||
* polkit, let's process it */
|
||||
assert(q->reply);
|
||||
|
||||
/* If the operation we want to authenticate changed between the first and the second time,
|
||||
* let's not use this authentication, it might be out of date as the object and context we
|
||||
* operate on might have changed. */
|
||||
if (!streq(q->action, action) ||
|
||||
!strv_equal(q->details, (char**) details))
|
||||
return -ESTALE;
|
||||
|
||||
if (sd_bus_message_is_method_error(q->reply, NULL)) {
|
||||
const sd_bus_error *e;
|
||||
|
||||
e = sd_bus_message_get_error(q->reply);
|
||||
|
||||
/* Treat no PK available as access denied */
|
||||
if (bus_error_is_unknown_service(e))
|
||||
return -EACCES;
|
||||
|
||||
/* Copy error from polkit reply */
|
||||
sd_bus_error_copy(ret_error, e);
|
||||
return -sd_bus_error_get_errno(e);
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
|
||||
if (r >= 0)
|
||||
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (authorized)
|
||||
return 1;
|
||||
|
||||
if (challenge)
|
||||
return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
/* This is the second invocation of this function, and there's already a response from
|
||||
* polkit, let's process it */
|
||||
if (q)
|
||||
return process_polkit_response(q, call, action, details, registry, ret_error);
|
||||
#endif
|
||||
|
||||
r = sd_bus_query_sender_privilege(call, capability);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if (r > 0)
|
||||
if (r > 0)
|
||||
return 1;
|
||||
|
||||
sender = sd_bus_message_get_sender(call);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
|
||||
#if ENABLE_POLKIT
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
|
||||
|
||||
@ -337,29 +362,7 @@ int bus_verify_polkit_async(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_new_method_call(
|
||||
call->bus,
|
||||
&pk,
|
||||
"org.freedesktop.PolicyKit1",
|
||||
"/org/freedesktop/PolicyKit1/Authority",
|
||||
"org.freedesktop.PolicyKit1.Authority",
|
||||
"CheckAuthorization");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(
|
||||
pk,
|
||||
"(sa{sv})s",
|
||||
"system-bus-name", 1, "name", "s", sender,
|
||||
action);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_message_append_strv_key_value(pk, details);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(pk, "us", interactive, NULL);
|
||||
r = bus_message_new_polkit_auth_call(call, action, details, interactive, &pk);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user