Introduce virPolkitAgentCreate, virPolkitAgentCheck, and virPolkitAgentDestroy
virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous
command in order to handle the local agent authentication via stdin/stdout.
virPolkitAgentCheck will run the polkit pkcheck command against the async
command process in order to perform the authentication
virPolkitAgentDestroy will close the command effectively reaping our
child process
Needed to move around or add the "#include vircommand.h" since,
virpolkit.h now uses it.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/libvirt_private.syms | 3 ++
src/util/virpolkit.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++-
src/util/virpolkit.h | 7 ++++
tests/virpolkittest.c | 3 +-
4 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5ae3618..e4d791d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2028,6 +2028,9 @@ virPidFileWritePath;
# util/virpolkit.h
+virPolkitAgentCheck;
+virPolkitAgentCreate;
+virPolkitAgentDestroy;
virPolkitCheckAuth;
diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c
index 56b1c31..e7c8603 100644
--- a/src/util/virpolkit.c
+++ b/src/util/virpolkit.c
@@ -26,8 +26,8 @@
# include <polkit-dbus/polkit-dbus.h>
#endif
-#include "virpolkit.h"
#include "vircommand.h"
+#include "virpolkit.h"
#include "virerror.h"
#include "virlog.h"
#include "virstring.h"
@@ -136,6 +136,77 @@ int virPolkitCheckAuth(const char *actionid,
}
+/* virPolkitAgentDestroy:
+ * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate
+ *
+ * Destroy resources used by Polkit Agent
+ */
+void
+virPolkitAgentDestroy(virCommandPtr cmd)
+{
+ virCommandFree(cmd);
+}
+
+/* virPolkitAgentCreate:
+ *
+ * Allocate and setup a polkit agent
+ *
+ * Returns a virCommandPtr on success and NULL on failure
+ */
+virCommandPtr
+virPolkitAgentCreate(void)
+{
+ virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL);
+ int outfd = STDOUT_FILENO;
+ int errfd = STDERR_FILENO;
+
+ virCommandAddArgFormat(cmd, "%lld", (long long int) getpid());
+ virCommandAddArg(cmd, "--fallback");
+ virCommandSetInputFD(cmd, STDIN_FILENO);
+ virCommandSetOutputFD(cmd, &outfd);
+ virCommandSetErrorFD(cmd, &errfd);
+ if (virCommandRunAsync(cmd, NULL) < 0)
+ goto error;
+ /* Give it a chance to get started */
+ sleep(1);
+
+ return cmd;
+
+ error:
+ virCommandFree(cmd);
+ return NULL;
+}
+
+
+/* virPolkitAgentCheck:
+ *
+ * Execute the pkcheck program against the running Polkit Agent
+ *
+ * returns 0 on success and -1 on failure.
+ */
+int
+virPolkitAgentCheck(void)
+{
+ int ret = -1;
+ virCommandPtr cmd = virCommandNewArgList(PKCHECK,
+ "--action-id",
+ "org.libvirt.unix.manage",
+ "--process",
+ NULL);
+
+ virCommandAddArgFormat(cmd, "%lld,0,%u",
+ (long long int) getpid(), (unsigned int) getuid());
+ virCommandAddArg(cmd, "--allow-user-interaction");
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ virCommandFree(cmd);
+ return ret;
+}
+
+
#elif WITH_POLKIT0
int virPolkitCheckAuth(const char *actionid,
pid_t pid,
@@ -254,4 +325,27 @@ 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;
+}
+
+
+int
+virPolkitAgentCheck(void)
+{
+ virReportError(VIR_ERR_AUTH_FAILED, "%s",
+ _("polkit text authentication agent unavailable"));
+ return -1;
+}
#endif /* WITH_POLKIT1 */
diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h
index 36122d0..fcfc855 100644
--- a/src/util/virpolkit.h
+++ b/src/util/virpolkit.h
@@ -24,6 +24,9 @@
# include "internal.h"
+# define PKTTYAGENT "/usr/bin/pkttyagent"
+# define PKCHECK "/usr/bin/pkcheck"
+
int virPolkitCheckAuth(const char *actionid,
pid_t pid,
unsigned long long startTime,
@@ -31,4 +34,8 @@ int virPolkitCheckAuth(const char *actionid,
const char **details,
bool allowInteraction);
+void virPolkitAgentDestroy(virCommandPtr cmd);
+virCommandPtr virPolkitAgentCreate(void);
+int virPolkitAgentCheck(void);
+
#endif /* __VIR_POLKIT_H__ */
diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c
index cdf78f5..b5bebf9 100644
--- a/tests/virpolkittest.c
+++ b/tests/virpolkittest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Red Hat, Inc.
+ * Copyright (C) 2013, 2014, 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
# include <stdlib.h>
# include <dbus/dbus.h>
+# include "vircommand.h"
# include "virpolkit.h"
# include "virdbus.h"
# include "virlog.h"
--
2.5.0