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`
This commit is contained in:
Sven Bachmann 2023-12-29 09:16:33 +01:00 committed by GitHub
parent 683b48182c
commit 1ce2af1238
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 {