From 1ce2af1238f0c8e0fa20dfe4cd4cab46688f88d3 Mon Sep 17 00:00:00 2001 From: Sven Bachmann Date: Fri, 29 Dec 2023 09:16:33 +0100 Subject: [PATCH] lib/protocol: handle empty names in unixOwnershipEqual (fixes #9039) (#9306) If syncOwnership is enabled and the remote uses for example a dockerized Syncthing it can't fetch the ownername and groupname of the local instance. Without this patch this led to an endless cycle of detected changes on the remote and failing re-sync attempts. This patch skips comparing the ownername and groupname if they zare empty on one side. See https://github.com/syncthing/syncthing/issues/9039 for details. ### Testing Proposed by @calmh in https://github.com/syncthing/syncthing/issues/9039#issuecomment-1870584783 and tested locally in my setup, Setup PC 1: - Syncthing is run in Docker as user `root` and has none of the users configured that synchronize their files Setup PC 2: - this PC has all users locally setup - Syncthing runs as `systemd` service as user `syncthing` and has multiple capabilities set to set the correct owner and permissions Setup PC 3: - same as PC 2 Handling: - `PC 1` is send & receive and uses just the `UID` and `GID` identifiers to store the files - `PC 2` and `PC 3` synchronize their files over `PC 1` but not directly to each other Outcome: - `PC 2` and `PC 3` should send and receive their files with the correct ownership and groups from `PC 1` --- lib/protocol/bep_extensions.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/protocol/bep_extensions.go b/lib/protocol/bep_extensions.go index 4ee23adc5..628353637 100644 --- a/lib/protocol/bep_extensions.go +++ b/lib/protocol/bep_extensions.go @@ -568,7 +568,9 @@ func unixOwnershipEqual(a, b *UnixData) bool { if a == nil || b == nil { return false } - return a.UID == b.UID && a.GID == b.GID && a.OwnerName == b.OwnerName && a.GroupName == b.GroupName + ownerEqual := a.OwnerName == "" || b.OwnerName == "" || a.OwnerName == b.OwnerName + groupEqual := a.GroupName == "" || b.GroupName == "" || a.GroupName == b.GroupName + return a.UID == b.UID && a.GID == b.GID && ownerEqual && groupEqual } func windowsOwnershipEqual(a, b *WindowsData) bool {