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