summaryrefslogtreecommitdiff
path: root/src/settings/plugins/keyfile/nms-keyfile-utils.c
Commit message (Collapse)AuthorAgeFilesLines
* all: move "src/" directory to "src/core/"Thomas Haller2021-02-041-389/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | Currently "src/" mostly contains the source code of the daemon. I say mostly, because that is not true, there are also the device, settings, wwan, ppp plugins, the initrd generator, the pppd and dhcp helper, and probably more. Also we have source code under libnm-core/, libnm/, clients/, and shared/ directories. That is all confusing. We should have one "src" directory, that contains subdirectories. Those subdirectories should contain individual parts (libraries or applications), that possibly have dependencies on other subdirectories. There should be a flat hierarchy of directories under src/, which contains individual modules. As the name "src/" is already taken, that prevents any sensible restructuring of the code. As a first step, move "src/" to "src/core/". This gives space to reorganize the code better by moving individual components into "src/". For inspiration, look at systemd's "src/" directory. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/743
* all: update deprecated SPDX license identifiersThomas Haller2021-01-051-1/+1
| | | | | | | | | | | | | | | | These SPDX license identifiers are deprecated ([1]). Update them. [1] https://spdx.org/licenses/ sed \ -e '1 s%^/\* SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+ \*/$%/* SPDX-License-Identifier: \1-or-later */%' \ -e '1,2 s%^\(--\|#\|//\) SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+$%\1 SPDX-License-Identifier: \2-or-later%' \ -i \ $(git grep -l SPDX-License-Identifier -- \ ':(exclude)shared/c-*/' \ ':(exclude)shared/n-*/' \ ':(exclude)shared/systemd/src' \ ':(exclude)src/systemd/src')
* all: unify comment style for SPDX-License-Identifier tagThomas Haller2020-09-291-1/+1
| | | | | | | | | | Our coding style recommends C style comments (/* */) instead of C++ (//). Also, systemd (which we partly fork) uses C style comments for the SPDX-License-Identifier. Unify the style. $ sed -i '1 s#// SPDX-License-Identifier: \([^ ]\+\)$#/* SPDX-License-Identifier: \1 */#' -- $(git ls-files -- '*.[hc]' '*.[hc]pp')
* format: replace tabs for indentation in code commentsac/clang-formatThomas Haller2020-09-281-6/+6
| | | | | | | | | | | | sed -i \ -e 's/^'$'\t'' \*/ */g' \ -e 's/^'$'\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t\t'' \*/ */g' \ -e 's/^'$'\t\t\t\t\t\t\t'' \*/ */g' \ $(git ls-files -- '*.[hc]')
* all: reformat all with new clang-format styleAntonio Cardace2020-09-281-303/+324
| | | | | | | | | | | | Run: ./contrib/scripts/nm-code-format.sh -i ./contrib/scripts/nm-code-format.sh -i Yes, it needs to run twice because the first run doesn't yet produce the final result. Signed-off-by: Antonio Cardace <acardace@redhat.com>
* all: replace cleanup macro "gs_unref_keyfile" by "nm_auto_unref_keyfile"Thomas Haller2020-09-021-2/+2
|
* all: fix minor typosYuri Chornoivan2020-07-071-1/+1
| | | | https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/565
* libnm/keyfile: build keyfile code as separate GPL licensed internal libraryThomas Haller2020-01-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Keyfile support was initially added under GPL-2.0+ license as part of core. It was moved to "libnm-core" in commit 59eb5312a5d6 ('keyfile: merge branch 'th/libnm-keyfile-bgo744699''). "libnm-core" is statically linked with by core and "libnm". In the former case under terms of GPL-2.0+ (good) and in the latter case under terms of LGPL-2.1+ (bad). In fact, to this day, "libnm" doesn't actually use the code. The linker will probably remove all the GPL-2.0+ symbols when compiled with gc-sections or LTO. Still, linking them together in the first place makes "libnm" only available under GPL code (despite the code not actually being used). Instead, move the GPL code to a separate static library "shared/nm-keyfile/libnm-keyfile.la" and only link it to the part that actually uses the code (and which is GPL licensed too). This fixes the license violation. Eventually, it would be very useful to be able to expose keyfile handling via "libnm". However that is not straight forward due to the licensing conflict. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/381
* all: unify format of our Copyright source code commentsThomas Haller2019-10-021-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ```bash readarray -d '' FILES < <( git ls-files -z \ ':(exclude)po' \ ':(exclude)shared/c-rbtree' \ ':(exclude)shared/c-list' \ ':(exclude)shared/c-siphash' \ ':(exclude)shared/c-stdaux' \ ':(exclude)shared/n-acd' \ ':(exclude)shared/n-dhcp4' \ ':(exclude)src/systemd/src' \ ':(exclude)shared/systemd/src' \ ':(exclude)m4' \ ':(exclude)COPYING*' ) sed \ -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) *[-–] *\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C1pyright#\5 - \7#\9/' \ -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) *[,] *\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C2pyright#\5, \7#\9/' \ -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C3pyright#\5#\7/' \ -e 's/^Copyright \(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/C4pyright#\1#\3/' \ -i \ "${FILES[@]}" echo ">>> untouched Copyright lines" git grep Copyright "${FILES[@]}" echo ">>> Copyright lines with unusual extra" git grep '\<C[0-9]pyright#' "${FILES[@]}" | grep -i reserved sed \ -e 's/\<C[0-9]pyright#\([^#]*\)#\(.*\)$/Copyright (C) \1 \2/' \ -i \ "${FILES[@]}" ``` https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/298
* all: manually drop code comments with file descriptionThomas Haller2019-10-011-2/+1
|
* all: SPDX header conversionLubomir Rintel2019-09-101-14/+1
| | | | | $ find * -type f |xargs perl contrib/scripts/spdx.pl $ git rm contrib/scripts/spdx.pl
* settings: return errno from nms_keyfile_nmmeta_write() for better loggingth/settings-improvementsThomas Haller2019-08-081-11/+16
| | | | | | | | | | | | I encountered a failure in the log <trace> [1564647990.7822] keyfile: commit: deleting nmmeta file "/etc/NetworkManager/system-connections/35370b0b-e53b-42ea-9fe3-f1b1d552343b.nmmeta" failed <trace> [1564647990.7822] keyfile: commit: deleting nmmeta file "/etc/NetworkManager/system-connections/35370b0b-e53b-42ea-9fe3-f1b1d552343b.nmmeta" simulated I think that was due to SELinux (rh #1738010). Let nms_keyfile_nmmeta_write() return an errno code so we can log more information about the failure.
* shared,all: return boolean success from nm_utils_file_get_contents()Thomas Haller2019-08-081-1/+6
| | | | | | | | | | | | | | | | | | | | | | ... and nm_utils_fd_get_contents() and nm_utils_file_set_contents(). Don't mix negative errno return value with a GError output. Instead, return a boolean result indicating success or failure. Also, optionally - output GError - set out_errsv to the positive errno (or 0 on success) Obviously, the return value and the output arguments (contents, length, out_errsv, error) must all agree in their success/failure result. That means, you may check any of the return value, out_errsv, error, and contents to reliably detect failure or success. Also note that out_errsv gives the positive(!) errno. But you probably shouldn't care about the distinction and use nm_errno_native() either way to normalize the value.
* shared: let nm_utils_file_set_contents() return a errno error codeThomas Haller2019-08-081-1/+1
| | | | | | | | | | | | | | | | nm_utils_file_set_contents() is a re-implementation of g_file_set_contents(), as such it returned merely a boolean success value. It's sometimes interesting to get the native error code. Let the function deviate from glib's original g_file_set_contents() and return the error code (as negative value) instead. This requires all callers to change. Also, it's potentially a dangerous change, as this is easy to miss. Note that nm_utils_file_get_contents() also returns an errno, and already deviates from g_file_get_contents() in the same way. This patch resolves at least the inconsistency with nm_utils_file_get_contents().
* settings: support storing "shadowed-storage" to .nmmeta filesThomas Haller2019-07-251-23/+88
| | | | | | | | | | | | | | | | | | | | | | | | | Before, the .nmmeta file could only contain one piece of information: the loaded-path. This was persisted to disk by writing a "$UUID.nmmeta" symlink that links to the loaded-path. Also, in practice this is used for tombstones, so the only valid loaded-path is "/dev/null" (all other paths are ignored). Extend the .nmmeta file format to also be able to store additional data: the shadowed-storage path. We will need that later but the idea is that if we have a tombstone on disk, then this tombstone might explicitly shadow another file. The use is when re-adding a profile with the same UUID, then the existing storage is used (instead of creating a new file). This will be necessary with Update2(NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED) flag. This flag first allows to clone a profile from persistent storage to a profile in /run. Later, when this profile gets deleted, the original profile will be left on disk. If the same profile then gets re-created with AddConnection(), then the original filename must be taken over again. This is to avoid duplication of profiles on disk. Note that this piece of information is relevent per-UUID, and as such it's correct to store it in the .nmmeta file. That is related to the "shadowed-storage" information that we store in the [.nmmeta] section of keyfiles.
* settings/trivial: rename NMS_KEYFILE_FILETYPE_NMLOADED to ↵Thomas Haller2019-07-251-3/+3
| | | | | | NMS_KEYFILE_FILETYPE_NMMETA This name is better suited for the file with extension ".nmmeta".
* settings: rework tracking settings connections and settings pluginsThomas Haller2019-07-161-20/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Completely rework how settings plugin handle connections and how NMSettings tracks the list of connections. Previously, settings plugins would return objects of (a subtype of) type NMSettingsConnection. The NMSettingsConnection was tightly coupled with the settings plugin. That has a lot of downsides. Change that. When changing this basic relation how settings connections are tracked, everything falls appart. That's why this is a huge change. Also, since I have to largely rewrite the settings plugins, I also added support for multiple keyfile directories, handle in-memory connections only by keyfile plugin and (partly) use copy-on-write NMConnection instances. I don't want to spend effort rewriting large parts while preserving the old way, that anyway should change. E.g. while rewriting ifcfg-rh, I don't want to let it handle in-memory connections because that's not right long-term. -- If the settings plugins themself create subtypes of NMSettingsConnection instances, then a lot of knowledge about tracking connections moves to the plugins. Just try to follow the code what happend during nm_settings_add_connection(). Note how the logic is spread out: - nm_settings_add_connection() calls plugin's add_connection() - add_connection() creates a NMSettingsConnection subtype - the plugin has to know that it's called during add-connection and not emit NM_SETTINGS_PLUGIN_CONNECTION_ADDED signal - NMSettings calls claim_connection() which hocks up the new NMSettingsConnection instance and configures the instance (like calling nm_settings_connection_added()). This summary does not sound like a lot, but try to follow that code. The logic is all over the place. Instead, settings plugins should have a very simple API for adding, modifying, deleting, loading and reloading connections. All the plugin does is to return a NMSettingsStorage handle. The storage instance is a handle to identify a profile in storage (e.g. a particular file). The settings plugin is free to subtype NMSettingsStorage, but it's not necessary. There are no more events raised, and the settings plugin implements the small API in a straightforward manner. NMSettings now drives all of this. Even NMSettingsConnection has now very little concern about how it's tracked and delegates only to NMSettings. This should make settings plugins simpler. Currently settings plugins are so cumbersome to implement, that we avoid having them. It should not be like that and it should be easy, beneficial and lightweight to create a new settings plugin. Note also how the settings plugins no longer care about duplicate UUIDs. Duplicated UUIDs are a fact of life and NMSettings must handle them. No need to overly concern settings plugins with that. -- NMSettingsConnection is exposed directly on D-Bus (being a subtype of NMDBusObject) but it was also a GObject type provided by the settings plugin. Hence, it was not possible to migrate a profile from one plugin to another. However that would be useful when one profile does not support a connection type (like ifcfg-rh not supporting VPN). Currently such migration is not implemented except for migrating them to/from keyfile's run directory. The problem is that migrating profiles in general is complicated but in some cases it is important to do. For example checkpoint rollback should recreate the profile in the right settings plugin, not just add it to persistent storage. This is not yet properly implemented. -- Previously, both keyfile and ifcfg-rh plugin implemented in-memory (unsaved) profiles, while ifupdown plugin cannot handle them. That meant duplication of code and a ifupdown profile could not be modified or made unsaved. This is now unified and only keyfile plugin handles in-memory profiles (bgo #744711). Also, NMSettings is aware of such profiles and treats them specially. In particular, NMSettings drives the migration between persistent and non-persistent storage. Note that a settings plugins may create truly generated, in-memory profiles. The settings plugin is free to generate and persist the profiles in any way it wishes. But the concept of "unsaved" profiles is now something explicitly handled by keyfile plugin. Also, these "unsaved" keyfile profiles are persisted to file system too, to the /run directory. This is great for two reasons: first of all, all profiles from keyfile storage in fact have a backing file -- even the unsaved ones. It also means you can create "unsaved" profiles in /run and load them with `nmcli connection load`, meaning there is a file based API for creating unsaved profiles. The other advantage is that these profiles now survive restarting NetworkManager. It's paramount that restarting the daemon is as non-disruptive as possible. Persisting unsaved files to /run improves here significantly. -- In the past, NMSettingsConnection also implemented NMConnection interface. That was already changed a while ago and instead users call now nm_settings_connection_get_connection() to delegate to a NMSimpleConnection. What however still happened was that the NMConnection instance gets never swapped but instead the instance was modified with nm_connection_replace_settings_from_connection(), clear-secrets, etc. Change that and treat the NMConnection instance immutable. Instead of modifying it, reference/clone a new instance. This changes that previously when somebody wanted to keep a reference to an NMConnection, then the profile would be cloned. Now, it is supposed to be safe to reference the instance directly and everybody must ensure not to modify the instance. nmtst_connection_assert_unchanging() should help with that. The point is that the settings plugins may keep references to the NMConnection instance, and so does the NMSettingsConnection. We want to avoid cloning the instances as long as they are the same. Likewise, the device's applied connection can now also be referenced instead of cloning it. This is not yet done, and possibly there are further improvements possible. -- Also implement multiple keyfile directores /usr/lib, /etc, /run (rh #1674545, bgo #772414). It was always the case that multiple files could provide the same UUID (both in case of keyfile and ifcfg-rh). For keyfile plugin, if a profile in read-only storage in /usr/lib gets modified, then it gets actually stored in /etc (or /run, if the profile is unsaved). -- While at it, make /etc/network/interfaces profiles for ifupdown plugin reloadable. -- https://bugzilla.gnome.org/show_bug.cgi?id=772414 https://bugzilla.gnome.org/show_bug.cgi?id=744711 https://bugzilla.redhat.com/show_bug.cgi?id=1674545
* settings/trivial: rename nm_keyfile_loaded_uuid_*() API to nm_keyfile_nmmeta_*()Thomas Haller2019-07-161-29/+29
| | | | | | The file got a wider scope to contain generic meta data about profiles. Rename the internal API to reflect that (and be consistend with the naming of the files).
* settings: change filename for per-connection metadata (previously UUID ↵Thomas Haller2019-07-161-46/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | nm-loaded symlinks) We may want to store meta-data for a profile to disk. The immediate need are "tombstones": markers that the particular UUID is shadowed and the profile does not exist (despite being in read-only location). Change the filename of these symlinks from ".loaded-${UUID}.nmconnection" to "${UUID}.nmmeta" The leading dot is not desirable as tools tend to hide such files. Use a different scheme for the filename that does not have the leading dot. Note that nm_keyfile_utils_ignore_filename() would also ignore ".nmmeta" as not a valid keyfile. This is just what we want, and influences the choice of this file suffix. Also, "nmmeta" is a better name, because this name alludes that there is a wider use for the file: namely to have addtional per-profile metadata. That is regardless that the upcoming first use will be only to store symlinks to "/dev/null" to indicate the tombstones. Note that per-profile metadata is not new. Currently we write the files /var/lib/NetworkManager/{seen-bssids,timestamps} that have a similar purpose. Maybe the content from these files could one day be migrated to the ".nmmeta" file. The naming scheme would make it suitable.
* settings/keyfile: output "struct stat" from nms_keyfile_loaded_uuid_read()Thomas Haller2019-07-161-3/+5
| | | | | We already stat() the file, so optionally return the stat result to the caller.
* all: drop emacs file variables from source filesThomas Haller2019-06-111-1/+0
| | | | | | | | | | | | | | | | | | | | | | 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.
* all: replace g_strerror() calls with nm_strerror_native()Thomas Haller2019-02-121-2/+2
|
* all: drop unnecessary includes of <errno.h> and <string.h>Thomas Haller2019-02-121-1/+0
| | | | | "nm-macros-interal.h" already includes <errno.h> and <string.h>. No need to include it everywhere else too.
* keyfile: add helper functions to record loaded UUID filesThomas Haller2018-12-031-15/+223
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* keyfile: move and rename NM_CONFIG_KEYFILE_PATH_DEFAULT defineThomas Haller2018-10-231-3/+2
|
* keyfile: move keyfile utilities from src/ to libnm-core/Thomas Haller2018-10-231-126/+0
| | | | | | | 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.
* keyfile: write keyfiles to "/run" directory with ".nmconnection" file suffixThomas Haller2018-10-181-5/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | For profiles in "/etc/NetworkManager/system-connections", we did not enforce that the keyfiles have a special suffix, nor did we generate the filenames in such a manner. In hindsight, I think that was a mistake. Recently we added "/run/NetworkManager/system-connections" as additional keyfile directory. Enforce a suffix and write keyfiles with such a name. In principle, we could also start writing keyfiles in /etc with the same suffix. But let's not do that, because we anyway cannot enforce it. An ugly part is, that during `nmcli connection load` we need to determine whether the to-be-loaded connection is under /etc or /run. Preferably, we would allow any kind of symlinking as what matters is the file object (inode) and not the path. Anyway, we don't do that but compare plain paths. That means, paths which are not in an expected form, will be rejected. In particular, the paths starting with "/run/..." and "/var/run/..." will be treated differently, and one of them will be rejected. Note that ifcfg-rh plugin strictly enforces that the path starts with IFCFG_DIR as well. So, while this is a breaking change for keyfile, I think it's reasonable.
* keyfile: refactor check whether filename starts with a dotThomas Haller2018-10-041-12/+5
| | | | | | check_prefix() was only ever called with "." as prefix. Simplify the implementation to explicitly check for a leading dot.
* keyfile: move file permission check of keyfile to helper functionThomas Haller2018-10-041-0/+60
|
* keyfile: refactor GObject type creationThomas Haller2016-10-061-2/+2
|
* keyfile: rename public keyfile functions and namesThomas Haller2016-10-061-3/+3
|
* keyfile: rename filesThomas Haller2016-10-061-0/+170
Setting plugins should have their own name prefix (nms) and keyfile should have as prefix "nms-kf". As a first step, rename the files.