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);
|
||||
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 *password,
|
||||
bool crypted);
|
||||
|
||||
int qemuAgentGetUsers(qemuAgentPtr mon,
|
||||
virTypedParameterPtr *params,
|
||||
int *nparams,
|
||||
int *maxparams);
|
||||
|
@ -902,6 +902,153 @@ testQemuAgentGetInterfaces(const void *data)
|
||||
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
|
||||
mymain(void)
|
||||
{
|
||||
@ -931,6 +1078,7 @@ mymain(void)
|
||||
DO_TEST(CPU);
|
||||
DO_TEST(ArbitraryCommand);
|
||||
DO_TEST(GetInterfaces);
|
||||
DO_TEST(Users);
|
||||
|
||||
DO_TEST(Timeout); /* Timeout should always be called last */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user