The function only has one caller and it should be simple enough
to perform the necessary steps right in nms_ifcfg_rh_writer_write_connection().
More functions don't (always) simplify the code.
- most connections are not Wi-Fi connections and thus don't have a seen-bssids
list. Only create the seen_bssids hash when required. This avoids allocating the
hash in common cases and avoids checking the hash for the content (which is often
empty).
- nm_settings_connection_get_seen_bssids() should return a sorted list.
Leaving the sort order undefined is ugly.
- in try_fill_ssid_for_hidden_ap(), we need to check all
NMSettingsConnection instances whether they know this bssid.
Reorder the checks, to first call nm_settings_connection_has_seen_bssid(), which
is faster and in most cases returns a negative result (shortcutting
the rest).
The function determines the filename automatically, but we
need to blacklist certain names.
That is, because NetworkManager keeps a list of loaded files
in memory. When writing a new file, we really want to choose
a filename that is not yet taken. For that we must not only
consider files on disk, but also files that existed on the last
time of loading.
- avoid cloing the basename. Determining the basename can be done conveniently
with strrchr().
- use cleanup macro for temporary variable.
- while in practice it should not happen, check that the colon in the name
of alias file names is not followed by another '/'.
nm_connection_verify() returns success for fully valid (normalized)
connections and also connections that are NM_SETTING_VERIFY_NORMALIZABLE.
We really want to fully normalize the profiles during add-and-activate.
The settings plugins are created by NMSettings when the plugin
gets loaded. There is no need for these instances to be singletons
or to have a singleton getter.
Also, while in practice we create a settings plugin instance of
each type only once, there is nothing that would prevent creating
multiple instances. Hence, having a singleton getter is not right.
What is however useful, is to track them and block shutdown
via nm_shutdown_wait_obj_register*(). While the actual waiting
is not yet implemented, we should mark the plugin instances to
block shutdown (in the future).
Logging pointer values is useful to identify the object in the logging message.
But plain pointer values also can be used to defeat ASLR and should not be logged.
Instead, print NM_HASH_OBFUSCATE_PTR() value, which is a 64 bit number based on
the pointer value and some random seed. A minor problem is that there is still the
chance of duplicates, albeit small.
The functionality of the ibft settings plugin is now handled by
nm-initrd-generator. There is no need for it anymore, drop it.
Note that ibft called iscsiadm, which requires CAP_SYS_ADMIN to work
([1]). We really want to drop this capability, so the current solution
of a settings plugin (as it is implemented) is wrong. The solution
instead is nm-initrd-generator.
Also, on Fedora the ibft was disabled and probably on most other
distributions as well. This was only used on RHEL.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1371201#c7
The previous logic seems complicated to me. I even think it is wrong.
Rework it, I think this makes sense.
Also, previously the existing path was used if the file didn't exist.
I think that is wrong. If for force a rename, then the filename must
not be used even if the file currently does not exist.
Also add an "allow_filename_cb" argument, to reject filenames that
are blacklisted.
The keyfile plugin is special. For one, NetworkManager will always load
it.
In the future, only this plugin should handle in-memory connections.
In-memory connections are kinda special, and we don't need general
plugins to be concerned about them. They should be handled by keyfile
plugin.
But then NMSettings needs to have a reference to the keyfile plugin
instance at hand.
Note that now the empty list will be represented as %NULL instead of an
empty strv array.
That makes no difference in pratice. The main use of this property is as
glue for NMDBusManager to expose the property on D-Bus. Thereby it uses
g_dbus_gvalue_to_gvariant() which handles %NULL just fine.
NMManager and NMSettings both may have multiple authorization requests
ongoing. They need to keep track of them, at the very least to be able
to cancel them on shutdown.
Since NMAuthChain is not ref-countable, it always has only one clear
user/owner. It makes little sense otherwise. Since most callers already
want to track their NMAuthChain instances, let NMAuthChain help with that.
Embed a "parent" CList field inside NMAuthChain. This avoids requiring
an additional GSList allocation to track the element. Also, it allows to
link and append an element without iterating the list.
This ties the caller and the NMAuthChain a bit tighter together (making them
less indepdendent). Generally that is not desirable. But here it seems the
logic (of tracking the NMAuthChain) is still trivial and well separated.
It's just that NMAuthChain instances now can be linked in a CList.
VPN settings (for openconnect) can only be handled by the keyfile settings
plugin.
In any case, such special casing belongs to the settings plugin and not
"nm-settings.c". The reason is that the settings plugin already has an
intimate understanding of the content of connections, it knows which fields
exist, their meaning, etc. It makes sense special handling of
openconnect is done there.
See also commit 304d0b869b ('core: openconnect migration hack').
Unfortunately it's not clear to me why/whether this is still the
right thing to do.
nm_device_check_connection_compatible() is potentially expensive.
Check first whether the connection candidate is of a relevant type,
hoping that this check is cheaper and thus shortcuts other checks
early.
NMSettings is complicated enough. We should try to move independent code out
of it, so that there is only logic that is essential there.
While at it, rework how we copy the GSList items. I don't like GSList as
a data structure, but there really is no need to allocate a new list.
Just unlink the list element and prepend it in the other list.
As nm_settings_plugin_initialize() could not fail (it returned no value indicating
failure), there is no reason to explicitly call this. Instead just
initialize the plugin when needed.
Also, we don't need the plugin to initialize early before nm_settings_plugin_get_connections().
Instead of
<info> [1558284380.2045] settings: Loaded settings plugin: SettingsPluginIfcfg ("/usr/lib64/NetworkManager/1.19.2/libnm-settings-plugin-ifcfg-rh.so")
log
<info> [1558284380.2045] settings: Loaded settings plugin: ifcfg-rh ("/usr/lib64/NetworkManager/1.19.2/libnm-settings-plugin-ifcfg-rh.so")
Note how `man NetworkManager.conf` documents "main.plugins" configuration
option where settings plugins have names like "keyfile" and "ifcfg-rh".
It's not helpful to log the GObject type name, which is an implementation
detail.
It was only kept to compare whether we loaded the same
plugin multiple times.
Note that load_plugins() already checks for duplicate plugin names,
so it actually could not happen that we tried to load the same file
more than once.
We no longer add these. If you use Emacs, configure it yourself.
Also, due to our "smart-tab" usage the editor anyway does a subpar
job handling our tabs. However, on the upside every user can choose
whatever tab-width he/she prefers. If "smart-tabs" are used properly
(like we do), every tab-width will work.
No manual changes, just ran commands:
F=($(git grep -l -e '-\*-'))
sed '1 { /\/\* *-\*- *[mM]ode.*\*\/$/d }' -i "${F[@]}"
sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}"
Check remaining lines with:
git grep -e '-\*-'
The ultimate purpose of this is to cleanup our files and eventually use
SPDX license identifiers. For that, first get rid of the boilerplate lines.
nmtst_get_rand_int() was originally named that way, because it
calls g_rand_int(). But I think if a function returns an uint32, it
should also be named that way.
Rename.
This code is now unused.
Also, it does not seem state of the art to me
anymore.
Drop it, it could always be resurrected if need by, but maybe
GFileMonitor could be used instead.
It's deprecated and off by default for a long time.
It is bad to automatically reload connection profiles. For example, ifcfg
files may consist of multiple files, there is no guarantee that we
pick up the connection when it's fully written.
Just don't do this anymore.
Users should use D-Bus API or `nmcli connection reload` or `nmcli
connection load $FILENAME` to reload profiles from disk.
Before commit e3ac45c026 the reader set the private key in the
setting using the libnm function, which also set the key as client
certificate if it was in PKCS #12 format.
After the commit, existing connections with a PKCS #12 private key but
without a client certificate became invalid. Restore the old behavior.
Fixes: e3ac45c026 ('ifcfg-rh: don't use 802-1x certifcate setter functions')
Completely refactor the team/JSON handling in libnm's NMSettingTeam and
NMSettingTeamPort.
- team handling was added as rh#1398925. The goal is to have a more
convenient way to set properties than constructing JSON. This requires
libnm to implement the hard task of parsing JSON (and exposing well-understood
properties) and generating JSON (based on these "artificial" properties).
But not only libnm. In particular nmcli and the D-Bus API must make this
"simpler" API accessible.
- since NMSettingTeam and NMSettingTeamPort are conceptually the same,
add "libnm-core/nm-team-utils.h" and NMTeamSetting that tries to
handle the similar code side-by-sdie.
The setting classes now just delegate for everything to NMTeamSetting.
- Previously, there was a very fuzzy understanding of the provided
JSON config. Tighten that up, when setting a JSON config it
regenerates/parses all other properties and tries to make the
best of it. When modifying any abstraction property, the entire
JSON config gets regenerated. In particular, don't try to merge
existing JSON config with the new fields. If the user uses the
abstraction API, then the entire JSON gets replaced.
For example note that nm_setting_team_add_link_watcher() would not
be reflected in the JSON config (a bug). That only accidentally worked
because client would serializing the changed link watcher to
GVariant/D-Bus, then NetworkManager would set it via g_object_set(),
which would renerate the JSON, and finally persist it to disk. But
as far as libnm is concerned, nm_setting_team_add_link_watcher() would
bring the settings instance in an inconsistent state where JSON and
the link watcher property disagree. Setting any property must
immediately update both the JSON and the abstraction API.
- when constucting a team setting from D-Bus, we would previously parse
both "config" and abstraction properties. That is wrong. Since our
settings plugins only support JSON, all information must be present
in the JSON config anyway. So, when "config" is present, only the JSON
must be parsed. In the best case, the other information is redudant and
contributes nothing. In the worse case, they information differs
(which might happen if the client version differs from the server
version). As the settings plugin only supports JSON, it's wrong to
consider redundant, differing information from D-Bus.
- we now only convert string to JSON or back when needed. Previously,
setting a property resulted in parsing several JSON multiple times
(per property). All operations should now scale well and be reasonably
efficient.
- also the property-changed signals are now handled correctly. Since
NMTeamSetting knows the current state of all attributes, it can emit
the exact property changed signals for what changed.
- we no longer use libjansson to generate the JSON. JSON is supposed
to be a machine readable exchange format, hence a major goal is
to be easily handled by applications. While parsing JSON is not so
trivial, writing a well-known set of values to JSON is.
The advantage is that when you build libnm without libjansson support,
then we still can convert the artificial properties to JSON.
- Requiring libjansson in libnm is a burden, because most of the time
it is not needed (as most users don't create team configurations). With
this change we only require it to parse the team settings (no longer to
write them). It should be reasonably simple to use a more minimalistic
JSON parser that is sufficient for us, so that we can get rid of the
libjansson dependency (for libnm). This also avoids the pain that we have
due to the symbol collision of libjansson and libjson-glib.
https://bugzilla.redhat.com/show_bug.cgi?id=1691619
We have nm_setting_verify() for a purpose.
The checks that ifcfg-rh reader does are either
- redundant (and thus unnecessary)
- wrong (and thus we cannot read valid settings)
- should belong to libnm's nm_setting_verify().
NMSettingTeam/NMSettingTeamPort are already very libraral and don't do
almost any strict validation. Previously, ifcfg reader would be even more
liberal. If there is totally invalid data in the profile, reading the profile
should fail.
We already have "libnm-core/tests/test-keyfile.c" from which we build
"test-keyfile".
Our test binaries should be named the following:
- "*/tests/test-*"
- the test binary "*/tests/test-*" should be build from a source file
"*/tests/test-*.c". Meaning: the source's and executable's name should
correspond.
- test binaries should be named uniquely. Also, because older meson
versions don't like having the same binary name more than once.
Rename to avoid the duplicate name.
I also like this because it's non-obvious that subscription IDs from
GDBusConnection are "guint" (contrary to signal handler IDs which are
"gulong"). So, by using this API you get a compiler error when using the
wrong type.
In the past, when switching to nm_clear_g_signal_handler() this uncovered
multiple bugs where the wrong type was used to hold the ID.
Out of the 33 callers of nm_auth_chain_add_call(), the permission
argument is:
- 29 times a C string literal like NM_AUTH_PERMISSION_NETWORK_CONTROL.
- 3 times assign a string that is in fact a static string (it's just
not a string literal)
- only NMManager's device_auth_request_cb() passes a permission of
(possibly) non static origin. But it already duplicates the string
for it's own purposes and attaches it as user-data to the
NMAuthChain.
There really is no need to duplicate the string.
Replace nm_auth_chain_add_call() by a macro that ensures that the
permission string is a C literal.
Rename nm_auth_chain_add_call() to nm_auth_chain_add_call_unsafe() to
indicate that the lifetime of the permission argument is now the
responsibility of the caller.
NMAuthChain usually requests several permissions at once. Hence, an error
argument in the overall callback does not make sense, because you
wouldn't know which request failed.
If at all, it could only mean that the overall request failed (like an
D-Bus failure communicating to D-Bus *for all permisssions*),
but we don't need to handle that specially. In fact, we don't really care
why permission was not granted, whether it's due to an error or legitimate
reasons.
The error in the callback was always set to %NULL. Remove it.
NMAuthChain is not ref-counted.
You may call nm_auth_chain_destroy() once before the callback
gets invoked. This destroys the auth-chain instance right away.
You may call nm_auth_chain_destroy() once from inside the callback.
This basically has no effect but is allowed for convenince.
All this does is remembering that destroy was called and asserts that
destroy gets called at most once.
After the callback returns, the auth-chain will always be destroyed.
That means, generally there is no need to call nm_auth_chain_destroy()
from inside the callback.
Remove that code, and refactor some code to return early (where it makes
sense).
The boolean value is intended to indicate success. It would indicated
failure due to a bug.
Fixes: 297d4985ab ('core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API'):