Fix obtaining the hostname from DNS (rh #1308974)
This commit is contained in:
parent
f561df45ac
commit
bb908ed4e4
197
0001-core-use-hostnamed-to-set-the-transient-hostname.patch
Normal file
197
0001-core-use-hostnamed-to-set-the-transient-hostname.patch
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
From f94c3736cd1c84aacaea1879154a0acdb58667d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||||
|
Date: Thu, 18 Feb 2016 18:19:30 +0100
|
||||||
|
Subject: [PATCH 1/3] core: use hostnamed to set the transient hostname
|
||||||
|
|
||||||
|
In commit 6dc35e66d45e ("settings: add hostnamed support") we started
|
||||||
|
to use systemd-hostnamed for setting the system static hostname
|
||||||
|
(i.e. the one written to /etc/hostname), but nm-policy.c still called
|
||||||
|
sethostname() to set the transient (dynamic) hostname when this needs
|
||||||
|
to be changed, for example after a reverse lookup of our dynamic IP
|
||||||
|
address.
|
||||||
|
|
||||||
|
Thus, when using systemd the hostname change failed because process'
|
||||||
|
capabilities are restricted and sethostname() requires CAP_SYS_ADMIN.
|
||||||
|
|
||||||
|
We should set also the transient hostname through hostnamed when this
|
||||||
|
is available.
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1308974
|
||||||
|
---
|
||||||
|
src/nm-policy.c | 45 ++++++++++++++++++++++++-----------
|
||||||
|
src/settings/nm-settings.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/settings/nm-settings.h | 7 ++++++
|
||||||
|
3 files changed, 97 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nm-policy.c b/src/nm-policy.c
|
||||||
|
index 68e50a1..cfb140f 100644
|
||||||
|
--- a/src/nm-policy.c
|
||||||
|
+++ b/src/nm-policy.c
|
||||||
|
@@ -118,9 +118,32 @@ get_best_ip6_device (NMPolicy *self, gboolean fully_activated)
|
||||||
|
|
||||||
|
#define FALLBACK_HOSTNAME4 "localhost.localdomain"
|
||||||
|
|
||||||
|
-static gboolean
|
||||||
|
-set_system_hostname (const char *new_hostname, const char *msg)
|
||||||
|
+static void settings_set_hostname_cb (const char *hostname,
|
||||||
|
+ gboolean result,
|
||||||
|
+ gpointer user_data)
|
||||||
|
{
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ if (!result) {
|
||||||
|
+ ret = sethostname (hostname, strlen (hostname));
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ int errsv = errno;
|
||||||
|
+
|
||||||
|
+ nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||||
|
+ hostname, errsv, strerror (errsv));
|
||||||
|
+ if (errsv == EPERM)
|
||||||
|
+ nm_log_warn (LOGD_DNS, "you should use hostnamed when systemd hardening is in effect!");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!ret)
|
||||||
|
+ nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+set_system_hostname (NMPolicy *self, const char *new_hostname, const char *msg)
|
||||||
|
+{
|
||||||
|
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
|
char old_hostname[HOST_NAME_MAX + 1];
|
||||||
|
const char *name;
|
||||||
|
int ret;
|
||||||
|
@@ -138,21 +161,16 @@ set_system_hostname (const char *new_hostname, const char *msg)
|
||||||
|
/* Don't set the hostname if it isn't actually changing */
|
||||||
|
if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||||
|
|| (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME4)))
|
||||||
|
- return FALSE;
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4;
|
||||||
|
|
||||||
|
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||||
|
- ret = sethostname (name, strlen (name));
|
||||||
|
- if (ret != 0) {
|
||||||
|
- int errsv = errno;
|
||||||
|
-
|
||||||
|
- nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||||
|
- name, errsv, strerror (errsv));
|
||||||
|
- if (errsv == EPERM)
|
||||||
|
- nm_log_warn (LOGD_DNS, "You should use hostnamed when systemd hardening is in effect!");
|
||||||
|
- }
|
||||||
|
+ nm_settings_set_transient_hostname (priv->settings,
|
||||||
|
+ name,
|
||||||
|
+ settings_set_hostname_cb,
|
||||||
|
+ NULL);
|
||||||
|
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
@@ -196,8 +214,7 @@ _set_hostname (NMPolicy *policy,
|
||||||
|
|
||||||
|
nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname);
|
||||||
|
|
||||||
|
- if (set_system_hostname (priv->cur_hostname, msg))
|
||||||
|
- nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
+ set_system_hostname (policy, priv->cur_hostname, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
|
||||||
|
index ee48e71..f79bbfa 100644
|
||||||
|
--- a/src/settings/nm-settings.c
|
||||||
|
+++ b/src/settings/nm-settings.c
|
||||||
|
@@ -1525,6 +1525,65 @@ impl_settings_reload_connections (NMSettings *self,
|
||||||
|
g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ char *hostname;
|
||||||
|
+ NMSettingsSetHostnameCb cb;
|
||||||
|
+ gpointer user_data;
|
||||||
|
+} SetHostnameInfo;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+set_transient_hostname_done (GObject *object,
|
||||||
|
+ GAsyncResult *res,
|
||||||
|
+ gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ GDBusProxy *proxy = G_DBUS_PROXY (object);
|
||||||
|
+ gs_free SetHostnameInfo *info = user_data;
|
||||||
|
+ gs_unref_variant GVariant *result = NULL;
|
||||||
|
+ gs_free_error GError *error = NULL;
|
||||||
|
+
|
||||||
|
+ result = g_dbus_proxy_call_finish (proxy, res, &error);
|
||||||
|
+
|
||||||
|
+ if (error) {
|
||||||
|
+ nm_log_warn (LOGD_SETTINGS, "couldn't set the system hostname to '%s' using hostnamed: %s",
|
||||||
|
+ info->hostname, error->message);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info->cb (info->hostname, !error, info->user_data);
|
||||||
|
+ g_free (info->hostname);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+nm_settings_set_transient_hostname (NMSettings *self,
|
||||||
|
+ const char *hostname,
|
||||||
|
+ NMSettingsSetHostnameCb cb,
|
||||||
|
+ gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ NMSettingsPrivate *priv;
|
||||||
|
+ SetHostnameInfo *info;
|
||||||
|
+
|
||||||
|
+ g_return_if_fail (NM_IS_SETTINGS (self));
|
||||||
|
+ priv = NM_SETTINGS_GET_PRIVATE (self);
|
||||||
|
+
|
||||||
|
+ if (!priv->hostname.hostnamed_proxy) {
|
||||||
|
+ cb (hostname, FALSE, user_data);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info = g_new0 (SetHostnameInfo, 1);
|
||||||
|
+ info->hostname = g_strdup (hostname);
|
||||||
|
+ info->cb = cb;
|
||||||
|
+ info->user_data = user_data;
|
||||||
|
+
|
||||||
|
+ g_dbus_proxy_call (priv->hostname.hostnamed_proxy,
|
||||||
|
+ "SetHostname",
|
||||||
|
+ g_variant_new ("(sb)", hostname, FALSE),
|
||||||
|
+ G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
+ -1,
|
||||||
|
+ NULL,
|
||||||
|
+ set_transient_hostname_done,
|
||||||
|
+ info);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
write_hostname (NMSettingsPrivate *priv, const char *hostname)
|
||||||
|
{
|
||||||
|
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
|
||||||
|
index 923b164..051c209 100644
|
||||||
|
--- a/src/settings/nm-settings.h
|
||||||
|
+++ b/src/settings/nm-settings.h
|
||||||
|
@@ -71,6 +71,8 @@ typedef struct {
|
||||||
|
void (*agent_registered) (NMSettings *self, NMSecretAgent *agent);
|
||||||
|
} NMSettingsClass;
|
||||||
|
|
||||||
|
+typedef void (*NMSettingsSetHostnameCb) (const char *name, gboolean result, gpointer user_data);
|
||||||
|
+
|
||||||
|
GType nm_settings_get_type (void);
|
||||||
|
|
||||||
|
NMSettings *nm_settings_new (void);
|
||||||
|
@@ -127,4 +129,9 @@ gint nm_settings_sort_connections (gconstpointer a, gconstpointer b);
|
||||||
|
|
||||||
|
gboolean nm_settings_get_startup_complete (NMSettings *self);
|
||||||
|
|
||||||
|
+void nm_settings_set_transient_hostname (NMSettings *self,
|
||||||
|
+ const char *hostname,
|
||||||
|
+ NMSettingsSetHostnameCb cb,
|
||||||
|
+ gpointer user_data);
|
||||||
|
+
|
||||||
|
#endif /* __NM_SETTINGS_H__ */
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
48
0002-policy-simplify-set_system_hostname.patch
Normal file
48
0002-policy-simplify-set_system_hostname.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From ff9c310454e36acf996491ad154487c85b19f87a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||||
|
Date: Mon, 22 Feb 2016 10:01:30 +0100
|
||||||
|
Subject: [PATCH 2/3] policy: simplify set_system_hostname()
|
||||||
|
|
||||||
|
Move some conditionals to the beginning of the function.
|
||||||
|
---
|
||||||
|
src/nm-policy.c | 14 ++++++++------
|
||||||
|
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nm-policy.c b/src/nm-policy.c
|
||||||
|
index cfb140f..fca4005 100644
|
||||||
|
--- a/src/nm-policy.c
|
||||||
|
+++ b/src/nm-policy.c
|
||||||
|
@@ -148,8 +148,13 @@ set_system_hostname (NMPolicy *self, const char *new_hostname, const char *msg)
|
||||||
|
const char *name;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- if (new_hostname)
|
||||||
|
- g_warn_if_fail (strlen (new_hostname));
|
||||||
|
+ if (!new_hostname)
|
||||||
|
+ name = FALLBACK_HOSTNAME4;
|
||||||
|
+ else if (!new_hostname[0]) {
|
||||||
|
+ g_warn_if_reached ();
|
||||||
|
+ name = FALLBACK_HOSTNAME4;
|
||||||
|
+ } else
|
||||||
|
+ name = new_hostname;
|
||||||
|
|
||||||
|
old_hostname[HOST_NAME_MAX] = '\0';
|
||||||
|
errno = 0;
|
||||||
|
@@ -159,13 +164,10 @@ set_system_hostname (NMPolicy *self, const char *new_hostname, const char *msg)
|
||||||
|
errno, strerror (errno));
|
||||||
|
} else {
|
||||||
|
/* Don't set the hostname if it isn't actually changing */
|
||||||
|
- if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||||
|
- || (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME4)))
|
||||||
|
+ if (nm_streq (name, old_hostname))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4;
|
||||||
|
-
|
||||||
|
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||||
|
nm_settings_set_transient_hostname (priv->settings,
|
||||||
|
name,
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
112
0003-policy-move-code-from-set_system_hostname-to-_set_ho.patch
Normal file
112
0003-policy-move-code-from-set_system_hostname-to-_set_ho.patch
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
From 078179c836fb39a81173ab5ce7db1ccc05eb3f7a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||||
|
Date: Mon, 22 Feb 2016 10:10:15 +0100
|
||||||
|
Subject: [PATCH 3/3] policy: move code from set_system_hostname() to
|
||||||
|
_set_hostname()
|
||||||
|
|
||||||
|
---
|
||||||
|
src/nm-policy.c | 74 ++++++++++++++++++++++++++++-----------------------------
|
||||||
|
1 file changed, 36 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nm-policy.c b/src/nm-policy.c
|
||||||
|
index fca4005..84d1e7e 100644
|
||||||
|
--- a/src/nm-policy.c
|
||||||
|
+++ b/src/nm-policy.c
|
||||||
|
@@ -141,48 +141,14 @@ static void settings_set_hostname_cb (const char *hostname,
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-set_system_hostname (NMPolicy *self, const char *new_hostname, const char *msg)
|
||||||
|
-{
|
||||||
|
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
|
- char old_hostname[HOST_NAME_MAX + 1];
|
||||||
|
- const char *name;
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- if (!new_hostname)
|
||||||
|
- name = FALLBACK_HOSTNAME4;
|
||||||
|
- else if (!new_hostname[0]) {
|
||||||
|
- g_warn_if_reached ();
|
||||||
|
- name = FALLBACK_HOSTNAME4;
|
||||||
|
- } else
|
||||||
|
- name = new_hostname;
|
||||||
|
-
|
||||||
|
- old_hostname[HOST_NAME_MAX] = '\0';
|
||||||
|
- errno = 0;
|
||||||
|
- ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||||
|
- if (ret != 0) {
|
||||||
|
- nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||||
|
- errno, strerror (errno));
|
||||||
|
- } else {
|
||||||
|
- /* Don't set the hostname if it isn't actually changing */
|
||||||
|
- if (nm_streq (name, old_hostname))
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||||
|
- nm_settings_set_transient_hostname (priv->settings,
|
||||||
|
- name,
|
||||||
|
- settings_set_hostname_cb,
|
||||||
|
- NULL);
|
||||||
|
-
|
||||||
|
- return (ret == 0);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
_set_hostname (NMPolicy *policy,
|
||||||
|
const char *new_hostname,
|
||||||
|
const char *msg)
|
||||||
|
{
|
||||||
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
|
||||||
|
+ char old_hostname[HOST_NAME_MAX + 1];
|
||||||
|
+ const char *name;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
/* The incoming hostname *can* be NULL, which will get translated to
|
||||||
|
* 'localhost.localdomain' or such in the hostname policy code, but we
|
||||||
|
@@ -214,9 +180,41 @@ _set_hostname (NMPolicy *policy,
|
||||||
|
priv->cur_hostname = g_strdup (new_hostname);
|
||||||
|
priv->hostname_changed = TRUE;
|
||||||
|
|
||||||
|
+ /* Notify the DNS manager of the hostname change so that the domain part, if
|
||||||
|
+ * present, can be added to the search list.
|
||||||
|
+ */
|
||||||
|
nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname);
|
||||||
|
|
||||||
|
- set_system_hostname (policy, priv->cur_hostname, msg);
|
||||||
|
+ /* Finally, set kernel hostname */
|
||||||
|
+
|
||||||
|
+ if (!priv->cur_hostname)
|
||||||
|
+ name = FALLBACK_HOSTNAME4;
|
||||||
|
+ else if (!priv->cur_hostname[0]) {
|
||||||
|
+ g_warn_if_reached ();
|
||||||
|
+ name = FALLBACK_HOSTNAME4;
|
||||||
|
+ } else
|
||||||
|
+ name = priv->cur_hostname;
|
||||||
|
+
|
||||||
|
+ old_hostname[HOST_NAME_MAX] = '\0';
|
||||||
|
+ errno = 0;
|
||||||
|
+ ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||||
|
+ errno, strerror (errno));
|
||||||
|
+ } else {
|
||||||
|
+ /* Don't set the hostname if it isn't actually changing */
|
||||||
|
+ if (nm_streq (name, old_hostname))
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nm_log_info (LOGD_DNS, "setting system hostname to '%s' (%s)", name, msg);
|
||||||
|
+
|
||||||
|
+ /* Ask NMSettings to update the transient hostname using its
|
||||||
|
+ * systemd-hostnamed proxy */
|
||||||
|
+ nm_settings_set_transient_hostname (priv->settings,
|
||||||
|
+ name,
|
||||||
|
+ settings_set_hostname_cb,
|
||||||
|
+ NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
%global ppp_version %(rpm -q ppp-devel >/dev/null && rpm -q --qf '%%{version}' ppp-devel || echo -n bad)
|
%global ppp_version %(rpm -q ppp-devel >/dev/null && rpm -q --qf '%%{version}' ppp-devel || echo -n bad)
|
||||||
|
|
||||||
%global snapshot .beta2.1
|
%global snapshot .beta2
|
||||||
%global git_sha %{nil}
|
%global git_sha %{nil}
|
||||||
%global rpm_version 1.2.0
|
%global rpm_version 1.2.0
|
||||||
%global real_version 1.1.91
|
%global real_version 1.1.91
|
||||||
%global release_version 0.6
|
%global release_version 0.7
|
||||||
%global epoch_version 1
|
%global epoch_version 1
|
||||||
|
|
||||||
%global obsoletes_nmver 1:0.9.9.95-1
|
%global obsoletes_nmver 1:0.9.9.95-1
|
||||||
@ -91,7 +91,10 @@ Source1: NetworkManager.conf
|
|||||||
Source2: 00-server.conf
|
Source2: 00-server.conf
|
||||||
Source3: 20-connectivity-fedora.conf
|
Source3: 20-connectivity-fedora.conf
|
||||||
|
|
||||||
#Patch1: 0001-some.patch
|
Patch0: 0001-device-fix-handling-of-available-connections.patch
|
||||||
|
Patch1: 0001-core-use-hostnamed-to-set-the-transient-hostname.patch
|
||||||
|
Patch2: 0002-policy-simplify-set_system_hostname.patch
|
||||||
|
Patch3: 0003-policy-move-code-from-set_system_hostname-to-_set_ho.patch
|
||||||
|
|
||||||
Requires(post): systemd
|
Requires(post): systemd
|
||||||
Requires(preun): systemd
|
Requires(preun): systemd
|
||||||
@ -162,8 +165,6 @@ BuildRequires: dbus-python
|
|||||||
BuildRequires: libselinux-devel
|
BuildRequires: libselinux-devel
|
||||||
BuildRequires: polkit-devel
|
BuildRequires: polkit-devel
|
||||||
|
|
||||||
Patch0: 0001-device-fix-handling-of-available-connections.patch
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
NetworkManager is a system service that manages network interfaces and
|
NetworkManager is a system service that manages network interfaces and
|
||||||
@ -334,8 +335,10 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q -n NetworkManager-%{real_version}
|
%setup -q -n NetworkManager-%{real_version}
|
||||||
|
|
||||||
#%patch1 -p1
|
%patch0 -p1
|
||||||
%patch0 -p1 -b .available-connections
|
%patch1 -p1
|
||||||
|
%patch2 -p1
|
||||||
|
%patch3 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
|
||||||
@ -633,6 +636,9 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 22 2016 Lubomir Rintel <lkundrak@v3.sk> - 1:1.2.0-0.7.beta2
|
||||||
|
- Fix obtaining the hostname from DNS (rh #1308974)
|
||||||
|
|
||||||
* Thu Mar 17 2016 Dan Williams <dcbw@redhat.com> - 1:1.2.0-0.6.beta2.1
|
* Thu Mar 17 2016 Dan Williams <dcbw@redhat.com> - 1:1.2.0-0.6.beta2.1
|
||||||
- Fix activating connections in some cases (rh #1316488)
|
- Fix activating connections in some cases (rh #1316488)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user