chiark / gitweb /
bus: fake client side creds in the proxy to the caller's creds
[elogind.git] / src / libsystemd-bus / bus-introspect.c
index c04d9b51f774cf71908bcf6355329993757a8e86..d528ab2a04b1fe826dc71a15c7b2d15578a19c4b 100644 (file)
 #include "bus-introspect.h"
 #include "bus-signature.h"
 #include "bus-internal.h"
+#include "bus-protocol.h"
 
-int introspect_begin(struct introspect *i) {
+int introspect_begin(struct introspect *i, bool trusted) {
         assert(i);
 
         zero(*i);
+        i->trusted = trusted;
 
         i->f = open_memstream(&i->introspection, &i->size);
         if (!i->f)
                 return -ENOMEM;
 
-        fputs(SD_BUS_INTROSPECT_DOCTYPE
+        fputs(BUS_INTROSPECT_DOCTYPE
               "<node>\n", i->f);
 
         return 0;
@@ -43,12 +45,12 @@ int introspect_begin(struct introspect *i) {
 int introspect_write_default_interfaces(struct introspect *i, bool object_manager) {
         assert(i);
 
-        fputs(SD_BUS_INTROSPECT_INTERFACE_PEER
-              SD_BUS_INTROSPECT_INTERFACE_INTROSPECTABLE
-              SD_BUS_INTROSPECT_INTERFACE_PROPERTIES, i->f);
+        fputs(BUS_INTROSPECT_INTERFACE_PEER
+              BUS_INTROSPECT_INTERFACE_INTROSPECTABLE
+              BUS_INTROSPECT_INTERFACE_PROPERTIES, i->f);
 
         if (object_manager)
-                fputs(SD_BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->f);
+                fputs(BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER, i->f);
 
         return 0;
 }
@@ -63,7 +65,7 @@ int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefi
                 const char *e;
 
                 e = object_path_startswith(node, prefix);
-                if (e)
+                if (e && e[0])
                         fprintf(i->f, " <node name=\"%s\"/>\n", e);
 
                 free(node);
@@ -76,15 +78,22 @@ static void introspect_write_flags(struct introspect *i, int type, int flags) {
         if (flags & SD_BUS_VTABLE_DEPRECATED)
                 fputs("   <annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n", i->f);
 
-        if (type == _SD_BUS_VTABLE_METHOD && flags & SD_BUS_VTABLE_METHOD_NO_REPLY)
+        if (type == _SD_BUS_VTABLE_METHOD && (flags & SD_BUS_VTABLE_METHOD_NO_REPLY))
                 fputs("   <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
 
         if (type == _SD_BUS_VTABLE_PROPERTY || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) {
-                if (!(flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))
-                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\n", i->f);
-                else if (flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)
+                if (flags & SD_BUS_VTABLE_PROPERTY_CONST)
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f);
+                else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)
                         fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"invalidates\"/>\n", i->f);
+                else if (!(flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))
+                        fputs("   <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>\n", i->f);
         }
+
+        if (!i->trusted &&
+            (type == _SD_BUS_VTABLE_METHOD || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) &&
+            !(flags & SD_BUS_VTABLE_UNPRIVILEGED))
+                fputs("   <annotation name=\"org.freedesktop.systemd1.Privileged\" value=\"true\"/>\n", i->f);
 }
 
 static int introspect_write_arguments(struct introspect *i, const char *signature, const char *direction) {
@@ -103,23 +112,27 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur
                 fprintf(i->f, "   <arg type=\"%.*s\"", (int) l, signature);
 
                 if (direction)
-                        fprintf(i->f, " direction=\"%s\">\n", direction);
+                        fprintf(i->f, " direction=\"%s\"/>\n", direction);
                 else
-                        fputs(">\n", i->f);
+                        fputs("/>\n", i->f);
 
                 signature += l;
         }
 }
 
-int introspect_write_interface(struct introspect *i, const char *interface, const sd_bus_vtable *v) {
+int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
         assert(i);
-        assert(interface);
         assert(v);
 
-        fprintf(i->f, " <interface name=\"%s\">\n", interface);
-
         for (; v->type != _SD_BUS_VTABLE_END; v++) {
 
+                /* Ignore methods, signals and properties that are
+                 * marked "hidden", but do show the interface
+                 * itself */
+
+                if (v->type != _SD_BUS_VTABLE_START && (v->flags & SD_BUS_VTABLE_HIDDEN))
+                        continue;
+
                 switch (v->type) {
 
                 case _SD_BUS_VTABLE_START:
@@ -129,8 +142,8 @@ int introspect_write_interface(struct introspect *i, const char *interface, cons
 
                 case _SD_BUS_VTABLE_METHOD:
                         fprintf(i->f, "  <method name=\"%s\">\n", v->x.method.member);
-                        introspect_write_arguments(i, v->x.method.signature, "in");
-                        introspect_write_arguments(i, v->x.method.result, "out");
+                        introspect_write_arguments(i, strempty(v->x.method.signature), "in");
+                        introspect_write_arguments(i, strempty(v->x.method.result), "out");
                         introspect_write_flags(i, v->type, v->flags);
                         fputs("  </method>\n", i->f);
                         break;
@@ -147,7 +160,7 @@ int introspect_write_interface(struct introspect *i, const char *interface, cons
 
                 case _SD_BUS_VTABLE_SIGNAL:
                         fprintf(i->f, "  <signal name=\"%s\">\n", v->x.signal.member);
-                        introspect_write_arguments(i, v->x.signal.signature, NULL);
+                        introspect_write_arguments(i, strempty(v->x.signal.signature), NULL);
                         introspect_write_flags(i, v->type, v->flags);
                         fputs("  </signal>\n", i->f);
                         break;
@@ -155,7 +168,6 @@ int introspect_write_interface(struct introspect *i, const char *interface, cons
 
         }
 
-        fputs(" </interface>\n", i->f);
         return 0;
 }
 
@@ -173,7 +185,7 @@ int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_b
         if (ferror(i->f))
                 return -ENOMEM;
 
-        r = sd_bus_message_new_method_return(bus, m, &q);
+        r = sd_bus_message_new_method_return(m, &q);
         if (r < 0)
                 return r;