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

Daniel P. Berrange berrange at redhat.com
Fri Nov 30 22:34:41 UTC 2007


On Thu, Nov 29, 2007 at 05:18:41PM +0000, Daniel P. Berrange wrote:
> 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.

Rebased to latest CVS. Added RPM dep on PolicyKit stuff, dependant on being
on Fedora 8 or later.

diff -r ca9413d4d890 configure.in
--- a/configure.in	Fri Nov 30 15:15:26 2007 -0500
+++ b/configure.in	Fri Nov 30 15:15:51 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 C compiler.
 AC_PROG_CC
@@ -395,6 +396,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,
@@ -634,6 +654,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 ca9413d4d890 libvirt.spec.in
--- a/libvirt.spec.in	Fri Nov 30 15:15:26 2007 -0500
+++ b/libvirt.spec.in	Fri Nov 30 15:15:51 2007 -0500
@@ -1,4 +1,10 @@
 # -*- rpm-spec -*-
+
+%if %{fedora} >= 8
+%define with_polkit 1
+%else
+%define with_polkit 0
+%endif
 
 Summary: Library providing a simple API virtualization
 Name: libvirt
@@ -20,6 +26,9 @@ Requires: cyrus-sasl
 # Not technically required, but makes 'out-of-box' config
 # work correctly & doesn't have onerous dependancies
 Requires: cyrus-sasl-md5
+%if %{with_polkit}
+Requires: PolicyKit >= 0.6
+%endif
 BuildRequires: xen-devel
 BuildRequires: libxml2-devel
 BuildRequires: readline-devel
@@ -31,6 +40,9 @@ BuildRequires: bridge-utils
 BuildRequires: bridge-utils
 BuildRequires: qemu
 BuildRequires: cyrus-sasl-devel
+%if %{with_polkit}
+BuildRequires: PolicyKit-devel >= 0.6
+%endif
 Obsoletes: libvir
 ExclusiveArch: i386 x86_64 ia64
 
@@ -143,6 +155,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 ca9413d4d890 qemud/Makefile.am
--- a/qemud/Makefile.am	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/Makefile.am	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/internal.h
--- a/qemud/internal.h	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/internal.h	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/libvirtd.conf
--- a/qemud/libvirtd.conf	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/libvirtd.conf	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/libvirtd.policy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qemud/libvirtd.policy	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/qemud.c
--- a/qemud/qemud.c	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/qemud.c	Fri Nov 30 15:15:51 2007 -0500
@@ -77,8 +77,13 @@ static int unix_sock_rw_mask = 0700; /* 
 static int unix_sock_rw_mask = 0700; /* Allow user only */
 static int unix_sock_ro_mask = 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 /* HAVE_POLKIT */
 #if HAVE_SASL
 static int auth_tcp = REMOTE_AUTH_SASL;
 #else
@@ -761,6 +766,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;
@@ -828,6 +848,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;
@@ -1783,6 +1807,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;
@@ -1818,6 +1846,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_mask = 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 ca9413d4d890 qemud/remote.c
--- a/qemud/remote.c	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote.c	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_dispatch_localvars.h
--- a/qemud/remote_dispatch_localvars.h	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_dispatch_localvars.h	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_dispatch_proc_switch.h
--- a/qemud/remote_dispatch_proc_switch.h	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_dispatch_proc_switch.h	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_dispatch_prototypes.h
--- a/qemud/remote_dispatch_prototypes.h	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_dispatch_prototypes.h	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_protocol.c
--- a/qemud/remote_protocol.c	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_protocol.c	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_protocol.h
--- a/qemud/remote_protocol.h	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_protocol.h	Fri Nov 30 15:15:51 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 ca9413d4d890 qemud/remote_protocol.x
--- a/qemud/remote_protocol.x	Fri Nov 30 15:15:26 2007 -0500
+++ b/qemud/remote_protocol.x	Fri Nov 30 15:15:51 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 ca9413d4d890 src/remote_internal.c
--- a/src/remote_internal.c	Fri Nov 30 15:15:26 2007 -0500
+++ b/src/remote_internal.c	Fri Nov 30 15:15:51 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,


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




More information about the libvir-list mailing list