]> xenbits.xensource.com Git - libvirt.git/commitdiff
src: set identity when opening secondary drivers
authorDaniel P. Berrangé <berrange@redhat.com>
Thu, 19 Nov 2020 15:21:15 +0000 (15:21 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 13 May 2021 10:07:41 +0000 (11:07 +0100)
The drivers can all call virGetConnectXXX to open a connection to a
secondary driver. For example, when creating a encrypted storage volume,
the storage driver has to open a secret driver connection, or when
starting a guest, the QEMU driver has to open the network driver to
lookup a virtual network.

When using monolithic libvirtd, the connection has the same effective
identity as the client, since everything is still in the same process.
When using the modular daemons, however, the remote daemon sees the
identity of the calling daemon. This is a mistake as it results in
the modular daemons seeing the client with elevated privileges.

We need to pass on the current identity explicitly when opening the
secondary drivers. This is the same thing that is done by daemon RPC
dispatcher code when it is directly forwarding top level API calls
from virtproxyd and other daemons.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/driver.c

index f8022d25224ce89b96f91ca920b2972bb8b79009..227bb56e48f7c435d0c36492b21dcc0856d3db77 100644 (file)
@@ -33,6 +33,8 @@
 #include "virstring.h"
 #include "virthread.h"
 #include "virutil.h"
+#include "viridentity.h"
+#include "datatypes.h"
 #include "configmake.h"
 
 VIR_LOG_INIT("driver");
@@ -136,6 +138,7 @@ static virConnectPtr
 virGetConnectGeneric(virThreadLocal *threadPtr, const char *name)
 {
     virConnectPtr conn;
+    virErrorPtr saved;
 
     if (virConnectCacheInitialize() < 0)
         return NULL;
@@ -153,8 +156,32 @@ virGetConnectGeneric(virThreadLocal *threadPtr, const char *name)
 
         conn = virConnectOpen(uri);
         VIR_DEBUG("Opened new %s connection %p", name, conn);
+        if (!conn)
+            return NULL;
+
+        if (conn->driver->connectSetIdentity != NULL) {
+            g_autoptr(virIdentity) ident = NULL;
+            virTypedParameterPtr identparams = NULL;
+            int nidentparams = 0;
+
+            VIR_DEBUG("Attempting to delegate current identity");
+            if (!(ident = virIdentityGetCurrent()))
+                goto error;
+
+            if (virIdentityGetParameters(ident, &identparams, &nidentparams) < 0)
+                goto error;
+
+            if (virConnectSetIdentity(conn, identparams, nidentparams, 0) < 0)
+                goto error;
+        }
     }
     return conn;
+
+ error:
+    saved = virSaveLastError();
+    virConnectClose(conn);
+    virSetError(saved);
+    return NULL;
 }