]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: Add virPolkitAgentAvailable
authorMartin Kletzander <mkletzan@redhat.com>
Tue, 16 Nov 2021 13:37:52 +0000 (14:37 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Tue, 23 Nov 2021 11:51:09 +0000 (12:51 +0100)
With this function we can decide whether to try running the polkit text agent
only if it is available, removing a potential needless error saying that the
agent binary does not exist, which is useful especially when running the agent
before knowing whether it is going to be needed.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/util/virpolkit.c
src/util/virpolkit.h

index a7bc50a4d16df4b6c43a4e9c1599051941133f17..c11be4eafa195c9d19281c8a44b156cb336facf6 100644 (file)
@@ -3078,6 +3078,7 @@ virPidFileWritePath;
 
 
 # util/virpolkit.h
+virPolkitAgentAvailable;
 virPolkitAgentCreate;
 virPolkitAgentDestroy;
 virPolkitCheckAuth;
index 86255a96760ffb73aacd9864b769f2aa3b726f7a..ebe131dc51df7ac5eba6a07c0b19ade2b15244eb 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include <fcntl.h>
 #include <unistd.h>
 
 #include "virpolkit.h"
@@ -217,6 +218,42 @@ virPolkitAgentCreate(void)
 }
 
 
+/*
+ * virPolkitAgentAvailable
+ *
+ * This function does some preliminary checking that the pkttyagent does not
+ * fail starting so that it can be started without waiting for first failed
+ * connection with VIR_ERR_AUTH_UNAVAILABLE.
+ */
+bool
+virPolkitAgentAvailable(void)
+{
+    const char *termid = ctermid(NULL);
+    VIR_AUTOCLOSE fd = -1;
+
+    if (!virFileIsExecutable(PKTTYAGENT))
+        return false;
+
+    if (!termid)
+        return false;
+
+    /*
+     *The pkttyagent needs to open the controlling terminal.
+     *
+     * Just in case we are running without a ctty make sure this open() does not
+     * change that.
+     *
+     * We could check if our session has a controlling terminal available
+     * instead, but it would require parsing `/proc/self/stat` on Linux, which
+     * is not portable and moreover requires way more work than just open().
+     */
+    fd = open(termid, O_RDWR | O_NOCTTY);
+    if (fd < 0)
+        return false;
+
+    return true;
+}
+
 #else /* ! WITH_POLKIT */
 
 int virPolkitCheckAuth(const char *actionid G_GNUC_UNUSED,
@@ -247,4 +284,11 @@ virPolkitAgentCreate(void)
                    _("polkit text authentication agent unavailable"));
     return NULL;
 }
+
+bool
+virPolkitAgentAvailable(void)
+{
+    return false;
+}
+
 #endif /* WITH_POLKIT */
index a577d59452bae283a7fa00b482eaae620cc65fc0..7bcd040e5e06cf60275e9b5f4bae0e5431eca13e 100644 (file)
@@ -37,3 +37,4 @@ typedef struct _virPolkitAgent virPolkitAgent;
 
 void virPolkitAgentDestroy(virPolkitAgent *cmd);
 virPolkitAgent *virPolkitAgentCreate(void);
+bool virPolkitAgentAvailable(void);