[Libvir] libvirt daemon UNIX socket auth with PolicyKit

Daniel P. Berrange berrange at redhat.com
Wed Aug 8 04:22:33 UTC 2007


Currently our authentication model for local connections is using the basic
UNIX file permissions, possibly with a setuid helper (in Xen case only). It 
can be summarized as

 - If app using libvirt is running as root
      => full access
 - Else
      => read only access

The latter is enforced by fact that in Xen case libvirt_proxy only has impl
for a handful of read only APIs, or in non-Xen case that the UNIX domain
socket for the daemon /var/run/libvirt/libvirt-sock is mode 0700, while 
/var/run/libvirt/libvirt-sock-ro is 0777 & the daemon enforces based on which
socket the client connects to.

This is good because it allows non-root to at least monitor guest state
while requiring root authentication for actually changing state.

This is bad because it requires any app which wants to change state to run
as root. ie we are required to launch virt-manager as root to gain ability 
to manage local guests.  Problem with this include:

 - running the entire PyGTK & GTK & X codebase as root is undesirable
 - no integration with the DBus desktop session (gnome-vfs integartion)
 - no integration with the GNOME keyring (for VNC server passwords)
 - redundant (&dangerous) if all you want to do is manage remote libvirt hosts

In summary what I really need for virt-manager is

  - Always run as non-root
  - Authenticate for local guest management (ie read+write)

UNIX domain sockets already provide a way for each end to identify the PID
and UID of the other end. This enables the libvirt daemon to determine the
identity of the application on the other end. With this information the
daemon merely needs to check this identity against some access control policy
rules. Where to get/define these rules though ?

Enter PolicyKit.

  http://lists.freedesktop.org/archives/hal/2006-March/004770.html
  http://lists.freedesktop.org/archives/hal/2007-June/008815.html

PolicyKit is a freedesktop.org project to replace all the distro specific
'do admin stuff as root' hacks like consolehelper[1], sudo, gksudo with
a standard mechanism. Most importantly this mechanism does not require 
that the application in question run as root, or ever gain root privileges.
In addition this is completely configurable by the administrator in a
application independant manner.

How would the daemon use PolicyKit for authenticating clients on UNIX
domain sockets 

  - libvirtd defines two actions it can check called 'libvirt-local-monitor
    (read only monitoring of state), and 'libvirt-local-manage' (full
    read-write management).

  - Both libvirt-sock and libvirt-sock-ro are mode 0777 (ie all users)

  - A connection arrives on the UNIX domain socket either libvirt-sock-ro
    or libvirt-sock

  - libvirtd use SO_PEERCRED to get the PID of the client

  - If the connection is on libvirt-sock-ro 'action' is 'libvirt-local-monitor'
    Else if connection is on libvirt-sock 'action' is 'libvirt-local-manage'

  - Libvirt asks policy kit if PID is allowed to perform the 'action'
      -> Yes, connection proceeds
      -> No, connection is dropped

NB, having two separate UNIX domain sockets is strictly speaking redundant
now - the daemon could simply check each 'action' in turn - but keeping the
separate sockets simplifies the code, because it minimises the diffs when
PolicyKit is not enabled by the 'configure' script.

How is policy determined by PolicyKit ?

  - libvirt RPM provides /usr/share/PolicyKit/policy/libvirt.policy

  - This file defines the two actions it supports 'libvirt-local-monitor'
    and 'libvirt-local-manage'.

  - For each action we define a default policy for an active desktop
    session, and an inactive desktop session. The sample policy is to
    allow 'libvirt-local-monitor' for any local desktop session, but 
    only allow 'libvirt-local-manage' for the active session with the
    additional requirement that the user authenticate with PolicyKit
    using the root password.

This basically replicates the existing security semantics, without requiring
that we run virt-manager itself as root. This accomplishes the core goal.

There are other benefits to PolicyKit though - the administrator can override
the application provided default Policy. For example, could add a rule that
says

  "if the user fred is logged into the local X session, allow them to do
   'libvirt-local-manage' without any further prompts for root password"

Since PolicyKit is a general framework, that rule could be generalized
beyond just virt-manager

  "if the user fred is logged into the local X session, allow them to do
   any defined action without any further prompts for root password"

Or going the other way the administrator can lock things down requiring a
root password even for read only monitoring of VMs. Or a halfway house of
requiring the user's own password (sudo equiv, instead of su equiva).

If course this doesn't just apply to virt-manager either. This transparently
'just works' for virsh too & any other apps using libvirt - eg if policy 
grants 'libvirt-local-manage' then you can do full management whether virsh 
is root or not.

This all talks about enforcement of policy from the daemon side. There is
one outstanding question - if the policy so requires, where/how do we ask
the user to enter their credentials.

PolicyKit provides two mechanisms for this:

  - A command line tool polkit-grant  which uses pam to authenticate you
    as root, or using your own user password. If successful you will have
    been granted the permission to perform that action for the remainder
    of the session.

  - A DBus service for triggering display of some UI for authenticating.
    There is a GNOME impl of this service & likely a KDE impl too.


eg with virsh  start off without any priveleges

  $ virsh --connect qemu:///system net-list
  libvir: Remote error : Connection reset by peer
  error: failed to connect to the hypervisor
  error: no valid connection

  $ polkit-grant --action libvirtd-local-manage2
  Authentication is required.
  Password: 
  Keep this privilege for the session? [no/session]?
  
  $ ./src/virsh --connect qemu:///system net-list --all
  Name                 State      Autostart 
  -----------------------------------------
  default              active     yes       


One option is to have the libvirt library spawn polkit-grant if not finding
any $DISPLAY, and call the DBus service (for UI prompt) if finding any. The
other option is to punt this code upto the application - eg virt-manager 
always call the DBus service, while virsh always call polkit-grant.

Finally, PolicyKit is new in Fedora 8 if you wish to try this out. The
configure script is setup so that it automagically detects presence of
PolicyKit and only turns it on at compile time if its available. The 
fallback is to continue current behaviour of restricting based on the
socket permissions.

  http://fedoraproject.org/wiki/Releases/FeaturePolicyKit

Finally, finally, if we enable PolicyKit support, then we should disable
the Xen specific  libvirt_proxy setuid binary, since it would subvert the
policy for libvirt-local-monitor. IMHO we should just kill the setuid 
binary altogether, since we already require that the libvirt daemon be
running for the networking APIs & this provides read-only access already
which works for non-Xen drivers too.

Attaching the patch implementing the proof of concept

$ diffstat  ~/libvirt-policykit.patch
 configure.in          |   60 ++++++++++++++++++--
 qemud/Makefile.am     |   12 +++-
 qemud/internal.h      |   23 ++++++-
 qemud/libvirtd.policy |   41 ++++++++++++++
 qemud/qemud.c         |  145 ++++++++++++++++++++++++++++++++++++++++++++------
 qemud/remote.c        |    6 +-
 6 files changed, 258 insertions(+), 29 deletions(-)


Oh, finally, finally, finally. PolicyKit is pretty new so I'd understand
if there's some resistance to including it in an official libvirt release
at this point. I think the patch is small enough that we could carry it
as add-on in the Fedora RPMs only to start with untill its proved to be
maintainable long term - I really need this for Fedora 8 to make virt-manager
work sanely - ie not need to run as root. 

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
Index: qemud/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt/qemud/Makefile.am,v
retrieving revision 1.29
diff -u -p -r1.29 Makefile.am
--- qemud/Makefile.am	27 Jun 2007 00:12:29 -0000	1.29
+++ qemud/Makefile.am	8 Aug 2007 04:10:44 -0000
@@ -18,9 +18,10 @@ libvirtd_CFLAGS = \
         -DSYSCONF_DIR="\"$(sysconfdir)\"" \
 	-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \
 	-DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\"" \
-        -DGETTEXT_PACKAGE=\"$(PACKAGE)\"
+        -DGETTEXT_PACKAGE=\"$(PACKAGE)\" \
+        $(POLKIT_CFLAGS) $(POLKIT_DBUS_CFLAGS)
 
-libvirtd_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS)
+libvirtd_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS) $(POLKIT_LIBS) $(POLKIT_DBUS_LIBS)
 libvirtd_DEPENDENCIES = ../src/libvirt.la
 libvirtd_LDADD = ../src/libvirt.la
 
@@ -53,6 +54,13 @@ EXTRA_DIST = libvirtd.init.in libvirtd.s
 	remote_dispatch_localvars.h \
 	remote_dispatch_proc_switch.h
 
+if HAVE_POLICY_KIT
+policydir = $(datadir)/PolicyKit/policy
+policy_DATA = libvirtd.policy
+endif
+EXTRA_DIST += libvirtd.policy
+
+
 .x.c:
 	rm -f $@
 	rpcgen -c -o $@ $<
Index: qemud/internal.h
===================================================================
RCS file: /data/cvs/libvirt/qemud/internal.h,v
retrieving revision 1.33
diff -u -p -r1.33 internal.h
--- qemud/internal.h	7 Aug 2007 13:02:35 -0000	1.33
+++ qemud/internal.h	8 Aug 2007 04:10:45 -0000
@@ -33,6 +33,10 @@
 #include "remote_protocol.h"
 #include "../config.h"
 
+#ifdef HAVE_POLICY_KIT
+#include "dbus/dbus.h"
+#endif
+
 #ifdef __GNUC__
 #ifdef HAVE_ANSIDECL_H
 #include <ansidecl.h>
@@ -60,6 +64,14 @@ typedef enum {
 } qemudLogPriority;
 
 
+enum libvirtd_auth {
+    LIBVIRTD_AUTH_NONE,
+    LIBVIRTD_AUTH_TLS,
+#ifdef HAVE_POLICY_KIT
+    LIBVIRTD_AUTH_POLICYKIT,
+#endif
+};
+
 enum qemud_mode {
     QEMUD_MODE_RX_HEADER,
     QEMUD_MODE_RX_PAYLOAD,
@@ -84,8 +96,8 @@ struct qemud_client {
     struct sockaddr_storage addr;
     socklen_t addrlen;
 
-    /* If set, TLS is required on this socket. */
-    int tls;
+    /* Required auth mode for incoming connections */
+    int auth;
     gnutls_session_t session;
     enum qemud_tls_direction direction;
 
@@ -111,8 +123,8 @@ struct qemud_client {
 struct qemud_socket {
     int fd;
     int readonly;
-    /* If set, TLS is required on this socket. */
-    int tls;
+    /* Required auth mode for incoming connections */
+    int auth;
 
     struct qemud_socket *next;
 };
@@ -126,6 +138,9 @@ struct qemud_server {
     int sigread;
     char logDir[PATH_MAX];
     unsigned int shutdown : 1;
+#ifdef HAVE_POLICY_KIT
+    DBusConnection *sysbus;
+#endif
 };
 
 void qemudLog(int priority, const char *fmt, ...)
Index: qemud/libvirtd.policy
===================================================================
RCS file: qemud/libvirtd.policy
diff -N qemud/libvirtd.policy
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ qemud/libvirtd.policy	8 Aug 2007 04:10:45 -0000
@@ -0,0 +1,41 @@
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+
+<!-- 
+Policy definitions for libvirt daemon
+
+Copyright (c) 2007 Daniel P. Berrange <berrange at redhat.com>
+
+libvirt is licensed to you under the GNU Lesser General Public License 
+version 2. See COPYING for details.
+
+NOTE: If you make changes to this file, make sure to validate the file
+using the polkit-policy-file-validate(1) tool. Changes made to this
+file are instantly applied.
+-->
+
+<policyconfig>
+  <group id="libvirtd">
+    <description>Virtualization</description>
+
+    <policy id="libvirtd-local-monitor">
+      <description>Monitor local virtualized systems</description>
+      <message>System policy prevents monitoring local virtualized systems</message>
+      <defaults>
+        <allow_inactive>yes</allow_inactive>
+        <allow_active>yes</allow_active>
+      </defaults>
+    </policy>
+
+    <policy id="libvirtd-local-manage">
+      <description>Manage local virtualized systems</description>
+      <message>System policy prevents managing local virtualized systems</message>
+      <defaults>
+        <allow_inactive>no</allow_inactive>
+        <allow_active>auth_admin</allow_active>
+      </defaults>
+    </policy>
+
+  </group>
+</policyconfig>
Index: qemud/qemud.c
===================================================================
RCS file: /data/cvs/libvirt/qemud/qemud.c,v
retrieving revision 1.56
diff -u -p -r1.56 qemud.c
--- qemud/qemud.c	7 Aug 2007 13:24:22 -0000	1.56
+++ qemud/qemud.c	8 Aug 2007 04:10:45 -0000
@@ -57,6 +57,11 @@
 #include "../src/conf.h"
 #include "event.h"
 
+#ifdef HAVE_POLICY_KIT
+#include <polkit/polkit.h>
+#include <polkit-dbus/polkit-dbus.h>
+#endif
+
 static int godaemon = 0;        /* -d: Be a daemon */
 static int verbose = 0;         /* -v: Verbose mode */
 static int timeout = -1;        /* -t: Shutdown timeout */
@@ -448,6 +453,9 @@ static int qemudListenUnix(struct qemud_
     }
 
     sock->readonly = readonly;
+#ifdef HAVE_POLICY_KIT
+    sock->auth = LIBVIRTD_AUTH_POLICYKIT;
+#endif
 
     if ((sock->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         qemudLog(QEMUD_ERR, "Failed to create socket: %s",
@@ -465,11 +473,14 @@ static int qemudListenUnix(struct qemud_
     if (addr.sun_path[0] == '@')
         addr.sun_path[0] = '\0';
 
-
+#ifdef HAVE_POLICY_KIT
+    oldmask = umask(~(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH));
+#else
     if (readonly)
         oldmask = umask(~(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH));
     else
         oldmask = umask(~(S_IRUSR | S_IWUSR));
+#endif
     if (bind(sock->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
         qemudLog(QEMUD_ERR, "Failed to bind socket to '%s': %s",
                  path, strerror(errno));
@@ -559,7 +570,7 @@ remoteMakeSockets (int *fds, int max_fds
 static int
 remoteListenTCP (struct qemud_server *server,
                  const char *port,
-                 int tls)
+                 int auth)
 {
     int fds[2];
     int nfds = 0;
@@ -584,7 +595,7 @@ remoteListenTCP (struct qemud_server *se
         server->nsockets++;
 
         sock->fd = fds[i];
-        sock->tls = tls;
+        sock->auth = auth;
 
         if (qemudSetCloseExec(sock->fd) < 0 ||
             qemudSetNonBlock(sock->fd) < 0)
@@ -667,6 +678,9 @@ static struct qemud_server *qemudInitial
     struct qemud_server *server;
     char sockname[PATH_MAX];
     char roSockname[PATH_MAX];
+#ifdef HAVE_POLICY_KIT
+    DBusError err;
+#endif
 
     if (!(server = calloc(1, sizeof(struct qemud_server)))) {
         qemudLog(QEMUD_ERR, "Failed to allocate struct qemud_server");
@@ -687,6 +701,16 @@ static struct qemud_server *qemudInitial
     if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1) < 0)
         goto cleanup;
 
+#ifdef HAVE_POLICY_KIT
+    dbus_error_init(&err);
+    server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+    if (!(server->sysbus)) {
+        qemudLog(QEMUD_ERR, "Failed to connect to system bus: %s", err.message);
+        dbus_error_free(&err);
+        goto cleanup;
+    }
+#endif
+
     __virEventRegisterImpl(virEventAddHandleImpl,
                            virEventRemoveHandleImpl,
                            virEventAddTimeoutImpl,
@@ -695,14 +719,14 @@ static struct qemud_server *qemudInitial
     virStateInitialize();
 
     if (ipsock) {
-        if (listen_tcp && remoteListenTCP (server, tcp_port, 0) < 0)
+        if (listen_tcp && remoteListenTCP (server, tcp_port, LIBVIRTD_AUTH_NONE) < 0)
             goto cleanup;
 
         if (listen_tls) {
             if (remoteInitializeGnuTLS () < 0)
                 goto cleanup;
 
-            if (remoteListenTCP (server, tls_port, 1) < 0)
+            if (remoteListenTCP (server, tls_port, LIBVIRTD_AUTH_TLS) < 0)
                 goto cleanup;
         }
     }
@@ -717,6 +741,9 @@ static struct qemud_server *qemudInitial
             sock = sock->next;
         }
 
+#ifdef HAVE_POLICY_KTI
+        dbus_connection_unref(server->sysbus);
+#endif
         free(server);
     }
     return NULL;
@@ -945,6 +972,7 @@ static int qemudDispatchServer(struct qe
     socklen_t addrlen = (socklen_t) (sizeof addr);
     struct qemud_client *client;
     int no_slow_start = 1;
+    int ret;
 
     if ((fd = accept(sock->fd, (struct sockaddr *)&addr, &addrlen)) < 0) {
         if (errno == EAGAIN)
@@ -967,19 +995,96 @@ static int qemudDispatchServer(struct qe
     client->magic = QEMUD_CLIENT_MAGIC;
     client->fd = fd;
     client->readonly = sock->readonly;
-    client->tls = sock->tls;
+    client->auth = sock->auth;
     memcpy (&client->addr, &addr, sizeof addr);
     client->addrlen = addrlen;
 
-    if (!client->tls) {
+    switch (client->auth) {
+#ifdef HAVE_POLICY_KIT
+    case LIBVIRTD_AUTH_POLICYKIT:
+        {
+            PolKitCaller *pkcaller = NULL;
+            PolKitAction *pkaction = NULL;
+            PolKitContext *pkcontext = NULL;
+            PolKitError *pkerr;
+            PolKitResult pkresult;
+            const char *action = sock->readonly ?
+                "libvirtd-local-monitor" :
+                "libvirtd-local-manage";
+            pid_t callerPid;
+            DBusError err;
+#ifdef SO_PEERCRED
+            struct ucred cr;   
+            unsigned int cr_len = sizeof (cr);
+    
+            if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) < 0) {
+                qemudLog(QEMUD_ERR, "Failed to verify client credentials: %s", strerror(errno));
+                close(fd);
+                free(client);
+                return -1;
+            }
+            callerPid = cr.pid;
+#else
+            /* XXX Many more OS support UNIX socket credentials we could port to ....*/
+#error "UNIX socket credentials not supported/implemeneted on this platform"
+#endif
+            
+            dbus_error_init(&err);
+            if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus, callerPid, &err))) {
+                qemudLog(QEMUD_ERR, "Failed to lookup policy kit caller: %s", err.message);
+                dbus_error_free(&err);
+                close(fd);
+                free(client);
+                return -1;
+            }
+
+            if (!(pkaction = polkit_action_new())) {
+                qemudLog(QEMUD_ERR, "Failed to create polkit action %s\n", strerror(errno));
+                polkit_caller_unref(pkcaller);
+                close(fd);
+                free(client);
+                return -1;
+            }
+            polkit_action_set_action_id(pkaction, action);
+            
+            if (!(pkcontext = polkit_context_new()) ||
+                !polkit_context_init(pkcontext, &pkerr)) {
+                qemudLog(QEMUD_ERR, "Failed to create polkit context %s\n", 
+                         pkerr ? polkit_error_get_error_message(pkerr) : strerror(errno));
+                if (pkerr)
+                    polkit_error_free(pkerr);
+                polkit_caller_unref(pkcaller);
+                polkit_action_unref(pkaction);
+                dbus_error_free(&err);
+                close(fd);
+                free(client);
+                return -1;
+            }
+
+            pkresult = polkit_context_can_caller_do_action(pkcontext, pkaction, pkcaller);
+            polkit_context_unref(pkcontext);
+            polkit_caller_unref(pkcaller);
+            polkit_action_unref(pkaction);
+            if (pkresult != POLKIT_RESULT_YES) {
+                qemudLog(QEMUD_ERR, "Policy kit denied action %s from pid %d, result: %s\n",
+                         action, callerPid, polkit_result_to_string_representation(pkresult));
+                close(fd);
+                free(client);
+                return -1;
+            }
+        }
+        /* Allowed by policy kit, so fallthrough to generic setup... */
+#endif
+
+    case LIBVIRTD_AUTH_NONE:
         client->mode = QEMUD_MODE_RX_HEADER;
         client->bufferLength = QEMUD_PKT_HEADER_XDR_LEN;
 
         if (qemudRegisterClientEvent (server, client, 0) < 0)
             goto cleanup;
-    } else {
-        int ret;
+        break;
 
+    case LIBVIRTD_AUTH_TLS:
         client->session = remoteInitializeTLSSession ();
         if (client->session == NULL)
             goto cleanup;
@@ -1009,6 +1114,13 @@ static int qemudDispatchServer(struct qe
                       gnutls_strerror (ret));
             goto cleanup;
         }
+        break;
+
+    default:
+        qemudLog(QEMUD_ERR, "Unknown authentication scheme configured: %d\n", sock->auth);
+        close(fd);
+        free(client);
+        return -1;
     }
 
     client->next = server->clients;
@@ -1048,7 +1160,8 @@ static void qemudDispatchClientFailure(s
     if (client->conn)
         virConnectClose(client->conn);
 
-    if (client->tls && client->session) gnutls_deinit (client->session);
+    if (client->auth == LIBVIRTD_AUTH_TLS && client->session)
+        gnutls_deinit (client->session);
     close(client->fd);
     free(client);
 }
@@ -1065,7 +1178,7 @@ static int qemudClientRead(struct qemud_
 
     /*qemudDebug ("qemudClientRead: len = %d", len);*/
 
-    if (!client->tls) {
+    if (client->auth != LIBVIRTD_AUTH_TLS) {
         if ((ret = read (client->fd, data, len)) <= 0) {
             if (ret == 0 || errno != EAGAIN) {
                 if (ret != 0)
@@ -1133,7 +1246,8 @@ static void qemudDispatchClientRead(stru
 
         client->mode = QEMUD_MODE_RX_PAYLOAD;
         client->bufferLength = h.length;
-        if (client->tls) client->direction = QEMUD_TLS_DIRECTION_READ;
+        if (client->auth == LIBVIRTD_AUTH_TLS)
+            client->direction = QEMUD_TLS_DIRECTION_READ;
         /* Note that we don't reset bufferOffset here because we want
          * to retain the whole message, including header.
          */
@@ -1221,7 +1335,7 @@ static int qemudClientWrite(struct qemud
     data = client->buffer + client->bufferOffset;
     len = client->bufferLength - client->bufferOffset;
 
-    if (!client->tls) {
+    if (client->auth != LIBVIRTD_AUTH_TLS) {
         if ((ret = write(client->fd, data, len)) == -1) {
             if (errno != EAGAIN) {
                 qemudLog (QEMUD_ERR, "write: %s", strerror (errno));
@@ -1260,7 +1374,8 @@ static void qemudDispatchClientWrite(str
             client->mode = QEMUD_MODE_RX_HEADER;
             client->bufferLength = QEMUD_PKT_HEADER_XDR_LEN;
             client->bufferOffset = 0;
-            if (client->tls) client->direction = QEMUD_TLS_DIRECTION_READ;
+            if (client->auth == LIBVIRTD_AUTH_TLS)
+                client->direction = QEMUD_TLS_DIRECTION_READ;
 
             if (qemudRegisterClientEvent (server, client, 1) < 0)
                 qemudDispatchClientFailure (server, client);
@@ -1329,7 +1444,7 @@ static int qemudRegisterClientEvent(stru
         if (virEventRemoveHandleImpl(client->fd) < 0)
             return -1;
 
-    if (client->tls) {
+    if (client->auth == LIBVIRTD_AUTH_TLS) {
         if (virEventAddHandleImpl(client->fd,
                                   (client->direction ?
                                    POLLOUT : POLLIN) | POLLERR | POLLHUP,
Index: qemud/remote.c
===================================================================
RCS file: /data/cvs/libvirt/qemud/remote.c,v
retrieving revision 1.6
diff -u -p -r1.6 remote.c
--- qemud/remote.c	24 Jul 2007 14:21:03 -0000	1.6
+++ qemud/remote.c	8 Aug 2007 04:10:45 -0000
@@ -266,7 +266,8 @@ remoteDispatchClientRequest (struct qemu
     client->mode = QEMUD_MODE_TX_PACKET;
     client->bufferLength = len;
     client->bufferOffset = 0;
-    if (client->tls) client->direction = QEMUD_TLS_DIRECTION_WRITE;
+    if (client->auth == LIBVIRTD_AUTH_TLS)
+        client->direction = QEMUD_TLS_DIRECTION_WRITE;
 }
 
 /* An error occurred during the dispatching process itself (ie. not
@@ -360,7 +361,8 @@ remoteDispatchError (struct qemud_client
     client->mode = QEMUD_MODE_TX_PACKET;
     client->bufferLength = len;
     client->bufferOffset = 0;
-    if (client->tls) client->direction = QEMUD_TLS_DIRECTION_WRITE;
+    if (client->auth == LIBVIRTD_AUTH_TLS)
+        client->direction = QEMUD_TLS_DIRECTION_WRITE;
 }
 
 /*----- Functions. -----*/
Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.80
diff -u -p -r1.80 configure.in
--- configure.in	7 Aug 2007 13:02:35 -0000	1.80
+++ configure.in	8 Aug 2007 04:11:09 -0000
@@ -12,6 +12,8 @@ LIBVIRT_VERSION_INFO=`expr $LIBVIRT_MAJO
 
 LIBVIRT_VERSION_NUMBER=`expr $LIBVIRT_MAJOR_VERSION \* 1000000 + $LIBVIRT_MINOR_VERSION \* 1000 + $LIBVIRT_MICRO_VERSION`
 
+POLKIT_REQUIRED=0.5
+
 if test -f CVS/Entries; then
   extra=`grep ChangeLog CVS/Entries | grep -v LIBVIR | sed -e s\%/ChangeLog/1\.%% -e s\%/.*$%%`
   echo extra=$extra
@@ -72,15 +74,15 @@ AC_SUBST(HTML_DIR)
 
 dnl Allow to build without Xen, QEMU/KVM, test or remote driver
 AC_ARG_WITH(xen,
-[  --with-xen              add XEN support (on)])
+[  --with-xen              add XEN support (on)],[],[with_xen=yes])
 AC_ARG_WITH(qemu,
-[  --with-qemu             add QEMU/KVM support (on)])
+[  --with-qemu             add QEMU/KVM support (on)],[],[with_qemu=yes])
 AC_ARG_WITH(openvz,
-[  --with-openvz           add OpenVZ support (off)])
+[  --with-openvz           add OpenVZ support (off)],[],[with_openvz=no])
 AC_ARG_WITH(test,
-[  --with-test             add test driver support (on)])
+[  --with-test             add test driver support (on)],[],[with_test=yes])
 AC_ARG_WITH(remote,
-[  --with-remote           add remote driver support (on)])
+[  --with-remote           add remote driver support (on)],[],[with_remote=yes])
 
 dnl
 dnl specific tests to setup DV devel environments with debug etc ...
@@ -95,7 +97,7 @@ AC_SUBST(STATIC_BINARIES)
 dnl --enable-debug=(yes|no)
 AC_ARG_ENABLE(debug,
               AC_HELP_STRING([--enable-debug=no/yes],
-                             [enable debugging output]))
+                             [enable debugging output]),[],[enable_debug=no])
 if test x"$enable_debug" = x"yes"; then
    AC_DEFINE(ENABLE_DEBUG, [], [whether debugging is enabled])
 fi
@@ -424,6 +426,36 @@ AC_SUBST(PYTHON_VERSION)
 AC_SUBST(PYTHON_INCLUDES)
 AC_SUBST(PYTHON_SITE_PACKAGES)
 
+PKG_PROG_PKG_CONFIG()
+
+AC_ARG_WITH(policykit,
+  [  --with-policykit         use policy kit for local authentication (on)],
+  [],
+  [with_policykit=check])
+
+if test "$with_policykit" = "check"; then
+  AC_MSG_CHECKING([if PolicyKit >= $POLKIT_REQUIRED is available])
+  PKG_CHECK_EXISTS(polkit >= $POLKIT_REQUIRED, [have_policykit=yes], [have_policykit=no])
+  AC_MSG_RESULT([$have_policykit])
+  with_policykit="$have_policykit"
+fi
+
+if test "$with_policykit" = "yes" ; then
+  PKG_CHECK_MODULES(POLKIT, polkit >= $POLKIT_REQUIRED)
+  PKG_CHECK_MODULES(POLKIT_DBUS, polkit-dbus >= $POLKIT_REQUIRED)
+  AC_DEFINE_UNQUOTED(HAVE_POLICY_KIT, 1, [whether policy kit is used for UNIX socket auth])
+else
+  POLKIT_CFLAGS=
+  POLKIT_LIBS=
+  POLKIT_DBUS_CFLAGS=
+  POLKIT_DBUS_LIBS=
+fi
+AM_CONDITIONAL(HAVE_POLICY_KIT, [test "$with_policykit" = "yes"])
+AC_SUBST(POLKIT_CFLAGS)
+AC_SUBST(POLKIT_LIBS)
+AC_SUBST(POLKIT_DBUS_CFLAGS)
+AC_SUBST(POLKIT_DBUS_LIBS)
+
 AC_MSG_CHECKING([whether this host is running a Xen kernel])
 RUNNING_XEN=
 if test -d /proc/sys/xen
@@ -490,3 +522,19 @@ AC_OUTPUT(Makefile src/Makefile include/
           tests/xmconfigdata/Makefile \
           tests/xencapsdata/Makefile \
           tests/virshdata/Makefile tests/confdata/Makefile)
+
+echo
+echo "Drivers:"
+echo "     Xen: $with_xen"
+echo "    QEMU: $with_qemu"
+echo "    Test: $with_test"
+echo "  OpenVZ: $with_openvz"
+echo "  Remote: $with_remote"
+echo
+echo "General features:"
+echo "   Debug: $enable_debug"
+if test "$with_remote" = "yes"; then
+  echo
+  echo "Remote driver features:"
+  echo "  PolicyKit: $with_policykit"
+fi


More information about the libvir-list mailing list