ifcfg-rh: merge branch 'th/ifcfg-rule-write-rh1384799'

https://bugzilla.redhat.com/show_bug.cgi?id=1384799
This commit is contained in:
Thomas Haller 2017-10-25 14:06:52 +02:00
commit fda635f5e9
22 changed files with 948 additions and 885 deletions

View file

@ -431,4 +431,16 @@ gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, g
/*****************************************************************************/
static inline int
nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
{
if (NM_IS_SETTING_IP4_CONFIG (s_ip))
return AF_INET;
if (NM_IS_SETTING_IP6_CONFIG (s_ip))
return AF_INET6;
g_return_val_if_reached (AF_UNSPEC);
}
/*****************************************************************************/
#endif

View file

@ -1219,7 +1219,7 @@ dispose (GObject *object)
if (to_delete) {
nm_log_dbg (LOGD_BT, "bluez[%s] removing Bluetooth connection for NAP device: '%s' (%s)", priv->path,
nm_connection_get_id (to_delete), nm_connection_get_uuid (to_delete));
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL, NULL);
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL);
g_object_unref (to_delete);
}

View file

@ -259,8 +259,8 @@ activate:
nm_connection_replace_settings_from_connection (NM_CONNECTION (connection),
dev_checkpoint->settings_connection);
nm_settings_connection_commit_changes (connection,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL);
}
} else {
@ -343,7 +343,7 @@ next_dev:
nm_settings_connection_get_uuid (con))) {
_LOGD ("rollback: deleting new connection %s",
nm_settings_connection_get_uuid (con));
nm_settings_connection_delete (con, NULL, NULL);
nm_settings_connection_delete (con, NULL);
}
}
}

View file

@ -339,7 +339,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active)
if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (connection, NULL, NULL);
nm_settings_connection_delete (connection, NULL);
}
g_object_unref (connection);
}
@ -1990,7 +1990,7 @@ recheck_assume_connection (NMManager *self,
if (generated) {
_LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed");
nm_settings_connection_delete (connection, NULL, NULL);
nm_settings_connection_delete (connection, NULL);
} else {
if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
@ -4035,8 +4035,9 @@ activation_add_done (NMSettings *settings,
if (_internal_activate_generic (self, active, &local)) {
nm_settings_connection_commit_changes (new_connection,
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
NULL, NULL);
NULL);
g_dbus_method_invocation_return_value (
context,
g_variant_new ("(oo)",
@ -4056,7 +4057,7 @@ activation_add_done (NMSettings *settings,
g_assert (error);
_internal_activation_failed (self, active, error->message);
if (new_connection)
nm_settings_connection_delete (new_connection, NULL, NULL);
nm_settings_connection_delete (new_connection, NULL);
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
NULL,

View file

@ -510,18 +510,12 @@ connection_changed_cb (NMSettingsConnection *self, gpointer unused)
_emit_updated (self, FALSE);
}
/* Update the settings of this connection to match that of 'new_connection',
* taking care to make a private copy of secrets.
*/
gboolean
nm_settings_connection_replace_settings (NMSettingsConnection *self,
NMConnection *new_connection,
gboolean update_unsaved,
const char *log_diff_name,
GError **error)
nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
NMConnection *new_connection,
GError **error)
{
NMSettingsConnectionPrivate *priv;
gboolean success = FALSE;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
@ -540,6 +534,30 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
return FALSE;
}
return TRUE;
}
gboolean
nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
NMConnection *new_connection,
gboolean prepare_new_connection,
gboolean update_unsaved,
const char *log_diff_name,
GError **error)
{
NMSettingsConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
if ( prepare_new_connection
&& !nm_settings_connection_replace_settings_prepare (self,
new_connection,
error))
return FALSE;
/* Do nothing if there's nothing to update */
if (nm_connection_compare (NM_CONNECTION (self),
new_connection,
@ -567,7 +585,6 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
* nm_connection_clear_secrets() and clears them.
*/
update_system_secrets_cache (self);
success = TRUE;
/* Add agent and always-ask secrets back; they won't necessarily be
* in the replacement connection data if it was eg reread from disk.
@ -594,114 +611,101 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
_emit_updated (self, TRUE);
return success;
return TRUE;
}
static void
ignore_cb (NMSettingsConnection *self,
GError *error,
gpointer user_data)
{
}
/* Replaces the settings in this connection with those in 'new_connection'. If
* any changes are made, commits them to permanent storage and to any other
* subsystems watching this connection. Before returning, 'callback' is run
* with the given 'user_data' along with any errors encountered.
/* Update the settings of this connection to match that of 'new_connection',
* taking care to make a private copy of secrets.
*/
static void
replace_and_commit (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
gboolean
nm_settings_connection_replace_settings (NMSettingsConnection *self,
NMConnection *new_connection,
gboolean update_unsaved,
const char *log_diff_name,
GError **error)
{
GError *error = NULL;
NMSettingsConnectionCommitReason commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION;
return nm_settings_connection_replace_settings_full (self,
new_connection,
TRUE,
update_unsaved,
log_diff_name,
error);
}
if (g_strcmp0 (nm_connection_get_id (NM_CONNECTION (self)),
nm_connection_get_id (new_connection)) != 0)
commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED;
gboolean
nm_settings_connection_commit_changes (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
GError **error)
{
NMSettingsConnectionClass *klass;
gs_free_error GError *local = NULL;
gs_unref_object NMConnection *reread_connection = NULL;
gs_free char *logmsg_change = NULL;
if (nm_settings_connection_replace_settings (self, new_connection, TRUE, "replace-and-commit-disk", &error))
nm_settings_connection_commit_changes (self, commit_reason, callback, user_data);
else {
g_assert (error);
if (callback)
callback (self, error, user_data);
g_clear_error (&error);
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
if (!klass->commit_changes) {
_LOGW ("write: setting plugin %s does not support to write connection",
G_OBJECT_TYPE_NAME (self));
g_set_error (error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_FAILED,
"writing settings not supported");
return FALSE;
}
}
void
nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
{
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
g_return_if_fail (NM_IS_CONNECTION (new_connection));
if ( new_connection
&& !nm_settings_connection_replace_settings_prepare (self,
new_connection,
&local)) {
_LOGW ("write: failed to prepare connection for writing: %s",
local->message);
g_propagate_error (error, g_steal_pointer (&local));
return FALSE;
}
NM_SETTINGS_CONNECTION_GET_CLASS (self)->replace_and_commit (self, new_connection, callback, user_data);
}
if (!klass->commit_changes (self,
new_connection,
commit_reason,
&reread_connection,
&logmsg_change,
&local)) {
_LOGW ("write: failure to write setting: %s",
local->message);
g_propagate_error (error, g_steal_pointer (&local));
return FALSE;
}
if (reread_connection || new_connection) {
if (!nm_settings_connection_replace_settings_full (self,
reread_connection ?: new_connection,
!reread_connection,
FALSE,
new_connection
? "update-during-write"
: "replace-and-commit-disk",
&local)) {
/* this can't really happen, because at this point replace-settings
* is no longer supposed to fail. It's a bug. */
_LOGE ("write: replacing setting failed: %s",
local->message);
g_propagate_error (error, g_steal_pointer (&local));
g_return_val_if_reached (FALSE);
}
}
static void
commit_changes (NMSettingsConnection *self,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
{
/* Subclasses only call this function if the save was successful, so at
* this point the connection is synced to disk and no longer unsaved.
*/
set_unsaved (self, FALSE);
g_object_ref (self);
callback (self, NULL, user_data);
g_object_unref (self);
}
if (reread_connection)
_LOGI ("write: successfully updated (%s), connection was modified in the process", logmsg_change);
else if (new_connection)
_LOGI ("write: successfully updated (%s)", logmsg_change);
else
_LOGI ("write: successfully commited (%s)", logmsg_change);
void
nm_settings_connection_commit_changes (NMSettingsConnection *self,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
{
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
if (NM_SETTINGS_CONNECTION_GET_CLASS (self)->commit_changes) {
NM_SETTINGS_CONNECTION_GET_CLASS (self)->commit_changes (self,
commit_reason,
callback ? callback : ignore_cb,
user_data);
} else {
GError *error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_FAILED,
"%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__);
if (callback)
callback (self, error, user_data);
g_error_free (error);
}
}
void
nm_settings_connection_delete (NMSettingsConnection *self,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
{
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
if (NM_SETTINGS_CONNECTION_GET_CLASS (self)->delete) {
NM_SETTINGS_CONNECTION_GET_CLASS (self)->delete (self,
callback ? callback : ignore_cb,
user_data);
} else {
GError *error = g_error_new (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_FAILED,
"%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__);
if (callback)
callback (self, error, user_data);
g_error_free (error);
}
return TRUE;
}
static void
@ -740,15 +744,32 @@ remove_entry_from_db (NMSettingsConnection *self, const char* db_name)
g_key_file_free (key_file);
}
static void
do_delete (NMSettingsConnection *self,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
gboolean
nm_settings_connection_delete (NMSettingsConnection *self,
GError **error)
{
gs_unref_object NMSettingsConnection *self_keep_alive = NULL;
NMSettingsConnectionClass *klass;
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMConnection *for_agents;
g_object_ref (self);
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
self_keep_alive = g_object_ref (self);
if (!klass->delete) {
g_set_error (error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_FAILED,
"delete not supported");
return FALSE;
}
if (!klass->delete (self,
error))
return FALSE;
set_visible (self, FALSE);
/* Tell agents to remove secrets for this connection */
@ -766,12 +787,10 @@ do_delete (NMSettingsConnection *self,
remove_entry_from_db (self, "seen-bssids");
nm_settings_connection_signal_remove (self, FALSE);
callback (self, NULL, user_data);
g_object_unref (self);
return TRUE;
}
/*****************************************************************************/
@ -886,15 +905,6 @@ secret_is_system_owned (NMSettingSecretFlags flags,
return !NM_FLAGS_HAS (flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED);
}
static void
new_secrets_commit_cb (NMSettingsConnection *self,
GError *error,
gpointer user_data)
{
if (error)
_LOGW ("Error saving new secrets to backing storage: %s", error->message);
}
static void
get_cmp_flags (NMSettingsConnection *self, /* only needed for logging */
GetSecretsInfo *info, /* only needed for logging */
@ -993,9 +1003,11 @@ nm_settings_connection_new_secrets (NMSettingsConnection *self,
update_system_secrets_cache (self);
update_agent_secrets_cache (self, NULL);
nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
new_secrets_commit_cb, NULL);
nm_settings_connection_commit_changes (self,
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL);
return TRUE;
}
@ -1109,7 +1121,10 @@ get_secrets_done_cb (NMAgentManager *manager,
setting_name,
info);
nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, new_secrets_commit_cb, NULL);
nm_settings_connection_commit_changes (self,
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL);
} else {
_LOGD ("(%s:%p) new agent secrets processed",
setting_name,
@ -1570,11 +1585,6 @@ typedef struct {
char *audit_args;
} UpdateInfo;
typedef struct {
GDBusMethodInvocation *context;
NMAuthSubject *subject;
} CallbackInfo;
static void
has_some_secrets_cb (NMSetting *setting,
const char *key,
@ -1651,14 +1661,82 @@ update_complete (NMSettingsConnection *self,
}
static void
con_update_cb (NMSettingsConnection *self,
GError *error,
gpointer user_data)
update_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
{
UpdateInfo *info = user_data;
NMConnection *for_agent;
UpdateInfo *info = data;
NMSettingsConnectionCommitReason commit_reason;
gs_free_error GError *local = NULL;
if (error) {
update_complete (self, info, error);
return;
}
if (info->new_settings) {
if (!any_secrets_present (info->new_settings)) {
/* If the new connection has no secrets, we do not want to remove all
* secrets, rather we keep all the existing ones. Do that by merging
* them in to the new connection.
*/
cached_secrets_to_connection (self, info->new_settings);
} else {
/* Cache the new secrets from the agent, as stuff like inotify-triggered
* changes to connection's backing config files will blow them away if
* they're in the main connection.
*/
update_agent_secrets_cache (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) {
if (info->new_settings) {
nm_settings_connection_replace_settings (self,
info->new_settings,
TRUE,
"replace-unsaved",
&local);
}
goto out;
}
if (info->new_settings) {
if (!nm_settings_connection_replace_settings_prepare (self,
info->new_settings,
&local))
goto out;
}
commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION;
if ( info->new_settings
&& !nm_streq0 (nm_connection_get_id (NM_CONNECTION (self)),
nm_connection_get_id (info->new_settings)))
commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED;
nm_settings_connection_commit_changes (self,
info->new_settings,
commit_reason,
&local);
out:
if (!local) {
gs_unref_object NMConnection *for_agent = NULL;
if (!error) {
/* Dupe the connection so we can clear out non-agent-owned secrets,
* as agent-owned secrets are the only ones we send back be saved.
* Only send secrets to agents of the same UID that called update too.
@ -1671,76 +1749,11 @@ con_update_cb (NMSettingsConnection *self,
nm_connection_get_path (NM_CONNECTION (self)),
for_agent,
info->subject);
g_object_unref (for_agent);
}
update_complete (self, info, error);
update_complete (self, info, local);
}
static void
update_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer data)
{
UpdateInfo *info = data;
GError *local = NULL;
if (error) {
update_complete (self, info, error);
return;
}
if (!info->new_settings) {
/* We're just calling Save(). Just commit the existing connection. */
if (info->save_to_disk) {
nm_settings_connection_commit_changes (self,
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION,
con_update_cb,
info);
}
return;
}
if (!any_secrets_present (info->new_settings)) {
/* If the new connection has no secrets, we do not want to remove all
* secrets, rather we keep all the existing ones. Do that by merging
* them in to the new connection.
*/
cached_secrets_to_connection (self, info->new_settings);
} else {
/* Cache the new secrets from the agent, as stuff like inotify-triggered
* changes to connection's backing config files will blow them away if
* they're in the main connection.
*/
update_agent_secrets_cache (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,
info->new_settings,
con_update_cb,
info);
} else {
if (!nm_settings_connection_replace_settings (self, info->new_settings, TRUE, "replace-and-commit-memory", &local))
g_assert (local);
con_update_cb (self, local, info);
g_clear_error (&local);
}
}
static const char *
get_update_modify_permission (NMConnection *old, NMConnection *new)
@ -1864,23 +1877,6 @@ impl_settings_connection_save (NMSettingsConnection *self,
settings_connection_update_helper (self, context, NULL, TRUE);
}
static void
con_delete_cb (NMSettingsConnection *self,
GError *error,
gpointer user_data)
{
CallbackInfo *info = user_data;
if (error)
g_dbus_method_invocation_return_gerror (info->context, error);
else
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self,
!error, NULL, info->subject, error ? error->message : NULL);
g_free (info);
}
static void
delete_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
@ -1888,7 +1884,7 @@ delete_auth_cb (NMSettingsConnection *self,
GError *error,
gpointer data)
{
CallbackInfo *info;
gs_free_error GError *local = NULL;
if (error) {
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject,
@ -1897,11 +1893,15 @@ delete_auth_cb (NMSettingsConnection *self,
return;
}
info = g_malloc0 (sizeof (*info));
info->context = context;
info->subject = subject;
nm_settings_connection_delete (self, &local);
nm_settings_connection_delete (self, con_delete_cb, info);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self,
!local, NULL, subject, local ? local->message : NULL);
if (local)
g_dbus_method_invocation_return_gerror (context, local);
else
g_dbus_method_invocation_return_value (context, NULL);
}
static const char *
@ -2020,23 +2020,6 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
g_dbus_method_invocation_take_error (context, error);
}
static void
clear_secrets_cb (NMSettingsConnection *self,
GError *error,
gpointer user_data)
{
CallbackInfo *info = user_data;
if (error)
g_dbus_method_invocation_return_gerror (info->context, error);
else
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
!error, NULL, info->subject, error ? error->message : NULL);
g_free (info);
}
static void
dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
GDBusMethodInvocation *context,
@ -2045,31 +2028,39 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
gpointer user_data)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
CallbackInfo *info;
gs_free_error GError *local = NULL;
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
FALSE, NULL, subject, error->message);
} else {
/* Clear secrets in connection and caches */
nm_connection_clear_secrets (NM_CONNECTION (self));
if (priv->system_secrets)
nm_connection_clear_secrets (priv->system_secrets);
if (priv->agent_secrets)
nm_connection_clear_secrets (priv->agent_secrets);
/* Tell agents to remove secrets for this connection */
nm_agent_manager_delete_secrets (priv->agent_mgr,
nm_connection_get_path (NM_CONNECTION (self)),
NM_CONNECTION (self));
info = g_malloc0 (sizeof (*info));
info->context = context;
info->subject = subject;
nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, clear_secrets_cb, info);
return;
}
/* Clear secrets in connection and caches */
nm_connection_clear_secrets (NM_CONNECTION (self));
if (priv->system_secrets)
nm_connection_clear_secrets (priv->system_secrets);
if (priv->agent_secrets)
nm_connection_clear_secrets (priv->agent_secrets);
/* Tell agents to remove secrets for this connection */
nm_agent_manager_delete_secrets (priv->agent_mgr,
nm_connection_get_path (NM_CONNECTION (self)),
NM_CONNECTION (self));
nm_settings_connection_commit_changes (self,
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
&local);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
!local, NULL, subject, local ? local->message : NULL);
if (local)
g_dbus_method_invocation_return_gerror (context, local);
else
g_dbus_method_invocation_return_value (context, NULL);
}
static void
@ -2902,9 +2893,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
object_class->get_property = get_property;
object_class->set_property = set_property;
class->replace_and_commit = replace_and_commit;
class->commit_changes = commit_changes;
class->delete = do_delete;
class->supports_secrets = supports_secrets;
obj_properties[PROP_VISIBLE] =

View file

@ -94,14 +94,6 @@ typedef struct _NMSettingsConnectionCallId *NMSettingsConnectionCallId;
typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *self,
GError *error,
gpointer user_data);
typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *self,
GError *error,
gpointer user_data);
struct _NMSettingsConnectionPrivate;
struct _NMSettingsConnection {
@ -112,20 +104,15 @@ struct _NMSettingsConnection {
struct _NMSettingsConnectionClass {
NMExportedObjectClass parent;
/* virtual methods */
void (*replace_and_commit) (NMSettingsConnection *self,
gboolean (*commit_changes) (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitFunc callback,
gpointer user_data);
NMSettingsConnectionCommitReason commit_reason,
NMConnection **out_reread_connection,
char **out_logmsg_change,
GError **error);
void (*commit_changes) (NMSettingsConnection *self,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data);
void (*delete) (NMSettingsConnection *self,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data);
gboolean (*delete) (NMSettingsConnection *self,
GError **error);
gboolean (*supports_secrets) (NMSettingsConnection *self,
const char *setting_name);
@ -137,10 +124,14 @@ gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsCon
NMConnection *applied_connection,
NMSettingCompareFlags compare_flage);
void nm_settings_connection_commit_changes (NMSettingsConnection *self,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data);
gboolean nm_settings_connection_commit_changes (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
GError **error);
gboolean nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
NMConnection *new_connection,
GError **error);
gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
NMConnection *new_connection,
@ -148,14 +139,15 @@ gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
const char *log_diff_name,
GError **error);
void nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
NMConnection *new_connection,
NMSettingsConnectionCommitFunc callback,
gpointer user_data);
gboolean nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
NMConnection *new_connection,
gboolean prepare_new_connection,
gboolean update_unsaved,
const char *log_diff_name,
GError **error);
void nm_settings_connection_delete (NMSettingsConnection *self,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data);
gboolean nm_settings_connection_delete (NMSettingsConnection *self,
GError **error);
typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self,
NMSettingsConnectionCallId call_id,

View file

@ -91,7 +91,6 @@ EXPORT(nm_inotify_helper_remove_watch)
EXPORT(nm_settings_connection_get_type)
EXPORT(nm_settings_connection_replace_settings)
EXPORT(nm_settings_connection_replace_and_commit)
/*****************************************************************************/
@ -1774,7 +1773,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quittin
* remains up and can be assumed if NM starts again.
*/
if (quitting == FALSE)
nm_settings_connection_delete (connection, NULL, NULL);
nm_settings_connection_delete (connection, NULL);
}
}

View file

@ -306,75 +306,52 @@ nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self)
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unrecognized_spec;
}
static void
replace_and_commit (NMSettingsConnection *connection,
NMConnection *new_connection,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
{
const char *filename;
GError *error = NULL;
filename = nm_settings_connection_get_filename (connection);
if (filename && utils_has_complex_routes (filename)) {
if (callback) {
error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"Cannot modify a connection that has an associated 'rule-' or 'rule6-' file");
callback (connection, error, user_data);
g_clear_error (&error);
}
return;
}
NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->replace_and_commit (connection, new_connection, callback, user_data);
}
static void
static gboolean
commit_changes (NMSettingsConnection *connection,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
NMConnection **out_reread_connection,
char **out_logmsg_change,
GError **error)
{
GError *error = NULL;
gboolean success = FALSE;
char *ifcfg_path = NULL;
const char *filename;
gs_unref_object NMConnection *reread = NULL;
gboolean reread_same = TRUE;
const char *operation_message;
gs_free char *ifcfg_path = NULL;
nm_assert (out_reread_connection && !*out_reread_connection);
nm_assert (!out_logmsg_change || !*out_logmsg_change);
filename = nm_settings_connection_get_filename (connection);
if (filename) {
success = writer_update_connection (NM_CONNECTION (connection),
IFCFG_DIR,
filename,
NULL,
NULL,
&error);
} else {
success = writer_new_connection (NM_CONNECTION (connection),
IFCFG_DIR,
&ifcfg_path,
NULL,
NULL,
&error);
if (success) {
nm_settings_connection_set_filename (connection, ifcfg_path);
g_free (ifcfg_path);
}
}
if (!nms_ifcfg_rh_writer_write_connection (new_connection ?: NM_CONNECTION (connection),
IFCFG_DIR,
filename,
&ifcfg_path,
&reread,
&reread_same,
error))
return FALSE;
if (success) {
/* Chain up to parent to handle success */
NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, commit_reason, callback, user_data);
} else {
/* Otherwise immediate error */
callback (connection, error, user_data);
g_error_free (error);
}
nm_assert ((!filename && ifcfg_path) || (filename && !ifcfg_path));
if (ifcfg_path) {
nm_settings_connection_set_filename (connection, ifcfg_path);
operation_message = "persist";
} else
operation_message = "update";
if (reread && !reread_same)
*out_reread_connection = g_steal_pointer (&reread);
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("ifcfg-rh: %s %s",
operation_message, filename));
return TRUE;
}
static void
do_delete (NMSettingsConnection *connection,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
static gboolean
delete (NMSettingsConnection *connection,
GError **error)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE ((NMIfcfgConnection *) connection);
const char *filename;
@ -390,7 +367,7 @@ do_delete (NMSettingsConnection *connection,
g_unlink (priv->route6file);
}
NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data);
return TRUE;
}
/*****************************************************************************/
@ -529,8 +506,7 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
object_class->get_property = get_property;
object_class->dispose = dispose;
settings_class->delete = do_delete;
settings_class->replace_and_commit = replace_and_commit;
settings_class->delete = delete;
settings_class->commit_changes = commit_changes;
obj_properties[PROP_UNMANAGED_SPEC] =

View file

@ -683,11 +683,11 @@ add_connection (NMSettingsPlugin *config,
/* Ensure we reject attempts to add the connection long before we're
* asked to write it to disk.
*/
if (!writer_can_write_connection (connection, error))
if (!nms_ifcfg_rh_writer_can_write_connection (connection, error))
return NULL;
if (save_to_disk) {
if (!writer_new_connection (connection, IFCFG_DIR, &path, NULL, NULL, error))
if (!nms_ifcfg_rh_writer_write_connection (connection, IFCFG_DIR, NULL, &path, NULL, NULL, error))
return NULL;
}
return NM_SETTINGS_CONNECTION (update_connection (self, connection, path, NULL, FALSE, NULL, error));

View file

@ -1175,6 +1175,7 @@ make_proxy_setting (shvarFile *ifcfg, GError **error)
static NMSetting *
make_ip4_setting (shvarFile *ifcfg,
const char *network_file,
gboolean routes_read,
gboolean *out_has_defroute,
GError **error)
{
@ -1196,6 +1197,7 @@ make_ip4_setting (shvarFile *ifcfg,
gint priority;
char inet_buf[NM_UTILS_INET_ADDRSTRLEN];
const char *const *item;
guint32 route_table;
nm_assert (out_has_defroute && !*out_has_defroute);
@ -1281,6 +1283,15 @@ make_ip4_setting (shvarFile *ifcfg,
return NULL;
}
/* the route table (policy routing) is ignored if we don't handle routes. */
route_table = svGetValueInt64 (ifcfg, "IPV4_ROUTE_TABLE", 10,
0, G_MAXUINT32, 0);
if ( route_table != 0
&& !routes_read) {
PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV4_ROUTE_TABLE) is ignored");
route_table = 0;
}
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, method,
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "PEERDNS", TRUE),
@ -1289,8 +1300,7 @@ make_ip4_setting (shvarFile *ifcfg,
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV4_FAILURE_FATAL", FALSE),
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10,
-1, G_MAXUINT32, -1),
NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) svGetValueInt64 (ifcfg, "IPV4_ROUTE_TABLE", 10,
0, G_MAXUINT32, 0),
NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table,
NULL);
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
@ -1326,7 +1336,7 @@ make_ip4_setting (shvarFile *ifcfg,
* added to the automatic ones. Note that this is not currently supported by
* the legacy 'network' service (ifup-eth).
*/
for (i = -1; i < 256; i++) {
for (i = -1;; i++) {
NMIPAddress *addr = NULL;
/* gateway will only be set if still unset. Hence, we don't leak gateway
@ -1424,13 +1434,13 @@ make_ip4_setting (shvarFile *ifcfg,
/* Static routes - route-<name> file */
route_path = utils_get_route_path (svFileGetName (ifcfg));
if (utils_has_complex_routes (route_path)) {
PARSE_WARNING ("'rule-' or 'rule6-' file is present; you will need to use a dispatcher script to apply these routes");
if (!routes_read) {
/* NOP */
} else if (utils_has_route_file_new_syntax (route_path)) {
/* Parse route file in new syntax */
route_ifcfg = utils_get_route_ifcfg (svFileGetName (ifcfg), FALSE);
if (route_ifcfg) {
for (i = 0; i < 256; i++) {
for (i = 0;; i++) {
NMIPRoute *route = NULL;
if (!read_one_ip4_route (route_ifcfg, i, &route, error)) {
@ -1591,6 +1601,7 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file
static NMSetting *
make_ip6_setting (shvarFile *ifcfg,
const char *network_file,
gboolean routes_read,
GError **error)
{
NMSettingIPConfig *s_ip6 = NULL;
@ -1612,6 +1623,7 @@ make_ip6_setting (shvarFile *ifcfg,
gboolean never_default = FALSE;
gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip;
NMSettingIP6ConfigPrivacy ip6_privacy_val;
guint32 route_table;
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
@ -1713,6 +1725,15 @@ make_ip6_setting (shvarFile *ifcfg,
NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
g_free (str_value);
/* the route table (policy routing) is ignored if we don't handle routes. */
route_table = svGetValueInt64 (ifcfg, "IPV6_ROUTE_TABLE", 10,
0, G_MAXUINT32, 0);
if ( route_table != 0
&& !routes_read) {
PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing (IPV6_ROUTE_TABLE) is ignored");
route_table = 0;
}
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, method,
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svGetValueBoolean (ifcfg, "IPV6_PEERDNS", TRUE),
@ -1721,8 +1742,7 @@ make_ip6_setting (shvarFile *ifcfg,
NM_SETTING_IP_CONFIG_MAY_FAIL, !svGetValueBoolean (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10,
-1, G_MAXUINT32, -1),
NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) svGetValueInt64 (ifcfg, "IPV6_ROUTE_TABLE", 10,
0, G_MAXUINT32, 0),
NM_SETTING_IP_CONFIG_ROUTE_TABLE, (guint) route_table,
NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val,
NULL);
@ -1847,12 +1867,13 @@ make_ip6_setting (shvarFile *ifcfg,
/* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */
if (!utils_has_complex_routes (svFileGetName (ifcfg))) {
if (!routes_read) {
/* NOP */
} else {
/* Read static routes from route6-<interface> file */
route6_path = utils_get_route6_path (svFileGetName (ifcfg));
if (!read_route_file (AF_INET6, route6_path, s_ip6, error))
goto error;
g_free (route6_path);
}
@ -5158,6 +5179,8 @@ connection_from_file_full (const char *filename,
NMSetting *s_ip4, *s_ip6, *s_proxy, *s_port, *s_dcb = NULL, *s_user;
const char *ifcfg_name = NULL;
gboolean has_ip4_defroute = FALSE;
gboolean has_complex_routes_v4;
gboolean has_complex_routes_v6;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (out_unhandled && !*out_unhandled, NULL);
@ -5369,13 +5392,32 @@ connection_from_file_full (const char *filename,
if (!connection)
return NULL;
s_ip6 = make_ip6_setting (parsed, network_file, error);
has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET);
has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6);
if (has_complex_routes_v4 || has_complex_routes_v6) {
if (has_complex_routes_v4 && !has_complex_routes_v6)
PARSE_WARNING ("'rule-' file is present; you will need to use a dispatcher script to apply these routes");
else if (has_complex_routes_v6 && !has_complex_routes_v4)
PARSE_WARNING ("'rule6-' file is present; you will need to use a dispatcher script to apply these routes");
else
PARSE_WARNING ("'rule-' and 'rule6-' files are present; you will need to use a dispatcher script to apply these routes");
}
s_ip6 = make_ip6_setting (parsed,
network_file,
!has_complex_routes_v4 && !has_complex_routes_v6,
error);
if (!s_ip6)
return NULL;
else
nm_connection_add_setting (connection, s_ip6);
s_ip4 = make_ip4_setting (parsed, network_file, &has_ip4_defroute, error);
s_ip4 = make_ip4_setting (parsed,
network_file,
!has_complex_routes_v4 && !has_complex_routes_v6,
&has_ip4_defroute,
error);
if (!s_ip4)
return NULL;
else {
@ -5433,11 +5475,11 @@ connection_from_file (const char *filename,
}
NMConnection *
connection_from_file_test (const char *filename,
const char *network_file,
const char *test_type,
char **out_unhandled,
GError **error)
nmtst_connection_from_file (const char *filename,
const char *network_file,
const char *test_type,
char **out_unhandled,
GError **error)
{
return connection_from_file_full (filename,
network_file,
@ -5451,7 +5493,6 @@ guint
devtimeout_from_file (const char *filename)
{
shvarFile *ifcfg;
char *devtimeout_str;
guint devtimeout;
g_return_val_if_fail (filename != NULL, 0);
@ -5460,14 +5501,7 @@ devtimeout_from_file (const char *filename)
if (!ifcfg)
return 0;
devtimeout_str = svGetValueStr_cp (ifcfg, "DEVTIMEOUT");
if (devtimeout_str) {
devtimeout = _nm_utils_ascii_str_to_int64 (devtimeout_str, 10, 0, G_MAXUINT, 0);
g_free (devtimeout_str);
} else
devtimeout = 0;
devtimeout = svGetValueInt64 (ifcfg, "DEVTIMEOUT", 10, 0, G_MAXUINT, 0);
svCloseFile (ifcfg);
return devtimeout;
}

View file

@ -30,11 +30,10 @@ NMConnection *connection_from_file (const char *filename,
guint devtimeout_from_file (const char *filename);
/* for test-ifcfg-rh */
NMConnection *connection_from_file_test (const char *filename,
const char *network_file,
const char *test_type,
char **out_unhandled,
GError **error);
NMConnection *nmtst_connection_from_file (const char *filename,
const char *network_file,
const char *test_type,
char **out_unhandled,
GError **error);
#endif /* __READER_H__ */

View file

@ -280,25 +280,22 @@ gone:
}
gboolean
utils_has_complex_routes (const char *filename)
utils_has_complex_routes (const char *filename, int addr_family)
{
char *rules;
g_return_val_if_fail (filename, TRUE);
g_return_val_if_fail (filename != NULL, TRUE);
if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) {
gs_free char *rules = utils_get_extra_path (filename, RULE_TAG);
rules = utils_get_extra_path (filename, RULE_TAG);
if (g_file_test (rules, G_FILE_TEST_EXISTS)) {
g_free (rules);
return TRUE;
if (g_file_test (rules, G_FILE_TEST_EXISTS))
return TRUE;
}
g_free (rules);
rules = utils_get_extra_path (filename, RULE6_TAG);
if (g_file_test (rules, G_FILE_TEST_EXISTS)) {
g_free (rules);
return TRUE;
if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) {
gs_free char *rules = utils_get_extra_path (filename, RULE6_TAG);
if (g_file_test (rules, G_FILE_TEST_EXISTS))
return TRUE;
}
g_free (rules);
return FALSE;
}

View file

@ -48,7 +48,7 @@ shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create);
shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create);
gboolean utils_has_route_file_new_syntax (const char *filename);
gboolean utils_has_complex_routes (const char *filename);
gboolean utils_has_complex_routes (const char *filename, int addr_family);
gboolean utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg);

File diff suppressed because it is too large Load diff

View file

@ -18,26 +18,20 @@
* Copyright (C) 2009 Red Hat, Inc.
*/
#ifndef _WRITER_H_
#define _WRITER_H_
#ifndef __NMS_IFCFG_RH_WRITER_H__
#define __NMS_IFCFG_RH_WRITER_H__
#include "nm-connection.h"
gboolean writer_can_write_connection (NMConnection *connection,
GError **error);
gboolean nms_ifcfg_rh_writer_can_write_connection (NMConnection *connection,
GError **error);
gboolean writer_new_connection (NMConnection *connection,
const char *ifcfg_dir,
char **out_filename,
NMConnection **out_reread,
gboolean *out_reread_same,
GError **error);
gboolean nms_ifcfg_rh_writer_write_connection (NMConnection *connection,
const char *ifcfg_dir,
const char *filename,
char **out_filename,
NMConnection **out_reread,
gboolean *out_reread_same,
GError **error);
gboolean writer_update_connection (NMConnection *connection,
const char *ifcfg_dir,
const char *filename,
NMConnection **out_reread,
gboolean *out_reread_same,
GError **error);
#endif /* _WRITER_H_ */
#endif /* __NMS_IFCFG_RH_WRITER_H__ */

View file

@ -794,7 +794,7 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
int errsv = 0;
char *arena;
const char *p, *q;
GError *local = NULL;
gs_free_error GError *local = NULL;
nm_auto_close int fd = -1;
if (create)
@ -824,11 +824,13 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
&arena,
NULL,
&local) < 0) {
if (create)
return svFile_new (name);
g_set_error (error, G_FILE_ERROR,
local->domain == G_FILE_ERROR ? local->code : G_FILE_ERROR_FAILED,
"Could not read file '%s': %s",
name, local->message);
g_error_free (local);
return NULL;
}
@ -1118,6 +1120,71 @@ svGetValueEnum (shvarFile *s, const char *key,
/*****************************************************************************/
static gboolean
_is_all_digits (const char *str)
{
return str[0]
&& NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch));
}
#define IS_NUMBERED_TAG(key, tab_name) \
({ \
const char *_key = (key); \
\
( (strncmp (_key, tab_name, NM_STRLEN (tab_name)) == 0) \
&& _is_all_digits (&_key[NM_STRLEN (tab_name)])); \
})
gboolean
svUnsetAll (shvarFile *s, SvKeyType match_key_type)
{
CList *current;
shvarLine *line;
gboolean changed = FALSE;
g_return_val_if_fail (s, FALSE);
c_list_for_each (current, &s->lst_head) {
line = c_list_entry (current, shvarLine, lst);
ASSERT_shvarLine (line);
if (!line->key)
continue;
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ANY))
goto do_clear;
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) {
if ( IS_NUMBERED_TAG (line->key, "ADDRESS")
|| IS_NUMBERED_TAG (line->key, "NETMASK")
|| IS_NUMBERED_TAG (line->key, "GATEWAY")
|| IS_NUMBERED_TAG (line->key, "METRIC")
|| IS_NUMBERED_TAG (line->key, "OPTIONS"))
goto do_clear;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) {
if ( IS_NUMBERED_TAG (line->key, "IPADDR")
|| IS_NUMBERED_TAG (line->key, "PREFIX")
|| IS_NUMBERED_TAG (line->key, "NETMASK")
|| IS_NUMBERED_TAG (line->key, "GATEWAY"))
goto do_clear;
}
if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) {
if (g_str_has_prefix (line->key, "NM_USER_"))
goto do_clear;
}
continue;
do_clear:
if (nm_clear_g_free (&line->line)) {
ASSERT_shvarLine (line);
changed = TRUE;
}
}
if (changed)
s->modified = TRUE;
return changed;
}
/* Same as svSetValueStr() but it preserves empty @value -- contrary to
* svSetValueStr() for which "" effectively means to remove the value. */
gboolean
@ -1216,27 +1283,6 @@ svUnsetValue (shvarFile *s, const char *key)
return svSetValue (s, key, NULL);
}
void
svUnsetValuesWithPrefix (shvarFile *s, const char *prefix)
{
CList *current;
g_return_if_fail (s);
g_return_if_fail (prefix);
c_list_for_each (current, &s->lst_head) {
shvarLine *line = c_list_entry (current, shvarLine, lst);
ASSERT_shvarLine (line);
if ( line->key
&& g_str_has_prefix (line->key, prefix)) {
if (nm_clear_g_free (&line->line))
s->modified = TRUE;
}
ASSERT_shvarLine (line);
}
}
/*****************************************************************************/
/* Write the current contents iff modified. Returns FALSE on error

View file

@ -86,7 +86,14 @@ gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value);
gboolean svUnsetValue (shvarFile *s, const char *key);
void svUnsetValuesWithPrefix (shvarFile *s, const char *prefix);
typedef enum {
SV_KEY_TYPE_ANY = (1LL << 0),
SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1),
SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2),
SV_KEY_TYPE_USER = (1LL << 3),
} SvKeyType;
gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type);
/* Write the current contents iff modified. Returns FALSE on error
* and TRUE on success. Do not write if no values have been modified.

View file

@ -232,7 +232,7 @@ _assert_expected_content (NMConnection *connection, const char *filename, const
g_assert (_ifcfg_dir && _ifcfg_dir[0]); \
g_assert (_filename && _filename[0]); \
\
_success = writer_update_connection (_connection, _ifcfg_dir, _filename, _out_reread, _out_reread_same, &_error); \
_success = nms_ifcfg_rh_writer_write_connection (_connection, _ifcfg_dir, _filename, NULL, _out_reread, _out_reread_same, &_error); \
nmtst_assert_success (_success, _error); \
_assert_expected_content (_connection, _filename, _expected); \
} G_STMT_END
@ -260,8 +260,8 @@ _connection_from_file (const char *filename,
g_assert (!out_unhandled || !*out_unhandled);
connection = connection_from_file_test (filename, network_file, test_type,
out_unhandled ?: &unhandled_fallback, &error);
connection = nmtst_connection_from_file (filename, network_file, test_type,
out_unhandled ?: &unhandled_fallback, &error);
g_assert_no_error (error);
g_assert (!unhandled_fallback);
@ -282,7 +282,7 @@ _connection_from_file_fail (const char *filename,
GError *local = NULL;
char *unhandled = NULL;
connection = connection_from_file_test (filename, network_file, test_type, &unhandled, &local);
connection = nmtst_connection_from_file (filename, network_file, test_type, &unhandled, &local);
g_assert (!connection);
g_assert (local);
@ -310,12 +310,13 @@ _writer_new_connection_reread (NMConnection *connection,
con_verified = nmtst_connection_duplicate_and_normalize (connection);
success = writer_new_connection (con_verified,
ifcfg_dir,
&filename,
reread,
out_reread_same,
&error);
success = nms_ifcfg_rh_writer_write_connection (con_verified,
ifcfg_dir,
NULL,
&filename,
reread,
out_reread_same,
&error);
nmtst_assert_success (success, error);
g_assert (filename && filename[0]);
@ -384,12 +385,13 @@ _writer_new_connection_fail (NMConnection *connection,
connection_normalized = nmtst_connection_duplicate_and_normalize (connection);
success = writer_new_connection (connection_normalized,
ifcfg_dir,
&filename,
&reread,
NULL,
&local);
success = nms_ifcfg_rh_writer_write_connection (connection_normalized,
ifcfg_dir,
NULL,
&filename,
&reread,
NULL,
&local);
nmtst_assert_no_success (success, local);
g_assert (!filename);
g_assert (!reread);

View file

@ -74,89 +74,81 @@ nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection)
return NM_IFNET_CONNECTION_GET_PRIVATE (connection)->conn_name;
}
static void
static gboolean
commit_changes (NMSettingsConnection *connection,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
NMConnection **out_reread_connection,
char **out_logmsg_change,
GError **error)
{
GError *error = NULL;
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
gchar *new_name = NULL;
char *new_name = NULL;
gboolean success = FALSE;
gboolean added = FALSE;
nm_assert (out_reread_connection && !*out_reread_connection);
nm_assert (!out_logmsg_change || !*out_logmsg_change);
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (priv->conn_name) {
/* Existing connection; update it */
success = ifnet_update_parsers_by_connection (NM_CONNECTION (connection),
priv->conn_name,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
&error);
error);
} else {
/* New connection, add it */
added = TRUE;
success = ifnet_add_new_connection (NM_CONNECTION (connection),
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
&error);
if (success)
reload_parsers ();
error);
}
g_assert (!!success == (new_name != NULL));
if (success) {
/* update connection name */
g_assert (new_name);
g_free (priv->conn_name);
priv->conn_name = new_name;
NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, commit_reason, callback, user_data);
nm_log_info (LOGD_SETTINGS, "Successfully updated %s", priv->conn_name);
} else {
nm_log_warn (LOGD_SETTINGS, "Failed to update %s",
priv->conn_name ? priv->conn_name :
nm_connection_get_id (NM_CONNECTION (connection)));
reload_parsers ();
callback (connection, error, user_data);
g_error_free (error);
}
reload_parsers ();
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
if (success) {
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("ifcfg-rh: %s %s",
added ? "persist" : "updated",
new_name));
}
return success;
}
static void
do_delete (NMSettingsConnection *connection,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
static gboolean
delete (NMSettingsConnection *connection,
GError **error)
{
GError *error = NULL;
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
/* Only connections which exist in /etc/conf.d/net will have a conn_name */
if (priv->conn_name) {
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL)) {
nm_log_warn (LOGD_SETTINGS, "Failed to delete %s", priv->conn_name);
reload_parsers ();
callback (connection, error, user_data);
g_error_free (error);
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
return;
/* let's not return an error. */
}
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
}
NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data);
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
nm_log_info (LOGD_SETTINGS, "Successfully deleted %s",
priv->conn_name ? priv->conn_name :
nm_connection_get_id (NM_CONNECTION (connection)));
return TRUE;
}
/*****************************************************************************/
@ -222,7 +214,7 @@ nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class)
object_class->finalize = finalize;
settings_class->delete = do_delete;
settings_class->delete = delete;
settings_class->commit_changes = commit_changes;
signals[IFNET_SETUP_MONITORS] =

View file

@ -138,9 +138,9 @@ monitor_file_changes (const char *filename,
info->callback = callback;
info->user_data = user_data;
g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free,
info);
info);
g_signal_connect (monitor, "changed", G_CALLBACK (file_changed),
info);
info);
} else {
nm_log_warn (LOGD_SETTINGS, "Monitoring %s failed, error: %s", filename,
error == NULL ? "nothing" : (*error)->message);
@ -150,34 +150,38 @@ monitor_file_changes (const char *filename,
}
static void
setup_monitors (NMIfnetConnection * connection, gpointer user_data)
setup_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
if (nm_config_get_monitor_connection_files (nm_config_get ())) {
priv->net_monitor =
monitor_file_changes (CONF_NET_FILE, (FileChangedFn) reload_connections,
user_data);
priv->wpa_monitor =
monitor_file_changes (WPA_SUPPLICANT_CONF, (FileChangedFn) reload_connections,
user_data);
}
if (!nm_config_get_monitor_connection_files (nm_config_get ()))
return;
if (priv->net_monitor || priv->wpa_monitor)
return;
priv->net_monitor = monitor_file_changes (CONF_NET_FILE,
(FileChangedFn) reload_connections,
user_data);
priv->wpa_monitor = monitor_file_changes (WPA_SUPPLICANT_CONF,
(FileChangedFn) reload_connections,
user_data);
}
static void
cancel_monitors (NMIfnetConnection * connection, gpointer user_data)
cancel_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
if (priv->net_monitor) {
g_file_monitor_cancel (priv->net_monitor);
g_object_unref (priv->net_monitor);
g_clear_object (&priv->net_monitor);
}
if (priv->wpa_monitor) {
g_file_monitor_cancel (priv->wpa_monitor);
g_object_unref (priv->wpa_monitor);
g_clear_object (&priv->wpa_monitor);
}
}

View file

@ -139,7 +139,10 @@ bind_device_to_connection (SettingsPluginIfupdown *self,
g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, address, NULL);
}
nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, NULL, NULL);
nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported),
NULL,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL);
}
static void
@ -409,7 +412,7 @@ init (NMSettingsPlugin *config)
exported = g_hash_table_lookup (priv->connections, block->name);
if (exported) {
nm_log_info (LOGD_SETTINGS, "deleting %s from connections", block->name);
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL, NULL);
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL);
g_hash_table_remove (priv->connections, block->name);
}

View file

@ -50,29 +50,30 @@ G_DEFINE_TYPE (NMSKeyfileConnection, nms_keyfile_connection, NM_TYPE_SETTINGS_CO
/*****************************************************************************/
static void
static gboolean
commit_changes (NMSettingsConnection *connection,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
NMSettingsConnectionCommitFunc callback,
gpointer user_data)
NMConnection **out_reread_connection,
char **out_logmsg_change,
GError **error)
{
char *path = NULL;
GError *error = NULL;
gs_free char *path = NULL;
gs_unref_object NMConnection *reread = NULL;
gboolean reread_same = FALSE;
if (!nms_keyfile_writer_connection (NM_CONNECTION (connection),
nm_assert (out_reread_connection && !*out_reread_connection);
nm_assert (!out_logmsg_change || !*out_logmsg_change);
if (!nms_keyfile_writer_connection (new_connection ?: NM_CONNECTION (connection),
nm_settings_connection_get_filename (connection),
NM_FLAGS_ALL (commit_reason, NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION
| NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED),
&path,
&reread,
&reread_same,
&error)) {
callback (connection, error, user_data);
g_clear_error (&error);
return;
}
error))
return FALSE;
/* Update the filename if it changed */
if ( path
@ -81,52 +82,37 @@ commit_changes (NMSettingsConnection *connection,
nm_settings_connection_set_filename (connection, path);
if (old_path) {
nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and rename from \"%s\"",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection),
old_path);
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and rename from \"%s\"",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection),
old_path));
} else {
nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and persist connection",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" and persist connection",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
}
} else {
nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT,
NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT,
NMS_KEYFILE_CONNECTION_LOG_ARG (connection)));
}
if (reread && !reread_same) {
gs_free_error GError *local = NULL;
if (reread && !reread_same)
*out_reread_connection = g_steal_pointer (&reread);
if (!nm_settings_connection_replace_settings (connection, reread, FALSE, "update-during-write", &local)) {
nm_log_warn (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" after persisting connection failed: %s",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection), local->message);
} else {
nm_log_info (LOGD_SETTINGS, "keyfile: update "NMS_KEYFILE_CONNECTION_LOG_FMT" after persisting connection",
NMS_KEYFILE_CONNECTION_LOG_ARG (connection));
}
}
g_free (path);
NM_SETTINGS_CONNECTION_CLASS (nms_keyfile_connection_parent_class)->commit_changes (connection,
commit_reason,
callback,
user_data);
return TRUE;
}
static void
do_delete (NMSettingsConnection *connection,
NMSettingsConnectionDeleteFunc callback,
gpointer user_data)
static gboolean
delete (NMSettingsConnection *connection,
GError **error)
{
const char *path;
path = nm_settings_connection_get_filename (connection);
if (path)
g_unlink (path);
NM_SETTINGS_CONNECTION_CLASS (nms_keyfile_connection_parent_class)->delete (connection,
callback,
user_data);
return TRUE;
}
/*****************************************************************************/
@ -192,5 +178,5 @@ nms_keyfile_connection_class_init (NMSKeyfileConnectionClass *keyfile_connection
NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class);
settings_class->commit_changes = commit_changes;
settings_class->delete = do_delete;
settings_class->delete = delete;
}