chiark / gitweb /
core: rearrange code so that libsystemd/sd-bus/ does not include header files from...
[elogind.git] / src / bus-proxyd / bus-proxyd.c
index 42fb0da0ef56ec2319139921a941dfd97fc440d0..64c11ffd169760d21866f3c76ba25f679232a460 100644 (file)
 #include "strv.h"
 #include "def.h"
 #include "capability.h"
-#include "bus-policy.h"
 #include "bus-control.h"
+#include "smack-util.h"
+#include "set.h"
+#include "bus-xml-policy.h"
 
 static char *arg_address = NULL;
 static char *arg_command_line_buffer = NULL;
@@ -959,6 +961,13 @@ static int process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m, Policy *polic
         }
 }
 
+static int handle_policy_error(sd_bus_message *m, int r) {
+        if (r == -ESRCH || r == -ENXIO)
+                return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", m->destination);
+
+        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) {
         int r;
 
@@ -980,9 +989,7 @@ static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *p
                         return 0;
 
                 /* The message came from the kernel, and is sent to our legacy client. */
-                r = sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
-                if (r < 0)
-                        return r;
+                sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
 
                 (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
                 (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
@@ -1044,15 +1051,13 @@ static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *p
                                                      SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID,
                                                      true, &destination_creds);
                         if (r < 0)
-                                return r;
-
-                        r = sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
-                        if (r < 0)
-                                return r;
+                                return handle_policy_error(m, r);
 
                         r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
                         if (r < 0)
-                                return r;
+                                return handle_policy_error(m, r);
+
+                        sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
 
                         (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
                         (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
@@ -1235,6 +1240,23 @@ static int patch_sender(sd_bus *a, sd_bus_message *m) {
         return 0;
 }
 
+static int mac_smack_apply_label_and_drop_cap_mac_admin(pid_t its_pid, const char *new_label) {
+#ifdef HAVE_SMACK
+        int r = 0, k;
+
+        if (!mac_smack_use())
+                return 0;
+
+        if (new_label && its_pid > 0)
+                r = mac_smack_apply_pid(its_pid, new_label);
+
+        k = drop_capability(CAP_MAC_ADMIN);
+        return r < 0 ? r : k;
+#else
+        return 0;
+#endif
+}
+
 int main(int argc, char *argv[]) {
 
         _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
@@ -1274,6 +1296,10 @@ int main(int argc, char *argv[]) {
         if (is_unix) {
                 (void) getpeercred(in_fd, &ucred);
                 (void) getpeersec(in_fd, &peersec);
+
+                r = mac_smack_apply_label_and_drop_cap_mac_admin(getpid(), peersec);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to set SMACK label (%s) and drop CAP_MAC_ADMIN: %m", peersec);
         }
 
         if (arg_drop_privileges) {