From nobody Wed May 14 11:43:29 2025 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 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 15241578956791005.4577357718247; Thu, 19 Apr 2018 10:11:35 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E69B7883BF; Thu, 19 Apr 2018 17:11:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B15C589E79; Thu, 19 Apr 2018 17:11:33 +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 537A6180596E; Thu, 19 Apr 2018 17:11:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3JHAK8f015189 for ; Thu, 19 Apr 2018 13:10:20 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8D1142024CA2; Thu, 19 Apr 2018 17:10:20 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC59F2017DEC; Thu, 19 Apr 2018 17:10:19 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Thu, 19 Apr 2018 18:10:01 +0100 Message-Id: <20180419171002.17117-14-berrange@redhat.com> In-Reply-To: <20180419171002.17117-1-berrange@redhat.com> References: <20180419171002.17117-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH WIP 13/14] remote: allow remote driver to connect to alternative 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.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 19 Apr 2018 17:11:34 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 If we are running inside the daemon, the remote driver usually declines URIs without a hostname present to avoid connecting back to itself, and to avoid accepting a URI that would be handled by a real local driver later in the probe order. It is now, however, possible to connect to alternative local daemons so this special hack based on hostname is insufficiently flexible. Instead we are willing to connect to a local UNIX socket, provided the local daemon does not have a driver registered for the URI. In this case we will then connect to an alternative daemon with a socket path based on the URI. Signed-off-by: Daniel P. Berrang=C3=A9 --- src/driver.h | 2 + src/libvirt.c | 24 +++++++++ src/remote/remote_daemon_dispatch.c | 11 +++- src/remote/remote_driver.c | 100 ++++++++++++++++++++++++++------= ---- src/remote/remote_driver.h | 3 -- 5 files changed, 109 insertions(+), 31 deletions(-) diff --git a/src/driver.h b/src/driver.h index b4e50ab987..e8f0c0ebdf 100644 --- a/src/driver.h +++ b/src/driver.h @@ -107,6 +107,8 @@ int virSetSharedNWFilterDriver(virNWFilterDriverPtr dri= ver) ATTRIBUTE_RETURN_CHE int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_C= HECK; int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN= _CHECK; =20 +bool virHasDriverForURIScheme(const char *scheme); + int virDriverLoadModule(const char *name, const char *regfunc, bool required); diff --git a/src/libvirt.c b/src/libvirt.c index 0a81cbfb99..d81b58aa10 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -689,6 +689,30 @@ virRegisterConnectDriver(virConnectDriverPtr driver, } =20 =20 +/** + * virHasDriverForURIScheme: + * @scheme: the URI scheme + * + * Determine if there is a driver registered that explicitly + * handles URIs with the scheme @scheme. + * + * Returns: true if a driver is registered + */ +bool virHasDriverForURIScheme(const char *scheme) +{ + size_t i, j; + for (i =3D 0; i < virConnectDriverTabCount; i++) { + if (!virConnectDriverTab[i]->uriSchemes) + continue; + for (j =3D 0; virConnectDriverTab[i]->uriSchemes[j]; j++) { + if (STREQ(virConnectDriverTab[i]->uriSchemes[j], scheme)) + return true; + } + } + + return false; +} + /** * virRegisterStateDriver: * @driver: pointer to a driver block diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index a8a5932d71..1eed9a0b38 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1833,7 +1833,16 @@ remoteDispatchConnectOpen(virNetServerPtr server ATT= RIBUTE_UNUSED, priv->networkConn =3D virObjectRef(priv->conn); priv->nodedevConn =3D virObjectRef(priv->conn); priv->nwfilterConn =3D virObjectRef(priv->conn); - priv->secretConn =3D virObjectRef(priv->conn); + if (STRPREFIX(name, "secret:///")) { + priv->secretConn =3D virObjectRef(priv->conn); + } else { + const char *uri =3D geteuid() =3D=3D 0 ? "secret:///system" : "sec= ret:///session"; + priv->secretConn =3D flags & VIR_CONNECT_RO + ? virConnectOpenReadOnly(uri) + : virConnectOpen(uri); + if (!priv->secretConn) + goto cleanup; + } priv->storageConn =3D virObjectRef(priv->conn); =20 /* force update the @readonly attribute which was inherited from the diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index b4b034423a..a3ace44b06 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -51,6 +51,7 @@ #include "virauth.h" #include "virauthconfig.h" #include "virstring.h" +#include "c-ctype.h" =20 #define VIR_FROM_THIS VIR_FROM_REMOTE =20 @@ -711,8 +712,7 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, continue; \ } =20 - -static char *remoteGetUNIXSocketNonRoot(void) +static char *remoteGetUNIXSocketNonRoot(const char *daemon_name) { char *sockname =3D NULL; char *userdir =3D virGetUserRuntimeDirectory(); @@ -720,23 +720,23 @@ static char *remoteGetUNIXSocketNonRoot(void) if (!userdir) return NULL; =20 - if (virAsprintf(&sockname, "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) <= 0) { + if (virAsprintf(&sockname, "%s/%s-sock", userdir, + inside_daemon ? daemon_name : "libvirt") < 0) { VIR_FREE(userdir); return NULL; } - VIR_FREE(userdir); =20 VIR_DEBUG("Chosen UNIX sockname %s", sockname); return sockname; } =20 -static char *remoteGetUNIXSocketRoot(unsigned int flags) +static char *remoteGetUNIXSocketRoot(const char *daemon_name, unsigned int= flags) { char *sockname =3D NULL; =20 - if (VIR_STRDUP(sockname, - flags & VIR_DRV_OPEN_REMOTE_RO ? - LIBVIRTD_PRIV_UNIX_SOCKET_RO : LIBVIRTD_PRIV_UNIX_SOCKE= T) < 0) + if (virAsprintf(&sockname, "%s/%s-%s", LOCALSTATEDIR "/run/libvirt", + inside_daemon ? daemon_name : "libvirt", + flags & VIR_DRV_OPEN_REMOTE_RO ? "sock-ro" : "sock") <= 0) return NULL; =20 VIR_DEBUG("Chosen UNIX sockname %s", sockname); @@ -768,6 +768,8 @@ doRemoteOpen(virConnectPtr conn, struct private_data *priv, const char *driver_str, const char *transport_str, + const char *daemon_name, + const char *daemon_env, virConnectAuthPtr auth ATTRIBUTE_UNUSED, virConfPtr conf, unsigned int flags) @@ -1004,7 +1006,7 @@ doRemoteOpen(virConnectPtr conn, goto failed; } =20 - if (!(sockname =3D remoteGetUNIXSocketRoot(flags))) + if (!(sockname =3D remoteGetUNIXSocketRoot(daemon_name, flags)= )) goto failed; } =20 @@ -1039,7 +1041,7 @@ doRemoteOpen(virConnectPtr conn, goto failed; } =20 - if (!(sockname =3D remoteGetUNIXSocketRoot(flags))) + if (!(sockname =3D remoteGetUNIXSocketRoot(daemon_name, flags)= )) goto failed; } =20 @@ -1067,20 +1069,21 @@ doRemoteOpen(virConnectPtr conn, case trans_unix: if (!sockname) { if (flags & VIR_DRV_OPEN_REMOTE_USER) - sockname =3D remoteGetUNIXSocketNonRoot(); + sockname =3D remoteGetUNIXSocketNonRoot(daemon_name); else - sockname =3D remoteGetUNIXSocketRoot(flags); + sockname =3D remoteGetUNIXSocketRoot(daemon_name, flags); if (!sockname) goto failed; } =20 - if ((flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) && - !(daemonPath =3D virFileFindResourceFull("libvirtd", - NULL, NULL, - abs_topbuilddir "/src", - SBINDIR, - "LIBVIRTD_PATH"))) - goto failed; + if (flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) { + if (!(daemonPath =3D virFileFindResourceFull(daemon_name, + NULL, NULL, + abs_topbuilddir "/s= rc", + SBINDIR, + daemon_env))) + goto failed; + } =20 if (!(priv->client =3D virNetClientNewUNIX(sockname, flags & VIR_DRV_OPEN_REMO= TE_AUTOSTART, @@ -1104,7 +1107,7 @@ doRemoteOpen(virConnectPtr conn, goto failed; } =20 - if (!(sockname =3D remoteGetUNIXSocketRoot(flags))) + if (!(sockname =3D remoteGetUNIXSocketRoot(daemon_name, flags)= )) goto failed; } =20 @@ -1312,6 +1315,9 @@ remoteAllocPrivateData(void) return priv; } =20 + +#define DRIVER_SCHEME_CHRS "abcdefghijklmnopqrstuvwxyz" + static virDrvOpenStatus remoteConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, @@ -1324,14 +1330,53 @@ remoteConnectOpen(virConnectPtr conn, const char *autostart =3D virGetEnvBlockSUID("LIBVIRT_AUTOSTART"); char *driver =3D NULL; char *transport =3D NULL; + char *daemon_name =3D NULL; + char *daemon_env =3D NULL; =20 - if (conn->uri && - remoteSplitURIScheme(conn->uri, &driver, &transport) < 0) - goto cleanup; + if (conn->uri) { + if (remoteSplitURIScheme(conn->uri, &driver, &transport) < 0) + goto cleanup; =20 - if (inside_daemon && (!conn->uri || !conn->uri->server)) { - ret =3D VIR_DRV_OPEN_DECLINED; - goto cleanup; + if (strspn(driver, DRIVER_SCHEME_CHRS) < strlen(driver)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid character in driver '%s'"), driver); + goto cleanup; + } + + if (inside_daemon) { + char *tmp; + if (virAsprintf(&daemon_name, "virt%sd", driver) < 0 || + virAsprintf(&daemon_env, "virt%sd_path", driver) < 0) + goto cleanup; + + tmp =3D daemon_env; + while (*tmp) { + *tmp =3D c_toupper(*tmp); + tmp++; + } + } else { + if (VIR_STRDUP(daemon_name, "libvirtd") < 0 || + VIR_STRDUP(daemon_env, "LIBVIRTD_PATH") < 0) + goto cleanup; + } + } + + if (inside_daemon) { + if (!conn->uri) { + ret =3D VIR_DRV_OPEN_DECLINED; + goto cleanup; + } + + /* + * If we're inside the daemon and there's a driver + * registered for this URI scheme, we should not + * handle this URI ourselves + */ + if (!conn->uri->server && + virHasDriverForURIScheme(driver)) { + ret =3D VIR_DRV_OPEN_DECLINED; + goto cleanup; + } } =20 if (!(priv =3D remoteAllocPrivateData())) @@ -1378,7 +1423,8 @@ remoteConnectOpen(virConnectPtr conn, } } =20 - ret =3D doRemoteOpen(conn, priv, driver, transport, auth, conf, rflags= ); + ret =3D doRemoteOpen(conn, priv, driver, transport, + daemon_name, daemon_env, auth, conf, rflags); if (ret !=3D VIR_DRV_OPEN_SUCCESS) { conn->privateData =3D NULL; remoteDriverUnlock(priv); diff --git a/src/remote/remote_driver.h b/src/remote/remote_driver.h index ef53179833..f6e3deb3d0 100644 --- a/src/remote/remote_driver.h +++ b/src/remote/remote_driver.h @@ -34,9 +34,6 @@ unsigned long remoteVersion(void); # define LIBVIRTD_LISTEN_ADDR NULL # define LIBVIRTD_TLS_PORT "16514" # define LIBVIRTD_TCP_PORT "16509" -# define LIBVIRTD_PRIV_UNIX_SOCKET LOCALSTATEDIR "/run/libvirt/libvirt-soc= k" -# define LIBVIRTD_PRIV_UNIX_SOCKET_RO LOCALSTATEDIR "/run/libvirt/libvirt-= sock-ro" -# define LIBVIRTD_USER_UNIX_SOCKET "libvirt-sock" =20 /* Defaults for PKI directory. */ # define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list