]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce API's for Polkit text authentication
authorJohn Ferlan <jferlan@redhat.com>
Tue, 9 Feb 2016 15:09:44 +0000 (10:09 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 1 Mar 2016 11:50:16 +0000 (06:50 -0500)
Introduce virPolkitAgentCreate and virPolkitAgentDestroy

virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous
command in order to handle the local agent authentication via stdin/stdout.
The code makes use of the pkttyagent --notify-fd mechanism to let it know
when the agent is successfully registered.

virPolkitAgentDestroy will close the command effectively reaping our
child process

src/libvirt_private.syms
src/util/virpolkit.c
src/util/virpolkit.h

index 4b406121988112b09d1c12d706167a52fb9dc79e..4c53bf42a0bfca2db6053e5a51460a6bf54154bf 100644 (file)
@@ -2032,6 +2032,8 @@ virPidFileWritePath;
 
 
 # util/virpolkit.h
+virPolkitAgentCreate;
+virPolkitAgentDestroy;
 virPolkitCheckAuth;
 
 
index df707f1a2d9ede6955e3455edf17db6ebf73e5b7..3bb60a5aa3662032cdd63f100f23a02d0d10eec5 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include <poll.h>
 
 #if WITH_POLKIT0
 # include <polkit/polkit.h>
 #endif
 
 #include "virpolkit.h"
-#include "vircommand.h"
 #include "virerror.h"
 #include "virlog.h"
 #include "virstring.h"
 #include "virprocess.h"
 #include "viralloc.h"
 #include "virdbus.h"
+#include "virfile.h"
 
 #define VIR_FROM_THIS VIR_FROM_POLKIT
 
 VIR_LOG_INIT("util.polkit");
 
 #if WITH_POLKIT1
+
+struct _virPolkitAgent {
+    virCommandPtr cmd;
+};
+
 /*
  * virPolkitCheckAuth:
  * @actionid: permission to check
@@ -136,6 +142,74 @@ int virPolkitCheckAuth(const char *actionid,
 }
 
 
+/* virPolkitAgentDestroy:
+ * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate
+ *
+ * Destroy resources used by Polkit Agent
+ */
+void
+virPolkitAgentDestroy(virPolkitAgentPtr agent)
+{
+    if (!agent)
+        return;
+
+    virCommandFree(agent->cmd);
+    VIR_FREE(agent);
+}
+
+/* virPolkitAgentCreate:
+ *
+ * Allocate and setup a polkit agent
+ *
+ * Returns a virCommandPtr on success and NULL on failure
+ */
+virPolkitAgentPtr
+virPolkitAgentCreate(void)
+{
+    virPolkitAgentPtr agent;
+    virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL);
+    int pipe_fd[2] = {-1, -1};
+    struct pollfd pollfd;
+    int outfd = STDOUT_FILENO;
+    int errfd = STDERR_FILENO;
+
+    if (!isatty(STDIN_FILENO))
+        goto error;
+
+    if (pipe2(pipe_fd, 0) < 0)
+        goto error;
+
+    if (VIR_ALLOC(agent) < 0)
+        goto error;
+    agent->cmd = cmd;
+
+    virCommandAddArgFormat(cmd, "%lld", (long long int) getpid());
+    virCommandAddArg(cmd, "--notify-fd");
+    virCommandAddArgFormat(cmd, "%d", pipe_fd[1]);
+    virCommandAddArg(cmd, "--fallback");
+    virCommandSetInputFD(cmd, STDIN_FILENO);
+    virCommandSetOutputFD(cmd, &outfd);
+    virCommandSetErrorFD(cmd, &errfd);
+    virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+    if (virCommandRunAsync(cmd, NULL) < 0)
+        goto error;
+
+    pollfd.fd = pipe_fd[0];
+    pollfd.events = POLLHUP;
+
+    if (poll(&pollfd, 1, -1) < 0)
+        goto error;
+
+    return agent;
+
+ error:
+    VIR_FORCE_CLOSE(pipe_fd[0]);
+    VIR_FORCE_CLOSE(pipe_fd[1]);
+    virPolkitAgentDestroy(agent);
+    return NULL;
+}
+
+
 #elif WITH_POLKIT0
 int virPolkitCheckAuth(const char *actionid,
                        pid_t pid,
@@ -254,4 +328,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED,
 }
 
 
+void
+virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED)
+{
+    return; /* do nothing */
+}
+
+
+virCommandPtr
+virPolkitAgentCreate(void)
+{
+    virReportError(VIR_ERR_AUTH_FAILED, "%s",
+                   _("polkit text authentication agent unavailable"));
+    return NULL;
+}
 #endif /* WITH_POLKIT1 */
index 36122d04ed1b34b9d7ea27424f58330e4d4f343a..14ff0730d346762ce1e931530cf6f9dd66a4bb58 100644 (file)
@@ -23,6 +23,9 @@
 # define __VIR_POLKIT_H__
 
 # include "internal.h"
+# include "vircommand.h"
+
+# define PKTTYAGENT "/usr/bin/pkttyagent"
 
 int virPolkitCheckAuth(const char *actionid,
                        pid_t pid,
@@ -31,4 +34,10 @@ int virPolkitCheckAuth(const char *actionid,
                        const char **details,
                        bool allowInteraction);
 
+typedef struct _virPolkitAgent virPolkitAgent;
+typedef virPolkitAgent *virPolkitAgentPtr;
+
+void virPolkitAgentDestroy(virPolkitAgentPtr cmd);
+virPolkitAgentPtr virPolkitAgentCreate(void);
+
 #endif /* __VIR_POLKIT_H__ */