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 -=|
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@xxxxxxxxxx> + +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
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list