]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: add varlink_invocation() call
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Sep 2023 14:00:00 +0000 (16:00 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 6 Oct 2023 09:49:38 +0000 (11:49 +0200)
This call checks if we are invoked in a socket-activation Varlink server
context. It's useful for commands that can be run from the command line
or as Varlink service and then either serve commands from the cmdline or
those from Varlink.

src/shared/varlink.c
src/shared/varlink.h

index e97127838a2116945d6d49c9983eec8675743b02..f061024785c50c37a46c1bbb002a222172b0c2e9 100644 (file)
@@ -3540,3 +3540,38 @@ int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *f
         LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss));
         return 0;
 }
+
+int varlink_invocation(VarlinkInvocationFlags flags) {
+        _cleanup_strv_free_ char **names = NULL;
+        int r, b;
+        socklen_t l = sizeof(b);
+
+        /* Returns true if this is a "pure" varlink server invocation, i.e. with one fd passed. */
+
+        r = sd_listen_fds_with_names(/* unset_environment= */ false, &names);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return false;
+        if (r > 1)
+                return -ETOOMANYREFS;
+
+        if (!strv_equal(names, STRV_MAKE("varlink")))
+                return false;
+
+        if (FLAGS_SET(flags, VARLINK_ALLOW_LISTEN|VARLINK_ALLOW_ACCEPT)) /* Both flags set? Then allow everything */
+                return true;
+
+        if ((flags & (VARLINK_ALLOW_LISTEN|VARLINK_ALLOW_ACCEPT)) == 0) /* Neither is set, then fail */
+                return -EISCONN;
+
+        if (getsockopt(SD_LISTEN_FDS_START, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
+                return -errno;
+
+        assert(l == sizeof(b));
+
+        if (!FLAGS_SET(flags, b ? VARLINK_ALLOW_LISTEN : VARLINK_ALLOW_ACCEPT))
+                return -EISCONN;
+
+        return true;
+}
index cfb7f7ed8be4c1c505effe4ca8a25cf9dee02e70..5fe529c8532786213c0ffa62e7f705dce9b1401c 100644 (file)
@@ -46,7 +46,6 @@ typedef enum VarlinkServerFlags {
         VARLINK_SERVER_MYSELF_ONLY      = 1 << 1, /* Only accessible by our own UID */
         VARLINK_SERVER_ACCOUNT_UID      = 1 << 2, /* Do per user accounting */
         VARLINK_SERVER_INHERIT_USERDATA = 1 << 3, /* Initialize Varlink connection userdata from VarlinkServer userdata */
-
         _VARLINK_SERVER_FLAGS_ALL = (1 << 4) - 1,
 } VarlinkServerFlags;
 
@@ -185,6 +184,15 @@ unsigned varlink_server_current_connections(VarlinkServer *s);
 
 int varlink_server_set_description(VarlinkServer *s, const char *description);
 
+typedef enum VarlinkInvocationFlags {
+        VARLINK_ALLOW_LISTEN                     = 1 << 0,
+        VARLINK_ALLOW_ACCEPT                     = 1 << 1,
+        _VARLINK_SERVER_INVOCATION_FLAGS_MAX     = (1 << 2) - 1,
+        _VARLINK_SERVER_INVOCATION_FLAGS_INVALID = -EINVAL,
+} VarlinkInvocationFlags;
+
+int varlink_invocation(VarlinkInvocationFlags flags);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_close_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_flush_close_unref);