mirror of
https://github.com/libvirt/libvirt.git
synced 2025-01-08 07:03:19 -06:00
virsh: Add support for text based polkit authentication
https://bugzilla.redhat.com/show_bug.cgi?id=872166 When the login session doesn't have an ssh -X type display agent in order for libvirtd to run the polkit session authentication, attempts to run 'virsh -c qemu:///system list' from an unauthorized user (or one that isn't part of the libvirt /etc/group) will fail with the following error from libvirtd: error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage' In order to handle the local authentication, we will use the new virPolkitAgentCreate API in order to create a text based authentication agent for our non readonly session to authenticate with. The new code will execute in a loop allowing 5 failures to authenticate before failing out. With this patch in place, the following occurs: $ virsh -c qemu:///system list ==== AUTHENTICATING FOR org.libvirt.unix.manage === System policy prevents management of local virtualized systems Authenticating as: Some User (SUser) Password: ==== AUTHENTICATION COMPLETE === Id Name State ---------------------------------------------------- 1 somedomain running $
This commit is contained in:
parent
6fb96a7f8b
commit
ea48397b01
@ -143,6 +143,8 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly)
|
||||
int interval = 5; /* Default */
|
||||
int count = 6; /* Default */
|
||||
bool keepalive_forced = false;
|
||||
virPolkitAgentPtr pkagent = NULL;
|
||||
int authfail = 0;
|
||||
|
||||
if (ctl->keepalive_interval >= 0) {
|
||||
interval = ctl->keepalive_interval;
|
||||
@ -153,10 +155,35 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly)
|
||||
keepalive_forced = true;
|
||||
}
|
||||
|
||||
c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
|
||||
readonly ? VIR_CONNECT_RO : 0);
|
||||
do {
|
||||
virErrorPtr err;
|
||||
|
||||
if ((c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
|
||||
readonly ? VIR_CONNECT_RO : 0)))
|
||||
break;
|
||||
|
||||
if (readonly)
|
||||
goto cleanup;
|
||||
|
||||
err = virGetLastError();
|
||||
if (err && err->domain == VIR_FROM_POLKIT &&
|
||||
err->code == VIR_ERR_AUTH_UNAVAILABLE) {
|
||||
if (!(pkagent = virPolkitAgentCreate()))
|
||||
goto cleanup;
|
||||
} else if (err && err->domain == VIR_FROM_POLKIT &&
|
||||
err->code == VIR_ERR_AUTH_FAILED) {
|
||||
authfail++;
|
||||
} else {
|
||||
goto cleanup;
|
||||
}
|
||||
virResetLastError();
|
||||
/* Failure to authenticate 5 times should be enough.
|
||||
* No sense prolonging the agony.
|
||||
*/
|
||||
} while (authfail < 5);
|
||||
|
||||
if (!c)
|
||||
return NULL;
|
||||
goto cleanup;
|
||||
|
||||
if (interval > 0 &&
|
||||
virConnectSetKeepAlive(c, interval, count) != 0) {
|
||||
@ -165,12 +192,15 @@ virshConnect(vshControl *ctl, const char *uri, bool readonly)
|
||||
_("Cannot setup keepalive on connection "
|
||||
"as requested, disconnecting"));
|
||||
virConnectClose(c);
|
||||
return NULL;
|
||||
c = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
vshDebug(ctl, VSH_ERR_INFO, "%s",
|
||||
_("Failed to setup keepalive on connection\n"));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
virPolkitAgentDestroy(pkagent);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
# include "internal.h"
|
||||
# include "virerror.h"
|
||||
# include "virthread.h"
|
||||
# include "virpolkit.h"
|
||||
# include "vsh.h"
|
||||
|
||||
# define VIRSH_PROMPT_RW "virsh # "
|
||||
|
Loading…
Reference in New Issue
Block a user