diff options
author | Thomas Haller <thaller@redhat.com> | 2021-04-19 18:17:00 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-04-19 18:17:00 +0200 |
commit | 457be83839eaa57047ec20a588520ad037d80e6c (patch) | |
tree | c71318aa93d01e2c16b496bef22909390427eeef | |
parent | 34e4a3ef174005439af78278500290ce68e4bebb (diff) | |
parent | 26de0e02d9059d3bc018308952a0f9480430b797 (diff) | |
download | NetworkManager-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.c | 2 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-iwd.c | 136 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-iwd-manager.c | 57 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-wifi-utils.c | 21 | ||||
-rw-r--r-- | src/core/nm-checkpoint.c | 18 | ||||
-rw-r--r-- | src/core/nm-core-utils.c | 1 | ||||
-rw-r--r-- | src/core/nm-manager.c | 19 | ||||
-rw-r--r-- | src/core/settings/nm-settings-connection.c | 1 | ||||
-rw-r--r-- | src/core/settings/nm-settings-connection.h | 3 | ||||
-rw-r--r-- | src/core/settings/nm-settings.c | 9 | ||||
-rw-r--r-- | src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 1 | ||||
-rw-r--r-- | src/core/settings/plugins/keyfile/nms-keyfile-utils.c | 8 | ||||
-rw-r--r-- | src/core/settings/plugins/keyfile/nms-keyfile-writer.c | 5 | ||||
-rw-r--r-- | src/libnm-core-impl/nm-connection.c | 6 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-io-utils.c | 27 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-io-utils.h | 13 | ||||
-rw-r--r-- | src/nm-initrd-generator/nm-initrd-generator.c | 2 |
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); |