mirror of
https://github.com/pgsty/minio.git
synced 2026-11-10 17:45:32 +03:00
fix(replication): keep Object Lock on a replicated delete
A trusted replica DELETE skipped the destination's retention check for every request, not only for the delete marker it is meant to create. A caller allowed s3:ReplicateDelete (root, or the replication account) could purge a version under legal hold or unexpired retention, or name a stored version in a delete marker, which replaces that version. Skip the check only for a delete-marker creation, whose version is not yet stored here, and make that request refuse to replace a protected version with RefuseLockedOverwrite, as batch replication pulls do; the pools layer applies it to the version in any pool. A replicated purge goes through the normal retention check. A source purge that bypassed GOVERNANCE retention is now refused by a target whose copy still carries it; the source records the purge as failed and retries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -3193,9 +3193,12 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
|
||||
vID := opts.VersionID
|
||||
if replica {
|
||||
opts.SetReplicaStatus(replication.Replica)
|
||||
if opts.VersionPurgeStatus().Empty() {
|
||||
// opts.VersionID holds delete marker version ID to replicate and not yet present on disk
|
||||
if opts.DeleteMarker && opts.VersionPurgeStatus().Empty() {
|
||||
// opts.VersionID names the delete marker to replicate, not yet
|
||||
// present here. It must not replace a stored version this site
|
||||
// protects; a replicated purge keeps the retention check below.
|
||||
vID = ""
|
||||
opts.RefuseLockedOverwrite = true
|
||||
}
|
||||
}
|
||||
opts.SetEvalRetentionBypassFn(func(goi ObjectInfo, gerr error) (err error) {
|
||||
|
||||
Reference in New Issue
Block a user