aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrislu <chris.lu@gmail.com>2025-07-18 16:25:45 -0700
committerchrislu <chris.lu@gmail.com>2025-07-18 16:25:45 -0700
commita0ab227e078987bf81551ff80586324fba6c7083 (patch)
tree6d1f632ab710de4e0f3c94afd00158b90da5ddec
parent2ad4a924be2a90a517c56eca6d87e94fed97c3fd (diff)
downloadseaweedfs-a0ab227e078987bf81551ff80586324fba6c7083.tar.xz
seaweedfs-a0ab227e078987bf81551ff80586324fba6c7083.zip
fixes
-rw-r--r--weed/s3api/s3api_bucket_config.go4
-rw-r--r--weed/s3api/s3api_object_retention.go9
2 files changed, 12 insertions, 1 deletions
diff --git a/weed/s3api/s3api_bucket_config.go b/weed/s3api/s3api_bucket_config.go
index 5bfae7666..41e750e5c 100644
--- a/weed/s3api/s3api_bucket_config.go
+++ b/weed/s3api/s3api_bucket_config.go
@@ -214,7 +214,9 @@ func (s3a *S3ApiServer) isVersioningEnabled(bucket string) (bool, error) {
return false, fmt.Errorf("failed to get bucket config: %v", errCode)
}
- return config.Versioning == "Enabled", nil
+ // Versioning is enabled if explicitly set to "Enabled" OR if object lock is enabled
+ // (since object lock requires versioning to be enabled)
+ return config.Versioning == s3_constants.VersioningEnabled || config.ObjectLockConfig != nil, nil
}
// getBucketVersioningStatus returns the versioning status for a bucket
diff --git a/weed/s3api/s3api_object_retention.go b/weed/s3api/s3api_object_retention.go
index 10d2a6bba..d69a5f857 100644
--- a/weed/s3api/s3api_object_retention.go
+++ b/weed/s3api/s3api_object_retention.go
@@ -599,6 +599,15 @@ func (s3a *S3ApiServer) checkGovernanceBypassPermission(request *http.Request, b
// checkObjectLockPermissions checks if an object can be deleted or modified
func (s3a *S3ApiServer) checkObjectLockPermissions(request *http.Request, bucket, object, versionId string, bypassGovernance bool) error {
+ // For delete operations without versionId (which create delete markers),
+ // we should allow the operation even if the object is under retention.
+ // This is because delete markers are logical deletes, not physical deletes.
+ // Only block deletions when a specific versionId is provided.
+ if versionId == "" {
+ // This is a delete marker creation - allow it
+ return nil
+ }
+
// Get the object entry once to check both retention and legal hold
entry, err := s3a.getObjectEntry(bucket, object, versionId)
if err != nil {