PutObjectAcl had four authorization and ownership bugs:
- The handler embedded the resource path into the action
(WriteAcp:bucket/object), and authRequest/CanDo then scoped it to
the request's bucket/object again. A bucket-wide WriteAcp:bucket
grant could never match, so legitimate owners got 403.
- After authRequest succeeded via an IAM or bucket policy, a leftover
identity.CanDo gate re-checked only the legacy Actions list, denying
identities authorized purely by policies.
- For canned and default ACLs, ExtractAcl generated the FULL_CONTROL
grant for the requesting account instead of the object owner. An
admin setting private/public-read on another account's object left
the owner metadata intact but reassigned full control to the admin.
- Objects without stored owner metadata (e.g. written via the filer
outside S3) fell back to treating the requester as the owner, so any
user with a WriteAcp grant could take them over. Non-admins are now
denied; admins keep the takeover fallback.
Grantee validation now also accepts the object's stored owner even when
that account has been removed from the registry, so canned/XML ACLs for
retired owners keep working.