- in nm_keyfile_read(), unify _read_setting() and
_read_setting_vpn_secret() in they way they are called
(that is, they no longer return any value and don't accept
any arguments aside @info).
- use cleanup attributes
- use nm_streq() instead of strcmp().
- wrap lines that have multiple statements or conditions.
Several callers access the length output argument, expecting
it to be zero also on failure. That is a bug, because glib does
not guarantee that.
Fix that by making a stronger promise from our wrappers: the output
argument should also be set on failure.
Also ensure that calls to g_keyfile_get_groups() and
g_keyfile_get_keys() don't rely on the length output to be valid,
when the function call fails.
Actually, these issues were not severe because:
- `g_key_file_get_*_list()`'s implementation always sets the output length
even on failure (undocumented).
- `g_key_file_get_groups()` cannot fail and always set the length.
- `g_key_file_get_keys()` is called under circumstances where it won't
fail.
Still, be explicit about it.
While nm_utils_inet*_ntop() accepts a %NULL buffer to fallback
to a static buffer, don't do that.
I find the possibility of using a static buffer here error prone
and something that should be avoided. There is of course the downside,
that in some cases it requires an additional line of code to allocate
the buffer on the stack as auto-variable.
In quite some cases we need the string representation on the heap.
While nm_utils_inet*_ntop() accepts NULL as output buffer to fallback
to a static buffer, such usage of a static buffer is discouraged.
So, we actually should always allocate a temporaray buffer on the
stack. But that is cumbersome to write.
Add simple wrappers that makes calling this more convenient.
Taken from systemd's in4_addr_netmask_to_prefixlen().
Yes, this adds the requirement that "int" is 32 bits. But systemd
already has the same requirement in u32ctz(), hence we anyway cannot
build on other architectures. If that is ever necessary, it's easy
to adjust.
The 'number' property in GSM settings is a legacy thing that comes
from when ModemManager used user-provided numbers, if any, to connect
3GPP modems.
Since ModemManager 1.0, this property is completely unused for 3GPP
modems, and so it doesn't make sense to use it in the NetworkManager
settings. Ofono does not use it either.
For AT+PPP-based 3GPP modems, the 'number' to call to establish the
data connection is decided by ModemManager itself, e.g. for standard
GSM/UMTS/LTE modems it will connect a given predefined PDP context,
and for other modems like Iridium it will have the number to call
hardcoded in the plugin itself.
https://github.com/NetworkManager/NetworkManager/pull/261
Describe how to specify multiple VFs and which attributes are
supported, so that this information is available in the nm-settings
manual page.
Also, clarify that SR-IOV parameters are managed only when the setting
is present.
https://bugzilla.redhat.com/show_bug.cgi?id=1651979
Report an error when the user tries to add an unknown attribute
instead of silently accepting (and ignoring) it.
Note that this commit also changes the behavior of public API
nm_utils_sriov_vf_from_str() to return an error when an unknown
attribute is found. I think the previous behavior was buggy as wrong
attributes were simply ignored without any way for the user to know.
Fixes: a9b4532fa7
nm_team_link_watcher_new_arp_ping2() is the more powerful variant of
nm_team_link_watcher_new_arp_ping(). It can do everything the new
variant can, and more.
Hence, v1 should be implemented based on v2. This way, validating and
constructing the watcher is all done in one place, not split in two places.
Add support for the teaming arp_ping link watcher 'vlanid' property.
Signed-off-by: Patrick Talbert <ptalbert@redhat.com>
[thaller@redhat.com: minor fixes to original patch]
https://bugzilla.redhat.com/show_bug.cgi?id=1652931
By setting "connection.permissions", a profile is restricted to a
particular user.
That means for example, that another user cannot see, modify, delete,
activate or deactivate the profile. It also means, that the profile
will only autoconnect when the user is logged in (has a session).
Note that root is always able to activate the profile. Likewise, the
user is also allowed to manually activate the own profile, even if no
session currently exists (which can easily happen with `sudo`).
When the user logs out (the session goes away), we want do disconnect
the profile, however there are conflicting goals here:
1) if the profile was activate by root user, then logging out the user
should not disconnect the profile. The patch fixes that by not
binding the activation to the connection, if the activation is done
by the root user.
2) if the profile was activated by the owner when it had no session,
then it should stay alive until the user logs in (once) and logs
out again. This is already handled by the previous commit.
Yes, this point is odd. If you first do
$ sudo -u $OTHER_USER nmcli connection up $PROFILE
the profile activates despite not having a session. If you then
$ ssh guest@localhost nmcli device
you'll still see the profile active. However, the moment the SSH session
ends, a session closes and the profile disconnects. It's unclear, how to
solve that any better. I think, a user who cares about this, should not
activate the profile without having a session in the first place.
There are quite some special cases, in particular with internal
activations. In those cases we need to decide whether to bind the
activation to the profile's visibility.
Also, expose the "bind" setting in the D-Bus API. Note, that in the future
this flag may be modified via D-Bus API. Like we may also add related API
that allows to tweak the lifetime of the activation.
Also, I think we broke handling of connection visiblity with 37e8c53eee
"core: Introduce helper class to track connection keep alive". This
should be fixed now too, with improved behavior.
Fixes: 37e8c53eeehttps://bugzilla.redhat.com/show_bug.cgi?id=1530977
This code will be used later.
We want to remember which keyfiles are currently loaded (or hidden).
With the addition or multiple keyfile directories (soon), there are
two cases where this matters:
- if there are multiple keyfiles which reference the same UUID,
we can only load one of them. That is already a problem today
with only one keyfile directory, where multiple files can reference
the same UUID.
The implementation will pick the file based on priorities (like
the file modification date). However, the user may call explicitly
call `nmcli connection load`. In that case, we cannot reload
all files to find out whether the to be loaded file is hidden
according to the defined priorities. We cannot do that, because we
must not make decisions based on files on disk, which we are not told
to reload. So, during a `nmcli connection load` we must look at
unrelated files, to determine how to load the file.
Instead, we do allow the user to load any file, even if it would be
shadowed by other files. When we do that, we may want to persist which
file is currently loaded, so that a service restart and a `nmcli connection
reload` does not undo the load again. This can be later later be solved by
writing a symlink
"/var/run/NetworkManager/system-connections/.loaded-$UUID.nmkeyfile"
which targets the currently active file.
- if a profile was loaded from read-only persistant storage, the user
may still delete the profile. We also need to remember the deletion
of the file. That will be achieved by symlinking "/dev/null" as
"/etc/NetworkManager/system-connections/.loaded-$UUID.nmkeyfile".
Add helper functions to read and write these symlinks.
Correct the spelling across the *entire* tree, including translations,
comments, etc. It's easier that way.
Even the places where it's not exposed to the user, such as tests, so
that we learn how is it spelled correctly.
CAK is a connection secret and can be NULL for various reasons
(agent-owned, no permissions to get secrets, etc.). verify() must not
require it.
Fixes: 474a0dbfbe
Add a new mode for the DHCPv4 client identifier.
"duid" is what the internal (systemd) DHCP client already does by
default. It is also the same as used by systemd-networkd's
"ClientIdentifier=duid" setting. What we still lack (compared to
networkd) are a way to overwrite IAID and the DUID.
Previously, this mode was used by the internal DHCP plugin
by default. However, it could not be explicitly configured.
In general, our default values should also be explicitly selectable.
Now the "duid" client identifier can also be used with the "dhclient"
plugin.
We already had "${DEVICE}" which uses the interface name.
In times of predictable interface naming, that works well.
It allows the user to generate IDs per device which don't
change when the hardware is replaced.
"${MAC}" is similar, except that is uses the permanent MAC
address of the device. The substitution results in the empty
word, if the device has no permanent MAC address (like software
devices).
The per-device substitutions "${DEVICE}" and "${MAC}" are especially
interesting with "connection.multi-connect=multiple".
The client-id is something that we want to determine top-down.
Meaning, if the user specifies it via ipv4.dhcp-client-id, then it
should be used. If the user leaves it unspecified, we choose a
default stable client-id. For the internal DHCP plugin, this is
a node specific client-id based on
- the predictable interface name
- and /etc/machine-id
It's not clear, why we should allow specifying the client-id in
the lease file as a third source of configuration. It really pushes
the configuration first down (when we do DHCP without lease file),
to store an additional bit of configuration for future DHCP attempts.
If the machine-id or the interface-name changes, then so does the
default client-id. In this case, also "ipv4.dhcp-client-id=stable"
changes. It's fair to require that the user keeps the machine-id
stable, if the machine identity doesn't change.
Also, the lease files are stored in /var/lib/NetworkManager, which
is more volatile than /etc/machine-id. So, if we think that machine-id
and interface-name is not stable, why would we assume that we have
a suitable lease file?
Also, if you do:
nmcli connection add con-name "$PROFILE" ... ipv4.dhcp-client-id ''
nmcli connection up $PROFILE
nmcli connection modify "$PROFILE" ipv4.dhcp-client-id mac
nmcli connection up $PROFILE
nmcli connection modify "$PROFILE" ipv4.dhcp-client-id ''
nmcli connection up $PROFILE
wouldn't you expect that the original (default) client-id is used again?
Also, this works badly with global connection defaults in
NetworkManager.conf. If you configure a connection default, previously
already this would always force the client-id and overrule the lease.
That is reasonable, but in which case would you ever want to use
the client-id from the lease?
The entire point of using version 3/5 UUIDs is to generate
stable UUIDs based on a string. It's usually important that
we don't change the UUID generation algorithm later on.
Since we didn't have a version 5 implementation, we would always
resort to the MD5 based version 3. Version 5 is recommended by RFC 4122:
o Choose either MD5 [4] or SHA-1 [8] as the hash algorithm; If
backward compatibility is not an issue, SHA-1 is preferred.
Add a version 5 implementation so we can use it in the future.
All test values are generated with python's uuid module or OSSP uuid.
We link against libuuid.so, but it was entirely internal to
libnm-core. We only exposed UUIDs in string form.
Add API to also handle UUIDs in binary form.
Note that libuuid already defines a type "uuid_t". However,
don't use it and instead use our own typedef NMUuid.
Reasons:
- uuid.h should be internal to libnm-core (nm-utils.c specifically),
and not be used by or exposed it other parts of the code.
- uuid_t is a typedef for a guchar[16] array. Typedefs
for arrays are confusing, because depending on whether
it's an automatic variable or a pointer in a function argument,
they behave differently regarding whether to take their address
or not and usage of "sizeof()".
NMConnection keeps a list (hash table) of all settings.
There are two lookup methods to find a setting in a connection:
- nm_connection_get_setting() by GType
- nm_connection_get_setting_by_name() by name
Note, that nm_connection_get_setting_by_name() first converts the
name to a GType, and then looks up the setting by GType.
But then, nm_connection_get_setting() would again convert the GType to
the type name, and hash the name. That is pointless, just index by GType
directly.
Maybe, using a hash table is anyway overkill because commonly there are
only a handful of settings in a connection. Regardless of that, change
the hashing.
NM_CONFIG_KEYFILE_PATH_IN_MEMORY is now called NMS_KEYFILE_PATH_NAME_RUN.
This name seems odd in the current context, it will be more suitable
when we also have NMS_KEYFILE_PATH_NAME_LIB (for /usr/lib).
These utilities are concerned with valid file names (as NetworkManager
daemon requires it). This is relevant for everybody who wants to write
keyfile files directly. Hence, move it to libnm-core. Still as internal
API.
Even if a direct pointer comparison should be fine, use the proper
function. GVariantType documentation says:
"Two types may not be compared by value; use g_variant_type_equal()
or g_variant_type_is_subtype_of()."
This also fixes coverity warnings.
3. NetworkManager-1.14.0/libnm-core/nm-utils.c:4944: var_compare_op: Comparing "str" to null implies that "str" might be null.
4. NetworkManager-1.14.0/libnm-core/nm-utils.c:4958: var_deref_op: Dereferencing null pointer "str".
# 4956|
# 4957| /* do some very basic validation to see if this might be a JSON object. */
# 4958|-> if (str[0] == '{') {
# 4959| gsize l;
# 4960|
keyfile already supports omitting the "connection.id" and
"connection.uuid". In that case, the ID would be taken from the
keyfile's name, and the UUID was generated by md5 hashing the
full filename.
No longer do this during nm_keyfile_read(), instead let all
callers call nm_keyfile_read_ensure_*() to their liking. This is done
for two reasons:
- a minor reason is, that one day we want to expose keyfile API
as public API. That means, we also want to read keyfiles from
stdin, where there is no filename available. The implementation
which parses stdio needs to define their own way of auto-generating
ID and UUID. Note how nm_keyfile_read()'s API no longer takes a
filename as argument, which would be awkward for the stdin case.
- Currently, we only support one keyfile directory, which (configurably)
is "/etc/NetworkManager/system-connections".
In the future, we want to support multiple keyfile dirctories, like
"/var/run/NetworkManager/profiles" or "/usr/lib/NetworkManager/profiles".
Here we want that a file "foo" (which does not specify a UUID) gets the
same UUID regardless of the directory it is in. That seems better, because
then the UUID won't change as you move the file between directories.
Yes, that means, that the same UUID will be provided by multiple
files, but NetworkManager must already cope with that situation anyway.
Unfortunately, the UUID generation scheme hashes the full path. That
means, we must hash the path name of the file "foo" inside the
original "system-connections" directory.
Refactor the code so that it accounds for a difference between the
filename of the keyfile, and the profile_dir used for generating
the UUID.
Split out the functionality for auto-detecting the ID and UUID of
a connection. First of all, nm_keyfile_read() is already overcomplicated.
The next commit will require the caller to explicitly call these
functions.
Add 3 variants of _nm_utils_hexstr2bin*():
- _nm_utils_hexstr2bin_full(), which takes a preallocated
buffer and fills it.
- _nm_utils_hexstr2bin_alloc() which returns a malloc'ed
buffer
- _nm_utils_hexstr2bin_buf(), which fills a preallocated
buffer of a specific size.