mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
Separate virGetHostname() API contract from driver APIs
Currently the virGetHostname() API has a bogus virConnectPtr parameter. This is because virtualization drivers directly reference this API in their virDriverPtr tables, tieing its API design to the public virConnectGetHostname API design. This also causes problems for access control checks since these must only be done for invocations from the public API, not internal invocation. Remove the bogus virConnectPtr parameter, and make each hypervisor driver provide a dedicated function for the driver API impl. This will allow access control checks to be easily inserted later. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
979e9c56a7
commit
ead630319d
@ -277,7 +277,7 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
|
|||||||
data->keepalive_count = 5;
|
data->keepalive_count = 5;
|
||||||
data->keepalive_required = 0;
|
data->keepalive_required = 0;
|
||||||
|
|
||||||
localhost = virGetHostname(NULL);
|
localhost = virGetHostname();
|
||||||
if (localhost == NULL) {
|
if (localhost == NULL) {
|
||||||
/* we couldn't resolve the hostname; assume that we are
|
/* we couldn't resolve the hostname; assume that we are
|
||||||
* running in disconnected operation, and report a less
|
* running in disconnected operation, and report a less
|
||||||
|
@ -44,7 +44,6 @@ while (<>) {
|
|||||||
|
|
||||||
# External impls
|
# External impls
|
||||||
next if $prefix eq "node";
|
next if $prefix eq "node";
|
||||||
next if $prefix eq "vir";
|
|
||||||
|
|
||||||
if (defined $mainprefix) {
|
if (defined $mainprefix) {
|
||||||
if ($mainprefix ne $prefix) {
|
if ($mainprefix ne $prefix) {
|
||||||
|
@ -1411,6 +1411,13 @@ libxlConnectGetVersion(virConnectPtr conn, unsigned long *version)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *libxlConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libxlConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
|
libxlConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -4203,7 +4210,7 @@ static virDriver libxlDriver = {
|
|||||||
.connectClose = libxlConnectClose, /* 0.9.0 */
|
.connectClose = libxlConnectClose, /* 0.9.0 */
|
||||||
.connectGetType = libxlConnectGetType, /* 0.9.0 */
|
.connectGetType = libxlConnectGetType, /* 0.9.0 */
|
||||||
.connectGetVersion = libxlConnectGetVersion, /* 0.9.0 */
|
.connectGetVersion = libxlConnectGetVersion, /* 0.9.0 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.9.0 */
|
.connectGetHostname = libxlConnectGetHostname, /* 0.9.0 */
|
||||||
.connectGetMaxVcpus = libxlConnectGetMaxVcpus, /* 0.9.0 */
|
.connectGetMaxVcpus = libxlConnectGetMaxVcpus, /* 0.9.0 */
|
||||||
.nodeGetInfo = libxlNodeGetInfo, /* 0.9.0 */
|
.nodeGetInfo = libxlNodeGetInfo, /* 0.9.0 */
|
||||||
.connectGetCapabilities = libxlConnectGetCapabilities, /* 0.9.0 */
|
.connectGetCapabilities = libxlConnectGetCapabilities, /* 0.9.0 */
|
||||||
|
@ -1562,6 +1562,13 @@ static int lxcConnectGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned lo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *lxcConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check whether the host supports CFS bandwidth
|
* check whether the host supports CFS bandwidth
|
||||||
*
|
*
|
||||||
@ -4402,7 +4409,7 @@ static virDriver lxcDriver = {
|
|||||||
.connectOpen = lxcConnectOpen, /* 0.4.2 */
|
.connectOpen = lxcConnectOpen, /* 0.4.2 */
|
||||||
.connectClose = lxcConnectClose, /* 0.4.2 */
|
.connectClose = lxcConnectClose, /* 0.4.2 */
|
||||||
.connectGetVersion = lxcConnectGetVersion, /* 0.4.6 */
|
.connectGetVersion = lxcConnectGetVersion, /* 0.4.6 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.6.3 */
|
.connectGetHostname = lxcConnectGetHostname, /* 0.6.3 */
|
||||||
.connectGetSysinfo = lxcConnectGetSysinfo, /* 1.0.5 */
|
.connectGetSysinfo = lxcConnectGetSysinfo, /* 1.0.5 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.6.5 */
|
.nodeGetInfo = nodeGetInfo, /* 0.6.5 */
|
||||||
.connectGetCapabilities = lxcConnectGetCapabilities, /* 0.6.5 */
|
.connectGetCapabilities = lxcConnectGetCapabilities, /* 0.6.5 */
|
||||||
|
@ -343,6 +343,13 @@ static int openvzConnectGetVersion(virConnectPtr conn, unsigned long *version) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *openvzConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *openvzDomainGetOSType(virDomainPtr dom)
|
static char *openvzDomainGetOSType(virDomainPtr dom)
|
||||||
{
|
{
|
||||||
struct openvz_driver *driver = dom->conn->privateData;
|
struct openvz_driver *driver = dom->conn->privateData;
|
||||||
@ -2182,7 +2189,7 @@ static virDriver openvzDriver = {
|
|||||||
.connectClose = openvzConnectClose, /* 0.3.1 */
|
.connectClose = openvzConnectClose, /* 0.3.1 */
|
||||||
.connectGetType = openvzConnectGetType, /* 0.3.1 */
|
.connectGetType = openvzConnectGetType, /* 0.3.1 */
|
||||||
.connectGetVersion = openvzConnectGetVersion, /* 0.5.0 */
|
.connectGetVersion = openvzConnectGetVersion, /* 0.5.0 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.9.12 */
|
.connectGetHostname = openvzConnectGetHostname, /* 0.9.12 */
|
||||||
.connectGetMaxVcpus = openvzConnectGetMaxVcpus, /* 0.4.6 */
|
.connectGetMaxVcpus = openvzConnectGetMaxVcpus, /* 0.4.6 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.3.2 */
|
.nodeGetInfo = nodeGetInfo, /* 0.3.2 */
|
||||||
.nodeGetCPUStats = nodeGetCPUStats, /* 0.9.12 */
|
.nodeGetCPUStats = nodeGetCPUStats, /* 0.9.12 */
|
||||||
|
@ -1043,6 +1043,13 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *parallelsConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parallelsConnectListDomains(virConnectPtr conn, int *ids, int maxids)
|
parallelsConnectListDomains(virConnectPtr conn, int *ids, int maxids)
|
||||||
{
|
{
|
||||||
@ -2393,7 +2400,7 @@ static virDriver parallelsDriver = {
|
|||||||
.connectOpen = parallelsConnectOpen, /* 0.10.0 */
|
.connectOpen = parallelsConnectOpen, /* 0.10.0 */
|
||||||
.connectClose = parallelsConnectClose, /* 0.10.0 */
|
.connectClose = parallelsConnectClose, /* 0.10.0 */
|
||||||
.connectGetVersion = parallelsConnectGetVersion, /* 0.10.0 */
|
.connectGetVersion = parallelsConnectGetVersion, /* 0.10.0 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.10.0 */
|
.connectGetHostname = parallelsConnectGetHostname, /* 0.10.0 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.10.0 */
|
.nodeGetInfo = nodeGetInfo, /* 0.10.0 */
|
||||||
.connectGetCapabilities = parallelsConnectGetCapabilities, /* 0.10.0 */
|
.connectGetCapabilities = parallelsConnectGetCapabilities, /* 0.10.0 */
|
||||||
.connectListDomains = parallelsConnectListDomains, /* 0.10.0 */
|
.connectListDomains = parallelsConnectListDomains, /* 0.10.0 */
|
||||||
|
@ -1412,6 +1412,13 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *qemuConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemuConnectListDomains(virConnectPtr conn, int *ids, int nids) {
|
static int qemuConnectListDomains(virConnectPtr conn, int *ids, int nids) {
|
||||||
virQEMUDriverPtr driver = conn->privateData;
|
virQEMUDriverPtr driver = conn->privateData;
|
||||||
int n;
|
int n;
|
||||||
@ -14703,7 +14710,7 @@ static virDriver qemuDriver = {
|
|||||||
.connectSupportsFeature = qemuConnectSupportsFeature, /* 0.5.0 */
|
.connectSupportsFeature = qemuConnectSupportsFeature, /* 0.5.0 */
|
||||||
.connectGetType = qemuConnectGetType, /* 0.2.0 */
|
.connectGetType = qemuConnectGetType, /* 0.2.0 */
|
||||||
.connectGetVersion = qemuConnectGetVersion, /* 0.2.0 */
|
.connectGetVersion = qemuConnectGetVersion, /* 0.2.0 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.3.3 */
|
.connectGetHostname = qemuConnectGetHostname, /* 0.3.3 */
|
||||||
.connectGetSysinfo = qemuConnectGetSysinfo, /* 0.8.8 */
|
.connectGetSysinfo = qemuConnectGetSysinfo, /* 0.8.8 */
|
||||||
.connectGetMaxVcpus = qemuConnectGetMaxVcpus, /* 0.2.1 */
|
.connectGetMaxVcpus = qemuConnectGetMaxVcpus, /* 0.2.1 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.2.0 */
|
.nodeGetInfo = nodeGetInfo, /* 0.2.0 */
|
||||||
|
@ -404,7 +404,7 @@ qemuMigrationCookieNew(virDomainObjPtr dom)
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
memcpy(mig->uuid, dom->def->uuid, VIR_UUID_BUFLEN);
|
memcpy(mig->uuid, dom->def->uuid, VIR_UUID_BUFLEN);
|
||||||
|
|
||||||
if (!(mig->localHostname = virGetHostname(NULL)))
|
if (!(mig->localHostname = virGetHostname()))
|
||||||
goto error;
|
goto error;
|
||||||
if (virGetHostUUID(mig->localHostuuid) < 0) {
|
if (virGetHostUUID(mig->localHostuuid) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
@ -2372,7 +2372,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
|
|||||||
if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;
|
if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;
|
||||||
|
|
||||||
/* Get hostname */
|
/* Get hostname */
|
||||||
if ((hostname = virGetHostname(NULL)) == NULL)
|
if ((hostname = virGetHostname()) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (STRPREFIX(hostname, "localhost")) {
|
if (STRPREFIX(hostname, "localhost")) {
|
||||||
|
@ -1223,6 +1223,12 @@ static int testConnectGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *testConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int testConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
|
static int testConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@ -5796,7 +5802,7 @@ static virDriver testDriver = {
|
|||||||
.connectOpen = testConnectOpen, /* 0.1.1 */
|
.connectOpen = testConnectOpen, /* 0.1.1 */
|
||||||
.connectClose = testConnectClose, /* 0.1.1 */
|
.connectClose = testConnectClose, /* 0.1.1 */
|
||||||
.connectGetVersion = testConnectGetVersion, /* 0.1.1 */
|
.connectGetVersion = testConnectGetVersion, /* 0.1.1 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.6.3 */
|
.connectGetHostname = testConnectGetHostname, /* 0.6.3 */
|
||||||
.connectGetMaxVcpus = testConnectGetMaxVcpus, /* 0.3.2 */
|
.connectGetMaxVcpus = testConnectGetMaxVcpus, /* 0.3.2 */
|
||||||
.nodeGetInfo = testNodeGetInfo, /* 0.1.1 */
|
.nodeGetInfo = testNodeGetInfo, /* 0.1.1 */
|
||||||
.connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */
|
.connectGetCapabilities = testConnectGetCapabilities, /* 0.2.1 */
|
||||||
|
@ -1494,6 +1494,13 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *umlConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int umlConnectListDomains(virConnectPtr conn, int *ids, int nids) {
|
static int umlConnectListDomains(virConnectPtr conn, int *ids, int nids) {
|
||||||
struct uml_driver *driver = conn->privateData;
|
struct uml_driver *driver = conn->privateData;
|
||||||
int n;
|
int n;
|
||||||
@ -2597,7 +2604,7 @@ static virDriver umlDriver = {
|
|||||||
.connectClose = umlConnectClose, /* 0.5.0 */
|
.connectClose = umlConnectClose, /* 0.5.0 */
|
||||||
.connectGetType = umlConnectGetType, /* 0.5.0 */
|
.connectGetType = umlConnectGetType, /* 0.5.0 */
|
||||||
.connectGetVersion = umlConnectGetVersion, /* 0.5.0 */
|
.connectGetVersion = umlConnectGetVersion, /* 0.5.0 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.5.0 */
|
.connectGetHostname = umlConnectGetHostname, /* 0.5.0 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.5.0 */
|
.nodeGetInfo = nodeGetInfo, /* 0.5.0 */
|
||||||
.connectGetCapabilities = umlConnectGetCapabilities, /* 0.5.0 */
|
.connectGetCapabilities = umlConnectGetCapabilities, /* 0.5.0 */
|
||||||
.connectListDomains = umlConnectListDomains, /* 0.5.0 */
|
.connectListDomains = umlConnectListDomains, /* 0.5.0 */
|
||||||
|
@ -1942,7 +1942,7 @@ char *virIndexToDiskName(int idx, const char *prefix)
|
|||||||
* we got from getaddrinfo(). Return the value from gethostname()
|
* we got from getaddrinfo(). Return the value from gethostname()
|
||||||
* and hope for the best.
|
* and hope for the best.
|
||||||
*/
|
*/
|
||||||
char *virGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
char *virGetHostname(void)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
char hostname[HOST_NAME_MAX+1], *result;
|
char hostname[HOST_NAME_MAX+1], *result;
|
||||||
|
@ -211,7 +211,7 @@ static inline int geteuid (void) { return 0; }
|
|||||||
static inline int getgid (void) { return 0; }
|
static inline int getgid (void) { return 0; }
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
char *virGetHostname(virConnectPtr conn);
|
char *virGetHostname(void);
|
||||||
|
|
||||||
char *virGetUserDirectory(void);
|
char *virGetUserDirectory(void);
|
||||||
char *virGetUserConfigDirectory(void);
|
char *virGetUserConfigDirectory(void);
|
||||||
|
@ -1090,6 +1090,13 @@ static int vboxConnectGetVersion(virConnectPtr conn, unsigned long *version) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *vboxConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int vboxConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
static int vboxConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
||||||
/* Driver is using local, non-network based transport */
|
/* Driver is using local, non-network based transport */
|
||||||
return 1;
|
return 1;
|
||||||
@ -9409,7 +9416,7 @@ virDriver NAME(Driver) = {
|
|||||||
.connectOpen = vboxConnectOpen, /* 0.6.3 */
|
.connectOpen = vboxConnectOpen, /* 0.6.3 */
|
||||||
.connectClose = vboxConnectClose, /* 0.6.3 */
|
.connectClose = vboxConnectClose, /* 0.6.3 */
|
||||||
.connectGetVersion = vboxConnectGetVersion, /* 0.6.3 */
|
.connectGetVersion = vboxConnectGetVersion, /* 0.6.3 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.6.3 */
|
.connectGetHostname = vboxConnectGetHostname, /* 0.6.3 */
|
||||||
.connectGetMaxVcpus = vboxConnectGetMaxVcpus, /* 0.6.3 */
|
.connectGetMaxVcpus = vboxConnectGetMaxVcpus, /* 0.6.3 */
|
||||||
.nodeGetInfo = nodeGetInfo, /* 0.6.3 */
|
.nodeGetInfo = nodeGetInfo, /* 0.6.3 */
|
||||||
.connectGetCapabilities = vboxConnectGetCapabilities, /* 0.6.3 */
|
.connectGetCapabilities = vboxConnectGetCapabilities, /* 0.6.3 */
|
||||||
|
@ -546,6 +546,13 @@ xenUnifiedConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *xenUnifiedConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
return virGetHostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xenUnifiedConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
|
xenUnifiedConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -2353,7 +2360,7 @@ static virDriver xenUnifiedDriver = {
|
|||||||
.connectSupportsFeature = xenUnifiedConnectSupportsFeature, /* 0.3.2 */
|
.connectSupportsFeature = xenUnifiedConnectSupportsFeature, /* 0.3.2 */
|
||||||
.connectGetType = xenUnifiedConnectGetType, /* 0.0.3 */
|
.connectGetType = xenUnifiedConnectGetType, /* 0.0.3 */
|
||||||
.connectGetVersion = xenUnifiedConnectGetVersion, /* 0.0.3 */
|
.connectGetVersion = xenUnifiedConnectGetVersion, /* 0.0.3 */
|
||||||
.connectGetHostname = virGetHostname, /* 0.7.3 */
|
.connectGetHostname = xenUnifiedConnectGetHostname, /* 0.7.3 */
|
||||||
.connectGetMaxVcpus = xenUnifiedConnectGetMaxVcpus, /* 0.2.1 */
|
.connectGetMaxVcpus = xenUnifiedConnectGetMaxVcpus, /* 0.2.1 */
|
||||||
.nodeGetInfo = xenUnifiedNodeGetInfo, /* 0.1.0 */
|
.nodeGetInfo = xenUnifiedNodeGetInfo, /* 0.1.0 */
|
||||||
.connectGetCapabilities = xenUnifiedConnectGetCapabilities, /* 0.2.1 */
|
.connectGetCapabilities = xenUnifiedConnectGetCapabilities, /* 0.2.1 */
|
||||||
|
@ -2926,7 +2926,7 @@ xenDaemonDomainSetAutostart(virDomainPtr domain, int autostart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xenDaemonDomainMigratePrepare(virConnectPtr dconn,
|
xenDaemonDomainMigratePrepare(virConnectPtr dconn ATTRIBUTE_UNUSED,
|
||||||
char **cookie ATTRIBUTE_UNUSED,
|
char **cookie ATTRIBUTE_UNUSED,
|
||||||
int *cookielen ATTRIBUTE_UNUSED,
|
int *cookielen ATTRIBUTE_UNUSED,
|
||||||
const char *uri_in,
|
const char *uri_in,
|
||||||
@ -2942,7 +2942,7 @@ xenDaemonDomainMigratePrepare(virConnectPtr dconn,
|
|||||||
* deallocates this string.
|
* deallocates this string.
|
||||||
*/
|
*/
|
||||||
if (uri_in == NULL) {
|
if (uri_in == NULL) {
|
||||||
*uri_out = virGetHostname(dconn);
|
*uri_out = virGetHostname();
|
||||||
if (*uri_out == NULL)
|
if (*uri_out == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user