Commit graph

120 commits

Author SHA1 Message Date
Thomas Haller
91cbbd99b9
ifcfg-rh: move code around in write_8021x_setting()
Makes more sense, to not interrupt the construction of the
phase2_auth string.
2022-04-06 13:47:21 +02:00
Thomas Haller
5f5641d304
ifcfg-rh/trivial: add fixme comments about lossy write/read of properties 2022-04-06 13:47:21 +02:00
Lubomir Rintel
82d16789a5 settings-connection: add a "plugin" argument to Update2()
This will allow migrating a connection. If specified, the connection will
be confined to a particular settings plugin when written back. If the
plugin differs from the existing one, it will be removed from the old one.
2022-03-28 13:29:28 +02:00
Lubomir Rintel
f4f165f945 settings: add "plugin" argument to AddAndActivate2()
This will confine a newly added connection to a particular settings
plugin.
2022-03-28 13:29:28 +02:00
Thomas Haller
6f948fcd2e
core: use nm_dbus_manager_lookup_object_with_type()
I think this makes it clearer that we should always look for a certain
type, because NMDBusManager tracks all D-Bus objects.
2022-03-13 12:02:08 +01:00
Beniamino Galvani
392daa5dab core: fall back to loading all known settings plugins
Currently it is possible to specify a list of default settings plugins
to be used when configuration doesn't contain the main.plugins key.

We want to add a mechanism that allows to automatically load any
plugin found in the plugins directory without needing
configuration. This mechanism is useful when plugins are shipped in a
different, optional subpackage, to automatically use them.

With such mechanism, the actual list of plugins will be determined
(in order of evaluation):

 1. via explicit user configuration in /etc, if any
 2. via distro configuration in /usr, if any
 3. using the build-time default, if any
 4. looking for known plugins in /usr/lib
2022-03-06 09:12:06 +01:00
Thomas Haller
ed9e3bac03
core: use NM_SHUTDOWN_TIMEOUT_1500_MSEC
At some places we scheduled a timeout in NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
There, we want to make sure that we don't take longer than
NM_SHUTDOWN_TIMEOUT_MAX_MSEC. But this leaves the actual wait time
unspecified.

Those callers don't want to wait an undefined time. They really should
be clear about how long they wait. Hence, use NM_SHUTDOWN_TIMEOUT_1500_MSEC
which makes it clear this is 1500 msec but also chosen to be not longer than
NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
2022-02-24 09:38:53 +01:00
Thomas Haller
32a828080c
core/trivial: rename NM_SHUTDOWN_TIMEOUT_MS to NM_SHUTDOWN_TIMEOUT_MAX_MSEC
The abbreviations "ms", "us", "ns" don't look good.
Spell out to "msec", "usec", "nsec" as done at other places.

Also, rename NM_SHUTDOWN_TIMEOUT_MS_WATCHDOG to
NM_SHUTDOWN_TIMEOUT_ADDITIONAL_MSEC.

Also, rename NM_SHUTDOWN_TIMEOUT_MS to NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
There are different timeouts, and this is the maximum gracetime we
will give during shutdown to complete async operations.

Naming is hard, but I think these are better names.
2022-02-24 09:38:52 +01:00
Thomas Haller
dab2ee8ac5
all: suppress wrong gcc-12 warning "-Wdangling-pointer"
gcc-12.0.1-0.8.fc36 is annoying with false positives.
It's related to g_error() and its `for(;;) ;`.

For example:

    ../src/libnm-glib-aux/nm-shared-utils.c: In function 'nm_utils_parse_inaddr_bin_full':
    ../src/libnm-glib-aux/nm-shared-utils.c:1145:26: error: dangling pointer to 'error' may be used [-Werror=dangling-pointer=]
     1145 |                     error->message);
          |                          ^~
    /usr/include/glib-2.0/glib/gmessages.h:343:32: note: in definition of macro 'g_error'
      343 |                                __VA_ARGS__);         \
          |                                ^~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1133:31: note: 'error' declared here
     1133 |         gs_free_error GError *error = NULL;
          |                               ^~~~~
    /usr/include/glib-2.0/glib/gmessages.h:341:25: error: dangling pointer to 'addrbin' may be used [-Werror=dangling-pointer=]
      341 |                         g_log (G_LOG_DOMAIN,         \
          |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      342 |                                G_LOG_LEVEL_ERROR,    \
          |                                ~~~~~~~~~~~~~~~~~~~~~~~
      343 |                                __VA_ARGS__);         \
          |                                ~~~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1141:13: note: in expansion of macro 'g_error'
     1141 |             g_error("unexpected assertion failure: could parse \"%s\" as %s, but not accepted by "
          |             ^~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1112:14: note: 'addrbin' declared here
     1112 |     NMIPAddr addrbin;
          |              ^~~~~~~

I think the warning could potentially be useful and prevent real bugs.
So don't disable it altogether, but go through the effort to suppress it
at the places where it currently happens.

Note that NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER macro only expands
to suppressing the warning with __GNUC__ equal to 12. The purpose is to
only suppress the warning where we know we want to. Hopefully other gcc
versions don't have this problem.

I guess, we could also write a NM_COMPILER_WARNING() check in
"m4/compiler_options.m4", to disable the warning if we detect it. But
that seems too cumbersome.
2022-02-21 19:50:52 +01:00
Thomas Haller
b2660b7012
keyfile: for keyfile owner check allow root and euid
This partly restores the previous behavior. The point of the
file owner check is to ensure that the file cannot be read
by unpriviledged processes as it may contain secrets. If the
file is owned by root, that is considered secure (even if our
euid is different).

Possibly, if our euid is not root, then we couldn't read the
file, but that is a different problem.
2022-01-18 18:10:56 +01:00
Thomas Haller
b1a14e3398
core: move nm_main_utils_get_nm_[ug]id() to "nm-core-utils.h"
There is a hierarchy of how files include each other. "main-utils.h"
is pretty much at the bottom (one above "main.c"), in the sense that
it only includes other headers, but is not included itself (aside
"main.c").

Move the utils function to a place where its accessible from everywhere
and rename.
2022-01-18 18:10:55 +01:00
Justin Spencer
604260c6ea
Assert keyfiles are owned by euid, not root 2022-01-18 17:30:45 +01:00
Justin Spencer
41db8c7563
Write keyfiles as euid / egid instead of 0 / 0 (root / root) 2022-01-18 17:30:45 +01:00
Thomas Haller
9a8c23879a
all: don't use strlen() to check whether string is empty/non-empty 2022-01-18 16:22:12 +01:00
Thomas Haller
a352647434
core: rename related things explicitly to "static-hostname"
We have at least static and transient hostnames. Let's be clear which
one we are talking about.

Note that also NM_SETTINGS_HOSTNAME gets renamed to
NM_SETTINGS_STATIC_HOSTNAME, because it seems clearer.
The only purpose of NM_SETTINGS_STATIC_HOSTNAME is to be the backing
property for the "Hostname" D-Bus property for the NMDBusObject glue.
So, while the new name makes more sense to me, it's now also
inconsistent with it's primary use (the D-Bus property). Still...
2022-01-10 20:43:17 +01:00
Thomas Haller
615221a99c format: reformat source tree with clang-format 13.0
We use clang-format for automatic formatting of our source files.
Since clang-format is actively maintained software, the actual
formatting depends on the used version of clang-format. That is
unfortunate and painful, but really unavoidable unless clang-format
would be strictly bug-compatible.

So the version that we must use is from the current Fedora release, which
is also tested by our gitlab-ci. Previously, we were using Fedora 34 with
clang-tools-extra-12.0.1-1.fc34.x86_64.

As Fedora 35 comes along, we need to update our formatting as Fedora 35
comes with version "13.0.0~rc1-1.fc35".
An alternative would be to freeze on version 12, but that has different
problems (like, it's cumbersome to rebuild clang 12 on Fedora 35 and it
would be cumbersome for our developers which are on Fedora 35 to use a
clang that they cannot easily install).

The (differently painful) solution is to reformat from time to time, as we
switch to a new Fedora (and thus clang) version.
Usually we would expect that such a reformatting brings minor changes.
But this time, the changes are huge. That is mentioned in the release
notes [1] as

  Makes PointerAligment: Right working with AlignConsecutiveDeclarations. (Fixes https://llvm.org/PR27353)

[1] https://releases.llvm.org/13.0.0/tools/clang/docs/ReleaseNotes.html#clang-format
2021-11-29 09:31:09 +00:00
Thomas Haller
aeb2426e88
libnm: change default value for "dcb.app-fcoe-mode" property
String properties in libnm's NMSetting really should have NULL as a
default value. The only property that didn't, was "dcb.app-fcoe-mode".

Change the default so that it is also NULL.

Changing a default value is an API change, but in this case probably no
issue. For one, DCB is little used. But also, it's not clear who would
care and notice the change. Also, because previously verify() would reject
a NULL value as invalid. That means, there are no existing, valid profiles
that have this value set to NULL.  We just make NULL the default, and
define that it means the same as "fabric".

Note that when we convert integer properties to D-Bus/GVariant, we often
omit the default value. For string properties, they are serialized as
"s" variant type. As such, NULL cannot be expressed as "s" type, so we
represent NULL by omitting the property. That makes especially sense if
the default value is also NULL. Otherwise, it's rather odd. We change
that, and we will now always express non-NULL value on D-Bus and let
NULL be encoded by omitting the property.
2021-11-04 20:25:18 +01:00
Thomas Haller
38d81cfa89
ifcfg: always read/write KEY_DCB_APP_FCOE_MODE key
The settings plugin is not supposed to normalize the profile. It should
read/write what is, and let NMConnection handle what is valid and what
needs normalization.
2021-11-04 20:25:18 +01:00
Thomas Haller
572ce7b7a7
glib-aux/trivial: rename GBytes helper API
Give a consistent name.

A bit odd are now the names nm_g_bytes_hash() and nm_g_bytes_equal()
as they go together with nm_pg_bytes_hash()/nm_pg_bytes_equal().
But here the problem is more with the naming of "nm_p*_{equal,hash}()"
functions, which probably should be renamed to "nm_*_ptr_{equal,hash}()".
2021-11-04 20:25:18 +01:00
Robin Ebert
b652202829
ifcfg-rh: add support for connection.dns-over-tls 2021-10-15 10:00:53 +02:00
Thomas Haller
c2ab21a1b9
ifupdown: downgrade warning about missing /etc/network/interfaces file
I don't think this warrants a warning. It's important to keep the number
of warnings and errors in the log low, and only print such messages if
there is really something that requires attention by the user. If you
run without /etc/network/interfaces, then this is pretty much expected
and the warning isn't going to tell you anything useful.
2021-09-16 08:35:05 +02:00
Thomas Haller
e38ddb52e3
all: rename nmtst_* functions that are used by the daemon
The name prefix "nmtst_*" is reserved for test helpers and stub
function. Such functions should not be in the actual build artifacts,
like the NetworkManager binary.

Instead, nmtst_connection_assert_unchanging() is not a test helper. It
is a assertion function that is only enabled with NM_MORE_ASSERTS
builds. That's different.

Rename.

In other words,

  $ nm src/core/NetworkManager src/libnm-client-impl/.libs/libnm.so | grep nmtst

should give no results.
2021-09-08 18:33:43 +02:00
Thomas Haller
10e0c4261e
format: reformat code with clang-format-12.0.1-1.fc34
The formatting produced by clang-format depends on the version of the
tool. The version that we use is the one of the current Fedora release.

Fedora 34 recently updated clang (and clang-tools-extra) from version
12.0.0 to 12.0.1. This brings some changes.

Update the formatting.
2021-08-30 13:14:00 +02:00
Thomas Haller
eafa88d438
core: fix crash for duplicate seen-bssid
This happens if there are duplicate BSSIDs for a profile in
"/var/lib/NetworkManager/seen-bssid" file.

  #0  c_list_unlink_stale (what=0x555555bc8768) at ./src/c-list/src/c-list.h:160
  #1  _seen_bssid_entry_free (data=0x555555bc8750) at src/core/settings/nm-settings-connection.c:98
  #2  0x00007ffff77e834a in g_hash_table_insert_node
      (hash_table=hash_table@entry=0x555555afa9e0 = {...}, node_index=node_index@entry=6, key_hash=key_hash@entry=967604099, new_key=new_key@entry=0x555555bc8750, new_value=new_value@entry=0x555555bc8750, keep_new_key=keep_new_key@entry=0, reusing_key=0) at ../glib/ghash.c:1352
  #3  0x00007ffff77e88f0 in g_hash_table_insert_internal (keep_new_key=0, value=0x555555bc8750, key=0x555555bc8750, hash_table=0x555555afa9e0 = {...}) at ../glib/ghash.c:1600
  #4  g_hash_table_insert (hash_table=0x555555afa9e0 = {...}, key=key@entry=0x555555bc8750, value=value@entry=0x555555bc8750) at ../glib/ghash.c:1629
  #5  0x000055555586c5e1 in _nm_settings_connection_register_kf_dbs (self=self@entry=0x555555bbf5a0, kf_db_timestamps=<optimized out>, kf_db_seen_bssids=<optimized out>)
      at src/core/settings/nm-settings-connection.c:2382
  #6  0x00005555555b7e19 in _connection_changed_update
      (self=self@entry=0x555555b1d0c0, sett_conn_entry=sett_conn_entry@entry=0x555555b60390, connection=0x555555b953f0, sett_flags=sett_flags@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, sett_mask=sett_mask@entry=_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK, update_reason=update_reason@entry=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET)) at src/core/settings/nm-settings.c:1080
  #7  0x00005555555b8b5a in _connection_changed_process_one
      (self=self@entry=0x555555b1d0c0, sett_conn_entry=0x555555b60390, allow_add_to_no_auto_default=allow_add_to_no_auto_default@entry=0, sett_flags=sett_flags@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, sett_mask=_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK,
      sett_mask@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, override_sett_flags=override_sett_flags@entry=1, update_reason=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET)) at src/core/settings/nm-settings.c:1304
  #8  0x00005555555b8c5e in _connection_changed_process_all_dirty
      (self=self@entry=0x555555b1d0c0, allow_add_to_no_auto_default=allow_add_to_no_auto_default@entry=0, sett_flags=sett_flags@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, sett_mask=sett_mask@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, override_sett_flags=override_sett_flags@entry=1, update_reason=update_reason@entry=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET)) at src/core/settings/nm-settings.c:1325
  #9  0x00005555555b8d40 in _plugin_connections_reload (self=self@entry=0x555555b1d0c0) at src/core/settings/nm-settings.c:1448
  #10 0x00005555555bddb5 in nm_settings_start (self=0x555555b1d0c0, error=error@entry=0x7fffffffe278) at src/core/settings/nm-settings.c:3892
  #11 0x000055555560013d in nm_manager_start (self=self@entry=0x555555b19060, error=error@entry=0x7fffffffe278) at src/core/nm-manager.c:6961
  #12 0x0000555555594b27 in main (argc=<optimized out>, argv=<optimized out>) at src/core/main.c:496

Fixes: 8278719840 ('settings: limit number of seen-bssids and preserve order')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/787
2021-08-30 08:19:00 +02:00
Thomas Haller
80cab06a14
ifcfg-rh/tests: fix unused variable warning in "test-ifcfg-rh.c"
Fixes: 556d76d570 ('ifcfg-rh/tests: refactor and cleanup ifcfg-rh unit tests')
2021-08-26 23:31:14 +02:00
Thomas Haller
556d76d570
ifcfg-rh/tests: refactor and cleanup ifcfg-rh unit tests
"test-ifcfg-rh.c" is huge, with lots of repeated, verbose code.
Refactor the code by using some helper macros so that the line noise
is smaller and we can easier see what is happening.

- use nmtst_connection_assert_setting() instead of
  nm_connection_get_setting*(), followed by an assertion.

- use _nm_connection_new_setting() instead of multiple lines to
  create and add the setting.

- drop all explicit unref/free and use cleanup macro.

- unify some variable names.

- drop some useless comments. In particular, comments were used as
  visual separators because the code is verbose and hard to read. The
  solution to verbose and hard to read is not more code/comments, the
  solution is clearer, conciser code.
2021-08-26 23:05:26 +02:00
Thomas Haller
222c070412
libnm,core: drop internal function _nm_connection_get_setting_bond_port()
These type-specific getters are not very useful. _nm_connection_get_setting() is
better because the setting type is a parameter so they can be used more generically.
Have less code and use generic helpers.
2021-08-26 23:05:19 +02:00
Thomas Haller
e3924a3ab6
ifcfg-rh: refactor write_bond_port_setting() and always write queue-id
- the writer/reader should be lossless. There is a difference
  on whether a NMConnection has/hasn't a NMSettingBondPort instance.
  If we thus have a NMSettingBondPort, we must always encode that
  in the ifcfg file, by writing BOND_PORT_QUEUE_ID=0. Otherwise,
  the reader will not create the setting.

- it's really not the task of the writer to validate what it writes.
  All these write_bridge_port_setting() really should not fail. They
  should serialize the setting as good as they can. And if they cannot,
  it's probably a bug in the writer (by not being lossless).
  write_bond_port_setting() did not ever fail. It should not ever fail.
  So don't let the function return a potential failure, and don't
  handle a failure that should never happen.
2021-08-26 23:05:18 +02:00
Thomas Haller
f15498eda3
ifcfg-rh: cleanup make_bond_port_setting()
- use svGetValue() instead of svGetValueStr(). The difference is that
  svGetValueStr() coerces "" to NULL. "" is not a valid value, but we
  want to parse the value and print an warning message about it. Also,
  the presence of the variable determines whether we add the bond-port
  setting or not.

- don't use nm_clear_g_free(). @value_to_free is gs_free, it will be
  cleared automatically.

- use g_object_set() instead of nm_g_object_set_property_uint(). The
  latter is our own implementation that does error checking (e.g., that
  the value is in range (0..2^16-1). But we already ensured that to
  be the case. So just call g_object_set(), it cannot fail and if it
  would, we want the assertion failure that it would cause.

- queue_id should be a "guint". It is always true on Linux/glib that
  sizeof(guint) >= sizeof(guint32), the opposite theoretically might not
  be true.
  But later we use the variable in the variadic function g_object_set(),
  where it should be guint.

- the errno from _nm_utils_ascii_str_to_uint64() isn't very useful for
  logging. It's either ERANGE or EINVAL, and logging the numeric values
  of these error codes isn't gonna help the user. We could stringify
  with nm_strerror_native(errno), but that message is also not very
  useful. Just say that the string is not a number.
2021-08-26 23:05:17 +02:00
Gris Ge
9958510f28
bond: add support of queue_id of bond port
Introduced `NMSettingBondPort` to hold the new setting class with single
property `NM_SETTING_BOND_PORT_QUEUE_ID`.

For dbus interface, please use `bond-port` as setting name and
`queue-id` as property name.

Unit test cases for ifcfg reader and writer included.

Signed-off-by: Gris Ge <fge@redhat.com>

https://bugzilla.redhat.com/show_bug.cgi?id=1949127

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/952
2021-08-26 23:04:31 +02:00
Thomas Haller
db13b93563
ifcfg-rh: fail nms_ifcfg_rh_writer_write_connection() without filename/dir
No actual caller should use the API without providing either a filename
or the directory name. I don't think this can actually happen, hence
fail and assert in that case.
2021-08-24 13:45:10 +02:00
Thomas Haller
1fa105eaef
ifcfg-rh: fix updating ifcfg file if file on disk is no longer present
Have an ifcfg file loaded in NetworkManager, then move/remove the file and try
to modify it. That will fail with:

  "failed to update connection: Could not read file '/etc/sysconfig/network-scripts/ifcfg-eth0': No such file or directory"

That is not right.

If the user didn't move/remove the file but merely modified it, NetworkManager
would silently overwrite it. There is no reason why move/remove should behave
differently and not just write a completely fresh file.

The reason why NetworkManager first loads the file before writing, is to
preserve comments and unrecognized shell variables. This is a certain effort
to play nice with users editing the file. It's not essential to load the file
first and a failure to do so should not result in a failure.

And of course, keyfile writer doesn't behave like this either.

This bug exists since 2009, but let's not add a "Fixes" comment for
commit 1974b257e0 ('ifcfg-rh: begin adding write support'), because
it seems not right to backport this patch to all the old releases.
2021-08-24 13:45:06 +02:00
Thomas Haller
8733d22343
ifcfg: read/write full IPv6 settings also for method ignore/disabled
Do "bother" to read/write settings.

For the umpteenth time, it's not up to the reader/writer to decide
what properties are valid for a profile or which makes sense.

Only nm_connection_verify() can decide that. For example nm_connection_verify()
has no problem with ipv6.method=disabled while also setting ipv6.addr-gen-mode.
We cannot just shortcut the parsing/writing.

The reader only ignores addresses, dns and dns-searches, so that we don't start
parsing invalid files, where the setting would have been ignore
previously.

In particular,

   echo "DEVICE=eth0" > /etc/sysconfig/network-scripts/ifcfg-xxx
   nmcli connection load /etc/sysconfig/network-scripts/ifcfg-xxx
   nmcli -f ipv6.method,ipv6.addr-gen-mode connection show /etc/sysconfig/network-scripts/ifcfg-xxx

needs to show eui64 addr-gen-mode.
2021-08-19 08:54:54 +02:00
Thomas Haller
7de4322d51
ifcfg: don't let write_ip[46]_setting() fail 2021-08-19 08:54:54 +02:00
Thomas Haller
00f63074d6
ifcfg: don't limit parsing DNS elements to 10 entries
It's not the task of the ifcfg reader to pre-normalize profiles
to truncate the DNS server list. It's only nm_connection_verify()'s
task to indicate what is valid and what not.

Increase the number to something excessive. Note that the parsing
scales with O(n^2). So don't have it totally unbounded and have an
overall limit (of 10000 entries).
2021-08-19 08:54:40 +02:00
Thomas Haller
1abf512831
ifcfg: fix crash due to not setting error on failure to parse DNS
Fixes: c2ad294290 ('ifcfg-rh: fix error handing in some functions that expect error != NULL')
2021-08-17 20:07:34 +02:00
Thomas Haller
02832b03ee
ifcfg/tests: fix evaluating environment variable to regenerate test files
Fixes: 1ae6719cf1 ('ifcfg-rh/tests: evalute environment for $NMTST_IFCFG_RH_UPDATE_EXPECTED only once')
2021-08-17 20:05:25 +02:00
Thomas Haller
30e7400528
ifup: extend ifup/ifdown to be smarter about NetworkManager profiles
Now that NetworkManager on Fedora 33 and RHEL 9 no longer writes
ifcfg-rh files by default ([1]), ifup/ifdown became less useful.

Possibly users shouldn't use it and it would be fine that new-style profiles
(keyfile) no longer work with these commands. But this is deemed as too
disruptive for users.

Note that our previous ifup/ifdown compat scripts only honored the argument
to be part of the ifcfg filename. That was not what initscripts were doing,
which called `need_config()` function that searched also the contents of
the files. With this extension, ifup/ifdown gets smarter too, to better
guess what the user might have wanted.

Extend the script by making it smarter, and to work with connection profile
names.

With this extension we further solidify ifup/ifdown as part of NetworkManager
command line API. That is problematic, because these tools pollute the
$PATH, by not having a clear NM-specific name. Also, these scripts
should only exist on Fedora/RHEL, which makes their usage non-portable
to other distros.
Also, other distros already ship different tools with name ifup/ifdown.
Extending the use of these scripts is thus undesirable, as it furthers
distro-specific commands.

Still, these arguments seem to not hold and users need to be "helped".
As Fedora users cannot be expected to unlearn "ifup" today, there is no
reason to assume they could in a few years. This likely means we will
never get rid of these scripts.

Also, if we truly would make ifup/ifdown part of NetworkManager, then a better
implementation would be that nmcli honors being called with these names.
That is not done, because nmcli's implementation currently is not as
nice to make that extension trivial (as it should be). It also would
mean to embrace ifup/ifdown officially. A shell script works well enough
as a hack.

[1] https://fedoraproject.org/wiki/Changes/NetworkManager_keyfile_instead_of_ifcfg_rh

https://bugzilla.redhat.com/show_bug.cgi?id=1954607

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/936
2021-08-07 15:31:04 +02:00
Thomas Haller
593cb57eb6
all: rename nm_utils_strdict_*() to nm_strdict_*() 2021-08-02 09:26:48 +02:00
Thomas Haller
3587cbd827
all: rename nm_utils_strsplit_set*() to nm_strsplit_set*() 2021-08-02 09:26:47 +02:00
Thomas Haller
d0ba87a1ad
all: rename nm_utils_strbuf_*() API to nm_strbuf_*()
The "utils" part does not seem useful in the name.

Note that we also have NMStrBuf, which is named nm_str_buf_*().
There is an unfortunate similarity between the two, but it's still
distinct enough (in particular, because one takes an NMStrBuf and
the other not).
2021-08-02 09:26:42 +02:00
Thomas Haller
4c3aac899e
all: unify and rename strv helper API
Naming is important, because the name of a thing should give you a good
idea what it does. Also, to find a thing, it needs a good name in the
first place. But naming is also hard.

Historically, some strv helper API was named as nm_utils_strv_*(),
and some API had a leading underscore (as it is internal API).

This was all inconsistent. Do some renaming and try to unify things.

We get rid of the leading underscore if this is just a regular
(internal) helper. But not for example from _nm_strv_find_first(),
because that is the implementation of nm_strv_find_first().

  - _nm_utils_strv_cleanup()                 -> nm_strv_cleanup()
  - _nm_utils_strv_cleanup_const()           -> nm_strv_cleanup_const()
  - _nm_utils_strv_cmp_n()                   -> _nm_strv_cmp_n()
  - _nm_utils_strv_dup()                     -> _nm_strv_dup()
  - _nm_utils_strv_dup_packed()              -> _nm_strv_dup_packed()
  - _nm_utils_strv_find_first()              -> _nm_strv_find_first()
  - _nm_utils_strv_sort()                    -> _nm_strv_sort()
  - _nm_utils_strv_to_ptrarray()             -> nm_strv_to_ptrarray()
  - _nm_utils_strv_to_slist()                -> nm_strv_to_gslist()
  - nm_utils_strv_cmp_n()                    -> nm_strv_cmp_n()
  - nm_utils_strv_dup()                      -> nm_strv_dup()
  - nm_utils_strv_dup_packed()               -> nm_strv_dup_packed()
  - nm_utils_strv_dup_shallow_maybe_a()      -> nm_strv_dup_shallow_maybe_a()
  - nm_utils_strv_equal()                    -> nm_strv_equal()
  - nm_utils_strv_find_binary_search()       -> nm_strv_find_binary_search()
  - nm_utils_strv_find_first()               -> nm_strv_find_first()
  - nm_utils_strv_make_deep_copied()         -> nm_strv_make_deep_copied()
  - nm_utils_strv_make_deep_copied_n()       -> nm_strv_make_deep_copied_n()
  - nm_utils_strv_make_deep_copied_nonnull() -> nm_strv_make_deep_copied_nonnull()
  - nm_utils_strv_sort()                     -> nm_strv_sort()

Note that no names are swapped and none of the new names existed
previously. That means, all the new names are really new, which
simplifies to find errors due to this larger refactoring. E.g. if
you backport a patch from after this change to an old branch, you'll
get a compiler error and notice that something is missing.
2021-07-29 10:26:50 +02:00
Thomas Haller
3775f4395a
all: drop unnecessary casts from nm_utils_strv_find_first()
And, where the argument is a GPtrArray, use
nm_strv_ptrarray_find_first() instead.
2021-07-29 09:33:50 +02:00
Beniamino Galvani
bace14fe1f core: introduce device 'allowed-connections' property
Configuration can have [device*] and [connection*] settings and both
can include a 'match-device=' key, which is a list of device-specs.

Introduce a new 'allowed-connections' key for [device*] sections,
which specifies a list of connection-specs to indicate which
connections can be activated on the device.

With this, it becomes possible to have a device configuration like:

  [device-enp1s0]
  match-device=interface-name:enp1s0
  allowed-connections=except:origin:nm-initrd-generator

so that NM in the real root ignores connections created by the
nm-initrd-generator, and starts activating a persistent
connection. This requires also setting 'keep-configuration=no' to not
generate an assumed connection.
2021-07-27 17:43:45 +02:00
Thomas Haller
6d07afaa8d
libnm: implement special setter for direct string property for ip address
This is a normalization employed by NMSettingIPConfig.gateway.

Also rework NMSettingIPConfig.set_property() to no longer assert against
valid input. We want to pass there untrusted strings from D-Bus,
asserting is a horrible idea. Instead, either normalize the string or
keep the invalid text that will be rejected by verify().
2021-07-23 17:02:03 +02:00
Thomas Haller
fc2f758af5
ifcfg: also ANSIC escape DEL character in ifcfg writer
This is like using nm_ascii_is_ctrl_or_del() instead of
nm_ascii_is_ctrl() in the previous version of the patch.
We thus now always will switch to ANSIC escaping if we see
a ASCII DEL character. That is probable desirable, but either
way should not make a big difference (because we can parse
the DEL character both in regular quotation and in ANSIC quotation).

The patch is however larger, to also take the opportunity to only check
for nm_ascii_is_regular() in the "fast path". The behavior is the same
as changing nm_ascii_is_ctrl() to nm_ascii_is_ctrl_or_del().
2021-07-19 09:03:52 +02:00
Thomas Haller
6841bb1b26
ifcfg: use nm_ascii_is_ctrl() helper in shvar.c
No change in behavior.
2021-07-19 08:59:34 +02:00
Thomas Haller
41be0c8fde
ifcfg: log messages about invalid an unrecognized lines in ifcfg files
Problems of this patch:

- the code does not differentiate between an ifcfg file and an alias
  file. Different shell variables are honored however depending on the
  context and the warning should reflect that.

- there are no warnings about /etc/sysconfig/network. The main problem
  is that we read this file for every ifcfg file we parse, and we would
  need to ratelimit the number of warnings. Another problem is that
  the file likely contains keys that we intentionally don't support.
  We would need a new way to omit warnings about those lines.

Example:

    TYPE=Ethernet
    PROXY_METHOD=none
    BROWSER_ONLY=no
    BOOTPROTO=dhcp
    DEFROUTE=yes
    STABLE_ID=$'xxx\xF4yy'
    IPV4_FAILURE_FATAL=no
    IPV6INIT=yes
    XX=foo
    XX1=foo'
    '
    IPV6_AUTOCONF=yes xxxx
    IPV6_DEFROUTE=yesx
    IPV6_DEFROUTE=yes
    IPV6_FAILURE_FATAL=no
    IPV6_ADDR_GEN_MODE=stable-privacy
    NAME=xxx
    UUID=9d8ed7ff-3cdd-4336-9e26-3e978dc87102
    ONBOOT=no

  <warn>  [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:6: key STABLE_ID does not contain valid UTF-8 and is treated as ""
  <debug> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:9: key XX is unknown and ignored
  <warn>  [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:10: key XX1 is badly quoted and is treated as ""
  <warn>  [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:11: invalid line ignored
  <warn>  [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:12: key IPV6_AUTOCONF is badly quoted and is treated as ""
  <warn>  [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:13: key IPV6_DEFROUTE is duplicated and the early occurrence ignored

https://bugzilla.redhat.com/show_bug.cgi?id=1959656
2021-07-15 09:06:34 +02:00
Thomas Haller
7c9b0d68e4
ifcfg: reject non-UTF-8 at the lowest layer when reading shell variable
ifcfg files are a text format. It makes no sense to ever accept
non-UTF-8 blobs. If binary data is to be encoded in a ifcfg file, then
the upper layers must escape/encode it in valid UTF-8.

Let svUnescape() silently reject any binary "text". This will lead to treat such
strings as empty strings "". This is no different than some invalid
quoting: the string is not parsable as (UTF-8) text and will be treated
as such.

This is potentially a breaking change. But the benefit is that all the
upper layers can rely on only getting valid UTF-8 strings. For example,
a non-UTF-8 string cannot be converted to a "s" GVariant (of course not,
it's not a string). But our nm_connection_verify() commonly does not
check that all strings are in fact valid UTF-8. So a user who edits
an ifcfg file could inject non-valid strings, and cause assertion
failures later on.

It's actually easy to provoke a crash (or at least an assertion failure)
by writing an ifcfg file with certain keys as binary.

Note that you can either reproduce the binary files by writing non-UTF-8
"strings" dirctly, or by using \x, \u, or \U escape sequences.

Note that also '\0' gets rejected and renders the string as invalid
(i.e. as empty). Before the returned string would have been simply
truncated and the rest ignored. Such NUL bytes can only be produced
using the escape sequences, because the ifcfg reader already (silently)
truncates the file on the first binary NUL.
2021-07-15 08:22:24 +02:00
Thomas Haller
5877928b46
ifcfg: ANSIC escape non-UTF-8 "strings" and preserve valid unicode
Note that previously the check

    if (s[slen] < ' ') {
        ...
        return (*to_free = _escape_ansic(s));
    }

would be TRUE for all UTF-8 characters if `char` is signed. That means,
depending on the compiler, we would always ANSI escape all UTF-8
characters. With this patch, we no longer do that!
Instead, valid unicode gets now preserved (albeit quoted).

On the other hand, always ANSIC escape invalid UTF-8 (regardless of the
compiler). ifcfg-rh is really a text based format. If a caller wants to store
binary data, they need to escape it first, for example with some own escaping
scheme, base64 or bin2hexstr.

A caller passing a non-text to svEscape() is likely a bug already and
they should have not done that.

Still, let svEscape() handle that by using ANSIC escaping. That works
as far as escaping is concerned, but likely later will be a problem
during unescaping, when the reader expects a valid UTF-8 string.
svEscape() is in no place to signal a sensible error, so proceed the
best it can, by escaping.
2021-07-15 08:19:05 +02:00