@@ -229,6 +229,24 @@ async function authorize_request_policy(req) {
229
229
if ( ! req . params . bucket ) return ;
230
230
if ( req . op_name === 'put_bucket' ) return ;
231
231
232
+ // Allow bucket owner or system owner to put a bucket policy
233
+ if ( req . op_name === 'put_bucket_policy' ) {
234
+ const { system_owner, bucket_owner } = await req . object_sdk . read_bucket_sdk_policy_info ( req . params . bucket ) ;
235
+ const account = req . object_sdk . requesting_account ;
236
+ const account_identifier_name = req . object_sdk . nsfs_config_root ? account . name . unwrap ( ) : account . email . unwrap ( ) ;
237
+ const account_identifier_id = req . object_sdk . nsfs_config_root ? account . _id : undefined ;
238
+
239
+ const is_system_owner = ( Boolean ( system_owner ) && system_owner . unwrap ( ) === account_identifier_name ) ||
240
+ ( Boolean ( system_owner ) && system_owner . unwrap ( ) === account_identifier_id ) ;
241
+ const is_bucket_owner = ( Boolean ( bucket_owner ) && bucket_owner . unwrap ( ) === account_identifier_name ) ||
242
+ ( Boolean ( bucket_owner ) && bucket_owner . unwrap ( ) === account_identifier_id ) ;
243
+
244
+ if ( is_system_owner || is_bucket_owner ) return ;
245
+
246
+ // If the account is neither the system owner nor the bucket owner, deny access
247
+ throw new S3Error ( S3Error . AccessDenied ) ;
248
+ }
249
+
232
250
// owner_account is { id: bucket.owner_account, email: bucket.bucket_owner };
233
251
const { s3_policy, system_owner, bucket_owner, owner_account } = await req . object_sdk . read_bucket_sdk_policy_info ( req . params . bucket ) ;
234
252
const auth_token = req . object_sdk . get_auth_token ( ) ;
@@ -279,30 +297,24 @@ async function authorize_request_policy(req) {
279
297
if ( is_owner || is_iam_account_and_same_root_account_owner ) return ;
280
298
throw new S3Error ( S3Error . AccessDenied ) ;
281
299
}
282
- // in case we have bucket policy
283
- let permission_by_id ;
284
- let permission_by_name ;
285
300
286
301
const public_access_block_cfg = await req . object_sdk . get_public_access_block ( { name : req . params . bucket } ) ;
287
302
// In NC, we allow principal to be:
288
303
// 1. account name (for backwards compatibility)
289
304
// 2. account id
290
305
// we start the permission check on account identifier intentionally
291
- if ( account_identifier_id ) {
292
- permission_by_id = await s3_bucket_policy_utils . has_bucket_policy_permission (
293
- s3_policy , account_identifier_id , method , arn_path , req , public_access_block_cfg ?. public_access_block ?. restrict_public_buckets ) ;
294
- dbg . log3 ( 'authorize_request_policy: permission_by_id' , permission_by_id ) ;
295
- }
296
- if ( permission_by_id === "DENY" ) throw new S3Error ( S3Error . AccessDenied ) ;
297
306
298
- if ( ( ! account_identifier_id || permission_by_id !== "DENY" ) && account . owner === undefined ) {
299
- permission_by_name = await s3_bucket_policy_utils . has_bucket_policy_permission (
300
- s3_policy , account_identifier_name , method , arn_path , req , public_access_block_cfg ?. public_access_block ?. restrict_public_buckets
301
- ) ;
302
- dbg . log3 ( 'authorize_request_policy: permission_by_name' , permission_by_name ) ;
303
- }
304
- if ( permission_by_name === "DENY" ) throw new S3Error ( S3Error . AccessDenied ) ;
305
- if ( ( permission_by_id === "ALLOW" || permission_by_name === "ALLOW" ) || is_owner ) return ;
307
+ const account_identifier = {
308
+ id : account_identifier_id ,
309
+ name : account_identifier_name ,
310
+ } ;
311
+
312
+ const bucket_permission = await s3_bucket_policy_utils . has_bucket_policy_permission (
313
+ s3_policy , account_identifier , method , arn_path , req , public_access_block_cfg ?. public_access_block ?. restrict_public_buckets ) ;
314
+ dbg . log3 ( 'authorize_request_policy: bucket_permission' , bucket_permission ) ;
315
+
316
+ if ( bucket_permission === "DENY" ) throw new S3Error ( S3Error . AccessDenied ) ;
317
+ if ( bucket_permission === "ALLOW" ) return ;
306
318
307
319
throw new S3Error ( S3Error . AccessDenied ) ;
308
320
}
0 commit comments