X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbus-proxyd%2Fbus-proxyd.c;h=d6607edfd6513ed10852a0789ed02684a8a1316f;hb=ed6d629a3487105e31415db9e175dd698ac20125;hp=c5aeaacf426f9be66c314450e85bbbfe61bd57a1;hpb=5bb24cccbce846c0d77e71b70a3be7f4b2ba6c0e;p=elogind.git diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c index c5aeaacf4..d6607edfd 100644 --- a/src/bus-proxyd/bus-proxyd.c +++ b/src/bus-proxyd/bus-proxyd.c @@ -469,7 +469,10 @@ static int peer_is_privileged(sd_bus *bus, sd_bus_message *m) { static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m, Policy *policy, const struct ucred *ucred) { int r; + char **name; char **names_strv; + bool granted = false; + Iterator i; assert(a); assert(b); @@ -485,18 +488,68 @@ static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m, Policy *polic if (r < 0) return r; -/* - if (!policy_check_recv(policy, ucred, names_hash, m->header->type, m->path, m->interface, m->member)) - return -EPERM; + STRV_FOREACH(name, names_strv) { + if (policy_check_send(policy, ucred, m->header->type, *name, m->path, m->interface, m->member)) { + r = free_and_strdup(&m->destination_ptr, *name); + if (r < 0) + break; + + granted = true; + break; + } + } - if (!policy_check_send(policy, ucred, names_strv, m->header->type, m->path, m->interface, m->member)) + if (r < 0) + return r; + + if (!granted) return -EPERM; -*/ + + granted = false; + + HASHMAP_FOREACH(name, names_hash, i) { + if (policy_check_recv(policy, ucred, m->header->type, *name, m->path, m->interface, m->member)) + return 0; + } + + return -EPERM; } else { + sd_bus_creds *bus_creds; + /* The message came from the legacy client, and is sent to kdbus. */ + r = sd_bus_get_name_creds(a, m->destination, SD_BUS_CREDS_WELL_KNOWN_NAMES, &bus_creds); + if (r < 0) + return r; + STRV_FOREACH(name, names_strv) { + if (policy_check_send(policy, ucred, m->header->type, *name, m->path, m->interface, m->member)) { + r = free_and_strdup(&m->destination_ptr, *name); + if (r < 0) + break; + r = bus_kernel_parse_unique_name(m->sender, &m->verify_destination_id); + if (r < 0) + break; + granted = true; + break; + } + } + + if (r < 0) + return r; + + if (!granted) + return -EPERM; + + granted = false; + + HASHMAP_FOREACH(name, names_hash, i) { + if (policy_check_recv(policy, ucred, m->header->type, *name, m->path, m->interface, m->member)) + return 0; + } + + return -EPERM; } return 0; @@ -1454,27 +1507,33 @@ int main(int argc, char *argv[]) { if (k > 0) r = k; else { - k = process_policy(a, b, m, &policy, &ucred); - if (k < 0) { - r = k; - log_error("Failed to process policy: %s", strerror(-r)); - goto finish; - } + bool retry; - k = sd_bus_send(a, m, NULL); - if (k < 0) { - if (k == -ECONNRESET) - r = 0; - else { + do { + retry = false; k = process_policy(a, b, m, p, &ucred); if (k < 0) { r = k; - log_error("Failed to send message: %s", strerror(-r)); + log_error("Failed to process policy: %s", strerror(-r)); + goto finish; } - goto finish; - } + k = sd_bus_send(a, m, NULL); + if (k < 0) { + if (k == -ECONNRESET) + r = 0; + else if (k == -EREMCHG) + retry = true; + else { + r = k; + log_error("Failed to send message: %s", strerror(-r)); + } + + if (!retry) + goto finish; + } + } while (retry); } } }