mirror of https://gitee.com/openkylin/libvirt.git
Added PolicyKit authentication support
This commit is contained in:
parent
f8f1977826
commit
282342c1c5
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
Wed Dec 5 13:20:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* configure.in: do PolicyKit checks via pkg-config
|
||||
* libvirt.spec.in: Add dep on PolicyKit if Fedora 8 or later
|
||||
* qemud/Makefile.am: Add PolicyKit build flags and default
|
||||
policy file
|
||||
* qemud/libvirtd.conf: Add comment about polkit auth option
|
||||
* qemud/libvirtd.policy: Default policy file
|
||||
* qemud/qemud.c, qemud/remote.c: Implementation of PolicyKit
|
||||
authentication
|
||||
* qemud/remote_protocol.x: Add RPC calls for PolicyKit auth
|
||||
* qemud/remote_dispatch*, qemud/remote_protocol.{c.h}: update
|
||||
for new RPC calls.
|
||||
* src/remote_internal.c: Fetch credentials for PolicyKit and
|
||||
perform client part of auth process
|
||||
|
||||
Wed Dec 5 18:00:00 UTC 2007 Richard W.M. Jones <rjones@redhat.com>
|
||||
|
||||
* src/Makefile.am, tests/Makefile.am: Remove LIBOBJS/LTLIBOBJS
|
||||
|
|
25
configure.in
25
configure.in
|
@ -25,6 +25,7 @@ dnl Required minimum versions of all libs we depend on
|
|||
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
|
||||
|
@ -394,6 +395,25 @@ AC_SUBST(SASL_CFLAGS)
|
|||
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,
|
||||
|
@ -627,6 +647,11 @@ AC_MSG_NOTICE([ avahi: $AVAHI_CFLAGS $AVAHI_LIBS])
|
|||
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([])
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# -*- rpm-spec -*-
|
||||
|
||||
%if %{fedora} >= 8
|
||||
%define with_polkit 1
|
||||
%else
|
||||
%define with_polkit 0
|
||||
%endif
|
||||
|
||||
Summary: Library providing a simple API virtualization
|
||||
Name: libvirt
|
||||
Version: @VERSION@
|
||||
|
@ -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: dnsmasq
|
|||
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
|
||||
|
|
|
@ -30,16 +30,25 @@ libvirtd_SOURCES = \
|
|||
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
|
||||
libvirtd_CFLAGS += $(AVAHI_CFLAGS)
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include <sasl/sasl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLKIT
|
||||
#include <dbus/dbus.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SYSLIMITS_H
|
||||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
|
@ -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, ...)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -77,8 +77,13 @@ static gid_t unix_sock_gid = 0; /* Only root by default */
|
|||
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
|
||||
|
@ -759,6 +764,21 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
|
|||
}
|
||||
#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;
|
||||
|
@ -826,6 +846,10 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
|
|||
sock = sock->next;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLKIT
|
||||
if (server->sysbus)
|
||||
dbus_connection_unref(server->sysbus);
|
||||
#endif
|
||||
free(server);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1780,6 +1804,10 @@ static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, cons
|
|||
#if HAVE_SASL
|
||||
} 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);
|
||||
|
@ -1816,6 +1844,13 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename)
|
|||
|
||||
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)
|
||||
|
|
135
qemud/remote.c
135
qemud/remote.c
|
@ -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 qemud_server *server,
|
|||
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_server *server ATTRIBUTE_UNUSED,
|
|||
#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
|
||||
|
|
|
@ -37,6 +37,7 @@ remote_domain_set_memory_args lv_remote_domain_set_memory_args;
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1308,6 +1308,15 @@ xdr_remote_auth_sasl_step_ret (XDR *xdrs, remote_auth_sasl_step_ret *objp)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@ typedef struct remote_error remote_error;
|
|||
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_start_args (XDR *, remote_auth_sasl_start_ar
|
|||
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_args ();
|
|||
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 ();
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -656,6 +657,10 @@ struct remote_auth_sasl_step_ret {
|
|||
char data<REMOTE_AUTH_SASL_DATA_MAX>;
|
||||
};
|
||||
|
||||
struct remote_auth_polkit_ret {
|
||||
int complete;
|
||||
};
|
||||
|
||||
/*----- Protocol. -----*/
|
||||
|
||||
/* Define the program number, protocol version and procedure numbers here. */
|
||||
|
@ -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. */
|
||||
|
|
|
@ -115,6 +115,9 @@ static int remoteAuthenticate (virConnectPtr conn, struct private_data *priv, in
|
|||
#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, struct private_data *priv, int in_open)
|
|||
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;
|
||||
|
@ -3444,6 +3456,29 @@ really_write_sasl (virConnectPtr conn, struct private_data *priv,
|
|||
}
|
||||
#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,
|
||||
int in_open /* if we are in virConnectOpen */,
|
||||
|
|
Loading…
Reference in New Issue