summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-04-19 18:17:00 +0200
committerThomas Haller <thaller@redhat.com>2021-04-19 18:17:00 +0200
commit457be83839eaa57047ec20a588520ad037d80e6c (patch)
treec71318aa93d01e2c16b496bef22909390427eeef
parent34e4a3ef174005439af78278500290ce68e4bebb (diff)
parent26de0e02d9059d3bc018308952a0f9480430b797 (diff)
downloadNetworkManager-457be83839eaa57047ec20a588520ad037d80e6c.tar.gz
wifi/iwd: merge branch 'balrog-kun:iwd-secrets-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/813
-rw-r--r--src/core/devices/nm-device.c2
-rw-r--r--src/core/devices/wifi/nm-device-iwd.c136
-rw-r--r--src/core/devices/wifi/nm-iwd-manager.c57
-rw-r--r--src/core/devices/wifi/nm-wifi-utils.c21
-rw-r--r--src/core/nm-checkpoint.c18
-rw-r--r--src/core/nm-core-utils.c1
-rw-r--r--src/core/nm-manager.c19
-rw-r--r--src/core/settings/nm-settings-connection.c1
-rw-r--r--src/core/settings/nm-settings-connection.h3
-rw-r--r--src/core/settings/nm-settings.c9
-rw-r--r--src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c1
-rw-r--r--src/core/settings/plugins/keyfile/nms-keyfile-utils.c8
-rw-r--r--src/core/settings/plugins/keyfile/nms-keyfile-writer.c5
-rw-r--r--src/libnm-core-impl/nm-connection.c6
-rw-r--r--src/libnm-glib-aux/nm-io-utils.c27
-rw-r--r--src/libnm-glib-aux/nm-io-utils.h13
-rw-r--r--src/nm-initrd-generator/nm-initrd-generator.c2
17 files changed, 226 insertions, 103 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 5b2903d809..0207a048c0 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -13633,7 +13633,7 @@ nm_device_set_ip_config(NMDevice * self,
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY,
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
- NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE,
+ NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET,
"update-external",
NULL);
}
diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c
index 760ed89e62..f57f8f8110 100644
--- a/src/core/devices/wifi/nm-device-iwd.c
+++ b/src/core/devices/wifi/nm-device-iwd.c
@@ -1317,6 +1317,7 @@ static gboolean
try_reply_agent_request(NMDeviceIwd * self,
NMConnection * connection,
GDBusMethodInvocation *invocation,
+ gboolean allow_existing,
const char ** setting_name,
const char ** setting_key,
gboolean * replied)
@@ -1331,56 +1332,64 @@ try_reply_agent_request(NMDeviceIwd * self,
*replied = FALSE;
if (nm_streq(method_name, "RequestPassphrase")) {
- const char *psk;
-
if (!s_wireless_sec)
return FALSE;
- psk = nm_setting_wireless_security_get_psk(s_wireless_sec);
- if (psk) {
- _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent");
+ if (allow_existing) {
+ const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec);
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk));
- *replied = TRUE;
- return TRUE;
+ if (psk) {
+ _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent");
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk));
+ *replied = TRUE;
+ return TRUE;
+ }
}
*setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
*setting_key = NM_SETTING_WIRELESS_SECURITY_PSK;
return TRUE;
} else if (nm_streq(method_name, "RequestPrivateKeyPassphrase")) {
- const char *password;
-
if (!s_8021x)
return FALSE;
- password = nm_setting_802_1x_get_private_key_password(s_8021x);
- if (password) {
- _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the private key password to the IWD Agent");
+ if (allow_existing) {
+ const char *password = nm_setting_802_1x_get_private_key_password(s_8021x);
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password));
- *replied = TRUE;
- return TRUE;
+ if (password) {
+ _LOGD(LOGD_DEVICE | LOGD_WIFI,
+ "Returning the private key password to the IWD Agent");
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password));
+ *replied = TRUE;
+ return TRUE;
+ }
}
*setting_name = NM_SETTING_802_1X_SETTING_NAME;
*setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD;
return TRUE;
} else if (nm_streq(method_name, "RequestUserNameAndPassword")) {
- const char *identity, *password;
+ const char *identity;
if (!s_8021x)
return FALSE;
identity = nm_setting_802_1x_get_identity(s_8021x);
- password = nm_setting_802_1x_get_password(s_8021x);
- if (identity && password) {
- _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the username and password to the IWD Agent");
- g_dbus_method_invocation_return_value(invocation,
- g_variant_new("(ss)", identity, password));
- *replied = TRUE;
- return TRUE;
+ if (allow_existing) {
+ const char *password = nm_setting_802_1x_get_password(s_8021x);
+
+ if (identity && password) {
+ _LOGD(LOGD_DEVICE | LOGD_WIFI,
+ "Returning the username and password to the IWD Agent");
+
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(ss)", identity, password));
+ *replied = TRUE;
+ return TRUE;
+ }
}
*setting_name = NM_SETTING_802_1X_SETTING_NAME;
@@ -1390,18 +1399,19 @@ try_reply_agent_request(NMDeviceIwd * self,
*setting_key = NM_SETTING_802_1X_PASSWORD;
return TRUE;
} else if (nm_streq(method_name, "RequestUserPassword")) {
- const char *password;
-
if (!s_8021x)
return FALSE;
- password = nm_setting_802_1x_get_password(s_8021x);
- if (password) {
- _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent");
+ if (allow_existing) {
+ const char *password = nm_setting_802_1x_get_password(s_8021x);
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password));
- *replied = TRUE;
- return TRUE;
+ if (password) {
+ _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent");
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password));
+ *replied = TRUE;
+ return TRUE;
+ }
}
*setting_name = NM_SETTING_802_1X_SETTING_NAME;
@@ -1452,6 +1462,8 @@ wifi_secrets_cb(NMActRequest * req,
gboolean replied;
NMSecretAgentGetSecretsFlags get_secret_flags =
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+ NMIwdNetworkSecurity security;
+ NMConnection * connection;
nm_utils_user_data_unpack(user_data, &self, &invocation);
@@ -1484,9 +1496,18 @@ wifi_secrets_cb(NMActRequest * req,
goto secrets_error;
}
+ connection = nm_device_get_applied_connection(device);
+
+ if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)
+ && security == NM_IWD_NETWORK_SECURITY_PSK) {
+ if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL))
+ get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
+ }
+
if (!try_reply_agent_request(self,
- nm_act_request_get_applied_connection(req),
+ connection,
invocation,
+ TRUE,
&setting_name,
&setting_key,
&replied))
@@ -1512,9 +1533,6 @@ wifi_secrets_cb(NMActRequest * req,
return;
}
- if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), NULL))
- get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
-
/* Request further secrets if we still need something */
wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation);
return;
@@ -1606,8 +1624,6 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data)
dbus_error = g_dbus_error_get_remote_error(error);
if (nm_streq0(dbus_error, "net.connman.iwd.Failed")) {
- nm_connection_clear_secrets(connection);
-
/* If secrets were wrong, we'd be getting a net.connman.iwd.Failed */
reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
} else if (nm_streq0(dbus_error, "net.connman.iwd.Aborted") && priv->secrets_failed) {
@@ -3156,8 +3172,11 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation)
const char * setting_key;
gboolean replied;
NMWifiAP * ap;
+ gboolean allow_existing = FALSE;
NMSecretAgentGetSecretsFlags get_secret_flags =
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+ NMIwdNetworkSecurity security;
+ NMConnection * connection;
nm_auto_ref_string NMRefString *network_path = NULL;
if (!invocation) {
@@ -3261,9 +3280,37 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation)
/* Otherwise handle as usual */
}
+ /* Normally for PSK networks require new secret every time IWD asks for
+ * it. IWD only queries us if it has not saved the PSK (e.g. by policy)
+ * or a previous attempt has failed with current secrets so it wants a
+ * fresh value. It doesn't know about agent-owned secrets so whenever
+ * possible and the PSK is saved and not asked from NM. However if this
+ * is a new connection it may include all of the needed settings already
+ * so allow using these, too. Connection timestamp is set after
+ * activation or after first activation failure (to 0).
+ *
+ * For 802.1x, since IWD assumes the network is pre-provisioned by an
+ * admin and tested, there's no reason for IWD to save secrets in
+ * the network config file and there's no reason to ask for a new value
+ * of a saved (i.e. system-owned) secret because it can't be wrong.
+ * Since NM has a richer set of secret storage options we never specify
+ * NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW and let
+ * nm_settings_connection_get_secrets decide.
+ */
+ connection = nm_device_get_applied_connection(device);
+
+ if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)
+ && security == NM_IWD_NETWORK_SECURITY_PSK) {
+ if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL))
+ get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
+ else
+ allow_existing = TRUE;
+ }
+
if (!try_reply_agent_request(self,
- nm_device_get_applied_connection(device),
+ connection,
invocation,
+ allow_existing,
&setting_name,
&setting_key,
&replied)) {
@@ -3274,17 +3321,6 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation)
if (replied)
return TRUE;
- /* Normally require new secrets every time IWD asks for them.
- * IWD only queries us if it has not saved the secrets (e.g. by policy)
- * or a previous attempt has failed with current secrets so it wants
- * a fresh set. However if this is a new connection it may include
- * all of the needed settings already so allow using these, too.
- * Connection timestamp is set after activation or after first
- * activation failure (to 0).
- */
- if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL))
- get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
-
nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NO_SECRETS);
wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation);
diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c
index 1c4b211f41..20a1703adb 100644
--- a/src/core/devices/wifi/nm-iwd-manager.c
+++ b/src/core/devices/wifi/nm-iwd-manager.c
@@ -10,12 +10,14 @@
#include <net/if.h>
#include <glib/gstdio.h>
#include <errno.h>
+#include <sys/stat.h>
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-manager.h"
#include "nm-device-iwd.h"
#include "nm-wifi-utils.h"
#include "libnm-glib-aux/nm-random-utils.h"
+#include "libnm-glib-aux/nm-io-utils.h"
#include "settings/nm-settings.h"
#include "libnm-std-aux/nm-dbus-compat.h"
#include "nm-config.h"
@@ -430,6 +432,25 @@ known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data)
}
}
+static gboolean
+iwd_config_write(GKeyFile * config,
+ const char * filepath,
+ const struct timespec *mtime,
+ GError ** error)
+{
+ gsize length;
+ gs_free char * data = g_key_file_to_data(config, &length, NULL);
+ struct timespec times[2] = {{.tv_nsec = UTIME_OMIT}, *mtime};
+
+ /* Atomically write or replace the file with the right permission bits
+ * and timestamps set. We rely on the temporary file created by
+ * nm_utils_file_set_contents having only upper-case letters and digits
+ * in the last few filename characters -- it cannot end in .open, .psk
+ * or .8021x.
+ */
+ return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, error);
+}
+
static void
sett_conn_changed(NMSettingsConnection * sett_conn,
guint update_reason,
@@ -449,13 +470,15 @@ sett_conn_changed(NMSettingsConnection * sett_conn,
const guint8 * ssid_data;
gsize ssid_len;
gboolean removed;
+ GStatBuf statbuf;
+ gboolean have_mtime;
nm_assert(sett_conn == data->mirror_connection);
- if (update_reason
- & (NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS
- | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
- | NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT))
+ if (!NM_FLAGS_ANY(update_reason,
+ NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS))
return;
/* If this is a generated connection it may be ourselves updating it */
@@ -496,9 +519,10 @@ sett_conn_changed(NMSettingsConnection * sett_conn,
* create another anyway because the SSID and security type are in the
* D-Bus object path, so no point renaming the file.
*/
- ssid = nm_setting_wireless_get_ssid(s_wifi);
- ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL;
- removed = FALSE;
+ ssid = nm_setting_wireless_get_ssid(s_wifi);
+ ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL;
+ removed = FALSE;
+ have_mtime = FALSE;
if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security)
|| security != data->id->security || !ssid_data || ssid_len != strlen(data->id->name)
@@ -507,6 +531,9 @@ sett_conn_changed(NMSettingsConnection * sett_conn,
nm_wifi_utils_get_iwd_config_filename(data->id->name, -1, data->id->security);
gs_free char *orig_full_path = g_strdup_printf("%s/%s", iwd_dir, orig_filename);
+ if (g_stat(orig_full_path, &statbuf) == 0)
+ have_mtime = TRUE;
+
if (g_remove(orig_full_path) == 0)
nm_log_dbg(LOGD_WIFI, "iwd: profile at %s removed", orig_full_path);
else if (errno != ENOENT)
@@ -558,7 +585,21 @@ sett_conn_changed(NMSettingsConnection * sett_conn,
return;
}
- if (!g_key_file_save_to_file(iwd_config, full_path, &error)) {
+ if (!removed && g_stat(full_path, &statbuf) == 0)
+ have_mtime = TRUE;
+
+ /* If modifying an existing network try to preserve the file mtime,
+ * otherwise use a small non-zero timespec value to signal that the
+ * network is autoconnectable (according to its AutoConnect value)
+ * but hasn't recently been connected to and thus shouldn't be
+ * prioritized by autoconnect.
+ */
+ if (!have_mtime) {
+ statbuf.st_mtim.tv_sec = 1;
+ statbuf.st_mtim.tv_nsec = 0;
+ }
+
+ if (!iwd_config_write(iwd_config, full_path, &statbuf.st_mtim, &error)) {
nm_log_dbg(LOGD_WIFI,
"iwd: changed Wi-Fi connection %s not mirrored as IWD profile: save error: %s",
nm_settings_connection_get_id(sett_conn),
diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c
index 2af1ab767c..5536aa4f08 100644
--- a/src/core/devices/wifi/nm-wifi-utils.c
+++ b/src/core/devices/wifi/nm-wifi-utils.c
@@ -14,6 +14,7 @@
#include "nm-utils.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-core-aux-intern/nm-common-macros.h"
+#include "libnm-base/nm-config-base.h"
static gboolean
verify_no_wep(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error)
@@ -996,6 +997,9 @@ nm_wifi_utils_get_iwd_config_filename(const char * ssid,
/*****************************************************************************/
+#define SECRETS_DONT_STORE_FLAGS \
+ (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED)
+
static gboolean
psk_setting_to_iwd_config(GKeyFile *file, NMSettingWirelessSecurity *s_wsec, GError **error)
{
@@ -1005,13 +1009,13 @@ psk_setting_to_iwd_config(GKeyFile *file, NMSettingWirelessSecurity *s_wsec, GEr
guint8 buffer[32];
const char * key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec);
- if (!psk || (psk_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
+ if (!psk || NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) {
g_key_file_set_comment(file,
"Security",
NULL,
"The passphrase is to be queried through the agent",
NULL);
- if (psk_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) {
+ if (NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) {
nm_log_info(
LOGD_WIFI,
"IWD network config is being created wihout the PSK but IWD will save the PSK on "
@@ -1184,7 +1188,7 @@ eap_certs_to_iwd_config(GKeyFile * file,
: nm_setting_802_1x_get_private_key_password(s_8021x);
key_password_flags = phase2 ? nm_setting_802_1x_get_phase2_private_key_password_flags(s_8021x)
: nm_setting_802_1x_get_private_key_password_flags(s_8021x);
- if (!key_password || (key_password_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
+ if (!key_password || NM_FLAGS_ANY(key_password_flags, SECRETS_DONT_STORE_FLAGS)) {
g_key_file_set_comment(
file,
"Security",
@@ -1320,7 +1324,7 @@ eap_optional_password_to_iwd_config(GKeyFile * file,
"the \"password\" property");
return FALSE;
}
- if (!password || (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) {
+ if (!password || NM_FLAGS_ANY(flags, SECRETS_DONT_STORE_FLAGS)) {
return g_key_file_set_comment(file,
"Security",
nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"),
@@ -1680,6 +1684,7 @@ nm_wifi_utils_connection_to_iwd_config(NMConnection *connection,
gsize ssid_len;
NMIwdNetworkSecurity security;
const char * cloned_mac_addr;
+ gs_free char * comment = NULL;
nm_auto_unref_keyfile GKeyFile *file = NULL;
if (!s_conn || !s_wifi
@@ -1722,6 +1727,14 @@ nm_wifi_utils_connection_to_iwd_config(NMConnection *connection,
file = g_key_file_new();
+ comment = g_strdup_printf(" Auto-generated from NetworkManager connection \"%s\"\n"
+ " Changes to that connection overwrite this file when "
+ "enabled by NM's [%s].%s value",
+ nm_setting_connection_get_id(s_conn),
+ NM_CONFIG_KEYFILE_GROUP_MAIN,
+ NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH);
+ g_key_file_set_comment(file, NULL, NULL, comment, NULL);
+
if (!nm_setting_connection_get_autoconnect(s_conn))
g_key_file_set_boolean(file, "Settings", "AutoConnect", FALSE);
diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c
index 3e22239608..76210abc0e 100644
--- a/src/core/nm-checkpoint.c
+++ b/src/core/nm-checkpoint.c
@@ -229,14 +229,16 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp
if (need_update) {
_LOGD("rollback: updating connection %s", nm_settings_connection_get_uuid(connection));
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP;
- nm_settings_connection_update(connection,
- dev_checkpoint->settings_connection,
- persist_mode,
- sett_flags,
- sett_mask,
- NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE,
- "checkpoint-rollback",
- NULL);
+ nm_settings_connection_update(
+ connection,
+ dev_checkpoint->settings_connection,
+ persist_mode,
+ sett_flags,
+ sett_mask,
+ NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET,
+ "checkpoint-rollback",
+ NULL);
}
} else {
/* The connection was deleted, recreate it */
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c
index ac146be9d8..8fe6b70982 100644
--- a/src/core/nm-core-utils.c
+++ b/src/core/nm-core-utils.c
@@ -2732,6 +2732,7 @@ _host_id_read(guint8 **out_host_id, gsize *out_host_id_len)
len,
0600,
NULL,
+ NULL,
&error)) {
nm_log_warn(
LOGD_CORE,
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index f5a696f1fa..90bfad73ee 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -2892,15 +2892,16 @@ recheck_assume_connection(NMManager *self, NMDevice *device)
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NULL));
- nm_settings_connection_update(sett_conn,
- con2,
- NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
- NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
- NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
- | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL,
- NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE,
- "assume-initrd",
- NULL);
+ nm_settings_connection_update(
+ sett_conn,
+ con2,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
+ NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
+ | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL,
+ NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET,
+ "assume-initrd",
+ NULL);
}
}
}
diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c
index 7b5477f477..a712831779 100644
--- a/src/core/settings/nm-settings-connection.c
+++ b/src/core/settings/nm-settings-connection.c
@@ -1536,6 +1536,7 @@ update_auth_cb(NMSettingsConnection * self,
: NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL)
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET
| (NM_FLAGS_HAS(info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)
? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT
: NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE),
diff --git a/src/core/settings/nm-settings-connection.h b/src/core/settings/nm-settings-connection.h
index 7c61dbebb4..79444823d1 100644
--- a/src/core/settings/nm-settings-connection.h
+++ b/src/core/settings/nm-settings-connection.h
@@ -63,6 +63,9 @@ typedef enum {
NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT = (1u << 8),
+ /* Is anything other than secrets changing */
+ NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET = (1u << 9),
+
} NMSettingsConnectionUpdateReason;
typedef enum {
diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c
index 4c43484d39..de4cd58a18 100644
--- a/src/core/settings/nm-settings.c
+++ b/src/core/settings/nm-settings.c
@@ -1433,7 +1433,8 @@ _plugin_connections_reload(NMSettings *self)
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
TRUE,
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
- | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS);
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET);
for (iter = priv->plugins; iter; iter = iter->next)
nm_settings_plugin_load_connections_done(iter->data);
@@ -1910,7 +1911,8 @@ again_delete_tombstone:
_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK,
FALSE,
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
- | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_AGENT_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET
| (NM_FLAGS_HAS(add_reason, NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT)
? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT
: NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE));
@@ -2810,7 +2812,8 @@ impl_settings_load_connections(NMDBusObject * obj,
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
TRUE,
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
- | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS);
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
+ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET);
for (iter = priv->plugins; iter; iter = iter->next)
nm_settings_plugin_load_connections_done(iter->data);
diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 955a9e89d5..9801d3b3e7 100644
--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -299,6 +299,7 @@ write_blobs(GHashTable *blobs, GError **error)
g_bytes_get_size(blob),
0600,
NULL,
+ NULL,
&write_error)) {
g_set_error(error,
NM_SETTINGS_ERROR,
diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c
index c26b8676f1..affe1c3d2a 100644
--- a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c
+++ b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c
@@ -269,7 +269,13 @@ nms_keyfile_nmmeta_write(const char *dirname,
contents = g_key_file_to_data(kf, &length, NULL);
- if (!nm_utils_file_set_contents(full_filename, contents, length, 0600, &errsv, NULL)) {
+ if (!nm_utils_file_set_contents(full_filename,
+ contents,
+ length,
+ 0600,
+ NULL,
+ &errsv,
+ NULL)) {
NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp));
return -NM_ERRNO_NATIVE(errsv);
}
diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c
index 661a828058..70afdc2362 100644
--- a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c
+++ b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c
@@ -125,13 +125,14 @@ cert_writer(NMConnection * connection,
/* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before
* being sure that the entire profile can be written and all circumstances are good to
- * proceed. That means, while writing we must only collect the blogs in-memory, and write
+ * proceed. That means, while writing we must only collect the blobs in-memory, and write
* them all in the end together (or not at all). */
success = nm_utils_file_set_contents(new_path,
(const char *) blob_data,
blob_len,
0600,
NULL,
+ NULL,
&local);
if (success) {
/* Write the path value to the keyfile.
@@ -378,7 +379,7 @@ _internal_write_connection(NMConnection * connection,
}
}
- nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, &local_err);
+ nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, NULL, &local_err);
if (local_err) {
g_set_error(error,
NM_SETTINGS_ERROR,
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c
index bc070a9d84..fe46274fbb 100644
--- a/src/libnm-core-impl/nm-connection.c
+++ b/src/libnm-core-impl/nm-connection.c
@@ -3375,9 +3375,9 @@ nm_connection_default_init(NMConnectionInterface *iface)
* NMConnection::changed:
* @connection: the object on which the signal is emitted
*
- * The ::changed signal is emitted when any property of any property
- * (including secrets) of any setting of the connection is modified,
- * or when settings are added or removed.
+ * The ::changed signal is emitted when any property (including secrets)
+ * of any setting of the connection is modified, or when settings are
+ * added or removed.
*/
signals[CHANGED] = g_signal_new(NM_CONNECTION_CHANGED,
NM_TYPE_CONNECTION,
diff --git a/src/libnm-glib-aux/nm-io-utils.c b/src/libnm-glib-aux/nm-io-utils.c
index e02049af1a..0176abf7f8 100644
--- a/src/libnm-glib-aux/nm-io-utils.c
+++ b/src/libnm-glib-aux/nm-io-utils.c
@@ -332,15 +332,17 @@ nm_utils_file_get_contents(int dirfd,
/*
* Copied from GLib's g_file_set_contents() et al., but allows
- * specifying a mode for the new file.
+ * specifying a mode for the new file and optionally the last access
+ * and last modification times.
*/
gboolean
-nm_utils_file_set_contents(const char *filename,
- const char *contents,
- gssize length,
- mode_t mode,
- int * out_errsv,
- GError ** error)
+nm_utils_file_set_contents(const char * filename,
+ const char * contents,
+ gssize length,
+ mode_t mode,
+ const struct timespec *times,
+ int * out_errsv,
+ GError ** error)
{
gs_free char *tmp_name = NULL;
struct stat statbuf;
@@ -399,6 +401,17 @@ nm_utils_file_set_contents(const char *filename,
}
}
+ if (times && futimens(fd, times) != 0) {
+ errsv = NM_ERRNO_NATIVE(errno);
+ nm_close(fd);
+ unlink(tmp_name);
+ return _get_contents_error(error,
+ errsv,
+ out_errsv,
+ "failed to set atime and mtime on %s",
+ tmp_name);
+ }
+
nm_close(fd);
if (rename(tmp_name, filename)) {
diff --git a/src/libnm-glib-aux/nm-io-utils.h b/src/libnm-glib-aux/nm-io-utils.h
index 8182f5cf60..2b132ff07d 100644
--- a/src/libnm-glib-aux/nm-io-utils.h
+++ b/src/libnm-glib-aux/nm-io-utils.h
@@ -40,12 +40,13 @@ gboolean nm_utils_file_get_contents(int dirfd,
int * out_errsv,
GError ** error);
-gboolean nm_utils_file_set_contents(const char *filename,
- const char *contents,
- gssize length,
- mode_t mode,
- int * out_errsv,
- GError ** error);
+gboolean nm_utils_file_set_contents(const char * filename,
+ const char * contents,
+ gssize length,
+ mode_t mode,
+ const struct timespec *times,
+ int * out_errsv,
+ GError ** error);
struct _NMStrBuf;
diff --git a/src/nm-initrd-generator/nm-initrd-generator.c b/src/nm-initrd-generator/nm-initrd-generator.c
index 337e4559d9..490a4547d5 100644
--- a/src/nm-initrd-generator/nm-initrd-generator.c
+++ b/src/nm-initrd-generator/nm-initrd-generator.c
@@ -54,7 +54,7 @@ output_conn(gpointer key, gpointer value, gpointer user_data)
filename = nm_keyfile_utils_create_filename(basename, TRUE);
full_filename = g_build_filename(connections_dir, filename, NULL);
- if (!nm_utils_file_set_contents(full_filename, data, len, 0600, NULL, &error))
+ if (!nm_utils_file_set_contents(full_filename, data, len, 0600, NULL, NULL, &error))
goto err_out;
} else
g_print("\n*** Connection '%s' ***\n\n%s", basename, data);