#include <config.h>
#include <unistd.h>
-#include <assert.h>
#include "virnetclient.h"
#include "virnetclientprogram.h"
/*----------------------------------------------------------------------*/
/* Helper functions for remoteOpen. */
-static char *get_transport_from_scheme(char *scheme);
+static int remoteSplitURIScheme(virURIPtr uri,
+ char **driver,
+ char **transport)
+{
+ char *p = strchr(uri->scheme, '+');
+
+ *driver = *transport = NULL;
+
+ if (VIR_STRNDUP(*driver, uri->scheme, p ? p - uri->scheme : -1) < 0)
+ return -1;
+
+ if (p &&
+ VIR_STRDUP(*transport, p + 1) < 0) {
+ VIR_FREE(*driver);
+ return -1;
+ }
+
+ return 0;
+}
+
static int
remoteStateInitialize(bool privileged ATTRIBUTE_UNUSED,
static int
doRemoteOpen(virConnectPtr conn,
struct private_data *priv,
+ const char *driver_str,
+ const char *transport_str,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
virConfPtr conf,
unsigned int flags)
{
- char *transport_str = NULL;
enum {
trans_tls,
trans_unix,
* URIs we don't care about */
if (conn->uri) {
- transport_str = get_transport_from_scheme(conn->uri->scheme);
-
if (!transport_str) {
if (conn->uri->server)
transport = trans_tls;
goto failed;
} else {
virURI tmpuri = {
- .scheme = conn->uri->scheme,
+ .scheme = (char *)driver_str,
.query = virURIFormatParams(conn->uri),
.path = conn->uri->path,
.fragment = conn->uri->fragment,
};
- /* Evil, blank out transport scheme temporarily */
- if (transport_str) {
- assert(transport_str[-1] == '+');
- transport_str[-1] = '\0';
- }
-
name = virURIFormat(&tmpuri);
VIR_FREE(tmpuri.query);
- /* Restore transport scheme */
- if (transport_str)
- transport_str[-1] = '+';
-
if (!name)
goto failed;
}
unsigned int flags)
{
struct private_data *priv;
- int ret, rflags = 0;
+ int ret = VIR_DRV_OPEN_ERROR;
+ int rflags = 0;
const char *autostart = virGetEnvBlockSUID("LIBVIRT_AUTOSTART");
+ char *driver = NULL;
+ char *transport = NULL;
- if (inside_daemon && (!conn->uri || !conn->uri->server))
- return VIR_DRV_OPEN_DECLINED;
+ if (conn->uri &&
+ remoteSplitURIScheme(conn->uri, &driver, &transport) < 0)
+ goto cleanup;
+
+ if (inside_daemon && (!conn->uri || !conn->uri->server)) {
+ ret = VIR_DRV_OPEN_DECLINED;
+ goto cleanup;
+ }
if (!(priv = remoteAllocPrivateData()))
- return VIR_DRV_OPEN_ERROR;
+ goto cleanup;
if (flags & VIR_CONNECT_RO)
rflags |= VIR_DRV_OPEN_REMOTE_RO;
!conn->uri->server &&
conn->uri->path &&
conn->uri->scheme &&
- ((strchr(conn->uri->scheme, '+') == 0)||
- (strstr(conn->uri->scheme, "+unix") != NULL)) &&
+ (transport == NULL || STREQ(transport, "unix")) &&
(STREQ(conn->uri->path, "/session") ||
STRPREFIX(conn->uri->scheme, "test+")) &&
geteuid() > 0) {
}
}
- ret = doRemoteOpen(conn, priv, auth, conf, rflags);
+ ret = doRemoteOpen(conn, priv, driver, transport, auth, conf, rflags);
if (ret != VIR_DRV_OPEN_SUCCESS) {
conn->privateData = NULL;
remoteDriverUnlock(priv);
conn->privateData = priv;
remoteDriverUnlock(priv);
}
+
+ cleanup:
+ VIR_FREE(driver);
+ VIR_FREE(transport);
return ret;
}
-/* In a string "driver+transport" return a pointer to "transport". */
-static char *
-get_transport_from_scheme(char *scheme)
-{
- char *p = strchr(scheme, '+');
- return p ? p + 1 : NULL;
-}
-
/*----------------------------------------------------------------------*/