From 886f43ad781ca58b8f87010c1f7d94fa5d9bbc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Mon, 18 May 2015 12:42:07 +0200 Subject: [PATCH] qemu: wire up virDomainSetUserPassword Base-64 encode the password and pass it to the guest agent via the 'guest-set-user-password' command. https://bugzilla.redhat.com/show_bug.cgi?id=1174177 --- src/qemu/qemu_agent.c | 39 ++++++++++++++++++++++++++++++ src/qemu/qemu_agent.h | 4 +++ src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index b57a3df65a..043695b3ac 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -42,6 +42,7 @@ #include "virtime.h" #include "virobject.h" #include "virstring.h" +#include "base64.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -2118,3 +2119,41 @@ qemuAgentGetInterfaces(qemuAgentPtr mon, goto cleanup; } + + +int +qemuAgentSetUserPassword(qemuAgentPtr mon, + const char *user, + const char *password, + bool crypted) +{ + int ret = -1; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + char *password64 = NULL; + + base64_encode_alloc(password, strlen(password), &password64); + if (!password64) { + virReportOOMError(); + goto cleanup; + } + + if (!(cmd = qemuAgentMakeCommand("guest-set-user-password", + "b:crypted", crypted, + "s:username", user, + "s:password", password64, + NULL))) + goto cleanup; + + if (qemuAgentCommand(mon, cmd, &reply, true, + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + VIR_FREE(password64); + return ret; +} diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 988228bd23..7cbf8ebb5e 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -114,4 +114,8 @@ int qemuAgentSetTime(qemuAgentPtr mon, int qemuAgentGetInterfaces(qemuAgentPtr mon, virDomainInterfacePtr **ifaces); +int qemuAgentSetUserPassword(qemuAgentPtr mon, + const char *user, + const char *password, + bool crypted); #endif /* __QEMU_AGENT_H__ */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b91b78e027..aa0acdef00 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20098,6 +20098,60 @@ qemuGetDHCPInterfaces(virDomainPtr dom, goto cleanup; } + +static int +qemuDomainSetUserPassword(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; + int ret = -1; + int rv; + + virCheckFlags(VIR_DOMAIN_PASSWORD_ENCRYPTED, -1); + + if (!(vm = qemuDomObjFromDomain(dom))) + return ret; + + if (virDomainSetUserPasswordEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + priv = vm->privateData; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + if (!qemuDomainAgentAvailable(vm, true)) + goto endjob; + + qemuDomainObjEnterAgent(vm); + rv = qemuAgentSetUserPassword(priv->agent, user, password, + flags & VIR_DOMAIN_PASSWORD_ENCRYPTED); + qemuDomainObjExitAgent(vm); + + if (rv < 0) + goto endjob; + + ret = 0; + + endjob: + qemuDomainObjEndJob(driver, vm); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + static virHypervisorDriver qemuHypervisorDriver = { .name = QEMU_DRIVER_NAME, .connectOpen = qemuConnectOpen, /* 0.2.0 */ @@ -20304,6 +20358,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .nodeAllocPages = qemuNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = qemuDomainGetFSInfo, /* 1.2.11 */ .domainInterfaceAddresses = qemuDomainInterfaceAddresses, /* 1.2.14 */ + .domainSetUserPassword = qemuDomainSetUserPassword, /* 1.2.16 */ };