libnm: validate settings in _nm_connection_verify() in defined order
Fully sort the settings in _nm_connection_verify(). Previously, only the NMSettingConnection instance was sorted first (as required). The remaining settings were in undefined order. That means, we would validate settings in undefined order, and if multiple settings have an issue, the reported error would be undefined. Instead, use nm_connection_get_settings() which fully sorts the settings (and of course, sorts NMSettingConnection first as we require it). Also, this way we no longer need to allocate multiple GSList instances but only malloc() one array large enough to contain all settings.
This commit is contained in:
@@ -1404,24 +1404,19 @@ nm_connection_verify (NMConnection *connection, GError **error)
|
||||
NMSettingVerifyResult
|
||||
_nm_connection_verify (NMConnection *connection, GError **error)
|
||||
{
|
||||
NMConnectionPrivate *priv;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIPConfig *s_ip4, *s_ip6;
|
||||
NMSettingProxy *s_proxy;
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
GSList *all_settings = NULL, *setting_i;
|
||||
gs_free NMSetting **settings = NULL;
|
||||
gs_free_error GError *normalizable_error = NULL;
|
||||
NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
|
||||
g_return_val_if_fail (!error || !*error, NM_SETTING_VERIFY_ERROR);
|
||||
|
||||
priv = NM_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
/* First, make sure there's at least 'connection' setting */
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
if (!s_con) {
|
||||
settings = nm_connection_get_settings (connection, NULL);
|
||||
if ( !settings
|
||||
|| !NM_IS_SETTING_CONNECTION (settings[0])) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_MISSING_SETTING,
|
||||
@@ -1430,25 +1425,13 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
||||
return NM_SETTING_VERIFY_ERROR;
|
||||
}
|
||||
|
||||
/* Build up the list of settings */
|
||||
g_hash_table_iter_init (&iter, priv->settings);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||
/* Order NMSettingConnection so that it will be verified first.
|
||||
* The reason is, that errors in this setting might be more fundamental
|
||||
* and should be checked and reported with higher priority.
|
||||
*/
|
||||
if (value == s_con)
|
||||
all_settings = g_slist_append (all_settings, value);
|
||||
else
|
||||
all_settings = g_slist_prepend (all_settings, value);
|
||||
}
|
||||
all_settings = g_slist_reverse (all_settings);
|
||||
|
||||
/* Now, run the verify function of each setting */
|
||||
for (setting_i = all_settings; setting_i; setting_i = setting_i->next) {
|
||||
for (i = 0; settings[i]; i++) {
|
||||
GError *verify_error = NULL;
|
||||
NMSettingVerifyResult verify_result;
|
||||
|
||||
nm_assert (NM_IS_SETTING (settings[i]));
|
||||
nm_assert (NM_IS_SETTING_CONNECTION (settings[i]) == (i == 0));
|
||||
|
||||
/* verify all settings. We stop if we find the first non-normalizable
|
||||
* @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue
|
||||
* but remember the error to return it to the user.
|
||||
@@ -1456,7 +1439,7 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
||||
* @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type,
|
||||
* we remember it instead (to return it as output).
|
||||
**/
|
||||
verify_result = _nm_setting_verify (NM_SETTING (setting_i->data), connection, &verify_error);
|
||||
verify_result = _nm_setting_verify (settings[i], connection, &verify_error);
|
||||
if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE ||
|
||||
verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) {
|
||||
if ( verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR
|
||||
@@ -1471,13 +1454,11 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
||||
}
|
||||
} else if (verify_result != NM_SETTING_VERIFY_SUCCESS) {
|
||||
g_propagate_error (error, verify_error);
|
||||
g_slist_free (all_settings);
|
||||
g_return_val_if_fail (verify_result == NM_SETTING_VERIFY_ERROR, NM_SETTING_VERIFY_ERROR);
|
||||
return NM_SETTING_VERIFY_ERROR;
|
||||
}
|
||||
g_clear_error (&verify_error);
|
||||
}
|
||||
g_slist_free (all_settings);
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||
|
Reference in New Issue
Block a user