mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
qemu: add helper for getting guest users
This function fetches the list of logged-in users from the qemu agent and adds them to a list of typed parameters so that they can be used internally in libvirt. Also add some basic tests for the function. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
e8b83b2aac
commit
1c8113f9c8
@ -2240,3 +2240,88 @@ qemuAgentSetUserPassword(qemuAgentPtr mon,
|
|||||||
VIR_FREE(password64);
|
VIR_FREE(password64);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuAgentGetUsers(qemuAgentPtr mon,
|
||||||
|
virTypedParameterPtr *params,
|
||||||
|
int *nparams,
|
||||||
|
int *maxparams)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(virJSONValue) cmd = NULL;
|
||||||
|
VIR_AUTOPTR(virJSONValue) reply = NULL;
|
||||||
|
virJSONValuePtr data = NULL;
|
||||||
|
size_t ndata;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!(cmd = qemuAgentMakeCommand("guest-get-users", NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuAgentCommand(mon, cmd, &reply, true,
|
||||||
|
VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(data = virJSONValueObjectGetArray(reply, "return"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("guest-get-users reply was missing return data"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virJSONValueIsArray(data)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Malformed guest-get-users data array"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndata = virJSONValueArraySize(data);
|
||||||
|
|
||||||
|
if (virTypedParamsAddUInt(params, nparams, maxparams,
|
||||||
|
"user.count", ndata) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < ndata; i++) {
|
||||||
|
virJSONValuePtr entry = virJSONValueArrayGet(data, i);
|
||||||
|
char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
|
||||||
|
const char *strvalue;
|
||||||
|
double logintime;
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("array element missing in guest-get-users return "
|
||||||
|
"value"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(strvalue = virJSONValueObjectGetString(entry, "user"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("'user' missing in reply of guest-get-users"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "user.%zu.name", i);
|
||||||
|
if (virTypedParamsAddString(params, nparams, maxparams,
|
||||||
|
param_name, strvalue) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* 'domain' is only present for windows guests */
|
||||||
|
if ((strvalue = virJSONValueObjectGetString(entry, "domain"))) {
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
||||||
|
"user.%zu.domain", i);
|
||||||
|
if (virTypedParamsAddString(params, nparams, maxparams,
|
||||||
|
param_name, strvalue) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberDouble(entry, "login-time", &logintime) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("'login-time' missing in reply of guest-get-users"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
||||||
|
"user.%zu.login-time", i);
|
||||||
|
if (virTypedParamsAddULLong(params, nparams, maxparams,
|
||||||
|
param_name, logintime * 1000) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ndata;
|
||||||
|
}
|
||||||
|
@ -120,3 +120,8 @@ int qemuAgentSetUserPassword(qemuAgentPtr mon,
|
|||||||
const char *user,
|
const char *user,
|
||||||
const char *password,
|
const char *password,
|
||||||
bool crypted);
|
bool crypted);
|
||||||
|
|
||||||
|
int qemuAgentGetUsers(qemuAgentPtr mon,
|
||||||
|
virTypedParameterPtr *params,
|
||||||
|
int *nparams,
|
||||||
|
int *maxparams);
|
||||||
|
@ -902,6 +902,153 @@ testQemuAgentGetInterfaces(const void *data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char testQemuAgentUsersResponse[] =
|
||||||
|
"{\"return\": "
|
||||||
|
" ["
|
||||||
|
" {\"user\": \"test\","
|
||||||
|
" \"login-time\": 1561739203.584038"
|
||||||
|
" },"
|
||||||
|
" {\"user\": \"test2\","
|
||||||
|
" \"login-time\": 1561739229.190697"
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const char testQemuAgentUsersResponse2[] =
|
||||||
|
"{\"return\": "
|
||||||
|
" ["
|
||||||
|
" {\"user\": \"test\","
|
||||||
|
" \"domain\": \"DOMAIN\","
|
||||||
|
" \"login-time\": 1561739203.584038"
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static int
|
||||||
|
checkUserInfo(virTypedParameterPtr params,
|
||||||
|
int nparams,
|
||||||
|
size_t nth,
|
||||||
|
const char *expUsername,
|
||||||
|
const char *expDomain,
|
||||||
|
unsigned long long expLogintime)
|
||||||
|
{
|
||||||
|
char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
|
||||||
|
const char *username = NULL;
|
||||||
|
const char *domain = NULL;
|
||||||
|
unsigned long long logintime = 0;
|
||||||
|
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
||||||
|
"user.%zu.name", nth);
|
||||||
|
if (virTypedParamsGetString(params, nparams, param_name, &username) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (STRNEQ_NULLABLE(expUsername, username)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expected user name '%s', got '%s'",
|
||||||
|
expUsername, username);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
||||||
|
"user.%zu.domain", nth);
|
||||||
|
virTypedParamsGetString(params, nparams, param_name, &domain);
|
||||||
|
if (STRNEQ_NULLABLE(expDomain, domain)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expected domain '%s', got '%s'",
|
||||||
|
NULLSTR(expDomain), NULLSTR(domain));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
||||||
|
"user.%zu.login-time", nth);
|
||||||
|
if (virTypedParamsGetULLong(params, nparams, param_name, &logintime) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (expLogintime != logintime) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expected login time of '%llu', got '%llu'",
|
||||||
|
expLogintime, logintime);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
testQemuAgentUsers(const void *data)
|
||||||
|
{
|
||||||
|
virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
|
||||||
|
qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
|
||||||
|
virTypedParameterPtr params = NULL;
|
||||||
|
int nparams = 0;
|
||||||
|
int maxparams = 0;
|
||||||
|
int ret = -1;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
if (!test)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddItem(test, "guest-get-users",
|
||||||
|
testQemuAgentUsersResponse) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* get users */
|
||||||
|
if (qemuAgentGetUsers(qemuMonitorTestGetAgent(test),
|
||||||
|
¶ms, &nparams, &maxparams) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virTypedParamsGetUInt(params, nparams, "user.count", &count) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (count != 2) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expected '2' users, got '%u'", count);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkUserInfo(params, nparams, 0, "test", NULL, 1561739203584) < 0 ||
|
||||||
|
checkUserInfo(params, nparams, 1, "test2", NULL, 1561739229190) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddItem(test, "guest-get-users",
|
||||||
|
testQemuAgentUsersResponse2) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
virTypedParamsFree(params, nparams);
|
||||||
|
params = NULL;
|
||||||
|
nparams = 0;
|
||||||
|
maxparams = 0;
|
||||||
|
|
||||||
|
/* get users with domain */
|
||||||
|
if (qemuAgentGetUsers(qemuMonitorTestGetAgent(test),
|
||||||
|
¶ms, &nparams, &maxparams) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virTypedParamsGetUInt(params, nparams, "user.count", &count) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (count != 1) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expected '1' user, got '%u'", count);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkUserInfo(params, nparams, 0, "test", "DOMAIN", 1561739203584) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virTypedParamsFree(params, nparams);
|
||||||
|
qemuMonitorTestFree(test);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
@ -931,6 +1078,7 @@ mymain(void)
|
|||||||
DO_TEST(CPU);
|
DO_TEST(CPU);
|
||||||
DO_TEST(ArbitraryCommand);
|
DO_TEST(ArbitraryCommand);
|
||||||
DO_TEST(GetInterfaces);
|
DO_TEST(GetInterfaces);
|
||||||
|
DO_TEST(Users);
|
||||||
|
|
||||||
DO_TEST(Timeout); /* Timeout should always be called last */
|
DO_TEST(Timeout); /* Timeout should always be called last */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user