Skip to content

Commit

Permalink
Enforce replica delete permissions
Browse files Browse the repository at this point in the history
Also check if object lock is enabled on
destination bucket while setting replication
configuration on a object lock enabled bucket.
  • Loading branch information
Poorna Krishnamoorthy committed Aug 4, 2020
1 parent 019fe69 commit a49b1ce
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cmd/api-errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const (
ErrNoSuchWebsiteConfiguration
ErrReplicationConfigurationNotFoundError
ErrReplicationDestinationNotFoundError
ErrReplicationDestinationMissingLock
ErrReplicationTargetNotFoundError
ErrBucketRemoteIdenticalToSource
ErrBucketRemoteAlreadyExists
Expand Down Expand Up @@ -830,6 +831,11 @@ var errorCodes = errorCodeMap{
Description: "The replication destination bucket does not exist",
HTTPStatusCode: http.StatusNotFound,
},
ErrReplicationDestinationMissingLock: {
Code: "ReplicationDestinationMissingLockError",
Description: "The replication destination bucket does not have object locking enabled",
HTTPStatusCode: http.StatusBadRequest,
},
ErrReplicationTargetNotFoundError: {
Code: "XminioAdminReplicationTargetNotFoundError",
Description: "The replication target does not exist",
Expand Down Expand Up @@ -1909,6 +1915,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
apiErr = ErrReplicationConfigurationNotFoundError
case BucketReplicationDestinationNotFound:
apiErr = ErrReplicationDestinationNotFoundError
case BucketReplicationDestinationMissingLock:
apiErr = ErrReplicationDestinationMissingLock
case BucketRemoteTargetNotFound:
apiErr = ErrReplicationTargetNotFoundError
case BucketRemoteAlreadyExists:
Expand Down
14 changes: 14 additions & 0 deletions cmd/bucket-handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,20 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
continue
}
}
if oi, err := getObjectInfoFn(ctx, bucket, object.ObjectName, ObjectOptions{}); err == nil {
if oi.ReplicationStatus == replication.Replica {
if apiErrCode := checkRequestAuthType(ctx, r, policy.ReplicateDeleteAction, bucket, object.ObjectName); apiErrCode != ErrNone {
apiErr := errorCodes.ToAPIErr(apiErrCode)
dErrs[index] = DeleteError{
Code: apiErr.Code,
Message: apiErr.Description,
Key: object.ObjectName,
VersionID: object.VersionID,
}
continue
}
}
}
}

// Avoid duplicate objects, we use map to filter them out.
Expand Down
8 changes: 8 additions & 0 deletions cmd/bucket-replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ func validateReplicationDestination(ctx context.Context, bucket string, rCfg *re
if found, _ := clnt.BucketExists(ctx, rCfg.GetDestination().Bucket); !found {
return false, BucketReplicationDestinationNotFound{Bucket: rCfg.GetDestination().Bucket}
}
if ret, err := globalBucketObjectLockSys.Get(bucket); err == nil {
if ret.LockEnabled {
lock, _, _, _, err := clnt.GetObjectLockConfig(ctx, rCfg.GetDestination().Bucket)
if err != nil || lock != "Enabled" {
return false, BucketReplicationDestinationMissingLock{Bucket: rCfg.GetDestination().Bucket}
}
}
}
// validate replication ARN against target endpoint
c, ok := globalBucketTargetSys.arnRemotesMap[rCfg.ReplicationArn]
if ok {
Expand Down
7 changes: 7 additions & 0 deletions cmd/object-api-errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,13 @@ func (e BucketReplicationDestinationNotFound) Error() string {
return "Destination bucket does not exist: " + e.Bucket
}

// BucketReplicationDestinationMissingLock bucket does not have object lock enabled.
type BucketReplicationDestinationMissingLock GenericError

func (e BucketReplicationDestinationMissingLock) Error() string {
return "Destination bucket does not have object lock enabled: " + e.Bucket
}

// BucketRemoteTargetNotFound remote target does not exist.
type BucketRemoteTargetNotFound GenericError

Expand Down
11 changes: 11 additions & 0 deletions cmd/object-handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2734,6 +2734,17 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
}
}
}
if opts.VersionID != "" {
if oi, err := getObjectInfo(ctx, bucket, object, opts); err == nil {
if oi.ReplicationStatus == replication.Replica {
permErr := checkRequestAuthType(ctx, r, policy.ReplicateDeleteAction, bucket, object)
if permErr != ErrNone {
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(permErr), r.URL, guessIsBrowserReq(r))
return
}
}
}
}

if apiErr == ErrNone {
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html
Expand Down

0 comments on commit a49b1ce

Please sign in to comment.