* s3api: split upload ACL assembly out of preparePutObjectACL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: store POST Object acl and grant fields on the object
The form acl and x-amz-grant-* fields were authorized but never assembled,
so the object kept no ACL: acl=private on a public-read bucket stayed
anonymously readable and invalid values were accepted. Build them with the
same rules as PutObject, which also covers the Block Public Access check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test POST Object stores its upload ACL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: take the POST Object ACL from the signed form only
ACL request headers are not covered by the POST policy, so a holder of a
signed form could add one and have it stored with the upload.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: reject a POST acl field the policy does not cover
The acl form field now sets the stored object ACL, so like the x-amz-*
fields it needs a policy condition, as AWS requires.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test unsigned ACL headers and uncovered acl fields on POST
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: evaluate POST upload policies on the canonical ACL
Policy conditions on the grant headers saw the raw form value, so an
equivalent spelling of a denied grantee passed. Use the PutObject request
shape that the PUT path evaluates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: check bucket policy for POST ACLs with auth disabled
PutObject applies the bucket policy to an explicit upload ACL when IAM is
off; POST now does the same before storing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: reject differing acl and x-amz-acl POST fields
Both promote to the canned ACL header, so map order picked the stored ACL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test POST grant canonicalization, auth-off ACL policy, acl conflicts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: check the auth-off POST ACL policy after loading the bucket
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: reject an empty acl or x-amz-acl POST field beside a differing one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test the auth-off POST ACL policy on a cold bucket cache and empty acl aliases
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: load the bucket before per-key object authorization
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test the POST ACL policy on a cold bucket cache with auth on
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: stop per-key object authorization when the bucket fails to load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* s3api: test the cold-bucket POST ACL allow path and a failed bucket load
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(s3): reject unknown POST policy conditions and extra x-amz form fields
CheckPostPolicy previously accepted policy conditions with unknown $keys
(e.g. "$foo") as satisfied, and only rejected stray X-Amz-Meta-* form
fields. Reject unknown condition keys outright, and extend the extra-
input-fields check to all X-Amz-* form fields except the reserved
auth/signing headers. Matches AWS S3 POST Object behavior.
* refactor(s3): drop redundant $x-amz-meta- prefix check in CheckPostPolicy
The $x-amz- prefix already subsumes $x-amz-meta-, so the explicit
$x-amz-meta- check adds no coverage. Simplify the else-if condition.
Addresses gemini-code-assist review on PR #9124.
* style(s3): align unknown-key policy error with [op, key, value] trailer
Reformat the unknown-condition-key error in CheckPostPolicy to include
the same "[op, key, value]" trailer used by the other condition-failed
messages. The value slot is empty because no comparison occurs for an
unknown key. The descriptive "unknown condition key" suffix is kept so
operators can still tell this failure from a mismatched value.
* fix(s3): honor starts-with prefix-stem POST policies when checking extras
AWS POST policies use ["starts-with","$x-amz-meta-",""] to allow any
X-Amz-Meta-* form field. The previous exact-match policyXAmzKeys would
flag every X-Amz-Meta-Foo as an "Extra input fields" failure because
only the stem X-Amz-Meta- was stored. Track starts-with conditions whose
key ends in "-" with an empty value as prefix stems, and accept any
X-Amz-* form field matching one of those stems.
* fix(s3): validate value prefix for starts-with POST policy stems
Drop the policy.Value == "" gate when detecting prefix-stem conditions
so that ["starts-with","$x-amz-meta-","pfx-"] is recognized as a prefix
rule. Track the required value prefix alongside the name prefix, enforce
it against every matching form field in the extras loop, and skip the
prefix-stem condition in the main iteration (it has no single form
field to evaluate). Also include policy.Value in the unknown-condition
error trailer for clearer debugging. Addresses gemini-code-assist
review on PR #9124.
* fix(s3): check every matching POST policy rule, not just the first
The extras loop exited early on exact-key match and broke on the first
matching prefix stem. Per AWS, a form field must satisfy every policy
condition that applies to it, so an exact-match field must still honor
any overlapping starts-with stem's value prefix, and multiple stems on
the same field must all hold. Drop both early exits: start matched from
the exact-key lookup, iterate all prefix stems, and fail on the first
value-prefix violation. Addresses gemini-code-assist review on PR
#9124.
* chore: remove unreachable dead code across the codebase
Remove ~50,000 lines of unreachable code identified by static analysis.
Major removals:
- weed/filer/redis_lua: entire unused Redis Lua filer store implementation
- weed/wdclient/net2, resource_pool: unused connection/resource pool packages
- weed/plugin/worker/lifecycle: unused lifecycle plugin worker
- weed/s3api: unused S3 policy templates, presigned URL IAM, streaming copy,
multipart IAM, key rotation, and various SSE helper functions
- weed/mq/kafka: unused partition mapping, compression, schema, and protocol functions
- weed/mq/offset: unused SQL storage and migration code
- weed/worker: unused registry, task, and monitoring functions
- weed/query: unused SQL engine, parquet scanner, and type functions
- weed/shell: unused EC proportional rebalance functions
- weed/storage/erasure_coding/distribution: unused distribution analysis functions
- Individual unreachable functions removed from 150+ files across admin,
credential, filer, iam, kms, mount, mq, operation, pb, s3api, server,
shell, storage, topology, and util packages
* fix(s3): reset shared memory store in IAM test to prevent flaky failure
TestLoadIAMManagerFromConfig_EmptyConfigWithFallbackKey was flaky because
the MemoryStore credential backend is a singleton registered via init().
Earlier tests that create anonymous identities pollute the shared store,
causing LookupAnonymous() to unexpectedly return true.
Fix by calling Reset() on the memory store before the test runs.
* style: run gofmt on changed files
* fix: restore KMS functions used by integration tests
* fix(plugin): prevent panic on send to closed worker session channel
The Plugin.sendToWorker method could panic with "send on closed channel"
when a worker disconnected while a message was being sent. The race was
between streamSession.close() closing the outgoing channel and sendToWorker
writing to it concurrently.
Add a done channel to streamSession that is closed before the outgoing
channel, and check it in sendToWorker's select to safely detect closed
sessions without panicking.