[libvirt] [PATCH v2] Add new error code VIR_ERROR_AUTH_CANCELLED

Cole Robinson crobinso at redhat.com
Fri Jan 27 20:44:42 UTC 2012


And hook it up for policykit auth. This allows virt-manager to detect
that the user clicked the policykit 'cancel' button and not throw
an 'authentication failed' error message at the user.

v2:
    Don't leak pkout

Signed-off-by: Cole Robinson <crobinso at redhat.com>
---
 daemon/remote.c             |   14 ++++++++++++--
 include/libvirt/virterror.h |    1 +
 src/util/virterror.c        |    6 ++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 1ada146..cedc26a 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -2471,6 +2471,8 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
     const char *action;
     int status = -1;
     char *ident = NULL;
+    int authdismissed = 0;
+    char *pkout = NULL;
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virCommandPtr cmd = NULL;
@@ -2481,6 +2483,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
         "org.libvirt.unix.manage";
 
     cmd = virCommandNewArgList(PKCHECK_PATH, "--action-id", action, NULL);
+    virCommandSetOutputBuffer(cmd, &pkout);
 
     VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
     if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
@@ -2509,6 +2512,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
     if (virCommandRun(cmd, &status) < 0)
         goto authfail;
 
+    authdismissed = (pkout && strstr(pkout, "dismissed=true"));
     if (status != 0) {
         char *tmp = virCommandTranslateStatus(status);
         VIR_ERROR(_("Policy kit denied action %s from pid %lld, uid %d: %s"),
@@ -2533,9 +2537,15 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
 error:
     virCommandFree(cmd);
     VIR_FREE(ident);
+    VIR_FREE(pkout);
     virResetLastError();
-    virNetError(VIR_ERR_AUTH_FAILED, "%s",
-                _("authentication failed"));
+    if (authdismissed) {
+        virNetError(VIR_ERR_AUTH_CANCELLED, "%s",
+                    _("authentication cancelled by user"));
+    } else {
+        virNetError(VIR_ERR_AUTH_FAILED, "%s",
+                    _("authentication failed"));
+    }
     virNetMessageSaveError(rerr);
     virMutexUnlock(&priv->lock);
     return -1;
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index e896d67..9844cbe 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -243,6 +243,7 @@ typedef enum {
                                            risky domain snapshot revert */
     VIR_ERR_OPERATION_ABORTED = 78,     /* operation on a domain was
                                            canceled/aborted by user */
+    VIR_ERR_AUTH_CANCELLED = 79,        /* authentication cancelled */
 } virErrorNumber;
 
 /**
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 85eec8d..31ddd9d 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1022,6 +1022,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("authentication failed: %s");
             break;
+        case VIR_ERR_AUTH_CANCELLED:
+            if (info == NULL)
+                errmsg = _("authentication cancelled");
+            else
+                errmsg = _("authentication cancelled: %s");
+            break;
         case VIR_ERR_NO_STORAGE_POOL:
             if (info == NULL)
                 errmsg = _("Storage pool not found");
-- 
1.7.7.5




More information about the libvir-list mailing list