From nobody Sun Feb 8 16:30:59 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1564420461; cv=none; d=zoho.com; s=zohoarc; b=nDfxwYwZwuRsmLQReTTpotsmDNUiGFlvVmdIEF0VyW88dLS5ac2dXfTk4/+Zz76WpXBCPnm5j2/CfVI/kHkj5saJqYXb4Se4K2rE2MKRm6TXT7DtO6AuNKQ4C0M8CB5nByjCwl+1VEFocGupULsO7zwWnR0t3vfUwxHUOYfdhQc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1564420461; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=fVjLf1oyt5D/OUum3wjrnqpGZrmWNQ98iwuyIR6JWvg=; b=JhxD6VqdAe0eMSHCVM7KUDZbVJtu8ySJwF0JXpmYV1DrCs5vSCc2uUHBC993J2FJKU/R+lI94DIBhs99LIA4VHDA3KX6s3mp0Zo7HOBX4ILKbljrwzv+nUEbUa8sQ4epdEV+vc/EMCF3V0DGtBEQWyzchOOL/m7ZTTKj7Ef7D2I= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1564420461378698.9697418627504; Mon, 29 Jul 2019 10:14:21 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D0C6308FC20; Mon, 29 Jul 2019 17:14:20 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DA7645D6B0; Mon, 29 Jul 2019 17:14:19 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9F8D11972E; Mon, 29 Jul 2019 17:14:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x6THEIj9029216 for ; Mon, 29 Jul 2019 13:14:18 -0400 Received: by smtp.corp.redhat.com (Postfix) id 860D25C22B; Mon, 29 Jul 2019 17:14:18 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-51.ams2.redhat.com [10.36.112.51]) by smtp.corp.redhat.com (Postfix) with ESMTP id 24D515C1A1; Mon, 29 Jul 2019 17:13:58 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Mon, 29 Jul 2019 18:11:30 +0100 Message-Id: <20190729171130.25484-49-berrange@redhat.com> In-Reply-To: <20190729171130.25484-1-berrange@redhat.com> References: <20190729171130.25484-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: Andrea Bolognani Subject: [libvirt] [PATCH v3 48/48] remote: pass identity across to newly opened daemons X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Mon, 29 Jul 2019 17:14:20 +0000 (UTC) When opening a connection to a second driver inside the daemon, we must ensure the identity of the current user is passed across. This allows the second daemon to perform access control checks against the real end users, instead of against the libvirt daemon that's proxying across the API calls. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Christophe de Dinechin --- src/libvirt_remote.syms | 1 + src/remote/remote_daemon_dispatch.c | 110 +++++++++++++++++++++++++--- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 18 ++++- src/remote_protocol-structs | 8 ++ src/rpc/virnetserverclient.c | 12 +++ src/rpc/virnetserverclient.h | 2 + 7 files changed, 140 insertions(+), 12 deletions(-) diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index 3307d74324..0493467f46 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -178,6 +178,7 @@ virNetServerClientSetAuthLocked; virNetServerClientSetAuthPendingLocked; virNetServerClientSetCloseHook; virNetServerClientSetDispatcher; +virNetServerClientSetIdentity; virNetServerClientSetQuietEOF; virNetServerClientSetReadonly; virNetServerClientStartKeepAlive; diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index 9ef76daa55..f828b75f3b 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -51,6 +51,7 @@ #include "virpolkit.h" #include "virthreadjob.h" #include "configmake.h" +#include "access/viraccessapicheck.h" =20 #define VIR_FROM_THIS VIR_FROM_RPC =20 @@ -1945,10 +1946,15 @@ static void remoteClientCloseFunc(virNetServerClien= tPtr client) static int remoteOpenConn(const char *uri, bool readonly, + bool preserveIdentity, virConnectPtr *conn) { - VIR_DEBUG("Getting secondary uri=3D%s readonly=3D%d conn=3D%p", - NULLSTR(uri), readonly, conn); + virTypedParameterPtr params =3D NULL; + int nparams =3D 0; + + VIR_DEBUG("Getting secondary uri=3D%s readonly=3D%d preserveIdent=3D%d= conn=3D%p", + NULLSTR(uri), readonly, preserveIdentity, conn); + if (*conn) return 0; =20 @@ -1957,15 +1963,42 @@ remoteOpenConn(const char *uri, return -1; } =20 + if (preserveIdentity) { + VIR_AUTOUNREF(virIdentityPtr) ident =3D NULL; + + if (!(ident =3D virIdentityGetCurrent())) + return -1; + + if (virIdentityGetParameters(ident, ¶ms, &nparams) < 0) + goto error; + } + VIR_DEBUG("Opening driver %s", uri); if (readonly) *conn =3D virConnectOpenReadOnly(uri); else *conn =3D virConnectOpen(uri); if (!*conn) - return -1; + goto error; VIR_DEBUG("Opened driver %p", *conn); + + if (preserveIdentity) { + if (virConnectSetIdentity(*conn, params, nparams, 0) < 0) + goto error; + + virTypedParamsFree(params, nparams); + VIR_DEBUG("Forwarded current identity to secondary driver"); + } + return 0; + + error: + virTypedParamsFree(params, nparams); + if (*conn) { + virConnectClose(*conn); + *conn =3D NULL; + } + return -1; } =20 =20 @@ -1992,6 +2025,7 @@ remoteGetInterfaceConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->interfaceURI, priv->readonly, + true, &priv->interfaceConn) < 0) return NULL; =20 @@ -2007,6 +2041,7 @@ remoteGetNetworkConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->networkURI, priv->readonly, + true, &priv->networkConn) < 0) return NULL; =20 @@ -2022,6 +2057,7 @@ remoteGetNodeDevConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->nodedevURI, priv->readonly, + true, &priv->nodedevConn) < 0) return NULL; =20 @@ -2037,6 +2073,7 @@ remoteGetNWFilterConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->nwfilterURI, priv->readonly, + true, &priv->nwfilterConn) < 0) return NULL; =20 @@ -2052,6 +2089,7 @@ remoteGetSecretConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->secretURI, priv->readonly, + true, &priv->secretConn) < 0) return NULL; =20 @@ -2067,6 +2105,7 @@ remoteGetStorageConn(virNetServerClientPtr client) =20 if (remoteOpenConn(priv->storageURI, priv->readonly, + true, &priv->storageConn) < 0) return NULL; =20 @@ -2235,6 +2274,7 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTR= IBUTE_UNUSED, #ifndef LIBVIRTD const char *type =3D NULL; #endif + bool preserveIdentity =3D false; =20 VIR_DEBUG("priv=3D%p conn=3D%p", priv, priv->conn); virMutexLock(&priv->lock); @@ -2264,14 +2304,16 @@ remoteDispatchConnectOpen(virNetServerPtr server AT= TRIBUTE_UNUSED, } #endif =20 +#ifdef VIRTPROXYD + preserveIdentity =3D true; +#endif /* VIRTPROXYD */ + VIR_DEBUG("Opening driver %s", name); - if (priv->readonly) { - if (!(priv->conn =3D virConnectOpenReadOnly(name))) - goto cleanup; - } else { - if (!(priv->conn =3D virConnectOpen(name))) - goto cleanup; - } + if (remoteOpenConn(name, + priv->readonly, + preserveIdentity, + &priv->conn) < 0) + goto cleanup; VIR_DEBUG("Opened %p", priv->conn); =20 #ifndef LIBVIRTD @@ -2375,6 +2417,54 @@ remoteDispatchConnectClose(virNetServerPtr server AT= TRIBUTE_UNUSED, } =20 =20 +static int +remoteDispatchConnectSetIdentity(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUS= ED, + remote_connect_set_identity_args *args) +{ + virTypedParameterPtr params =3D NULL; + int nparams =3D 0; + int rv =3D -1; + virConnectPtr conn =3D remoteGetHypervisorConn(client); + virIdentityPtr ident =3D NULL; + if (!conn) + goto cleanup; + + VIR_DEBUG("Received forwarded identity"); + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) args->param= s.params_val, + args->params.params_len, + REMOTE_CONNECT_IDENTITY_PARAMS_MAX, + ¶ms, + &nparams) < 0) + goto cleanup; + + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + if (virConnectSetIdentityEnsureACL(conn) < 0) + goto cleanup; + + if (!(ident =3D virIdentityNew())) + goto cleanup; + + if (virIdentitySetParameters(ident, params, nparams) < 0) + goto cleanup; + + virNetServerClientSetIdentity(client, ident); + + rv =3D 0; + + cleanup: + virTypedParamsFree(params, nparams); + virObjectUnref(ident); + if (rv < 0) + virNetMessageSaveError(rerr); + return rv; +} + + + static int remoteDispatchDomainGetSchedulerType(virNetServerPtr server ATTRIBUTE_UNUS= ED, virNetServerClientPtr client, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 889d62ba4f..e2d2dc66be 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8510,6 +8510,7 @@ static virHypervisorDriver hypervisor_driver =3D { .name =3D "remote", .connectOpen =3D remoteConnectOpen, /* 0.3.0 */ .connectClose =3D remoteConnectClose, /* 0.3.0 */ + .connectSetIdentity =3D remoteConnectSetIdentity, /* 5.6.0 */ .connectSupportsFeature =3D remoteConnectSupportsFeature, /* 0.3.0 */ .connectGetType =3D remoteConnectGetType, /* 0.3.0 */ .connectGetVersion =3D remoteConnectGetVersion, /* 0.3.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2f91bd1921..42e61ba20f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -53,6 +53,9 @@ typedef string remote_nonnull_string; /* A long string, which may be NULL. */ typedef remote_nonnull_string *remote_string; =20 +/* Upper limit on identity parameters */ +const REMOTE_CONNECT_IDENTITY_PARAMS_MAX =3D 20; + /* Upper limit on lists of domains. */ const REMOTE_DOMAIN_LIST_MAX =3D 16384; =20 @@ -3723,6 +3726,11 @@ struct remote_domain_checkpoint_delete_args { unsigned int flags; }; =20 +struct remote_connect_set_identity_args { + remote_typed_param params; + unsigned int flags; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -6538,7 +6546,7 @@ enum remote_procedure { */ REMOTE_PROC_NETWORK_PORT_DELETE =3D 410, =20 - /** + /** * @generate: both * @acl: domain:checkpoint * @acl: domain:fs_freeze:VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE @@ -6584,5 +6592,11 @@ enum remote_procedure { * @generate: both * @acl: domain:checkpoint */ - REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417 + REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417, + + /** + * @generate: client + * @acl: connect:write + */ + REMOTE_PROC_CONNECT_SET_IDENTITY =3D 418 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index a42b4a9671..05229f00c5 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3105,6 +3105,13 @@ struct remote_domain_checkpoint_delete_args { remote_nonnull_domain_checkpoint checkpoint; u_int flags; }; +struct remote_connect_set_identity_args { + struct { + u_int params_len; + remote_typed_param * params_val; + } params; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3523,4 +3530,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME =3D 415, REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT =3D 416, REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417, + REMOTE_PROC_CONNECT_SET_IDENTITY =3D 418, }; diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index 1f020a5a04..2a278171f5 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -844,6 +844,18 @@ virIdentityPtr virNetServerClientGetIdentity(virNetSer= verClientPtr client) } =20 =20 +void virNetServerClientSetIdentity(virNetServerClientPtr client, + virIdentityPtr identity) +{ + virObjectLock(client); + virObjectUnref(client->identity); + client->identity =3D identity; + if (client->identity) + virObjectRef(client->identity); + virObjectUnlock(client); +} + + int virNetServerClientGetSELinuxContext(virNetServerClientPtr client, char **context) { diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 1b01bedbcb..1c520fef6b 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -123,6 +123,8 @@ int virNetServerClientGetSELinuxContext(virNetServerCli= entPtr client, char **context); =20 virIdentityPtr virNetServerClientGetIdentity(virNetServerClientPtr client); +void virNetServerClientSetIdentity(virNetServerClientPtr client, + virIdentityPtr identity); =20 void *virNetServerClientGetPrivateData(virNetServerClientPtr client); =20 --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list