diff options
author | Thomas Haller <thaller@redhat.com> | 2022-09-26 09:58:01 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-09-28 13:27:14 +0200 |
commit | baf9b38650e32453766bcd5aa37081310a5b6b90 (patch) | |
tree | 5e450a3bc8c224c349099ce7050d352c2d7e3b6f | |
parent | 98197386078a471ed993d009e34e08a6aa7c22d9 (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.c | 17 |
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; |