Add daemon and client code to serialize/deserialize virDomainUserInfo Signed-off-by: Jonathon Jongsma <jjong...@redhat.com> --- src/remote/remote_daemon_dispatch.c | 89 +++++++++++++++++++++++++++++ src/remote/remote_driver.c | 82 +++++++++++++++++++++++++- src/remote/remote_protocol.x | 26 ++++++++- src/remote_protocol-structs | 17 ++++++ 4 files changed, 212 insertions(+), 2 deletions(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..05c4b11b11 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -7465,3 +7465,92 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, } return -1; } + +static int +remoteDispatchDomainGetGuestUsers(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_guest_users_args *args, + remote_domain_get_guest_users_ret *ret) +{ + int rv = -1; + size_t i; + struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); + virDomainUserInfoPtr *info = NULL; + virDomainPtr dom = NULL; + remote_domain_userinfo *dst; + int ninfo = 0; + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if ((ninfo = virDomainGetGuestUsers(dom, &info, args->flags)) < 0) + goto cleanup; + + if (ninfo > REMOTE_DOMAIN_GUEST_USERS_MAX) { + virReportError(VIR_ERR_RPC, + _("Too many users in userinfo: %d for limit %d"), + ninfo, REMOTE_DOMAIN_GUEST_USERS_MAX); + goto cleanup; + } + + if (ninfo) { + if (VIR_ALLOC_N(ret->info.info_val, ninfo) < 0) + goto cleanup; + + ret->info.info_len = ninfo; + + for (i = 0; i < ninfo; i++) { + dst = &ret->info.info_val[i]; + if (VIR_STRDUP(dst->user, info[i]->user) < 0) + goto cleanup; + + if (info[i]->domain) { + if (VIR_ALLOC(*dst->domain) < 0) + goto cleanup; + if (VIR_STRDUP(*dst->domain, info[i]->domain) < 0) + goto cleanup; + } + + dst->login_time = info[i]->loginTime; + + } + + } else { + ret->info.info_len = 0; + ret->info.info_val = NULL; + } + + ret->ret = ninfo; + + rv = 0; + + cleanup: + if (rv < 0) { + virNetMessageSaveError(rerr); + + if (ret->info.info_val && ninfo > 0) { + for (i = 0; i < ninfo; i++) { + dst = &ret->info.info_val[i]; + VIR_FREE(dst->user); + if(dst->domain) + VIR_FREE(*dst->domain); + VIR_FREE(dst->domain); + } + VIR_FREE(ret->info.info_val); + } + } + virObjectUnref(dom); + if (ninfo >= 0) + for (i = 0; i < ninfo; i++) + virDomainUserInfoFree(info[i]); + VIR_FREE(info); + + return rv; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 925ada1cac..86e2071d3b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8167,6 +8167,85 @@ remoteNetworkPortGetParameters(virNetworkPortPtr port, return rv; } +static int +remoteDomainGetGuestUsers(virDomainPtr dom, + virDomainUserInfoPtr **info, + unsigned int flags) +{ + int rv = -1; + size_t i; + struct private_data *priv = dom->conn->privateData; + remote_domain_get_guest_users_args args; + remote_domain_get_guest_users_ret ret; + remote_domain_userinfo *src; + virDomainUserInfoPtr *info_ret = NULL; + + remoteDriverLock(priv); + + make_nonnull_domain(&args.dom, dom); + + args.flags = flags; + + memset(&ret, 0, sizeof(ret)); + + if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_GUEST_USERS, + (xdrproc_t)xdr_remote_domain_get_guest_users_args, (char *)&args, + (xdrproc_t)xdr_remote_domain_get_guest_users_ret, (char *)&ret) == -1) + goto done; + + if (ret.info.info_len > REMOTE_DOMAIN_GUEST_USERS_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Too many users in userinfo: %d for limit %d"), + ret.info.info_len, REMOTE_DOMAIN_GUEST_USERS_MAX); + goto cleanup; + } + + if (info) { + if (!ret.info.info_len) { + *info = NULL; + rv = ret.ret; + goto cleanup; + } + + if (VIR_ALLOC_N(info_ret, ret.info.info_len) < 0) + goto cleanup; + + for (i = 0; i < ret.info.info_len; i++) { + src = &ret.info.info_val[i]; + + if (VIR_ALLOC(info_ret[i]) < 0) + goto cleanup; + + if (VIR_STRDUP(info_ret[i]->user, src->user) < 0) + goto cleanup; + + if (src->domain) { + if (VIR_STRDUP(info_ret[i]->domain, *src->domain) < 0) + goto cleanup; + } + + info_ret[i]->loginTime = src->login_time; + } + + *info = info_ret; + info_ret = NULL; + } + + rv = ret.ret; + + cleanup: + if (info_ret) { + for (i = 0; i < ret.info.info_len; i++) + virDomainUserInfoFree(info_ret[i]); + VIR_FREE(info_ret); + } + xdr_free((xdrproc_t)xdr_remote_domain_get_guest_users_ret, + (char *) &ret); + + done: + remoteDriverUnlock(priv); + return rv; +} /* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. @@ -8573,7 +8652,8 @@ static virHypervisorDriver hypervisor_driver = { .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */ .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */ .nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */ - .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo /* 4.5.0 */ + .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo, /* 4.5.0 */ + .domainGetGuestUsers = remoteDomainGetGuestUsers /* 5.6.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2e45b5cef0..5f2f350cb0 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -266,6 +266,9 @@ const REMOTE_NODE_SEV_INFO_MAX = 64; /* Upper limit on number of launch security information entries */ const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX = 64; +/* Upper limit on number of guest user information entries */ +const REMOTE_DOMAIN_GUEST_USERS_MAX = 64; + /* * Upper limit on list of network port parameters */ @@ -3649,6 +3652,21 @@ struct remote_network_port_delete_args { unsigned int flags; }; +struct remote_domain_userinfo { + remote_nonnull_string user; + remote_string domain; + unsigned hyper login_time; +}; + +struct remote_domain_get_guest_users_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_get_guest_users_ret { + remote_domain_userinfo info<REMOTE_DOMAIN_GUEST_USERS_MAX>; + unsigned int ret; +}; /*----- Protocol. -----*/ @@ -6463,5 +6481,11 @@ enum remote_procedure { * @generate: both * @acl: network_port:delete */ - REMOTE_PROC_NETWORK_PORT_DELETE = 410 + REMOTE_PROC_NETWORK_PORT_DELETE = 410, + + /** + * @generate: none + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_GET_GUEST_USERS = 411 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 2398494520..ee39fb2d0d 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3043,6 +3043,22 @@ struct remote_network_port_delete_args { remote_nonnull_network_port port; u_int flags; }; +struct remote_domain_userinfo { + remote_nonnull_string user; + remote_string domain; + uint64_t login_time; +}; +struct remote_domain_get_guest_users_args { + remote_nonnull_domain dom; + u_int flags; +}; +struct remote_domain_get_guest_users_ret { + struct { + u_int info_len; + remote_domain_userinfo * info_val; + } info; + u_int ret; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -3454,4 +3470,5 @@ enum remote_procedure { REMOTE_PROC_NETWORK_PORT_SET_PARAMETERS = 408, REMOTE_PROC_NETWORK_PORT_GET_XML_DESC = 409, REMOTE_PROC_NETWORK_PORT_DELETE = 410, + REMOTE_PROC_DOMAIN_GET_GUEST_USERS = 411, }; -- 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list