mirror of https://gitee.com/openkylin/libvirt.git
Convert remote daemon & acl code to use polkit API
Convert the remote daemon auth check and the access control code to use the common polkit API for checking auth. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
64a5dc1b6a
commit
c754257347
|
@ -141,7 +141,7 @@ libvirtd_SOURCES = $(DAEMON_SOURCES)
|
||||||
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
|
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
|
||||||
libvirtd_CFLAGS = \
|
libvirtd_CFLAGS = \
|
||||||
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
|
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
|
||||||
$(XDR_CFLAGS) $(POLKIT_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \
|
$(XDR_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \
|
||||||
$(WARN_CFLAGS) $(PIE_CFLAGS) \
|
$(WARN_CFLAGS) $(PIE_CFLAGS) \
|
||||||
$(COVERAGE_CFLAGS) \
|
$(COVERAGE_CFLAGS) \
|
||||||
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\""
|
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\""
|
||||||
|
@ -158,7 +158,6 @@ libvirtd_LDADD = \
|
||||||
$(GNUTLS_LIBS) \
|
$(GNUTLS_LIBS) \
|
||||||
$(SASL_LIBS) \
|
$(SASL_LIBS) \
|
||||||
$(DBUS_LIBS) \
|
$(DBUS_LIBS) \
|
||||||
$(POLKIT_LIBS) \
|
|
||||||
$(LIBNL_LIBS)
|
$(LIBNL_LIBS)
|
||||||
|
|
||||||
if WITH_DTRACE_PROBES
|
if WITH_DTRACE_PROBES
|
||||||
|
|
235
daemon/remote.c
235
daemon/remote.c
|
@ -24,11 +24,6 @@
|
||||||
|
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
|
|
||||||
#if WITH_POLKIT0
|
|
||||||
# include <polkit/polkit.h>
|
|
||||||
# include <polkit-dbus/polkit-dbus.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "libvirtd.h"
|
#include "libvirtd.h"
|
||||||
#include "libvirt_internal.h"
|
#include "libvirt_internal.h"
|
||||||
|
@ -55,6 +50,7 @@
|
||||||
#include "virprobe.h"
|
#include "virprobe.h"
|
||||||
#include "viraccessapicheck.h"
|
#include "viraccessapicheck.h"
|
||||||
#include "viraccessapicheckqemu.h"
|
#include "viraccessapicheckqemu.h"
|
||||||
|
#include "virpolkit.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_RPC
|
#define VIR_FROM_THIS VIR_FROM_RPC
|
||||||
|
|
||||||
|
@ -3230,7 +3226,6 @@ remoteDispatchAuthSaslStep(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if WITH_POLKIT1
|
|
||||||
static int
|
static int
|
||||||
remoteDispatchAuthPolkit(virNetServerPtr server,
|
remoteDispatchAuthPolkit(virNetServerPtr server,
|
||||||
virNetServerClientPtr client,
|
virNetServerClientPtr client,
|
||||||
|
@ -3243,26 +3238,16 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
|
||||||
uid_t callerUid = -1;
|
uid_t callerUid = -1;
|
||||||
unsigned long long timestamp;
|
unsigned long long timestamp;
|
||||||
const char *action;
|
const char *action;
|
||||||
int status = -1;
|
|
||||||
char *ident = NULL;
|
char *ident = NULL;
|
||||||
bool authdismissed = 0;
|
|
||||||
char *pkout = NULL;
|
|
||||||
struct daemonClientPrivate *priv =
|
struct daemonClientPrivate *priv =
|
||||||
virNetServerClientGetPrivateData(client);
|
virNetServerClientGetPrivateData(client);
|
||||||
virCommandPtr cmd = NULL;
|
int rv;
|
||||||
# ifndef PKCHECK_SUPPORTS_UID
|
|
||||||
static bool polkitInsecureWarned;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
virMutexLock(&priv->lock);
|
virMutexLock(&priv->lock);
|
||||||
action = virNetServerClientGetReadonly(client) ?
|
action = virNetServerClientGetReadonly(client) ?
|
||||||
"org.libvirt.unix.monitor" :
|
"org.libvirt.unix.monitor" :
|
||||||
"org.libvirt.unix.manage";
|
"org.libvirt.unix.manage";
|
||||||
|
|
||||||
cmd = virCommandNewArgList(PKCHECK_PATH, "--action-id", action, NULL);
|
|
||||||
virCommandSetOutputBuffer(cmd, &pkout);
|
|
||||||
virCommandSetErrorBuffer(cmd, &pkout);
|
|
||||||
|
|
||||||
VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
|
VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
|
||||||
if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
|
if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
|
||||||
VIR_ERROR(_("client tried invalid PolicyKit init request"));
|
VIR_ERROR(_("client tried invalid PolicyKit init request"));
|
||||||
|
@ -3283,38 +3268,17 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
|
||||||
VIR_INFO("Checking PID %lld running as %d",
|
VIR_INFO("Checking PID %lld running as %d",
|
||||||
(long long) callerPid, callerUid);
|
(long long) callerPid, callerUid);
|
||||||
|
|
||||||
virCommandAddArg(cmd, "--process");
|
rv = virPolkitCheckAuth(action,
|
||||||
|
callerPid,
|
||||||
# ifdef PKCHECK_SUPPORTS_UID
|
timestamp,
|
||||||
virCommandAddArgFormat(cmd, "%lld,%llu,%lu",
|
callerUid,
|
||||||
(long long) callerPid,
|
NULL,
|
||||||
timestamp,
|
true);
|
||||||
(unsigned long) callerUid);
|
if (rv == -1)
|
||||||
# else
|
|
||||||
if (!polkitInsecureWarned) {
|
|
||||||
VIR_WARN("No support for caller UID with pkcheck. "
|
|
||||||
"This deployment is known to be insecure.");
|
|
||||||
polkitInsecureWarned = true;
|
|
||||||
}
|
|
||||||
virCommandAddArgFormat(cmd, "%lld,%llu", (long long) callerPid, timestamp);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
virCommandAddArg(cmd, "--allow-user-interaction");
|
|
||||||
|
|
||||||
if (virAsprintf(&ident, "pid:%lld,uid:%d",
|
|
||||||
(long long) callerPid, callerUid) < 0)
|
|
||||||
goto authfail;
|
goto authfail;
|
||||||
|
else if (rv == -2)
|
||||||
if (virCommandRun(cmd, &status) < 0)
|
|
||||||
goto authfail;
|
|
||||||
|
|
||||||
authdismissed = (pkout && strstr(pkout, "dismissed=true"));
|
|
||||||
if (status != 0) {
|
|
||||||
VIR_ERROR(_("Policy kit denied action %s from pid %lld, uid %d "
|
|
||||||
"with status %d"),
|
|
||||||
action, (long long) callerPid, callerUid, status);
|
|
||||||
goto authdeny;
|
goto authdeny;
|
||||||
}
|
|
||||||
PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
|
PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
|
||||||
"client=%p auth=%d identity=%s",
|
"client=%p auth=%d identity=%s",
|
||||||
client, REMOTE_AUTH_POLKIT, ident);
|
client, REMOTE_AUTH_POLKIT, ident);
|
||||||
|
@ -3325,27 +3289,10 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
|
||||||
virNetServerClientSetAuth(client, 0);
|
virNetServerClientSetAuth(client, 0);
|
||||||
virNetServerTrackCompletedAuth(server);
|
virNetServerTrackCompletedAuth(server);
|
||||||
virMutexUnlock(&priv->lock);
|
virMutexUnlock(&priv->lock);
|
||||||
virCommandFree(cmd);
|
|
||||||
VIR_FREE(pkout);
|
|
||||||
VIR_FREE(ident);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
virCommandFree(cmd);
|
|
||||||
VIR_FREE(ident);
|
|
||||||
virResetLastError();
|
|
||||||
|
|
||||||
if (authdismissed) {
|
|
||||||
virReportError(VIR_ERR_AUTH_CANCELLED, "%s",
|
|
||||||
_("authentication cancelled by user"));
|
|
||||||
} else if (pkout && *pkout) {
|
|
||||||
virReportError(VIR_ERR_AUTH_FAILED, _("polkit: %s"), pkout);
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_AUTH_FAILED, "%s", _("authentication failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_FREE(pkout);
|
|
||||||
virNetMessageSaveError(rerr);
|
virNetMessageSaveError(rerr);
|
||||||
virMutexUnlock(&priv->lock);
|
virMutexUnlock(&priv->lock);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -3362,166 +3309,6 @@ remoteDispatchAuthPolkit(virNetServerPtr server,
|
||||||
client, REMOTE_AUTH_POLKIT, ident);
|
client, REMOTE_AUTH_POLKIT, ident);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#elif WITH_POLKIT0
|
|
||||||
static int
|
|
||||||
remoteDispatchAuthPolkit(virNetServerPtr server,
|
|
||||||
virNetServerClientPtr client,
|
|
||||||
virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
|
||||||
virNetMessageErrorPtr rerr,
|
|
||||||
remote_auth_polkit_ret *ret)
|
|
||||||
{
|
|
||||||
pid_t callerPid;
|
|
||||||
gid_t callerGid;
|
|
||||||
uid_t callerUid;
|
|
||||||
PolKitCaller *pkcaller = NULL;
|
|
||||||
PolKitAction *pkaction = NULL;
|
|
||||||
PolKitContext *pkcontext = NULL;
|
|
||||||
PolKitError *pkerr = NULL;
|
|
||||||
PolKitResult pkresult;
|
|
||||||
DBusError err;
|
|
||||||
const char *action;
|
|
||||||
char *ident = NULL;
|
|
||||||
struct daemonClientPrivate *priv =
|
|
||||||
virNetServerClientGetPrivateData(client);
|
|
||||||
DBusConnection *sysbus;
|
|
||||||
unsigned long long timestamp;
|
|
||||||
|
|
||||||
virMutexLock(&priv->lock);
|
|
||||||
|
|
||||||
action = virNetServerClientGetReadonly(client) ?
|
|
||||||
"org.libvirt.unix.monitor" :
|
|
||||||
"org.libvirt.unix.manage";
|
|
||||||
|
|
||||||
VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
|
|
||||||
if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
|
|
||||||
VIR_ERROR(_("client tried invalid PolicyKit init request"));
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virNetServerClientGetUNIXIdentity(client, &callerUid, &callerGid,
|
|
||||||
&callerPid, ×tamp) < 0) {
|
|
||||||
VIR_ERROR(_("cannot get peer socket identity"));
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virAsprintf(&ident, "pid:%lld,uid:%d",
|
|
||||||
(long long) callerPid, callerUid) < 0)
|
|
||||||
goto authfail;
|
|
||||||
|
|
||||||
if (!(sysbus = virDBusGetSystemBus()))
|
|
||||||
goto authfail;
|
|
||||||
|
|
||||||
VIR_INFO("Checking PID %lld running as %d",
|
|
||||||
(long long) callerPid, callerUid);
|
|
||||||
dbus_error_init(&err);
|
|
||||||
if (!(pkcaller = polkit_caller_new_from_pid(sysbus,
|
|
||||||
callerPid, &err))) {
|
|
||||||
VIR_ERROR(_("Failed to lookup policy kit caller: %s"), err.message);
|
|
||||||
dbus_error_free(&err);
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pkaction = polkit_action_new())) {
|
|
||||||
char ebuf[1024];
|
|
||||||
VIR_ERROR(_("Failed to create polkit action %s"),
|
|
||||||
virStrerror(errno, ebuf, sizeof(ebuf)));
|
|
||||||
polkit_caller_unref(pkcaller);
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
polkit_action_set_action_id(pkaction, action);
|
|
||||||
|
|
||||||
if (!(pkcontext = polkit_context_new()) ||
|
|
||||||
!polkit_context_init(pkcontext, &pkerr)) {
|
|
||||||
char ebuf[1024];
|
|
||||||
VIR_ERROR(_("Failed to create polkit context %s"),
|
|
||||||
(pkerr ? polkit_error_get_error_message(pkerr)
|
|
||||||
: virStrerror(errno, ebuf, sizeof(ebuf))));
|
|
||||||
if (pkerr)
|
|
||||||
polkit_error_free(pkerr);
|
|
||||||
polkit_caller_unref(pkcaller);
|
|
||||||
polkit_action_unref(pkaction);
|
|
||||||
dbus_error_free(&err);
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
# if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
|
|
||||||
pkresult = polkit_context_is_caller_authorized(pkcontext,
|
|
||||||
pkaction,
|
|
||||||
pkcaller,
|
|
||||||
0,
|
|
||||||
&pkerr);
|
|
||||||
if (pkerr && polkit_error_is_set(pkerr)) {
|
|
||||||
VIR_ERROR(_("Policy kit failed to check authorization %d %s"),
|
|
||||||
polkit_error_get_error_code(pkerr),
|
|
||||||
polkit_error_get_error_message(pkerr));
|
|
||||||
goto authfail;
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
pkresult = polkit_context_can_caller_do_action(pkcontext,
|
|
||||||
pkaction,
|
|
||||||
pkcaller);
|
|
||||||
# endif
|
|
||||||
polkit_context_unref(pkcontext);
|
|
||||||
polkit_caller_unref(pkcaller);
|
|
||||||
polkit_action_unref(pkaction);
|
|
||||||
if (pkresult != POLKIT_RESULT_YES) {
|
|
||||||
VIR_ERROR(_("Policy kit denied action %s from pid %lld, uid %d, result: %s"),
|
|
||||||
action, (long long) callerPid, callerUid,
|
|
||||||
polkit_result_to_string_representation(pkresult));
|
|
||||||
goto authdeny;
|
|
||||||
}
|
|
||||||
PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
|
|
||||||
"client=%p auth=%d identity=%s",
|
|
||||||
client, REMOTE_AUTH_POLKIT, ident);
|
|
||||||
VIR_INFO("Policy allowed action %s from pid %lld, uid %d, result %s",
|
|
||||||
action, (long long) callerPid, callerUid,
|
|
||||||
polkit_result_to_string_representation(pkresult));
|
|
||||||
ret->complete = 1;
|
|
||||||
|
|
||||||
virNetServerClientSetAuth(client, 0);
|
|
||||||
virNetServerTrackCompletedAuth(server);
|
|
||||||
virMutexUnlock(&priv->lock);
|
|
||||||
VIR_FREE(ident);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
VIR_FREE(ident);
|
|
||||||
virResetLastError();
|
|
||||||
virReportError(VIR_ERR_AUTH_FAILED, "%s",
|
|
||||||
_("authentication failed"));
|
|
||||||
virNetMessageSaveError(rerr);
|
|
||||||
virMutexUnlock(&priv->lock);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
authfail:
|
|
||||||
PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
|
|
||||||
"client=%p auth=%d",
|
|
||||||
client, REMOTE_AUTH_POLKIT);
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
authdeny:
|
|
||||||
PROBE(RPC_SERVER_CLIENT_AUTH_DENY,
|
|
||||||
"client=%p auth=%d identity=%s",
|
|
||||||
client, REMOTE_AUTH_POLKIT, ident);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !WITH_POLKIT0 & !HAVE_POLKIT1*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
|
|
||||||
virNetServerClientPtr client ATTRIBUTE_UNUSED,
|
|
||||||
virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
|
||||||
virNetMessageErrorPtr rerr,
|
|
||||||
remote_auth_polkit_ret *ret ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
VIR_ERROR(_("client tried unsupported PolicyKit init request"));
|
|
||||||
virReportError(VIR_ERR_AUTH_FAILED, "%s",
|
|
||||||
_("authentication failed"));
|
|
||||||
virNetMessageSaveError(rerr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* WITH_POLKIT1 */
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
|
|
|
@ -2486,13 +2486,11 @@ libvirt_net_rpc_server_la_CFLAGS = \
|
||||||
$(AVAHI_CFLAGS) \
|
$(AVAHI_CFLAGS) \
|
||||||
$(DBUS_CFLAGS) \
|
$(DBUS_CFLAGS) \
|
||||||
$(XDR_CFLAGS) \
|
$(XDR_CFLAGS) \
|
||||||
$(AM_CFLAGS) \
|
$(AM_CFLAGS)
|
||||||
$(POLKIT_CFLAGS)
|
|
||||||
libvirt_net_rpc_server_la_LDFLAGS = \
|
libvirt_net_rpc_server_la_LDFLAGS = \
|
||||||
$(AM_LDFLAGS) \
|
$(AM_LDFLAGS) \
|
||||||
$(AVAHI_LIBS) \
|
$(AVAHI_LIBS) \
|
||||||
$(DBUS_LIBS) \
|
$(DBUS_LIBS) \
|
||||||
$(POLKIT_LIBS) \
|
|
||||||
$(CYGWIN_EXTRA_LDFLAGS) \
|
$(CYGWIN_EXTRA_LDFLAGS) \
|
||||||
$(MINGW_EXTRA_LDFLAGS)
|
$(MINGW_EXTRA_LDFLAGS)
|
||||||
libvirt_net_rpc_server_la_LIBADD = \
|
libvirt_net_rpc_server_la_LIBADD = \
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
|
#include "virpolkit.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_ACCESS
|
#define VIR_FROM_THIS VIR_FROM_ACCESS
|
||||||
|
@ -71,29 +72,26 @@ virAccessDriverPolkitFormatAction(const char *typename,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static int
|
||||||
virAccessDriverPolkitFormatProcess(const char *actionid)
|
virAccessDriverPolkitGetCaller(const char *actionid,
|
||||||
|
pid_t *pid,
|
||||||
|
unsigned long long *startTime,
|
||||||
|
uid_t *uid)
|
||||||
{
|
{
|
||||||
virIdentityPtr identity = virIdentityGetCurrent();
|
virIdentityPtr identity = virIdentityGetCurrent();
|
||||||
pid_t pid;
|
int ret = -1;
|
||||||
unsigned long long startTime;
|
|
||||||
uid_t uid;
|
|
||||||
char *ret = NULL;
|
|
||||||
#ifndef PKCHECK_SUPPORTS_UID
|
|
||||||
static bool polkitInsecureWarned;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!identity) {
|
if (!identity) {
|
||||||
virAccessError(VIR_ERR_ACCESS_DENIED,
|
virAccessError(VIR_ERR_ACCESS_DENIED,
|
||||||
_("Policy kit denied action %s from <anonymous>"),
|
_("Policy kit denied action %s from <anonymous>"),
|
||||||
actionid);
|
actionid);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
if (virIdentityGetUNIXProcessID(identity, &pid) < 0)
|
if (virIdentityGetUNIXProcessID(identity, pid) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (virIdentityGetUNIXProcessTime(identity, &startTime) < 0)
|
if (virIdentityGetUNIXProcessTime(identity, startTime) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (virIdentityGetUNIXUserID(identity, &uid) < 0)
|
if (virIdentityGetUNIXUserID(identity, uid) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
@ -101,25 +99,14 @@ virAccessDriverPolkitFormatProcess(const char *actionid)
|
||||||
_("No UNIX process ID available"));
|
_("No UNIX process ID available"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!startTime) {
|
|
||||||
virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("No UNIX process start time available"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PKCHECK_SUPPORTS_UID
|
if (virIdentityGetUNIXProcessTime(identity, startTime) < 0)
|
||||||
if (virAsprintf(&ret, "%llu,%llu,%llu",
|
|
||||||
(unsigned long long)pid, startTime, (unsigned long long)uid) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
#else
|
|
||||||
if (!polkitInsecureWarned) {
|
if (virIdentityGetUNIXUserID(identity, uid) < 0)
|
||||||
VIR_WARN("No support for caller UID with pkcheck. This deployment is known to be insecure.");
|
|
||||||
polkitInsecureWarned = true;
|
|
||||||
}
|
|
||||||
if (virAsprintf(&ret, "%llu,%llu",
|
|
||||||
(unsigned long long)pid, startTime) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
#endif
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virObjectUnref(identity);
|
virObjectUnref(identity);
|
||||||
|
@ -134,53 +121,43 @@ virAccessDriverPolkitCheck(virAccessManagerPtr manager ATTRIBUTE_UNUSED,
|
||||||
const char **attrs)
|
const char **attrs)
|
||||||
{
|
{
|
||||||
char *actionid = NULL;
|
char *actionid = NULL;
|
||||||
char *process = NULL;
|
|
||||||
virCommandPtr cmd = NULL;
|
|
||||||
int status;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
pid_t pid;
|
||||||
|
uid_t uid;
|
||||||
|
unsigned long long startTime;
|
||||||
|
int rv;
|
||||||
|
|
||||||
if (!(actionid = virAccessDriverPolkitFormatAction(typename, permname)))
|
if (!(actionid = virAccessDriverPolkitFormatAction(typename, permname)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(process = virAccessDriverPolkitFormatProcess(actionid)))
|
if (virAccessDriverPolkitGetCaller(actionid,
|
||||||
|
&pid,
|
||||||
|
&startTime,
|
||||||
|
&uid) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
VIR_DEBUG("Check action '%s' for process '%s'", actionid, process);
|
VIR_DEBUG("Check action '%s' for process '%d' time %lld uid %d",
|
||||||
|
actionid, pid, startTime, uid);
|
||||||
|
|
||||||
cmd = virCommandNewArgList(PKCHECK_PATH,
|
rv = virPolkitCheckAuth(actionid,
|
||||||
"--action-id", actionid,
|
pid,
|
||||||
"--process", process,
|
startTime,
|
||||||
NULL);
|
uid,
|
||||||
|
attrs,
|
||||||
|
false);
|
||||||
|
|
||||||
while (attrs && attrs[0] && attrs[1]) {
|
if (rv == 0) {
|
||||||
virCommandAddArgList(cmd, "--detail", attrs[0], attrs[1], NULL);
|
|
||||||
attrs += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virCommandRun(cmd, &status) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (status == 0) {
|
|
||||||
ret = 1; /* Allowed */
|
ret = 1; /* Allowed */
|
||||||
} else {
|
} else {
|
||||||
if (status == 1 ||
|
if (rv == -2) {
|
||||||
status == 2 ||
|
|
||||||
status == 3) {
|
|
||||||
ret = 0; /* Denied */
|
ret = 0; /* Denied */
|
||||||
} else {
|
} else {
|
||||||
ret = -1; /* Error */
|
ret = -1; /* Error */
|
||||||
virAccessError(VIR_ERR_ACCESS_DENIED,
|
|
||||||
_("Policy kit denied action %s from %s: "
|
|
||||||
"exit status %d"),
|
|
||||||
actionid, process, status);
|
|
||||||
}
|
}
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virCommandFree(cmd);
|
|
||||||
VIR_FREE(actionid);
|
VIR_FREE(actionid);
|
||||||
VIR_FREE(process);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue