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