99cbc7
From c7d644f205a64175961218c82f764cdd10766bff Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <c7d644f205a64175961218c82f764cdd10766bff@dist-git>
99cbc7
From: John Ferlan <jferlan@redhat.com>
99cbc7
Date: Wed, 3 Apr 2019 07:22:20 -0400
99cbc7
Subject: [PATCH] access: Modify the VIR_ERR_ACCESS_DENIED to include
99cbc7
 driverName
99cbc7
99cbc7
https://bugzilla.redhat.com/show_bug.cgi?id=1631606
99cbc7
99cbc7
Changes made to manage and utilize a secondary connection
99cbc7
driver to APIs outside the scope of the primary connection
99cbc7
driver have resulted in some confusion processing polkit rules
99cbc7
since the simple "access denied" error message doesn't provide
99cbc7
enough of a clue when combined with the "authentication failed:
99cbc7
access denied by policy" as to which connection driver refused
99cbc7
or failed the ACL check.
99cbc7
99cbc7
In order to provide some context, let's modify the existing
99cbc7
"access denied" error returned from the various vir*EnsureACL
99cbc7
API's to provide the connection driver name that is causing
99cbc7
the failure. This should provide the context for writing the
99cbc7
polkit rules that would allow access via the driver, but yet
99cbc7
still adhere to the virAccessManagerSanitizeError commentary
99cbc7
regarding not telling the user why access was denied.
99cbc7
99cbc7
Signed-off-by: John Ferlan <jferlan@redhat.com>
99cbc7
(cherry picked from commit 605496be609e153526fcdd3e98df8cf5244bc8fa)
99cbc7
Message-Id: <20190403112220.23881-1-jferlan@redhat.com>
99cbc7
Reviewed-by: Erik Skultety <eskultet@redhat.com>
99cbc7
---
99cbc7
 src/access/viraccessmanager.c | 26 ++++++++++++++------------
99cbc7
 src/rpc/gendispatch.pl        |  3 ++-
99cbc7
 2 files changed, 16 insertions(+), 13 deletions(-)
99cbc7
99cbc7
diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c
99cbc7
index e7b5bf38da..f5d62604cf 100644
99cbc7
--- a/src/access/viraccessmanager.c
99cbc7
+++ b/src/access/viraccessmanager.c
99cbc7
@@ -196,11 +196,13 @@ static void virAccessManagerDispose(void *object)
99cbc7
  * should the admin need to debug things
99cbc7
  */
99cbc7
 static int
99cbc7
-virAccessManagerSanitizeError(int ret)
99cbc7
+virAccessManagerSanitizeError(int ret,
99cbc7
+                              const char *driverName)
99cbc7
 {
99cbc7
     if (ret < 0) {
99cbc7
         virResetLastError();
99cbc7
-        virAccessError(VIR_ERR_ACCESS_DENIED, NULL);
99cbc7
+        virAccessError(VIR_ERR_ACCESS_DENIED,
99cbc7
+                       _("'%s' denied access"), driverName);
99cbc7
     }
99cbc7
 
99cbc7
     return ret;
99cbc7
@@ -217,7 +219,7 @@ int virAccessManagerCheckConnect(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkConnect)
99cbc7
         ret = manager->drv->checkConnect(manager, driverName, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 
99cbc7
@@ -233,7 +235,7 @@ int virAccessManagerCheckDomain(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkDomain)
99cbc7
         ret = manager->drv->checkDomain(manager, driverName, domain, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckInterface(virAccessManagerPtr manager,
99cbc7
@@ -248,7 +250,7 @@ int virAccessManagerCheckInterface(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkInterface)
99cbc7
         ret = manager->drv->checkInterface(manager, driverName, iface, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckNetwork(virAccessManagerPtr manager,
99cbc7
@@ -263,7 +265,7 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkNetwork)
99cbc7
         ret = manager->drv->checkNetwork(manager, driverName, network, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager,
99cbc7
@@ -278,7 +280,7 @@ int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkNodeDevice)
99cbc7
         ret = manager->drv->checkNodeDevice(manager, driverName, nodedev, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckNWFilter(virAccessManagerPtr manager,
99cbc7
@@ -293,7 +295,7 @@ int virAccessManagerCheckNWFilter(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkNWFilter)
99cbc7
         ret = manager->drv->checkNWFilter(manager, driverName, nwfilter, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager,
99cbc7
@@ -308,7 +310,7 @@ int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkNWFilterBinding)
99cbc7
         ret = manager->drv->checkNWFilterBinding(manager, driverName, binding, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckSecret(virAccessManagerPtr manager,
99cbc7
@@ -323,7 +325,7 @@ int virAccessManagerCheckSecret(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkSecret)
99cbc7
         ret = manager->drv->checkSecret(manager, driverName, secret, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckStoragePool(virAccessManagerPtr manager,
99cbc7
@@ -338,7 +340,7 @@ int virAccessManagerCheckStoragePool(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkStoragePool)
99cbc7
         ret = manager->drv->checkStoragePool(manager, driverName, pool, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
 
99cbc7
 int virAccessManagerCheckStorageVol(virAccessManagerPtr manager,
99cbc7
@@ -354,5 +356,5 @@ int virAccessManagerCheckStorageVol(virAccessManagerPtr manager,
99cbc7
     if (manager->drv->checkStorageVol)
99cbc7
         ret = manager->drv->checkStorageVol(manager, driverName, pool, vol, perm);
99cbc7
 
99cbc7
-    return virAccessManagerSanitizeError(ret);
99cbc7
+    return virAccessManagerSanitizeError(ret, driverName);
99cbc7
 }
99cbc7
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
99cbc7
index 0c4648c0fb..a8b9f5aeca 100755
99cbc7
--- a/src/rpc/gendispatch.pl
99cbc7
+++ b/src/rpc/gendispatch.pl
99cbc7
@@ -2199,7 +2199,8 @@ elsif ($mode eq "client") {
99cbc7
                     print "        virObjectUnref(mgr);\n";
99cbc7
                     if ($action eq "Ensure") {
99cbc7
                         print "        if (rv == 0)\n";
99cbc7
-                        print "            virReportError(VIR_ERR_ACCESS_DENIED, NULL);\n";
99cbc7
+                        print "            virReportError(VIR_ERR_ACCESS_DENIED,\n";
99cbc7
+                        print"                            _(\"'%s' denied access\"), conn->driver->name);\n";
99cbc7
                         print "        return $fail;\n";
99cbc7
                     } else {
99cbc7
                         print "        virResetLastError();\n";
99cbc7
-- 
99cbc7
2.21.0
99cbc7