mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
Don't do polkit auth as root
This commit is contained in:
parent
62ee5d5711
commit
d4a6fe9f99
@ -1,3 +1,9 @@
|
|||||||
|
Fri Apr 4 11:00:08 EDT 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/libvirt.c: Don't run polkit-auth if running as root
|
||||||
|
* qemud/qemud.c, qemud/remote.c, qemud/internal.h: Don't
|
||||||
|
ask client for polkit auth if they are running as root
|
||||||
|
|
||||||
Fri Apr 4 13:19:08 CEST 2008 Daniel Veillard <veillard@redhat.com>
|
Fri Apr 4 13:19:08 CEST 2008 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* src/virsh.c: patch from Shigeki Sakamoto adding message on vcpupin
|
* src/virsh.c: patch from Shigeki Sakamoto adding message on vcpupin
|
||||||
|
@ -179,6 +179,9 @@ void qemudLog(int priority, const char *fmt, ...)
|
|||||||
void remoteDispatchClientRequest (struct qemud_server *server,
|
void remoteDispatchClientRequest (struct qemud_server *server,
|
||||||
struct qemud_client *client);
|
struct qemud_client *client);
|
||||||
|
|
||||||
|
#if HAVE_POLKIT
|
||||||
|
int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1040,6 +1040,28 @@ remoteCheckAccess (struct qemud_client *client)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_POLKIT
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) {
|
static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) {
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
@ -1075,6 +1097,26 @@ static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket
|
|||||||
memcpy (&client->addr, &addr, sizeof addr);
|
memcpy (&client->addr, &addr, sizeof addr);
|
||||||
client->addrlen = addrlen;
|
client->addrlen = addrlen;
|
||||||
|
|
||||||
|
#if HAVE_POLKIT
|
||||||
|
/* 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 (client->auth == REMOTE_AUTH_POLKIT) {
|
||||||
|
uid_t uid;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (qemudGetSocketIdentity(client->fd, &uid, &pid) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Cient is running as root, so disable auth */
|
||||||
|
if (uid == 0) {
|
||||||
|
qemudLog(QEMUD_INFO, _("Turn off polkit auth for privileged client %d"), pid);
|
||||||
|
client->auth = REMOTE_AUTH_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (client->type != QEMUD_SOCK_TYPE_TLS) {
|
if (client->type != QEMUD_SOCK_TYPE_TLS) {
|
||||||
client->mode = QEMUD_MODE_RX_HEADER;
|
client->mode = QEMUD_MODE_RX_HEADER;
|
||||||
client->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
|
client->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
|
||||||
|
180
qemud/remote.c
180
qemud/remote.c
@ -2570,27 +2570,6 @@ remoteDispatchAuthSaslStep (struct qemud_server *server ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
#if HAVE_POLKIT
|
#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
|
static int
|
||||||
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||||
struct qemud_client *client,
|
struct qemud_client *client,
|
||||||
@ -2600,6 +2579,15 @@ remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
|||||||
{
|
{
|
||||||
pid_t callerPid;
|
pid_t callerPid;
|
||||||
uid_t callerUid;
|
uid_t callerUid;
|
||||||
|
PolKitCaller *pkcaller = NULL;
|
||||||
|
PolKitAction *pkaction = NULL;
|
||||||
|
PolKitContext *pkcontext = NULL;
|
||||||
|
PolKitError *pkerr = NULL;
|
||||||
|
PolKitResult pkresult;
|
||||||
|
DBusError err;
|
||||||
|
const char *action = client->readonly ?
|
||||||
|
"org.libvirt.unix.monitor" :
|
||||||
|
"org.libvirt.unix.manage";
|
||||||
|
|
||||||
REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
|
REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
|
||||||
if (client->auth != REMOTE_AUTH_POLKIT) {
|
if (client->auth != REMOTE_AUTH_POLKIT) {
|
||||||
@ -2615,98 +2603,78 @@ remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only do policy checks for non-root - allow root user
|
qemudLog(QEMUD_INFO, _("Checking PID %d running as %d"),
|
||||||
through with no checks, as a fail-safe - root can easily
|
callerPid, callerUid);
|
||||||
change policykit policy anyway, so its pointless trying
|
dbus_error_init(&err);
|
||||||
to restrict root */
|
if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
|
||||||
if (callerUid == 0) {
|
callerPid, &err))) {
|
||||||
qemudLog(QEMUD_INFO, _("Allowing PID %d running as root"), callerPid);
|
qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
|
||||||
ret->complete = 1;
|
err.message);
|
||||||
client->auth = REMOTE_AUTH_NONE;
|
dbus_error_free(&err);
|
||||||
} else {
|
remoteDispatchFailAuth(client, req);
|
||||||
PolKitCaller *pkcaller = NULL;
|
return -2;
|
||||||
PolKitAction *pkaction = NULL;
|
}
|
||||||
PolKitContext *pkcontext = NULL;
|
|
||||||
PolKitError *pkerr = NULL;
|
|
||||||
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"),
|
if (!(pkaction = polkit_action_new())) {
|
||||||
callerPid, callerUid);
|
qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
|
||||||
dbus_error_init(&err);
|
strerror(errno));
|
||||||
if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
|
polkit_caller_unref(pkcaller);
|
||||||
callerPid, &err))) {
|
remoteDispatchFailAuth(client, req);
|
||||||
qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
|
return -2;
|
||||||
err.message);
|
}
|
||||||
dbus_error_free(&err);
|
polkit_action_set_action_id(pkaction, action);
|
||||||
remoteDispatchFailAuth(client, req);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pkaction = polkit_action_new())) {
|
if (!(pkcontext = polkit_context_new()) ||
|
||||||
qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
|
!polkit_context_init(pkcontext, &pkerr)) {
|
||||||
strerror(errno));
|
qemudLog(QEMUD_ERR, _("Failed to create polkit context %s\n"),
|
||||||
polkit_caller_unref(pkcaller);
|
(pkerr ? polkit_error_get_error_message(pkerr)
|
||||||
remoteDispatchFailAuth(client, req);
|
: strerror(errno)));
|
||||||
return -2;
|
if (pkerr)
|
||||||
}
|
polkit_error_free(pkerr);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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)) {
|
|
||||||
qemudLog(QEMUD_ERR,
|
|
||||||
_("Policy kit failed to check authorization %d %s"),
|
|
||||||
polkit_error_get_error_code(pkerr),
|
|
||||||
polkit_error_get_error_message(pkerr));
|
|
||||||
remoteDispatchFailAuth(client, req);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
pkresult = polkit_context_can_caller_do_action(pkcontext,
|
|
||||||
pkaction,
|
|
||||||
pkcaller);
|
|
||||||
#endif
|
|
||||||
polkit_context_unref(pkcontext);
|
|
||||||
polkit_caller_unref(pkcaller);
|
polkit_caller_unref(pkcaller);
|
||||||
polkit_action_unref(pkaction);
|
polkit_action_unref(pkaction);
|
||||||
if (pkresult != POLKIT_RESULT_YES) {
|
dbus_error_free(&err);
|
||||||
qemudLog(QEMUD_ERR,
|
remoteDispatchFailAuth(client, req);
|
||||||
_("Policy kit denied action %s from pid %d, uid %d,"
|
return -2;
|
||||||
" result: %s\n"),
|
}
|
||||||
action, callerPid, callerUid,
|
|
||||||
polkit_result_to_string_representation(pkresult));
|
#if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
|
||||||
remoteDispatchFailAuth(client, req);
|
pkresult = polkit_context_is_caller_authorized(pkcontext,
|
||||||
return -2;
|
pkaction,
|
||||||
}
|
pkcaller,
|
||||||
qemudLog(QEMUD_INFO,
|
0,
|
||||||
_("Policy allowed action %s from pid %d, uid %d, result %s"),
|
&pkerr);
|
||||||
|
if (pkerr && polkit_error_is_set(pkerr)) {
|
||||||
|
qemudLog(QEMUD_ERR,
|
||||||
|
_("Policy kit failed to check authorization %d %s"),
|
||||||
|
polkit_error_get_error_code(pkerr),
|
||||||
|
polkit_error_get_error_message(pkerr));
|
||||||
|
remoteDispatchFailAuth(client, req);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
#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) {
|
||||||
|
qemudLog(QEMUD_ERR,
|
||||||
|
_("Policy kit denied action %s from pid %d, uid %d,"
|
||||||
|
" result: %s\n"),
|
||||||
action, callerPid, callerUid,
|
action, callerPid, callerUid,
|
||||||
polkit_result_to_string_representation(pkresult));
|
polkit_result_to_string_representation(pkresult));
|
||||||
ret->complete = 1;
|
remoteDispatchFailAuth(client, req);
|
||||||
client->auth = REMOTE_AUTH_NONE;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -116,17 +116,23 @@ static int virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
switch (cred[i].type) {
|
switch (cred[i].type) {
|
||||||
#if defined(POLKIT_AUTH)
|
|
||||||
case VIR_CRED_EXTERNAL: {
|
case VIR_CRED_EXTERNAL: {
|
||||||
if (STRNEQ(cred[i].challenge, "PolicyKit"))
|
if (STRNEQ(cred[i].challenge, "PolicyKit"))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#if defined(POLKIT_AUTH)
|
||||||
if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
|
if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Ignore & carry on. Although we can't auth
|
||||||
|
* directly, the user may have authenticated
|
||||||
|
* themselves already outside context of libvirt
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case VIR_CRED_USERNAME:
|
case VIR_CRED_USERNAME:
|
||||||
case VIR_CRED_AUTHNAME:
|
case VIR_CRED_AUTHNAME:
|
||||||
case VIR_CRED_ECHOPROMPT:
|
case VIR_CRED_ECHOPROMPT:
|
||||||
@ -186,9 +192,7 @@ static int virConnectCredTypeDefault[] = {
|
|||||||
VIR_CRED_REALM,
|
VIR_CRED_REALM,
|
||||||
VIR_CRED_PASSPHRASE,
|
VIR_CRED_PASSPHRASE,
|
||||||
VIR_CRED_NOECHOPROMPT,
|
VIR_CRED_NOECHOPROMPT,
|
||||||
#if defined(POLKIT_AUTH)
|
|
||||||
VIR_CRED_EXTERNAL,
|
VIR_CRED_EXTERNAL,
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static virConnectAuth virConnectAuthDefault = {
|
static virConnectAuth virConnectAuthDefault = {
|
||||||
|
Loading…
Reference in New Issue
Block a user