diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 24c6a25f63..525291e9ce 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -391,6 +391,7 @@ enslave_slave (NMDevice *device, NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean success = TRUE, no_firmware = FALSE; const char *slave_iface = nm_device_get_ip_iface (slave); + NMConnection *master_con; nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND); @@ -405,6 +406,25 @@ enslave_slave (NMDevice *device, return FALSE; _LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface); + + /* The active_slave option can be set only after the interface is enslaved */ + master_con = nm_device_get_applied_connection (device); + if (master_con) { + NMSettingBond *s_bond = nm_connection_get_setting_bond (master_con); + const char *active; + + if (s_bond) { + active = nm_setting_bond_get_option_by_name (s_bond, "active_slave"); + if (active && nm_streq0 (active, nm_device_get_iface (slave))) { + nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, + nm_device_get_ifindex (device), + "active_slave", + active); + _LOGD (LOGD_BOND, "setting slave %s as active one for master %s", + active, nm_device_get_iface (device)); + } + } + } } else _LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface); @@ -478,6 +498,116 @@ create_and_realize (NMDevice *device, return TRUE; } +static gboolean +check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error) +{ + guint i, num; + const char *name, *value_a, *value_b; + + /* Check that options in @s_a have compatible changes in @s_b */ + + num = nm_setting_bond_get_num_options (s_a); + for (i = 0; i < num; i++) { + nm_setting_bond_get_option (s_a, i, &name, &value_a); + + /* We support changes to these */ + if (NM_IN_STRSET (name, + NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, + NM_SETTING_BOND_OPTION_PRIMARY)) { + continue; + } + + /* Missing in @s_b, but has a default value in @s_a */ + value_b = nm_setting_bond_get_option_by_name (s_b, name); + if ( !value_b + && nm_streq0 (value_a, nm_setting_bond_get_option_default (s_a, name))) { + continue; + } + + /* Reject any other changes */ + if (!nm_streq0 (value_a, value_b)) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply '%s' bond option", + name); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +can_reapply_change (NMDevice *device, + const char *setting_name, + NMSetting *s_old, + NMSetting *s_new, + GHashTable *diffs, + GError **error) +{ + NMDeviceClass *device_class; + NMSettingBond *s_bond_old, *s_bond_new; + + /* Only handle bond setting here, delegate other settings to parent class */ + if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) { + if (!nm_device_hash_check_invalid_keys (diffs, + NM_SETTING_BOND_SETTING_NAME, + error, + NM_SETTING_BOND_OPTIONS)) + return FALSE; + + s_bond_old = NM_SETTING_BOND (s_old); + s_bond_new = NM_SETTING_BOND (s_new); + + if ( !check_changed_options (s_bond_old, s_bond_new, error) + || !check_changed_options (s_bond_new, s_bond_old, error)) { + return FALSE; + } + + return TRUE; + } + + device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class); + return device_class->can_reapply_change (device, + setting_name, + s_old, + s_new, + diffs, + error); +} + +static void +reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_new) +{ + NMDeviceBond *self = NM_DEVICE_BOND (device); + const char *value; + NMSettingBond *s_bond; + NMBondMode mode; + + NM_DEVICE_CLASS (nm_device_bond_parent_class)->reapply_connection (device, + con_old, + con_new); + + _LOGD (LOGD_BOND, "reapplying bond settings"); + s_bond = nm_connection_get_setting_bond (con_new); + g_return_if_fail (s_bond); + + value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE); + if (!value) + value = "balance-rr"; + + mode = _nm_setting_bond_mode_from_string (value); + g_return_if_fail (mode != NM_BOND_MODE_UNKNOWN); + + /* Primary */ + value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_PRIMARY, value ? value : ""); + + /* Active slave */ + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); +} + /*****************************************************************************/ static void @@ -506,6 +636,8 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; parent_class->enslave_slave = enslave_slave; parent_class->release_slave = release_slave; + parent_class->can_reapply_change = can_reapply_change; + parent_class->reapply_connection = reapply_connection; nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_BOND_SKELETON, diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 2023feb577..a4067f9c26 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -134,4 +134,9 @@ guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is NM_DEVICE_CLASS (klass)->link_types = link_types; \ } +gboolean _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, + GError **error, const char **argv); +#define nm_device_hash_check_invalid_keys(hash, setting_name, error, ...) \ + _nm_device_hash_check_invalid_keys (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL })) + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ef96243b2f..94b94c0151 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -8331,12 +8331,14 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type) addrconf6_cleanup (self); } -static gboolean -_hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GError **error, const char **argv) +gboolean +_nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, + GError **error, const char **argv) { guint found_keys = 0; guint i; + nm_assert (hash && g_hash_table_size (hash) > 0); nm_assert (argv && argv[0]); #if NM_MORE_ASSERTS > 10 @@ -8352,9 +8354,6 @@ _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GErro } #endif - if (!hash || g_hash_table_size (hash) == 0) - return TRUE; - for (i = 0; argv[i]; i++) { if (g_hash_table_contains (hash, argv[i])) found_keys++; @@ -8395,7 +8394,6 @@ _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GErro return TRUE; } -#define _hash_check_invalid_keys(hash, setting_name, error, ...) _hash_check_invalid_keys_impl (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL })) void nm_device_reactivate_ip4_config (NMDevice *self, @@ -8473,12 +8471,55 @@ nm_device_reactivate_ip6_config (NMDevice *self, } } +static gboolean +can_reapply_change (NMDevice *self, const char *setting_name, + NMSetting *s_old, NMSetting *s_new, + GHashTable *diffs, GError **error) +{ + if (!NM_IN_STRSET (setting_name, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_CONNECTION_SETTING_NAME)) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply any changes to '%s' setting", + setting_name); + return FALSE; + } -/* reapply_connection: + /* whitelist allowed properties from "connection" setting which are allowed to differ. + * + * This includes UUID, there is no principal problem with reapplying a connection + * and changing it's UUID. In fact, disallowing it makes it cumbersome for the user + * to reapply any connection but the original settings-connection. */ + if ( nm_streq0 (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) + && !nm_device_hash_check_invalid_keys (diffs, + NM_SETTING_CONNECTION_SETTING_NAME, + error, + NM_SETTING_CONNECTION_ID, + NM_SETTING_CONNECTION_UUID, + NM_SETTING_CONNECTION_STABLE_ID, + NM_SETTING_CONNECTION_AUTOCONNECT, + NM_SETTING_CONNECTION_ZONE, + NM_SETTING_CONNECTION_METERED)) + return FALSE; + + return TRUE; +} + +static void +reapply_connection (NMDevice *self, NMConnection *con_old, NMConnection *con_new) +{ + +} + +/* check_and_reapply_connection: * @connection: the new connection settings to be applied or %NULL to reapply * the current settings connection * @version_id: either zero, or the current version id for the applied * connection. + * @audit_args: on return, a string representing the changes * @error: the error if %FALSE is returned * * Change configuration of an already configured device if possible. @@ -8487,11 +8528,13 @@ nm_device_reactivate_ip6_config (NMDevice *self, * Return: %FALSE if the new configuration can not be reapplied. */ static gboolean -reapply_connection (NMDevice *self, - NMConnection *connection, - guint64 version_id, - GError **error) +check_and_reapply_connection (NMDevice *self, + NMConnection *connection, + guint64 version_id, + char **audit_args, + GError **error) { + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *applied = nm_device_get_applied_connection (self); gs_unref_object NMConnection *applied_clone = NULL; @@ -8499,6 +8542,7 @@ reapply_connection (NMDevice *self, NMConnection *con_old, *con_new; NMSettingIPConfig *s_ip4_old, *s_ip4_new; NMSettingIPConfig *s_ip6_old, *s_ip6_new; + GHashTableIter iter; if (priv->state != NM_DEVICE_STATE_ACTIVATED) { g_set_error_literal (error, @@ -8514,30 +8558,27 @@ reapply_connection (NMDevice *self, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, &diffs); + if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) + *audit_args = nm_utils_format_con_diff_for_audit (diffs); + /************************************************************************** * check for unsupported changes and reject to reapply *************************************************************************/ - if (!_hash_check_invalid_keys (diffs, NULL, error, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_CONNECTION_SETTING_NAME)) - return FALSE; + if (diffs) { + char *setting_name; + GHashTable *setting_diff; - /* whitelist allowed properties from "connection" setting which are allowed to differ. - * - * This includes UUID, there is no principal problem with reapplying a connection - * and changing it's UUID. In fact, disallowing it makes it cumbersome for the user - * to reapply any connection but the original settings-connection. */ - if (!_hash_check_invalid_keys (diffs ? g_hash_table_lookup (diffs, NM_SETTING_CONNECTION_SETTING_NAME) : NULL, - NM_SETTING_CONNECTION_SETTING_NAME, - error, - NM_SETTING_CONNECTION_ID, - NM_SETTING_CONNECTION_UUID, - NM_SETTING_CONNECTION_STABLE_ID, - NM_SETTING_CONNECTION_AUTOCONNECT, - NM_SETTING_CONNECTION_ZONE, - NM_SETTING_CONNECTION_METERED)) - return FALSE; + g_hash_table_iter_init (&iter, diffs); + while (g_hash_table_iter_next (&iter, (gpointer *) &setting_name, (gpointer *) &setting_diff)) { + if (!klass->can_reapply_change (self, + setting_name, + nm_connection_get_setting_by_name (applied, setting_name), + nm_connection_get_setting_by_name (connection, setting_name), + setting_diff, + error)) + return FALSE; + } + } if ( version_id != 0 && version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) { @@ -8567,7 +8608,7 @@ reapply_connection (NMDevice *self, NMSettingConnection *s_con_a, *s_con_n; /* we allow re-applying a connection with differing ID, UUID, STABLE_ID and AUTOCONNECT. - * This is for convenience but these values are not actually changable. So, check + * This is for convenience but these values are not actually changeable. So, check * if they changed, and if the did revert to the original values. */ s_con_a = nm_connection_get_setting_connection (applied); s_con_n = nm_connection_get_setting_connection (connection); @@ -8595,18 +8636,19 @@ reapply_connection (NMDevice *self, } else con_old = con_new = applied; - s_ip4_new = nm_connection_get_setting_ip4_config (con_new); - s_ip4_old = nm_connection_get_setting_ip4_config (con_old); - s_ip6_new = nm_connection_get_setting_ip6_config (con_new); - s_ip6_old = nm_connection_get_setting_ip6_config (con_old); - /************************************************************************** * Reapply changes *************************************************************************/ + klass->reapply_connection (self, con_old, con_new); nm_device_update_firewall_zone (self); nm_device_update_metered (self); + s_ip4_old = nm_connection_get_setting_ip4_config (con_old); + s_ip4_new = nm_connection_get_setting_ip4_config (con_new); + s_ip6_old = nm_connection_get_setting_ip6_config (con_old); + s_ip6_new = nm_connection_get_setting_ip6_config (con_new); + nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new); nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new); @@ -8629,6 +8671,7 @@ reapply_cb (NMDevice *self, guint64 version_id = 0; gs_unref_object NMConnection *connection = NULL; GError *local = NULL; + gs_free char *audit_args = NULL; if (reapply_data) { connection = reapply_data->connection; @@ -8637,20 +8680,21 @@ reapply_cb (NMDevice *self, } if (error) { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, subject, error->message); g_dbus_method_invocation_return_gerror (context, error); return; } - if (!reapply_connection (self, - connection ? : (NMConnection *) nm_device_get_settings_connection (self), - version_id, - &local)) { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message); + if (!check_and_reapply_connection (self, + connection ? : (NMConnection *) nm_device_get_settings_connection (self), + version_id, + &audit_args, + &local)) { + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, audit_args, subject, local->message); g_dbus_method_invocation_take_error (context, local); local = NULL; } else { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, subject, NULL); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL); g_dbus_method_invocation_return_value (context, NULL); } } @@ -8673,7 +8717,7 @@ impl_device_reapply (NMDevice *self, error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "Invalid flags specified"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); g_dbus_method_invocation_take_error (context, error); return; } @@ -8682,7 +8726,7 @@ impl_device_reapply (NMDevice *self, error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, "Device is not activated"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); g_dbus_method_invocation_take_error (context, error); return; } @@ -8698,7 +8742,7 @@ impl_device_reapply (NMDevice *self, &error); if (!connection) { g_prefix_error (&error, "The settings specified are invalid: "); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); g_dbus_method_invocation_take_error (context, error); return; } @@ -8828,7 +8872,7 @@ disconnect_cb (NMDevice *self, if (error) { g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, error->message); return; } @@ -8837,7 +8881,7 @@ disconnect_cb (NMDevice *self, local = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, "Device is not active"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, local->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, local->message); g_dbus_method_invocation_take_error (context, local); } else { nm_device_set_autoconnect_intern (self, FALSE); @@ -8846,7 +8890,7 @@ disconnect_cb (NMDevice *self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_USER_REQUESTED); g_dbus_method_invocation_return_value (context, NULL); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, subject, NULL); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, NULL, subject, NULL); } } @@ -8897,12 +8941,12 @@ delete_cb (NMDevice *self, if (error) { g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, NULL, subject, error->message); return; } /* Authorized */ - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, NULL, subject, NULL); if (nm_device_unrealize (self, TRUE, &local)) g_dbus_method_invocation_return_value (context, NULL); else @@ -13607,6 +13651,8 @@ nm_device_class_init (NMDeviceClass *klass) klass->unmanaged_on_quit = unmanaged_on_quit; klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr; klass->parent_changed_notify = parent_changed_notify; + klass->can_reapply_change = can_reapply_change; + klass->reapply_connection = reapply_connection; obj_properties[PROP_UDI] = g_param_spec_string (NM_DEVICE_UDI, "", "", diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 8a39fd7c5d..d1e9a9455a 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -380,6 +380,17 @@ typedef struct { NMConnection * (* new_default_connection) (NMDevice *self); gboolean (* unmanaged_on_quit) (NMDevice *self); + + gboolean (* can_reapply_change) (NMDevice *self, + const char *setting_name, + NMSetting *s_old, + NMSetting *s_new, + GHashTable *diffs, + GError **error); + + void (* reapply_connection) (NMDevice *self, + NMConnection *con_old, + NMConnection *con_new); } NMDeviceClass; typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device, diff --git a/src/nm-audit-manager.c b/src/nm-audit-manager.c index eeb9d2ba80..a78f066344 100644 --- a/src/nm-audit-manager.c +++ b/src/nm-audit-manager.c @@ -302,11 +302,11 @@ _nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file, guint void _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, NMDevice *device, - gboolean result, gpointer subject_context, + gboolean result, const char *args, gpointer subject_context, const char *reason) { gs_unref_ptrarray GPtrArray *fields = NULL; - AuditField interface_field = { }, ifindex_field = { }; + AuditField interface_field = { }, ifindex_field = { }, args_field = { }; int ifindex; g_return_if_fail (op); @@ -324,6 +324,11 @@ _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint l g_ptr_array_add (fields, &ifindex_field); } + if (args) { + _audit_field_init_string (&args_field, "args", args, FALSE, BACKEND_ALL); + g_ptr_array_add (fields, &args_field); + } + _audit_log_helper (self, fields, file, line, func, op, result, subject_context, reason); } diff --git a/src/nm-audit-manager.h b/src/nm-audit-manager.h index 29bde1a50d..56e26584e5 100644 --- a/src/nm-audit-manager.h +++ b/src/nm-audit-manager.h @@ -83,13 +83,13 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self); } \ } G_STMT_END -#define nm_audit_log_device_op(op, device, result, subject_context, reason) \ +#define nm_audit_log_device_op(op, device, result, args, subject_context, reason) \ G_STMT_START { \ NMAuditManager *_audit = nm_audit_manager_get (); \ \ if (nm_audit_manager_audit_enabled (_audit)) { \ _nm_audit_manager_log_device_op (_audit, __FILE__, __LINE__, G_STRFUNC, \ - (op), (device), (result), (subject_context), (reason)); \ + (op), (device), (result), (args), (subject_context), (reason)); \ } \ } G_STMT_END @@ -114,6 +114,7 @@ void _nm_audit_manager_log_generic_op (NMAuditManager *self, const char *file void _nm_audit_manager_log_device_op (NMAuditManager *self, const char *file, guint line, const char *func, const char *op, NMDevice *device, - gboolean result, gpointer subject_context, const char *reason); + gboolean result, const char *args, gpointer subject_context, + const char *reason); #endif /* __NM_AUDIT_MANAGER_H__ */ diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 75c44b7865..b71974d838 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -4311,3 +4311,31 @@ skip: return result; } +char * +nm_utils_format_con_diff_for_audit (GHashTable *diff) +{ + GHashTable *setting_diff; + char *setting_name, *prop_name; + GHashTableIter iter, iter2; + GString *str; + + str = g_string_sized_new (32); + g_hash_table_iter_init (&iter, diff); + + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_diff)) { + if (!setting_diff) + continue; + + g_hash_table_iter_init (&iter2, setting_diff); + + while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL)) + g_string_append_printf (str, "%s.%s,", setting_name, prop_name); + } + + if (str->len) + str->str[str->len - 1] = '\0'; + + return g_string_free (str, FALSE); +} diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index a1d9c2d462..b0dbe9bf06 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -469,5 +469,7 @@ struct stat; gboolean nm_utils_validate_plugin (const char *path, struct stat *stat, GError **error); char **nm_utils_read_plugin_paths (const char *dirname, const char *prefix); +char *nm_utils_format_con_diff_for_audit (GHashTable *diff); + #endif /* __NM_CORE_UTILS_H__ */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 827a67b2cc..bfbe051f11 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1653,49 +1653,6 @@ con_update_cb (NMSettingsConnection *self, update_complete (self, info, error); } -static char * -con_list_changed_props (NMConnection *old, NMConnection *new) -{ - gs_unref_hashtable GHashTable *diff = NULL; - GHashTable *setting_diff; - char *setting_name, *prop_name; - GHashTableIter iter, iter2; - gboolean same; - GString *str; - - same = nm_connection_diff (old, new, - NM_SETTING_COMPARE_FLAG_EXACT | - NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, - &diff); - - if (same || !diff) - return NULL; - - str = g_string_sized_new (32); - g_hash_table_iter_init (&iter, diff); - - while (g_hash_table_iter_next (&iter, - (gpointer *) &setting_name, - (gpointer *) &setting_diff)) { - if (!setting_diff) - continue; - - g_hash_table_iter_init (&iter2, setting_diff); - - while (g_hash_table_iter_next (&iter2, (gpointer *) &prop_name, NULL)) { - g_string_append (str, setting_name); - g_string_append_c (str, '.'); - g_string_append (str, prop_name); - g_string_append_c (str, ','); - } - } - - if (str->len) - str->str[str->len - 1] = '\0'; - - return g_string_free (str, FALSE); -} - static void update_auth_cb (NMSettingsConnection *self, GDBusMethodInvocation *context, @@ -1736,8 +1693,17 @@ update_auth_cb (NMSettingsConnection *self, update_agent_secrets_cache (self, info->new_settings); } - if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) - info->audit_args = con_list_changed_props (NM_CONNECTION (self), info->new_settings); + if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) { + gs_unref_hashtable GHashTable *diff = NULL; + gboolean same; + + same = nm_connection_diff (NM_CONNECTION (self), info->new_settings, + NM_SETTING_COMPARE_FLAG_EXACT | + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, + &diff); + if (!same && diff) + info->audit_args = nm_utils_format_con_diff_for_audit (diff); + } if (info->save_to_disk) { nm_settings_connection_replace_and_commit (self,