From a9da4193cf0c11b85d24f088458224be129cd550 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 2 Jan 2014 12:20:18 +0000 Subject: [PATCH] libvirt-auth: Provide a friendlier wrapper around virConnectAuthPtrDefault (RHBZ#1044014). (cherry picked from commit 4125064554c8cb1b96680e24e49d74ee6024f761) --- 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 8888603..a1f3f02 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 #include +#include #ifdef HAVE_LIBVIRT #include @@ -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" : "", - 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