---
src/guestfs-internal.h | 1 +
src/libvirt-auth.c | 55 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 5356920..d81fa6b 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -469,6 +469,7 @@ struct guestfs_h
unsigned int nr_supported_credentials;
int supported_credentials[NR_CREDENTIAL_TYPES];
const char *saved_libvirt_uri; /* Doesn't need to be freed. */
+ bool wrapper_warning_done;
unsigned int nr_requested_credentials;
virConnectCredentialPtr requested_credentials;
#endif
diff --git a/src/libvirt-auth.c b/src/libvirt-auth.c
index fb18f8a..f8ed1b1 100644
--- a/src/libvirt-auth.c
+++ b/src/libvirt-auth.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#ifdef HAVE_LIBVIRT
#include <libvirt/libvirt.h>
@@ -147,6 +148,34 @@ libvirt_auth_callback (virConnectCredentialPtr cred,
return 0;
}
+/* Libvirt provides a default authentication handler. However it is
+ * confusing to end-users
+ * (
https://bugzilla.redhat.com/show_bug.cgi?id=1044014#c0).
+ *
+ * Unfortunately #1 the libvirt handler cannot easily be modified to
+ * make it non-confusing, but unfortunately #2 we have to actually
+ * call it because it handles all the policykit crap.
+ *
+ * Therefore we add a wrapper around it here.
+ */
+static int
+libvirt_auth_default_wrapper (virConnectCredentialPtr cred,
+ unsigned int ncred,
+ void *gv)
+{
+ guestfs_h *g = gv;
+
+ if (!g->wrapper_warning_done) {
+ printf (_("libvirt needs authentication to connect to libvirt URI %s\n"
+ "(see also:
http://libvirt.org/auth.html
http://libvirt.org/uri.html)\n"),
+ g->saved_libvirt_uri ? g->saved_libvirt_uri : "NULL");
+ g->wrapper_warning_done = true;
+ }
+
+ return virConnectAuthPtrDefault->cb (cred, ncred,
+ virConnectAuthPtrDefault->cbdata);
+}
+
static int
exists_libvirt_auth_event (guestfs_h *g)
{
@@ -165,31 +194,37 @@ guestfs___open_libvirt_connection (guestfs_h *g, const char *uri,
unsigned int flags)
{
virConnectAuth authdata;
- virConnectAuthPtr authdataptr;
virConnectPtr conn;
+ const char *authtype;
+
+ g->saved_libvirt_uri = uri;
+ g->wrapper_warning_done = false;
/* Did the caller register a GUESTFS_EVENT_LIBVIRT_AUTH event and
* call guestfs_set_libvirt_supported_credentials?
*/
if (g->nr_supported_credentials > 0 && exists_libvirt_auth_event (g)) {
+ authtype = "custom";
memset (&authdata, 0, sizeof authdata);
authdata.credtype = g->supported_credentials;
authdata.ncredtype = g->nr_supported_credentials;
authdata.cb = libvirt_auth_callback;
authdata.cbdata = g;
- authdataptr = &authdata;
- g->saved_libvirt_uri = uri;
}
- else
- authdataptr = virConnectAuthPtrDefault;
+ else {
+ /* Wrapper around libvirt's virConnectAuthPtrDefault, see comment
+ * above.
+ */
+ authtype = "default+wrapper";
+ authdata = *virConnectAuthPtrDefault;
+ authdata.cb = libvirt_auth_default_wrapper;
+ authdata.cbdata = g;
+ }
debug (g, "opening libvirt handle: URI = %s, auth = %s, flags = %u",
- uri ? uri : "NULL",
- authdataptr == virConnectAuthPtrDefault
- ? "virConnectAuthPtrDefault" : "<virConnectAuth *>",
- flags);
+ uri ? uri : "NULL", authtype, flags);
- conn = virConnectOpenAuth (uri, authdataptr, flags);
+ conn = virConnectOpenAuth (uri, &authdata, flags);
if (conn)
debug (g, "successfully opened libvirt handle: conn = %p", conn);
--
1.8.4.2