X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbus-proxyd%2Fbus-xml-policy.c;h=f6ac0c009355f1fb8362d6e08faa8d01de769992;hb=1fa2f38f0f011010bf57522b42fcc168856a7003;hp=b3daad50177beb0820ace73f3e53502994f174f8;hpb=c4bc1a8434f2a34840ea6f63064fa998ecfae738;p=elogind.git diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c index b3daad501..f6ac0c009 100644 --- a/src/bus-proxyd/bus-xml-policy.c +++ b/src/bus-proxyd/bus-xml-policy.c @@ -22,6 +22,7 @@ #include "xml.h" #include "fileio.h" #include "strv.h" +#include "set.h" #include "conf-files.h" #include "bus-internal.h" #include "bus-message.h" @@ -865,15 +866,14 @@ bool policy_check_hello(Policy *p, uid_t uid, gid_t gid) { return verdict == ALLOW; } -bool policy_check_recv(Policy *p, - uid_t uid, - gid_t gid, - int message_type, - const char *name, - const char *path, - const char *interface, - const char *member, - bool dbus_to_kernel) { +bool policy_check_one_recv(Policy *p, + uid_t uid, + gid_t gid, + int message_type, + const char *name, + const char *path, + const char *interface, + const char *member) { struct policy_check_filter filter = { .class = POLICY_ITEM_RECV, @@ -886,30 +886,64 @@ bool policy_check_recv(Policy *p, .member = member, }; - int verdict; - assert(p); - verdict = policy_check(p, &filter); - - log_full(LOG_AUTH | (verdict != ALLOW ? LOG_WARNING : LOG_DEBUG), - "Receive permission check %s for uid=" UID_FMT " gid=" GID_FMT" message=%s name=%s path=%s interface=%s member=%s: %s", - dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(name), - strna(path), strna(interface), strna(member), strna(verdict_to_string(verdict))); - - return verdict == ALLOW; + return policy_check(p, &filter) == ALLOW; } -bool policy_check_send(Policy *p, +bool policy_check_recv(Policy *p, uid_t uid, gid_t gid, int message_type, - const char *name, + Set *names, + char **namesv, const char *path, const char *interface, const char *member, bool dbus_to_kernel) { + char *n, **nv, *last = NULL; + bool allow = false; + Iterator i; + + assert(p); + + if (set_isempty(names) && strv_isempty(namesv)) { + allow = policy_check_one_recv(p, uid, gid, message_type, NULL, path, interface, member); + } else { + SET_FOREACH(n, names, i) { + last = n; + allow = policy_check_one_recv(p, uid, gid, message_type, n, path, interface, member); + if (allow) + break; + } + if (!allow) { + STRV_FOREACH(nv, namesv) { + last = *nv; + allow = policy_check_one_recv(p, uid, gid, message_type, *nv, path, interface, member); + if (allow) + break; + } + } + } + + log_full(LOG_AUTH | (!allow ? LOG_WARNING : LOG_DEBUG), + "Receive permission check %s for uid=" UID_FMT " gid=" GID_FMT" message=%s name=%s path=%s interface=%s member=%s: %s", + dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(last), + strna(path), strna(interface), strna(member), allow ? "ALLOW" : "DENY"); + + return allow; +} + +bool policy_check_one_send(Policy *p, + uid_t uid, + gid_t gid, + int message_type, + const char *name, + const char *path, + const char *interface, + const char *member) { + struct policy_check_filter filter = { .class = POLICY_ITEM_SEND, .uid = uid, @@ -921,18 +955,57 @@ bool policy_check_send(Policy *p, .member = member, }; - int verdict; + assert(p); + + return policy_check(p, &filter) == ALLOW; +} + +bool policy_check_send(Policy *p, + uid_t uid, + gid_t gid, + int message_type, + Set *names, + char **namesv, + const char *path, + const char *interface, + const char *member, + bool dbus_to_kernel, + char **out_used_name) { + + char *n, **nv, *last = NULL; + bool allow = false; + Iterator i; assert(p); - verdict = policy_check(p, &filter); + if (set_isempty(names) && strv_isempty(namesv)) { + allow = policy_check_one_send(p, uid, gid, message_type, NULL, path, interface, member); + } else { + SET_FOREACH(n, names, i) { + last = n; + allow = policy_check_one_send(p, uid, gid, message_type, n, path, interface, member); + if (allow) + break; + } + if (!allow) { + STRV_FOREACH(nv, namesv) { + last = *nv; + allow = policy_check_one_send(p, uid, gid, message_type, *nv, path, interface, member); + if (allow) + break; + } + } + } - log_full(LOG_AUTH | (verdict != ALLOW ? LOG_WARNING : LOG_DEBUG), + if (out_used_name) + *out_used_name = last; + + log_full(LOG_AUTH | (!allow ? LOG_WARNING : LOG_DEBUG), "Send permission check %s for uid=" UID_FMT " gid=" GID_FMT" message=%s name=%s path=%s interface=%s member=%s: %s", - dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(name), - strna(path), strna(interface), strna(member), strna(verdict_to_string(verdict))); + dbus_to_kernel ? "dbus-1 to kernel" : "kernel to dbus-1", uid, gid, bus_message_type_to_string(message_type), strna(last), + strna(path), strna(interface), strna(member), allow ? "ALLOW" : "DENY"); - return verdict == ALLOW; + return allow; } int policy_load(Policy *p, char **files) { @@ -1056,7 +1129,7 @@ static void dump_items(PolicyItem *items, const char *prefix) { user = uid_to_name(i->uid); - printf("%sUser: %s (%d)\n", + printf("%sUser: %s ("UID_FMT")\n", prefix, strna(user), i->uid); } @@ -1065,7 +1138,7 @@ static void dump_items(PolicyItem *items, const char *prefix) { group = gid_to_name(i->gid); - printf("%sGroup: %s (%d)\n", + printf("%sGroup: %s ("GID_FMT")\n", prefix, strna(group), i->gid); } printf("%s-\n", prefix); @@ -1145,6 +1218,7 @@ SharedPolicy *shared_policy_free(SharedPolicy *sp) { policy_free(sp->policy); pthread_rwlock_destroy(&sp->rwlock); pthread_mutex_destroy(&sp->lock); + strv_free(sp->configuration); free(sp); return NULL; @@ -1161,6 +1235,7 @@ static int shared_policy_reload_unlocked(SharedPolicy *sp, char **configuration) if (r < 0) return log_error_errno(r, "Failed to load policy: %m"); + log_debug("Reloading configuration"); /* policy_dump(&buffer); */ pthread_rwlock_wrlock(&sp->rwlock); @@ -1176,28 +1251,36 @@ static int shared_policy_reload_unlocked(SharedPolicy *sp, char **configuration) return 0; } -int shared_policy_reload(SharedPolicy *sp, char **configuration) { +int shared_policy_reload(SharedPolicy *sp) { int r; assert(sp); pthread_mutex_lock(&sp->lock); - r = shared_policy_reload_unlocked(sp, configuration); + r = shared_policy_reload_unlocked(sp, sp->configuration); pthread_mutex_unlock(&sp->lock); return r; } int shared_policy_preload(SharedPolicy *sp, char **configuration) { - int r; + _cleanup_strv_free_ char **conf = NULL; + int r = 0; assert(sp); + conf = strv_copy(configuration); + if (!conf) + return log_oom(); + pthread_mutex_lock(&sp->lock); - if (!sp->policy) - r = shared_policy_reload_unlocked(sp, configuration); - else - r = 0; + if (!sp->policy) { + r = shared_policy_reload_unlocked(sp, conf); + if (r >= 0) { + sp->configuration = conf; + conf = NULL; + } + } pthread_mutex_unlock(&sp->lock); return r;