chiark / gitweb /
fsckd: the error code is actually returned in 'fd'
[elogind.git] / src / bus-proxyd / bus-xml-policy.c
index b3daad50177beb0820ace73f3e53502994f174f8..497bce7b5699805d1b87968cb9a8c88040d1fb89 100644 (file)
@@ -22,9 +22,9 @@
 #include "xml.h"
 #include "fileio.h"
 #include "strv.h"
+#include "set.h"
 #include "conf-files.h"
 #include "bus-internal.h"
-#include "bus-message.h"
 #include "bus-xml-policy.h"
 #include "sd-login.h"
 
@@ -865,15 +865,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 +885,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 +954,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 +1128,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 +1137,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 +1217,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 +1234,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 +1250,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;