mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 23:50:10 +01:00
hostname: merge branch 'th/hostname-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/908
This commit is contained in:
commit
5a3761c5e2
6 changed files with 141 additions and 167 deletions
|
|
@ -17653,7 +17653,7 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use
|
|||
gboolean valid;
|
||||
|
||||
resolver->hostname = g_steal_pointer(&output);
|
||||
valid = nm_hostname_manager_validate_hostname(resolver->hostname);
|
||||
valid = nm_utils_validate_hostname(resolver->hostname);
|
||||
|
||||
_LOGD(LOGD_DNS,
|
||||
"hostname-from-dns: lookup done for %s, result %s%s%s%s",
|
||||
|
|
|
|||
|
|
@ -86,6 +86,19 @@ NM_DEFINE_SINGLETON_GETTER(NMHostnameManager, nm_hostname_manager_get, NM_TYPE_H
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline GFileMonitor *
|
||||
_file_monitor_new(const char *path)
|
||||
{
|
||||
gs_unref_object GFile *file = NULL;
|
||||
|
||||
nm_assert(path);
|
||||
|
||||
file = g_file_new_for_path(path);
|
||||
return g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if defined(HOSTNAME_PERSIST_GENTOO)
|
||||
static char *
|
||||
read_hostname_gentoo(const char *path)
|
||||
|
|
@ -162,21 +175,51 @@ hostname_is_dynamic(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Returns an allocated string which the caller owns and must eventually free */
|
||||
char *
|
||||
nm_hostname_manager_read_hostname(NMHostnameManager *self)
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_hostname_manager_get_hostname(NMHostnameManager *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_HOSTNAME_MANAGER(self), NULL);
|
||||
return NM_HOSTNAME_MANAGER_GET_PRIVATE(self)->current_hostname;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_hostname(NMHostnameManager *self, const char *hostname)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
char * old_hostname;
|
||||
|
||||
hostname = nm_str_not_empty(hostname);
|
||||
|
||||
if (nm_streq0(hostname, priv->current_hostname))
|
||||
return;
|
||||
|
||||
_LOGI("hostname changed from %s%s%s to %s%s%s",
|
||||
NM_PRINT_FMT_QUOTED(priv->current_hostname, "\"", priv->current_hostname, "\"", "(none)"),
|
||||
NM_PRINT_FMT_QUOTED(hostname, "\"", hostname, "\"", "(none)"));
|
||||
|
||||
old_hostname = priv->current_hostname;
|
||||
priv->current_hostname = g_strdup(hostname);
|
||||
g_free(old_hostname);
|
||||
|
||||
_notify(self, PROP_HOSTNAME);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_hostname_read_file(NMHostnameManager *self)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
char * hostname = NULL;
|
||||
gs_free char * hostname = NULL;
|
||||
|
||||
if (priv->hostnamed_proxy) {
|
||||
hostname = g_strdup(priv->current_hostname);
|
||||
goto out;
|
||||
/* read-hostname returns the current hostname with hostnamed. */
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HOSTNAME_PERSIST_SUSE)
|
||||
if (priv->dhcp_monitor_id && hostname_is_dynamic())
|
||||
return NULL;
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(HOSTNAME_PERSIST_GENTOO)
|
||||
|
|
@ -188,95 +231,32 @@ nm_hostname_manager_read_hostname(NMHostnameManager *self)
|
|||
g_strchomp(hostname);
|
||||
#endif
|
||||
|
||||
out:
|
||||
if (hostname && !hostname[0]) {
|
||||
g_free(hostname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hostname;
|
||||
_set_hostname(self, hostname);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_hostname_manager_get_hostname(NMHostnameManager *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_HOSTNAME_MANAGER(self), NULL);
|
||||
return NM_HOSTNAME_MANAGER_GET_PRIVATE(self)->current_hostname;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_hostname_take(NMHostnameManager *self, char *hostname)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
_LOGI("hostname changed from %s%s%s to %s%s%s",
|
||||
NM_PRINT_FMT_QUOTED(priv->current_hostname, "\"", priv->current_hostname, "\"", "(none)"),
|
||||
NM_PRINT_FMT_QUOTED(hostname, "\"", hostname, "\"", "(none)"));
|
||||
|
||||
g_free(priv->current_hostname);
|
||||
priv->current_hostname = hostname;
|
||||
_notify(self, PROP_HOSTNAME);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_hostname(NMHostnameManager *self, const char *hostname)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
hostname = nm_str_not_empty(hostname);
|
||||
if (!nm_streq0(hostname, priv->current_hostname))
|
||||
_set_hostname_take(self, g_strdup(hostname));
|
||||
}
|
||||
|
||||
static void
|
||||
_set_hostname_read(NMHostnameManager *self)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
char * hostname;
|
||||
|
||||
if (priv->hostnamed_proxy) {
|
||||
/* read-hostname returns the current hostname with hostnamed. */
|
||||
return;
|
||||
}
|
||||
|
||||
hostname = nm_hostname_manager_read_hostname(self);
|
||||
|
||||
if (nm_streq0(hostname, priv->current_hostname)) {
|
||||
g_free(hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
_set_hostname_take(self, hostname);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char * hostname;
|
||||
NMHostnameManagerSetHostnameCb 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;
|
||||
GDBusProxy * proxy = G_DBUS_PROXY(object);
|
||||
gs_unref_variant GVariant *result = NULL;
|
||||
gs_free_error GError * error = NULL;
|
||||
gs_free char * hostname = NULL;
|
||||
NMHostnameManagerSetHostnameCb cb;
|
||||
gpointer cb_user_data;
|
||||
|
||||
nm_utils_user_data_unpack(user_data, &hostname, &cb, &cb_user_data);
|
||||
|
||||
result = g_dbus_proxy_call_finish(proxy, res, &error);
|
||||
|
||||
if (error) {
|
||||
_LOGW("couldn't set the system hostname to '%s' using hostnamed: %s",
|
||||
info->hostname,
|
||||
hostname,
|
||||
error->message);
|
||||
}
|
||||
|
||||
info->cb(info->hostname, !error, info->user_data);
|
||||
g_free(info->hostname);
|
||||
cb(hostname, !error, cb_user_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -286,7 +266,6 @@ nm_hostname_manager_set_transient_hostname(NMHostnameManager * self,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv;
|
||||
SetHostnameInfo * info;
|
||||
|
||||
g_return_if_fail(NM_IS_HOSTNAME_MANAGER(self));
|
||||
|
||||
|
|
@ -297,11 +276,6 @@ nm_hostname_manager_set_transient_hostname(NMHostnameManager * self,
|
|||
return;
|
||||
}
|
||||
|
||||
info = g_new0(SetHostnameInfo, 1);
|
||||
info->hostname = g_strdup(hostname);
|
||||
info->cb = cb;
|
||||
info->user_data = user_data;
|
||||
|
||||
g_dbus_proxy_call(priv->hostnamed_proxy,
|
||||
"SetHostname",
|
||||
g_variant_new("(sb)", hostname, FALSE),
|
||||
|
|
@ -309,7 +283,7 @@ nm_hostname_manager_set_transient_hostname(NMHostnameManager * self,
|
|||
-1,
|
||||
NULL,
|
||||
set_transient_hostname_done,
|
||||
info);
|
||||
nm_utils_user_data_pack(g_strdup(hostname), cb, user_data));
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -428,43 +402,6 @@ nm_hostname_manager_write_hostname(NMHostnameManager *self, const char *hostname
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_hostname_manager_validate_hostname(const char *hostname)
|
||||
{
|
||||
const char *p;
|
||||
gboolean dot = TRUE;
|
||||
|
||||
if (!hostname || !hostname[0])
|
||||
return FALSE;
|
||||
|
||||
for (p = hostname; *p; p++) {
|
||||
if (*p == '.') {
|
||||
if (dot)
|
||||
return FALSE;
|
||||
dot = TRUE;
|
||||
} else {
|
||||
if (!g_ascii_isalnum(*p) && (*p != '-') && (*p != '_'))
|
||||
return FALSE;
|
||||
dot = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (dot)
|
||||
return FALSE;
|
||||
|
||||
return (p - hostname <= HOST_NAME_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
hostname_file_changed_cb(GFileMonitor * monitor,
|
||||
GFile * file,
|
||||
GFile * other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
_set_hostname_read(user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -473,26 +410,55 @@ hostnamed_properties_changed(GDBusProxy *proxy,
|
|||
char ** invalidated_properties,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMHostnameManager * self = user_data;
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
GVariant * v_hostname;
|
||||
NMHostnameManager * self = user_data;
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
|
||||
v_hostname = g_dbus_proxy_get_cached_property(priv->hostnamed_proxy, "StaticHostname");
|
||||
if (v_hostname) {
|
||||
_set_hostname(self, g_variant_get_string(v_hostname, NULL));
|
||||
g_variant_unref(v_hostname);
|
||||
variant = g_dbus_proxy_get_cached_property(priv->hostnamed_proxy, "StaticHostname");
|
||||
if (variant && g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING))
|
||||
_set_hostname(self, g_variant_get_string(variant, NULL));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_file_monitors_file_changed_cb(GFileMonitor * monitor,
|
||||
GFile * file,
|
||||
GFile * other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
_set_hostname_read_file(user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
_file_monitors_clear(NMHostnameManager *self)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
if (priv->monitor) {
|
||||
nm_clear_g_signal_handler(priv->monitor, &priv->monitor_id);
|
||||
g_file_monitor_cancel(priv->monitor);
|
||||
g_clear_object(&priv->monitor);
|
||||
}
|
||||
|
||||
if (priv->dhcp_monitor) {
|
||||
nm_clear_g_signal_handler(priv->dhcp_monitor, &priv->dhcp_monitor_id);
|
||||
g_file_monitor_cancel(priv->dhcp_monitor);
|
||||
g_clear_object(&priv->dhcp_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_hostname_file_monitors(NMHostnameManager *self)
|
||||
_file_monitors_setup(NMHostnameManager *self)
|
||||
{
|
||||
NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE(self);
|
||||
GFileMonitor * monitor;
|
||||
const char * path = HOSTNAME_FILE;
|
||||
char * link_path = NULL;
|
||||
gs_free char * link_path = NULL;
|
||||
struct stat file_stat;
|
||||
GFile * file;
|
||||
|
||||
_file_monitors_clear(self);
|
||||
|
||||
/* resolve the path to the hostname file if it is a symbolic link */
|
||||
if (lstat(path, &file_stat) == 0 && S_ISLNK(file_stat.st_mode)
|
||||
|
|
@ -505,29 +471,24 @@ setup_hostname_file_monitors(NMHostnameManager *self)
|
|||
}
|
||||
|
||||
/* monitor changes to hostname file */
|
||||
file = g_file_new_for_path(path);
|
||||
monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_object_unref(file);
|
||||
g_free(link_path);
|
||||
monitor = _file_monitor_new(path);
|
||||
if (monitor) {
|
||||
priv->monitor_id =
|
||||
g_signal_connect(monitor, "changed", G_CALLBACK(hostname_file_changed_cb), self);
|
||||
g_signal_connect(monitor, "changed", G_CALLBACK(_file_monitors_file_changed_cb), self);
|
||||
priv->monitor = monitor;
|
||||
}
|
||||
|
||||
#if defined(HOSTNAME_PERSIST_SUSE)
|
||||
/* monitor changes to dhcp file to know whether the hostname is valid */
|
||||
file = g_file_new_for_path(CONF_DHCP);
|
||||
monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_object_unref(file);
|
||||
monitor = _file_monitor_new(CONF_DHCP);
|
||||
if (monitor) {
|
||||
priv->dhcp_monitor_id =
|
||||
g_signal_connect(monitor, "changed", G_CALLBACK(hostname_file_changed_cb), self);
|
||||
g_signal_connect(monitor, "changed", G_CALLBACK(_file_monitors_file_changed_cb), self);
|
||||
priv->dhcp_monitor = monitor;
|
||||
}
|
||||
#endif
|
||||
|
||||
_set_hostname_read(self);
|
||||
_set_hostname_read_file(self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -591,7 +552,7 @@ constructed(GObject *object)
|
|||
}
|
||||
|
||||
if (!priv->hostnamed_proxy)
|
||||
setup_hostname_file_monitors(self);
|
||||
_file_monitors_setup(self);
|
||||
|
||||
G_OBJECT_CLASS(nm_hostname_manager_parent_class)->constructed(object);
|
||||
}
|
||||
|
|
@ -609,21 +570,7 @@ dispose(GObject *object)
|
|||
g_clear_object(&priv->hostnamed_proxy);
|
||||
}
|
||||
|
||||
if (priv->monitor) {
|
||||
if (priv->monitor_id)
|
||||
g_signal_handler_disconnect(priv->monitor, priv->monitor_id);
|
||||
|
||||
g_file_monitor_cancel(priv->monitor);
|
||||
g_clear_object(&priv->monitor);
|
||||
}
|
||||
|
||||
if (priv->dhcp_monitor) {
|
||||
if (priv->dhcp_monitor_id)
|
||||
g_signal_handler_disconnect(priv->dhcp_monitor, priv->dhcp_monitor_id);
|
||||
|
||||
g_file_monitor_cancel(priv->dhcp_monitor);
|
||||
g_clear_object(&priv->dhcp_monitor);
|
||||
}
|
||||
_file_monitors_clear(self);
|
||||
|
||||
nm_clear_g_free(&priv->current_hostname);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ NMHostnameManager *nm_hostname_manager_get(void);
|
|||
|
||||
const char *nm_hostname_manager_get_hostname(NMHostnameManager *self);
|
||||
|
||||
char *nm_hostname_manager_read_hostname(NMHostnameManager *self);
|
||||
|
||||
gboolean nm_hostname_manager_write_hostname(NMHostnameManager *self, const char *hostname);
|
||||
|
||||
void nm_hostname_manager_set_transient_hostname(NMHostnameManager * self,
|
||||
|
|
@ -47,6 +45,4 @@ void nm_hostname_manager_set_transient_hostname(NMHostnameManager * s
|
|||
|
||||
gboolean nm_hostname_manager_get_transient_hostname(NMHostnameManager *self, char **hostname);
|
||||
|
||||
gboolean nm_hostname_manager_validate_hostname(const char *hostname);
|
||||
|
||||
#endif /* __NM_HOSTNAME_MANAGER_H__ */
|
||||
|
|
|
|||
|
|
@ -3441,7 +3441,7 @@ impl_settings_save_hostname(NMDBusObject * obj,
|
|||
g_variant_get(parameters, "(&s)", &hostname);
|
||||
|
||||
/* Minimal validation of the hostname */
|
||||
if (!nm_hostname_manager_validate_hostname(hostname)) {
|
||||
if (!nm_utils_validate_hostname(hostname)) {
|
||||
error_code = NM_SETTINGS_ERROR_INVALID_HOSTNAME;
|
||||
error_reason = "The hostname was too long or contained invalid characters";
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -6356,3 +6356,32 @@ nm_utils_get_process_exit_status_desc(int status)
|
|||
else
|
||||
return g_strdup_printf("exited with unknown status 0x%x", status);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_utils_validate_hostname(const char *hostname)
|
||||
{
|
||||
const char *p;
|
||||
gboolean dot = TRUE;
|
||||
|
||||
if (!hostname || !hostname[0])
|
||||
return FALSE;
|
||||
|
||||
for (p = hostname; *p; p++) {
|
||||
if (*p == '.') {
|
||||
if (dot)
|
||||
return FALSE;
|
||||
dot = TRUE;
|
||||
} else {
|
||||
if (!g_ascii_isalnum(*p) && (*p != '-') && (*p != '_'))
|
||||
return FALSE;
|
||||
dot = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (dot)
|
||||
return FALSE;
|
||||
|
||||
return (p - hostname <= HOST_NAME_MAX);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2992,4 +2992,6 @@ void nm_crypto_md5_hash(const guint8 *salt,
|
|||
|
||||
char *nm_utils_get_process_exit_status_desc(int status);
|
||||
|
||||
gboolean nm_utils_validate_hostname(const char *hostname);
|
||||
|
||||
#endif /* __NM_SHARED_UTILS_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue