On Thu, Jun 11, 2009 at 05:49:55PM +0200, Daniel Veillard wrote:
On Wed, Jun 03, 2009 at 05:31:13PM +0100, Daniel P. Berrange wrote:
> There are currently far too many cases where a correct URI returns an
> generic 'failed to connect to hypervisor' error message. This gives the
> user no idea why they could not connect. Of particular importance is
> that they cannot distinguish a correct URI + plus a driver problem, vs
> incorrect URI. Consider the following examples
[...]
> The core problem here is that far too many places are using the return
> code VIR_DRV_OPEN_DECLINED instead of VIR_DRV_OPEN_ERROR. The former
> provides no way to give any error info to the user. With this patch
> I have taken the view that a driver must *only* ever use the return
> code VIR_DRV_OPEN_DECLINED when:
>
> - Auto-probe of a driver URI, and this driver is not active
> - Explicit URI with 'server' specified
> - URI scheme does not match the driver
okay
> The remote driver is special in that it *must* accept all URIs given to
As long as we check first it's a correct URI...
Well the URI is parsed by libxml already so its good enough for the
remote driver. It'll just pass it onto the libvirtd daemon, where a
real driver will accept or decline it. So the remote driver doesn't
need todo any validation itself really.
> static virDrvOpenStatus openvzOpen(virConnectPtr conn,
> virConnectAuthPtr auth ATTRIBUTE_UNUSED,
> int flags ATTRIBUTE_UNUSED)
> {
> struct openvz_driver *driver;
> - if (!openvzProbe())
> - return VIR_DRV_OPEN_DECLINED;
>
> if (conn->uri == NULL) {
> + if (!virFileExists("/proc/vz"))
> + return VIR_DRV_OPEN_DECLINED;
> +
> + if (access("/proc/vz", W_OK) < 0)
> + return VIR_DRV_OPEN_DECLINED;
> +
Okay I was confused at first about dropping geteuid() == 0 check but
it's a more specific check,
And geteuid() will soon be wrong when the libvirtd daemon runs as
non-root, but with appropriate capabilities to access /proc/vz.
> enum virDrvOpenRemoteFlags {
> VIR_DRV_OPEN_REMOTE_RO = (1 << 0),
> - VIR_DRV_OPEN_REMOTE_UNIX = (1 << 1),
> - VIR_DRV_OPEN_REMOTE_USER = (1 << 2),
> - VIR_DRV_OPEN_REMOTE_AUTOSTART = (1 << 3),
> -};
> -
> -/* What transport? */
> -enum {
> - trans_tls,
> - trans_unix,
> - trans_ssh,
> - trans_ext,
> - trans_tcp,
> -} transport;
> -
> -
> + VIR_DRV_OPEN_REMOTE_USER = (1 << 1), /* Use the per-user socket path
*/
> + VIR_DRV_OPEN_REMOTE_AUTOSTART = (1 << 2), /* Autostart a per-user daemon
*/
> +};
> +
> +
> +/*
> + * URIs that this driver needs to handle:
> + *
> + * The easy answer:
> + * - Everything that no one else has yet claimed, but nothing if
> + * we're inside the libvirtd daemon
> + *
> + * The hard answer:
> + * - Plain paths (///var/lib/xen/xend-socket) -> UNIX domain socket
> + * - xxx://servername/ -> TLS connection
> + * - xxx+tls://servername/ -> TLS connection
> + * - xxx+tls:/// -> TLS connection to localhost
> + * - xxx+tcp://servername/ -> TCP connection
> + * - xxx+tcp:/// -> TCP connection to localhost
> + * - xxx+unix:/// -> UNIX domain socket
> + * - xxx:/// -> UNIX domain socket
> + */
> static int
> doRemoteOpen (virConnectPtr conn,
> struct private_data *priv,
> @@ -328,37 +335,51 @@ doRemoteOpen (virConnectPtr conn,
> {
> int wakeupFD[2] = { -1, -1 };
> char *transport_str = NULL;
> + enum {
> + trans_tls,
> + trans_unix,
> + trans_ssh,
> + trans_ext,
> + trans_tcp,
> + } transport;
hum ... I would have expected this to remain global somehow, but
thinking about it, fine :-)
Its not entirely clear at first glance, but the original code was
declaring a global variable 'transport' with an anonymous enum.
And this global variable was used from the 'doRemoteOpen' method.
This is totally & utterly unsafe, it should always have been a
local variable :-)
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|