diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2015-01-17 18:07:58 +0100 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2015-01-17 18:27:23 +0100 |
commit | c4bc1a8434f2a34840ea6f63064fa998ecfae738 (patch) | |
tree | c10ae7cfd3864cc74fc83c997baaf45e81215b48 /src/bus-proxyd/proxy.c | |
parent | b58d857136496ee463223cd90af46512e9eef152 (diff) |
bus-proxy: share policy between threads
This implements a shared policy cache with read-write locks. We no longer
parse the XML policy in each thread.
This will allow us to easily implement ReloadConfig().
Diffstat (limited to 'src/bus-proxyd/proxy.c')
-rw-r--r-- | src/bus-proxyd/proxy.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c index 744b11da5c..ab164474fa 100644 --- a/src/bus-proxyd/proxy.c +++ b/src/bus-proxyd/proxy.c @@ -255,16 +255,27 @@ Proxy *proxy_free(Proxy *p) { return NULL; } -int proxy_load_policy(Proxy *p, char **configuration) { +int proxy_set_policy(Proxy *p, SharedPolicy *sp, char **configuration) { _cleanup_strv_free_ char **strv = NULL; + Policy *policy; int r; assert(p); + assert(sp); /* no need to load legacy policy if destination is not kdbus */ if (!p->dest_bus->is_kernel) return 0; + p->policy = sp; + + policy = shared_policy_acquire(sp); + if (policy) { + /* policy already pre-loaded */ + shared_policy_release(sp, policy); + return 0; + } + if (!configuration) { const char *scope; @@ -291,30 +302,30 @@ int proxy_load_policy(Proxy *p, char **configuration) { configuration = strv; } - r = policy_load(&p->policy_buffer, configuration); - if (r < 0) - return log_error_errno(r, "Failed to load policy: %m"); - - p->policy = &p->policy_buffer; - /* policy_dump(p->policy); */ - - return 0; + return shared_policy_preload(sp, configuration); } int proxy_hello_policy(Proxy *p, uid_t original_uid) { + Policy *policy; + int r = 0; + assert(p); if (!p->policy) return 0; + policy = shared_policy_acquire(p->policy); + if (p->local_creds.uid == original_uid) log_debug("Permitting access, since bus owner matches bus client."); - else if (policy_check_hello(p->policy, p->local_creds.uid, p->local_creds.gid)) + else if (policy_check_hello(policy, p->local_creds.uid, p->local_creds.gid)) log_debug("Permitting access due to XML policy."); else - return log_error_errno(EPERM, "Policy denied connection."); + r = log_error_errno(EPERM, "Policy denied connection."); - return 0; + shared_policy_release(p->policy, policy); + + return r; } static int proxy_wait(Proxy *p) { @@ -384,7 +395,7 @@ static int handle_policy_error(sd_bus_message *m, int r) { return r; } -static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) { +static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) { int r; assert(from); @@ -584,6 +595,19 @@ static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *p return 0; } +static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, SharedPolicy *sp, const struct ucred *our_ucred, Set *owned_names) { + Policy *policy; + int r; + + assert(sp); + + policy = shared_policy_acquire(sp); + r = process_policy_unlocked(from, to, m, policy, our_ucred, owned_names); + shared_policy_release(sp, policy); + + return r; +} + static int process_hello(Proxy *p, sd_bus_message *m) { _cleanup_bus_message_unref_ sd_bus_message *n = NULL; bool is_hello; |