summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-09-26 09:58:01 +0200
committerThomas Haller <thaller@redhat.com>2022-09-28 13:27:14 +0200
commitbaf9b38650e32453766bcd5aa37081310a5b6b90 (patch)
tree5e450a3bc8c224c349099ce7050d352c2d7e3b6f
parent98197386078a471ed993d009e34e08a6aa7c22d9 (diff)
nmcli: ensure profiles matching by "uuid","path" selector are unique
The "connection.uuid" and the D-Bus path are supposed to be unique on D-Bus. Anything else indicates to a bug somewhere. Still, with `nmcli connection $operation [uuid|path] $arg ...` ensure that the result is always unique. In practice, this should make no difference. In the case of an unexpected duplicate, it seems better to fail and uphold the guarantee that these selectors give unique results. Also, next we will accept matching prefixes of the UUID. While partial match will then be supported, it should still be unique. That is, the "uuid" specifier should always only yield one result. While this patch should make not difference in practice today (albeit enforcing something that should be valid), it will make a difference then.
-rw-r--r--src/nmcli/common.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/nmcli/common.c b/src/nmcli/common.c
index ff4c15c37e..16827eda2f 100644
--- a/src/nmcli/common.c
+++ b/src/nmcli/common.c
@@ -432,10 +432,13 @@ nmc_find_connection(const GPtrArray *connections,
GPtrArray *result = out_result ? *out_result : NULL;
const guint result_inital_len = result ? result->len : 0u;
guint i, j;
+ gboolean must_match_uniquely;
nm_assert(connections);
nm_assert(filter_val);
+ must_match_uniquely = NM_IN_STRSET(filter_type, "uuid", "path");
+
for (i = 0; i < connections->len; i++) {
gboolean match_by_uuid = FALSE;
NMConnection *connection;
@@ -483,14 +486,26 @@ nmc_find_connection(const GPtrArray *connections,
continue;
found:
+
+ if (must_match_uniquely && (best_candidate || best_candidate_uuid)) {
+ /* We found duplicates. This is wrong. */
+ if (out_result && *out_result) {
+ /* Remove the element that we added before. */
+ g_ptr_array_set_size(*out_result, result_inital_len);
+ }
+ return NULL;
+ }
+
if (match_by_uuid) {
if (!complete && !out_result)
return connection;
- best_candidate_uuid = connection;
+ if (!best_candidate_uuid)
+ best_candidate_uuid = connection;
} else {
if (!best_candidate)
best_candidate = connection;
}
+
if (out_result) {
gboolean already_tracked = FALSE;