Without this, `nmcli device modify "$DEVICE"` leads to a crash. At least
since commit c5d45848dd ('cli: mark argv argument for command line
parsing as const'), when this happens.
That is, because it passes a NULL strv array with argc being set to
zero. nmc_process_connection_properties() is not supposed to access
the array, if there are no elements there.
Fixes: c5d45848dd ('cli: mark argv argument for command line parsing as const')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/492
Before 1.24, nm_setting_bond_add_option() would clear
miimon/arp_interval settings when the respective other was set.
That was no longer done, with the effect that enabling (for example)
miimon on a bond profile that has arp_interval enabled, sets both
conflicting options.
That is not a severe problem, because the profile still validates.
However, at runtime only one of the settings can be actually configured.
Fix that, by restoring the previous behavior for the client. But note
that this time it's implemented in the client, and not in libnm's
nm_setting_bond_add_option().
Rework parsing of nmcli's passwd-file.
1) support backslash escaping of secrets.
- only the secret can be backslash escaped, the property and setting
name cannot.
This is a change in behavior for passwd-files with secrets that contain
a backslash.
2) strip the white space around the secret. This is a change in behavior
for secrets that had leading or trailing spaces. Note that you can
backslash escape spaces in secrets.
3) strip white space around the setting.property key. This is also a
change in behavior, but such keys would never have been valid
previously (or the caller would have performed the same kind of
stripping).
4) accept '=' as alternative delimiter beside ':'. The ':' feels really
odd and unexpected. Also accept '='. This is a change in behavior if
keys would contain '=', which they really shouldn't.
5) reject non-UTF-8 secrets and keys. For keys, that is not an issue,
because such keys were never valid. For secrets, it probably didn't
work anyway to specify non-UTF-8 secrets, because most (if not all)
secrets are transmitted via D-Bus as strings where arbitrary binary
is not allowed.
6) ignore empty lines and lines starting with '#'.
7) ensure we don't leak any secrets in memory.
1) to 4) are changes in behavior. 3) and 4) seem less severe, as they
only concern unusual setting.property keys, which really shouldn't be
used (although, VPN secrets can have almost arbitrary names *sigh*).
1) and 2) is more dangerous, as it changes behavior for secrets that
contain backslashes or leading/trailing white space.
lgtm.com flags this as "Empty block without comment".
Avoid it.
This code is of course ugly. Much work was already done to
port such occurrences, and more is needed. I won't add a FIXME
comment, because lgtm.com flags those too. :)
Static analysis tools flag the use of localtime() because it is not
thread safe. Of course, that was no problem here, but avoiding the
warning is simple.
Also, if we allocate 128 bytes, let strftime use it.
Many func implementations are asynchronous, that means, they
cannot return right away. Instead, they record the return value
in nmc->result_value.
The return value from the command functions was thus redundant.
In the best case, the return value agrees with the cached result
in nmc->result_value, in which it was unnecessary. In the worst case,
they disagree, and overwrite each other.
nmc->result_value is state. Tracking state is hard, and there should
be fewer places where the state gets mutated. Also, the rules how that
happened should be clearer. Drop the redundant, conflicting mechanism.
It's bad style to pass the argv argument around and mutate it.
We shouldn't mutate it, and not assume that it stays around after
the function returns to the caller (meaning, we should clone the
array if we intend to use it later).
Add const specifier.
It is useful from inside a function to know the command that it belongs to.
Currently we have do_networking_on() and do_networking_off() as separate
functions. However, these are basically the same with a minor difference.
If the func callback could know the "cmd" that it was called for, these
function can be combined.
Of course, without passing the NMCCommand instance, you still can
achieve the same results, especially as the NMCCommand instances are
static and known at compile time: just have separate func
implementations. But by passing the command to the function, they
*can* be combined, which is a useful thing to do.
- move the main func declarations to nmcli.h and give them a common
prefix "nmc_command_func_" prefix.
- remove some of the header files that are now empty. In fact, these
headers did not really declare some well separated module. While we
probably should structure the code in nmcli better with better layering,
it was not and still is not. Having these dummy headers don't mean that
the code is well structured and they serve little purpose.
- move the static NMCommand lists variables into the function scope
where they are used.
We should not use global variables, and we should minimize the state
that we pass around. Instead of requiring the full NmCli struct in
nm_cli_spawn_pager(), pass only the necessary data.
This reduces our use of global variables.
Of course, we later pass the point on, where we need to cast the constness away
again. This is more a reminder that we aren't suppost to change the variable.
We should try to avoid access to global variables. For libreadline
callbacks we still need a global variable.
Introduce a global variable nm_cli_global_readline, specially for this
use. It makes the places clear where we use it, and discourages
the use at other places, where we better avoid global variables.
g_clear_pointer() would always cast the destroy notify function
pointer to GDestroyNotify. That means, it lost some type safety, like
GPtrArray *ptr_arr = ...
g_clear_pointer (&ptr_arr, g_array_unref);
Since glib 2.58 ([1]), g_clear_pointer() is also more type safe. But
this is not used by NetworkManager, because we don't set
GLIB_VERSION_MIN_REQUIRED to 2.58.
[1] f9a9902aac
We have nm_clear_pointer() to avoid this issue for a long time (pre
1.12.0). Possibly we should redefine in our source tree g_clear_pointer()
as nm_clear_pointer(). However, I don't like to patch glib functions
with our own variant. Arguably, we do patch g_clear_error() in
such a manner. But there the point is to make the function inlinable.
Also, nm_clear_pointer() returns a boolean that indicates whether
anything was cleared. That is sometimes useful. I think we should
just consistently use nm_clear_pointer() instead, which does always
the preferable thing.
Replace:
sed 's/\<g_clear_pointer *(\([^;]*\), *\([a-z_A-Z0-9]\+\) *)/nm_clear_pointer (\1, \2)/g' $(git grep -l g_clear_pointer) -i
nmcli should not perform checks on the interface name length,
this kind of operations should only be performed by the NetworkManager
daemon and not be duplicated inside cli applications.
Several macros are used to define function. They had a "_STATIC" variant,
to define the function as static.
I think those macros should not try to abstract entirely what they do.
They should not accept the function scope as argument (or have two
variants per scope). This also because it might make sense to add
additional __attribute__(()) to the function. That only works, if
the macro does not pretend to *not* define a plain function.
Instead, embrace what the function does and let the users place the
function scope as they see fit.
This also follows what is already done with
static NM_CACHED_QUARK_FCN ("autoconnect-root", autoconnect_root_quark)
In all the cases, we don't want to perform locale dependent comparison.
$ sed -i 's/\<strcasecmp\>/g_ascii_\0/g' $(git grep -w -l strcasecmp -- ':(exclude)shared/systemd/' )
The abbreviations "ns" and "ms" seem not very clear to me. Spell them
out to nsec/msec. Also, in parts we already used the longer abbreviations,
so it wasn't consistent.
It is a waste of resources instantiating a NMClient, filling the
object cache and then throwing everything away without using it. This
can take seconds on slow systems with many objects. Since the
ReloadConnections doesn't need anything from the cache, just execute
the D-Bus method call directly.
Various cleanups:
- after detecting the modifier, remove it from the string right away.
It's redundant and confusing to do it later.
- rename variables and move to inner scope.
- don't use g_str_split() to split the property name at the
first dot. strchr() is sufficient.
Also, now that we strip the modifier from option early, they start also
working for aliases. There is no need to not support (or behave
differently) w.r.t. whether aliases support modifiers or not.
This fixes:
$ nmcli connection modify r +ip4 192.168.5.2/24
Error: invalid <setting>.<property> 'ip4'.
The enum values are unique throughout the source code so they
can easier be searched (e.g. with grep), compared to '\0'. It
is often interesting where a certain modifier is used, so searching
the source code is important to give relevant results.
Also, the modifier is really an enum and we shouldn't misuse char type.
If that would be a good idea in general, we wouldn't need any enums
at all. But we use them for good reasons.
Instead of straight-out rejecting extra parameters for various nmcli
sub-commands (such as "nmcli dev status", "nmcli dev wifi rescan" or
"nmcli dev wifi connect", etc.), we just print a warning and go ahead.
This is unhelpful. In case the user makes a typo, we'll do the wrong
thing and possibly even drown the warning in the output.
While at that, let's make the error message consistent. One less string
to translate.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/217
Make use of the new API. Note that AddConnection2() covers all
functionality of AddConnection() and AddConnectionUnsaved(). Let's
only use one API for all.
There is a minor downside to this patch: now nmcli requires
libnm 1.20 API. Note that libnm's nm_client_add_connection2()
makes an effort to avoid AddConnection2() under the hood to
still work against older server versions. So, you can use nmcli
with libnm 1.20 to talk to older versions of NetworkManager.
But with this change nmcli strictly requires libnm 1.20. I think that is
sensible because commonly nmcli requires a libnm version that is as new
as itself.
Also, the value of allowing nmcli to talk to older NetworkManager
versions is during package upgrade (where the daemon might not be
restarted). This is much less concern w.r.t. to updating the nmcli/libnm
combo, which is commonly packaged together.
The 'bt-type' property alias accepts values provided by
gen_func_bt_type(); instead the 'bluetooth.type' property can only be
set to [dun, panu, nap] and therefore it doesn't need special
handling.