[Libvir] PATCH: 4/10: PolicyKit authentication support

Daniel P. Berrange berrange at redhat.com
Thu Nov 29 17:18:41 UTC 2007


This patch adds support for an PolicyKit authentication mechanism. This
was previously described here:

http://www.redhat.com/archives/libvir-list/2007-September/msg00168.html

If PolicyKit is compiled in, then the UNIX domain sockets have their
default settings changed to make sure of PolicyKit. Thus, when PolicyKit
is enabled, both the RO & RW sockets are mode 0777. PolicyKit is then
called upon client connect to decide whether to allow the client to gain
access.

The policyfile is shipped in /usr/share/PolicyKit/policy and has default
settings to mimic current non-PolicyKit access. If making a read-only
connection, any application will be granted access by default. If making
a read-write connection, applications will need to authenticate against
policykit by providing the user's own password. This is akin to 'sudo'
style auth. The credentials persist until the user logs out.

The file in /etc/PolicyKit/PolicyKit.conf can be used by the local sysadmin
to override the default policy on a per-host basis. eg, they could restrict
access to the read-only connections, or open up the read-write connections
to more apps. See 'man PolicyKit.conf' for more info.

The configure script will check for PolicyKit using pkg-config and only
enable it if actually present. So any OS without PolicyKit will not be
impacted by this patch.

 b/qemud/libvirtd.policy             |   42 +++++++++++
 configure.in                        |   25 ++++++
 libvirt.spec.in                     |    3 
 qemud/Makefile.am                   |   11 ++
 qemud/internal.h                    |    7 +
 qemud/libvirtd.conf                 |   18 +++-
 qemud/qemud.c                       |   37 +++++++++
 qemud/remote.c                      |  135 +++++++++++++++++++++++++++++++++++-
 qemud/remote_dispatch_localvars.h   |    1 
 qemud/remote_dispatch_proc_switch.h |    6 +
 qemud/remote_dispatch_prototypes.h  |    1 
 qemud/remote_protocol.c             |    9 ++
 qemud/remote_protocol.h             |    9 ++
 qemud/remote_protocol.x             |   10 ++
 src/remote_internal.c               |   35 +++++++++
 15 files changed, 340 insertions(+), 9 deletions(-)



diff -r 40e7c976f974 configure.in
--- a/configure.in	Thu Nov 29 09:51:32 2007 -0500
+++ b/configure.in	Thu Nov 29 10:02:52 2007 -0500
@@ -25,6 +25,7 @@ LIBXML_REQUIRED="2.5.0"
 LIBXML_REQUIRED="2.5.0"
 GNUTLS_REQUIRED="1.0.25"
 AVAHI_REQUIRED="0.6.0"
+POLKIT_REQUIRED="0.6"
 
 dnl Checks for programs.
 AC_PROG_CC
@@ -388,6 +389,25 @@ AC_SUBST(SASL_LIBS)
 AC_SUBST(SASL_LIBS)
 
 
+dnl PolicyKit library
+POLKIT_CFLAGS=
+POLKIT_LIBS=
+AC_ARG_WITH(polkit,
+  [  --with-polkit         use PolicyKit for UNIX socket access checks],
+  [],
+  [with_polkit=check])
+
+if test "$with_polkit" = "check"; then
+  PKG_CHECK_EXISTS(polkit-dbus >= $POLKIT_REQUIRED, [with_polkit=yes], [with_polkit=no])
+fi
+
+if test "$with_polkit" = "yes"; then
+  PKG_CHECK_MODULES(POLKIT, polkit-dbus >= $POLKIT_REQUIRED)
+  AC_DEFINE_UNQUOTED(HAVE_POLKIT, 1, [use PolicyKit for UNIX socket access checks])
+fi
+AM_CONDITIONAL(HAVE_POLKIT, [test "$with_polkit" = "yes"])
+AC_SUBST(POLKIT_CFLAGS)
+AC_SUBST(POLKIT_LIBS)
 
 dnl Avahi library
 AC_ARG_WITH(avahi,
@@ -608,6 +628,11 @@ else
 else
 AC_MSG_NOTICE([   avahi: no])
 fi
+if test "$with_polkit" = "yes" ; then
+AC_MSG_NOTICE([  polkit: $POLKIT_CFLAGS $POLKIT_LIBS])
+else
+AC_MSG_NOTICE([  polkit: no])
+fi
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Miscellaneous])
 AC_MSG_NOTICE([])
diff -r 40e7c976f974 libvirt.spec.in
--- a/libvirt.spec.in	Thu Nov 29 09:51:32 2007 -0500
+++ b/libvirt.spec.in	Thu Nov 29 10:02:52 2007 -0500
@@ -18,6 +18,7 @@ Requires: iptables
 Requires: iptables
 Requires: cyrus-sasl
 Requires: cyrus-sasl-gssapi
+Requires: PolicyKit
 BuildRequires: xen-devel
 BuildRequires: libxml2-devel
 BuildRequires: readline-devel
@@ -29,6 +30,7 @@ BuildRequires: bridge-utils
 BuildRequires: bridge-utils
 BuildRequires: qemu
 BuildRequires: cyrus-sasl-devel
+BuildRequires: PolicyKit-devel
 Obsoletes: libvir
 ExclusiveArch: i386 x86_64 ia64
 
@@ -141,6 +143,7 @@ fi
 %{_datadir}/libvirt/networks/default.xml
 %dir %{_localstatedir}/run/libvirt/
 %dir %{_localstatedir}/lib/libvirt/
+%{_datadir}/PolicyKit/policy/libvirtd.policy
 %dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
 %attr(4755, root, root) %{_libexecdir}/libvirt_proxy
 %attr(0755, root, root) %{_sbindir}/libvirtd
diff -r 40e7c976f974 qemud/Makefile.am
--- a/qemud/Makefile.am	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/Makefile.am	Thu Nov 29 10:02:52 2007 -0500
@@ -30,15 +30,24 @@ libvirtd_CFLAGS = \
 libvirtd_CFLAGS = \
         -I$(top_srcdir)/include -I$(top_builddir)/include \
         $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
+        $(POLKIT_CFLAGS) \
         $(WARN_CFLAGS) -DLOCAL_STATE_DIR="\"$(localstatedir)\"" \
         -DSYSCONF_DIR="\"$(sysconfdir)\"" \
 	-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" \
 	-DREMOTE_PID_FILE="\"$(REMOTE_PID_FILE)\"" \
         -DGETTEXT_PACKAGE=\"$(PACKAGE)\"
 
-libvirtd_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS) $(GNUTLS_LIBS) $(SASL_LIBS)
+libvirtd_LDFLAGS = $(WARN_CFLAGS) $(LIBXML_LIBS) $(GNUTLS_LIBS) $(SASL_LIBS) \
+                   $(POLKIT_LIBS)
 libvirtd_DEPENDENCIES = ../src/libvirt.la
 libvirtd_LDADD = ../src/libvirt.la
+
+
+if HAVE_POLKIT
+policydir = $(datadir)/PolicyKit/policy
+policy_DATA = libvirtd.policy
+endif
+EXTRA_DIST += libvirtd.policy
 
 if HAVE_AVAHI
 libvirtd_SOURCES += mdns.c mdns.h
diff -r 40e7c976f974 qemud/internal.h
--- a/qemud/internal.h	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/internal.h	Thu Nov 29 10:02:52 2007 -0500
@@ -30,6 +30,10 @@
 #include "../src/gnutls_1_0_compat.h"
 #if HAVE_SASL
 #include <sasl/sasl.h>
+#endif
+
+#ifdef HAVE_POLKIT
+#include <dbus/dbus.h>
 #endif
 
 #ifdef HAVE_SYS_SYSLIMITS_H
@@ -155,6 +159,9 @@ struct qemud_server {
 #if HAVE_SASL
     char **saslUsernameWhitelist;
 #endif
+#if HAVE_POLKIT
+    DBusConnection *sysbus;
+#endif
 };
 
 void qemudLog(int priority, const char *fmt, ...)
diff -r 40e7c976f974 qemud/libvirtd.conf
--- a/qemud/libvirtd.conf	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/libvirtd.conf	Thu Nov 29 10:02:52 2007 -0500
@@ -82,8 +82,11 @@
 # Set the UNIX socket permissions for the R/W socket. This is used
 # for full management of VMs
 #
-# Default allows only root. If setting group ownership may want to
-# relax this to:
+# Default allows only root. If PolicyKit is enabled on the socket,
+# the default will change to allow everyone (eg, 0777)
+#
+# If not using PolicyKit and setting group ownership for access
+# control then you may want to relax this to:
 # unix_sock_rw_perms "0770"
 
 
@@ -103,7 +106,12 @@
 #          socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
 #          For non-TCP or TLS sockets,  any scheme is allowed.
 #
-
+#  - polkit: use PolicyKit to authenticate. This is only suitable
+#            for use on the UNIX sockets. The default policy will
+#            require a user to supply their own password to gain
+#            full read/write access (aka sudo like), while anyone
+#            is allowed read/only access.
+#
 # Set an authentication scheme for UNIX read-only sockets
 # By default socket permissions allow anyone to connect
 #
@@ -112,7 +120,9 @@
 # auth_unix_ro = "none"
 
 # Set an authentication scheme for UNIX read-write sockets
-# By default socket permissions only allow root.
+# By default socket permissions only allow root. If PolicyKit
+# support was compiled into libvirt, the default will be to
+# use 'polkit' auth.
 #
 # If the unix_sock_rw_perms are changed you may wish to enable
 # an authentication mechanism here
diff -r 40e7c976f974 qemud/libvirtd.policy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qemud/libvirtd.policy	Thu Nov 29 10:02:52 2007 -0500
@@ -0,0 +1,42 @@
+<!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 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>
+    <action id="org.libvirt.unix.monitor">
+      <description>Monitor local virtualized systems</description>
+      <message>System policy prevents monitoring of local virtualized systems</message>
+      <defaults>
+        <!-- Any program can use libvirt in read-only mode for monitoring,
+             even if not part of a session -->
+        <allow_any>yes</allow_any>
+        <allow_inactive>yes</allow_inactive>
+        <allow_active>yes</allow_active>
+      </defaults>
+    </action>
+
+    <action id="org.libvirt.unix.manage">
+      <description>Manage local virtualized systems</description>
+      <message>System policy prevents management of local virtualized systems</message>
+      <defaults>
+        <!-- Only a program in the active host session can use libvirt in
+             read-write mode for management, and we require user password -->
+        <allow_any>no</allow_any>
+        <allow_inactive>no</allow_inactive>
+        <allow_active>auth_self_keep_session</allow_active>
+      </defaults>
+    </action>
+</policyconfig>
\ No newline at end of file
diff -r 40e7c976f974 qemud/qemud.c
--- a/qemud/qemud.c	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/qemud.c	Thu Nov 29 10:02:52 2007 -0500
@@ -77,9 +77,14 @@ static int unix_sock_rw_perms = 0700; /*
 static int unix_sock_rw_perms = 0700; /* Allow user only */
 static int unix_sock_ro_perms = 0777; /* Allow world */
 
-
+#if HAVE_POLKIT
+static int auth_unix_rw = REMOTE_AUTH_POLKIT;
+static int auth_unix_ro = REMOTE_AUTH_POLKIT;
+#else
 static int auth_unix_rw = REMOTE_AUTH_NONE;
 static int auth_unix_ro = REMOTE_AUTH_NONE;
+#endif
+
 #if HAVE_SASL
 static int auth_tcp = REMOTE_AUTH_SASL;
 #else
@@ -762,6 +767,21 @@ static struct qemud_server *qemudNetwork
     }
 #endif
 
+#ifdef HAVE_POLKIT
+    if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
+        auth_unix_ro == REMOTE_AUTH_POLKIT) {
+        DBusError derr;
+        dbus_error_init(&derr);
+        server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
+        if (!(server->sysbus)) {
+            qemudLog(QEMUD_ERR, "Failed to connect to system bus for PolicyKit auth: %s",
+                     derr.message);
+            dbus_error_free(&derr);
+            goto cleanup;
+        }
+    }
+#endif
+
     if (ipsock) {
         if (listen_tcp && remoteListenTCP (server, tcp_port, QEMUD_SOCK_TYPE_TCP, auth_tcp) < 0)
             goto cleanup;
@@ -829,6 +849,10 @@ static struct qemud_server *qemudNetwork
             sock = sock->next;
         }
 
+#ifdef HAVE_POLKIT
+        if (server->sysbus)
+            dbus_connection_unref(server->sysbus);
+#endif
         free(server);
     }
     return NULL;
@@ -1716,6 +1740,10 @@ static int remoteConfigGetAuth(virConfPt
     } else if (STREQ(p->str, "sasl")) {
         *auth = REMOTE_AUTH_SASL;
 #endif
+#if HAVE_POLKIT
+    } else if (STREQ(p->str, "polkit")) {
+        *auth = REMOTE_AUTH_POLKIT;
+#endif
     } else {
         qemudLog (QEMUD_ERR, "remoteReadConfigFile: %s: %s: unsupported auth %s\n", filename, key, p->str);
         return -1;
@@ -1767,6 +1795,13 @@ remoteReadConfigFile (struct qemud_serve
 
     if (remoteConfigGetAuth(conf, "auth_unix_rw", &auth_unix_rw, filename) < 0)
         return -1;
+#if HAVE_POLKIT
+    /* Change default perms to be wide-open if PolicyKit is enabled.
+     * Admin can always override in config file
+     */
+    if (auth_unix_rw == REMOTE_AUTH_POLKIT)
+        unix_sock_rw_perms = 0777;
+#endif
     if (remoteConfigGetAuth(conf, "auth_unix_ro", &auth_unix_ro, filename) < 0)
         return -1;
     if (remoteConfigGetAuth(conf, "auth_tcp", &auth_tcp, filename) < 0)
diff -r 40e7c976f974 qemud/remote.c
--- a/qemud/remote.c	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote.c	Thu Nov 29 10:02:52 2007 -0500
@@ -46,6 +46,11 @@
 #include <assert.h>
 #include <fnmatch.h>
 
+#ifdef HAVE_POLKIT
+#include <polkit/polkit.h>
+#include <polkit-dbus/polkit-dbus.h>
+#endif
+
 #include <libvirt/virterror.h>
 
 #include "internal.h"
@@ -132,7 +137,8 @@ remoteDispatchClientRequest (struct qemu
         if (req.proc != REMOTE_PROC_AUTH_LIST &&
             req.proc != REMOTE_PROC_AUTH_SASL_INIT &&
             req.proc != REMOTE_PROC_AUTH_SASL_START &&
-            req.proc != REMOTE_PROC_AUTH_SASL_STEP
+            req.proc != REMOTE_PROC_AUTH_SASL_STEP &&
+            req.proc != REMOTE_PROC_AUTH_POLKIT
             ) {
             remoteDispatchError (client, &req, "authentication required");
             xdr_destroy (&xdr);
@@ -2550,6 +2556,133 @@ remoteDispatchAuthSaslStep (struct qemud
 #endif /* HAVE_SASL */
 
 
+#if HAVE_POLKIT
+static int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
+#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));
+        return -1;
+    }
+
+    *pid = cr.pid;
+    *uid = cr.uid;
+#else
+    /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
+#error "UNIX socket credentials not supported/implemented on this platform yet..."
+#endif
+    return 0;
+}
+
+
+static int
+remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
+                          struct qemud_client *client,
+                          remote_message_header *req,
+                          void *args ATTRIBUTE_UNUSED,
+                          remote_auth_polkit_ret *ret)
+{
+    pid_t callerPid;
+    uid_t callerUid;
+
+    REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
+    if (client->auth != REMOTE_AUTH_POLKIT) {
+        qemudLog(QEMUD_ERR, "client tried invalid PolicyKit init request");
+        remoteDispatchFailAuth(client, req);
+        return -2;
+    }
+
+    if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
+        qemudLog(QEMUD_ERR, "cannot get peer socket identity");
+        remoteDispatchFailAuth(client, req);
+        return -2;
+    }
+
+    /* Only do policy checks for non-root - allow root user
+       through with no checks, as a fail-safe - root can easily
+       change policykit policy anyway, so its pointless trying
+       to restrict root */
+    if (callerUid == 0) {
+        qemudLog(QEMUD_INFO, "Allowing PID %d running as root", callerPid);
+        ret->complete = 1;
+        client->auth = REMOTE_AUTH_NONE;
+    } else {
+        PolKitCaller *pkcaller = NULL;
+        PolKitAction *pkaction = NULL;
+        PolKitContext *pkcontext = NULL;
+        PolKitError *pkerr;
+        PolKitResult pkresult;
+        DBusError err;
+        const char *action = client->readonly ?
+            "org.libvirt.unix.monitor" :
+            "org.libvirt.unix.manage";
+
+        qemudLog(QEMUD_INFO, "Checking PID %d running as %d", callerPid, callerUid);
+        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);
+            remoteDispatchFailAuth(client, req);
+            return -2;
+        }
+
+        if (!(pkaction = polkit_action_new())) {
+            qemudLog(QEMUD_ERR, "Failed to create polkit action %s\n", strerror(errno));
+            polkit_caller_unref(pkcaller);
+            remoteDispatchFailAuth(client, req);
+            return -2;
+        }
+        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);
+            remoteDispatchFailAuth(client, req);
+            return -2;
+        }
+
+        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, uid %d, result: %s\n",
+                     action, callerPid, callerUid, polkit_result_to_string_representation(pkresult));
+            remoteDispatchFailAuth(client, req);
+            return -2;
+        }
+        qemudLog(QEMUD_INFO, "Policy allowed action %s from pid %d, uid %d, result %s",
+                 action, callerPid, callerUid, polkit_result_to_string_representation(pkresult));
+        ret->complete = 1;
+        client->auth = REMOTE_AUTH_NONE;
+    }
+
+    return 0;
+}
+
+#else /* HAVE_POLKIT */
+
+static int
+remoteDispatchAuthPolkitInit (struct qemud_server *server ATTRIBUTE_UNUSED,
+                              struct qemud_client *client,
+                              remote_message_header *req,
+                              void *args ATTRIBUTE_UNUSED,
+                              remote_auth_polkit_ret *ret ATTRIBUTE_UNUSED)
+{
+    qemudLog(QEMUD_ERR, "client tried unsupported PolicyKit init request");
+    remoteDispatchFailAuth(client, req);
+    return -1;
+}
+#endif /* HAVE_POLKIT */
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
diff -r 40e7c976f974 qemud/remote_dispatch_localvars.h
--- a/qemud/remote_dispatch_localvars.h	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_dispatch_localvars.h	Thu Nov 29 10:02:52 2007 -0500
@@ -37,6 +37,7 @@ remote_domain_create_linux_args lv_remot
 remote_domain_create_linux_args lv_remote_domain_create_linux_args;
 remote_domain_create_linux_ret lv_remote_domain_create_linux_ret;
 remote_domain_set_scheduler_parameters_args lv_remote_domain_set_scheduler_parameters_args;
+remote_auth_polkit_ret lv_remote_auth_polkit_ret;
 remote_auth_sasl_start_args lv_remote_auth_sasl_start_args;
 remote_auth_sasl_start_ret lv_remote_auth_sasl_start_ret;
 remote_domain_interface_stats_args lv_remote_domain_interface_stats_args;
diff -r 40e7c976f974 qemud/remote_dispatch_proc_switch.h
--- a/qemud/remote_dispatch_proc_switch.h	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_dispatch_proc_switch.h	Thu Nov 29 10:02:52 2007 -0500
@@ -8,6 +8,12 @@ case REMOTE_PROC_AUTH_LIST:
 	ret = (char *) &lv_remote_auth_list_ret;
 	memset (&lv_remote_auth_list_ret, 0, sizeof lv_remote_auth_list_ret);
 	break;
+case REMOTE_PROC_AUTH_POLKIT:
+	fn = (dispatch_fn) remoteDispatchAuthPolkit;
+	ret_filter = (xdrproc_t) xdr_remote_auth_polkit_ret;
+	ret = (char *) &lv_remote_auth_polkit_ret;
+	memset (&lv_remote_auth_polkit_ret, 0, sizeof lv_remote_auth_polkit_ret);
+	break;
 case REMOTE_PROC_AUTH_SASL_INIT:
 	fn = (dispatch_fn) remoteDispatchAuthSaslInit;
 	ret_filter = (xdrproc_t) xdr_remote_auth_sasl_init_ret;
diff -r 40e7c976f974 qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_dispatch_prototypes.h	Thu Nov 29 10:02:52 2007 -0500
@@ -3,6 +3,7 @@
  */
 
 static int remoteDispatchAuthList (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_auth_list_ret *ret);
+static int remoteDispatchAuthPolkit (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_auth_polkit_ret *ret);
 static int remoteDispatchAuthSaslInit (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, void *args, remote_auth_sasl_init_ret *ret);
 static int remoteDispatchAuthSaslStart (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_auth_sasl_start_args *args, remote_auth_sasl_start_ret *ret);
 static int remoteDispatchAuthSaslStep (struct qemud_server *server, struct qemud_client *client, remote_message_header *req, remote_auth_sasl_step_args *args, remote_auth_sasl_step_ret *ret);
diff -r 40e7c976f974 qemud/remote_protocol.c
--- a/qemud/remote_protocol.c	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_protocol.c	Thu Nov 29 10:02:52 2007 -0500
@@ -1309,6 +1309,15 @@ xdr_remote_auth_sasl_step_ret (XDR *xdrs
 }
 
 bool_t
+xdr_remote_auth_polkit_ret (XDR *xdrs, remote_auth_polkit_ret *objp)
+{
+
+	 if (!xdr_int (xdrs, &objp->complete))
+		 return FALSE;
+	return TRUE;
+}
+
+bool_t
 xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
 {
 
diff -r 40e7c976f974 qemud/remote_protocol.h
--- a/qemud/remote_protocol.h	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_protocol.h	Thu Nov 29 10:02:52 2007 -0500
@@ -68,6 +68,7 @@ enum remote_auth_type {
 enum remote_auth_type {
 	REMOTE_AUTH_NONE = 0,
 	REMOTE_AUTH_SASL = 1,
+	REMOTE_AUTH_POLKIT = 2,
 };
 typedef enum remote_auth_type remote_auth_type;
 
@@ -719,6 +720,11 @@ struct remote_auth_sasl_step_ret {
 	} data;
 };
 typedef struct remote_auth_sasl_step_ret remote_auth_sasl_step_ret;
+
+struct remote_auth_polkit_ret {
+	int complete;
+};
+typedef struct remote_auth_polkit_ret remote_auth_polkit_ret;
 #define REMOTE_PROGRAM 0x20008086
 #define REMOTE_PROTOCOL_VERSION 1
 
@@ -792,6 +798,7 @@ enum remote_procedure {
 	REMOTE_PROC_AUTH_SASL_INIT = 67,
 	REMOTE_PROC_AUTH_SASL_START = 68,
 	REMOTE_PROC_AUTH_SASL_STEP = 69,
+	REMOTE_PROC_AUTH_POLKIT = 70,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -935,6 +942,7 @@ extern  bool_t xdr_remote_auth_sasl_star
 extern  bool_t xdr_remote_auth_sasl_start_ret (XDR *, remote_auth_sasl_start_ret*);
 extern  bool_t xdr_remote_auth_sasl_step_args (XDR *, remote_auth_sasl_step_args*);
 extern  bool_t xdr_remote_auth_sasl_step_ret (XDR *, remote_auth_sasl_step_ret*);
+extern  bool_t xdr_remote_auth_polkit_ret (XDR *, remote_auth_polkit_ret*);
 extern  bool_t xdr_remote_procedure (XDR *, remote_procedure*);
 extern  bool_t xdr_remote_message_direction (XDR *, remote_message_direction*);
 extern  bool_t xdr_remote_message_status (XDR *, remote_message_status*);
@@ -1054,6 +1062,7 @@ extern bool_t xdr_remote_auth_sasl_start
 extern bool_t xdr_remote_auth_sasl_start_ret ();
 extern bool_t xdr_remote_auth_sasl_step_args ();
 extern bool_t xdr_remote_auth_sasl_step_ret ();
+extern bool_t xdr_remote_auth_polkit_ret ();
 extern bool_t xdr_remote_procedure ();
 extern bool_t xdr_remote_message_direction ();
 extern bool_t xdr_remote_message_status ();
diff -r 40e7c976f974 qemud/remote_protocol.x
--- a/qemud/remote_protocol.x	Thu Nov 29 09:51:32 2007 -0500
+++ b/qemud/remote_protocol.x	Thu Nov 29 10:02:52 2007 -0500
@@ -132,7 +132,8 @@ struct remote_error {
 /* Authentication types available thus far.... */
 enum remote_auth_type {
     REMOTE_AUTH_NONE = 0,
-    REMOTE_AUTH_SASL = 1
+    REMOTE_AUTH_SASL = 1,
+    REMOTE_AUTH_POLKIT = 2
 };
 
 
@@ -654,6 +655,10 @@ struct remote_auth_sasl_step_ret {
     int complete;
     int nil;
     char data<REMOTE_AUTH_SASL_DATA_MAX>;
+};
+
+struct remote_auth_polkit_ret {
+    int complete;
 };
 
 /*----- Protocol. -----*/
@@ -731,7 +736,8 @@ enum remote_procedure {
     REMOTE_PROC_AUTH_LIST = 66,
     REMOTE_PROC_AUTH_SASL_INIT = 67,
     REMOTE_PROC_AUTH_SASL_START = 68,
-    REMOTE_PROC_AUTH_SASL_STEP = 69
+    REMOTE_PROC_AUTH_SASL_STEP = 69,
+    REMOTE_PROC_AUTH_POLKIT = 70
 };
 
 /* Custom RPC structure. */
diff -r 40e7c976f974 src/remote_internal.c
--- a/src/remote_internal.c	Thu Nov 29 09:51:32 2007 -0500
+++ b/src/remote_internal.c	Thu Nov 29 10:02:52 2007 -0500
@@ -115,6 +115,9 @@ static int remoteAuthenticate (virConnec
 #if HAVE_SASL
 static int remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open);
 #endif
+#if HAVE_POLKIT
+static int remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open);
+#endif /* HAVE_POLKIT */
 static void error (virConnectPtr conn, virErrorNumber code, const char *info);
 static void server_error (virConnectPtr conn, remote_error *err);
 static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
@@ -2854,6 +2857,15 @@ remoteAuthenticate (virConnectPtr conn, 
         break;
 #endif
 
+#if HAVE_POLKIT
+    case REMOTE_AUTH_POLKIT:
+        if (remoteAuthPolkit(conn, priv, in_open) < 0) {
+            free(ret.types.types_val);
+            return -1;
+        }
+        break;
+#endif
+
     case REMOTE_AUTH_NONE:
         /* Nothing todo, hurrah ! */
         break;
@@ -3443,6 +3455,29 @@ really_write_sasl (virConnectPtr conn, s
     return really_write_buf(conn, priv, in_open, output, outputlen);
 }
 #endif
+
+
+#if HAVE_POLKIT
+/* Perform the PolicyKit authentication process
+ */
+static int
+remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open)
+{
+    remote_auth_polkit_ret ret;
+
+    remoteDebug(priv, "Client initialize PolicyKit authentication");
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, in_open, REMOTE_PROC_AUTH_POLKIT,
+              (xdrproc_t) xdr_void, (char *)NULL,
+              (xdrproc_t) xdr_remote_auth_polkit_ret, (char *) &ret) != 0) {
+        return -1; /* virError already set by call */
+    }
+
+    remoteDebug(priv, "PolicyKit authentication complete");
+    return 0;
+}
+#endif /* HAVE_POLKIT */
 
 static int
 really_write (virConnectPtr conn, struct private_data *priv,

-- 
|=- 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  -=| 




More information about the libvir-list mailing list