@@ -3509,7 +3509,6 @@ class RGWRadosPutObj : public RGWHTTPStreamRWRequest::ReceiveCB
35093509{
35103510 const DoutPrefixProvider *dpp;
35113511 CephContext* cct;
3512- rgw_obj obj;
35133512 rgw::sal::DataProcessor *filter;
35143513 boost::optional<RGWPutObj_Compress>& compressor;
35153514 bool try_etag_verify;
@@ -3528,6 +3527,18 @@ class RGWRadosPutObj : public RGWHTTPStreamRWRequest::ReceiveCB
35283527 uint64_t ofs{0 };
35293528 uint64_t lofs{0 }; /* logical ofs */
35303529 std::function<int (map<string, bufferlist>&)> attrs_handler;
3530+ /*
3531+ src_bucket_perms, if provided, serves as a fallback mechanism to validate the
3532+ source bucket's ACL before initiating the fetch operation. It ensures
3533+ backward compatibility with legacy implementations where the `rgwx-perm-check-uid`
3534+ arg might not be honored, and the destination zone does not return the
3535+ `x-rgw-perm-checked` header, which confirms that the source object's
3536+ permissions were validated against the specified `rgwx-perm-check-uid`.
3537+
3538+ @todo drop src_bucket_perms and src_obj in T+2 release.
3539+ */
3540+ const rgw_obj& src_obj;
3541+ const std::optional<RGWUserPermHandler::Bucket>& src_bucket_perms;
35313542
35323543public:
35333544 RGWRadosPutObj (const DoutPrefixProvider *dpp,
@@ -3537,7 +3548,9 @@ class RGWRadosPutObj : public RGWHTTPStreamRWRequest::ReceiveCB
35373548 rgw::sal::ObjectProcessor *p,
35383549 void (*_progress_cb)(off_t , void *),
35393550 void *_progress_data,
3540- std::function<int(map<string, bufferlist>&)> _attrs_handler) :
3551+ std::function<int(map<string, bufferlist>&)> _attrs_handler,
3552+ const rgw_obj& src_obj,
3553+ const std::optional<RGWUserPermHandler::Bucket>& _src_bucket_perms = std::nullopt) :
35413554 dpp(dpp),
35423555 cct(cct),
35433556 filter(p),
@@ -3547,7 +3560,9 @@ class RGWRadosPutObj : public RGWHTTPStreamRWRequest::ReceiveCB
35473560 processor(p),
35483561 progress_cb(_progress_cb),
35493562 progress_data(_progress_data),
3550- attrs_handler(_attrs_handler) {}
3563+ attrs_handler(_attrs_handler),
3564+ src_obj(src_obj),
3565+ src_bucket_perms(_src_bucket_perms) {}
35513566
35523567
35533568 int process_attrs (void ) {
@@ -3730,6 +3745,23 @@ class RGWRadosPutObj : public RGWHTTPStreamRWRequest::ReceiveCB
37303745 return " " ;
37313746 }
37323747 }
3748+
3749+ int handle_headers (const map<string, string>& headers, int http_status) override {
3750+ if (src_bucket_perms && http_status != 403 && http_status != 401 ) {
3751+ auto iter = headers.find (" RGWX_PERM_CHECKED" );
3752+ // if the header is not present, we need to check the ACL
3753+ // of the source bucket against the fallback UID
3754+ if (iter == headers.end ()) {
3755+ // old ACL should still win s3:ReplicateObject
3756+ if (!src_bucket_perms->verify_bucket_permission (src_obj.key , rgw::IAM::s3ReplicateObject)) {
3757+ ldpp_dout (dpp, 4 ) << " ERROR: " << __func__ << " (): fallback permission check denied" << dendl;
3758+ return -EACCES;
3759+ }
3760+ }
3761+ }
3762+
3763+ return 0 ;
3764+ }
37333765};
37343766
37353767/*
@@ -4381,6 +4413,32 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
43814413
43824414 std::optional<rgw_user> override_owner;
43834415
4416+ // load src bucket perm handler for backward compatibility
4417+ // @todo drop me in t+2 release.
4418+ std::optional<RGWUserPermHandler::Bucket> src_bucket_perms;
4419+ if (perm_check_uid) {
4420+ std::unique_ptr<rgw::sal::Bucket> src_bucket;
4421+ ret = driver->load_bucket (rctx.dpp , src_obj.bucket , &src_bucket, rctx.y );
4422+ if (ret < 0 ) {
4423+ ldpp_dout (rctx.dpp , 0 ) << " ERROR: failed to load src bucket=" << src_obj << " ret=" << ret << dendl;
4424+ return ret;
4425+ }
4426+
4427+ RGWUserPermHandler user_perms (rctx.dpp , driver, cct, *perm_check_uid);
4428+ ret = user_perms.init ();
4429+ if (ret < 0 ) {
4430+ ldpp_dout (rctx.dpp , 0 ) << " ERROR: failed to init user perms for: " << src_obj << " ret=" << ret << dendl;
4431+ return ret;
4432+ }
4433+
4434+ src_bucket_perms.emplace ();
4435+ ret = user_perms.init_bucket (src_bucket->get_info (), src_bucket->get_attrs (), &*src_bucket_perms);
4436+ if (ret < 0 ) {
4437+ ldpp_dout (rctx.dpp , 0 ) << " ERROR: failed to init bucket perms for: " << src_obj << " ret=" << ret << dendl;
4438+ return ret;
4439+ }
4440+ }
4441+
43844442 RGWRadosPutObj cb (rctx.dpp , cct, plugin, compressor, &processor, progress_cb, progress_data,
43854443 [&](map<string, bufferlist>& obj_attrs) {
43864444 const rgw_placement_rule *ptail_rule;
@@ -4414,7 +4472,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
44144472 return ret;
44154473 }
44164474 return 0 ;
4417- });
4475+ }, src_obj, src_bucket_perms );
44184476
44194477 string etag;
44204478 real_time set_mtime;
@@ -5349,7 +5407,7 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
53495407 }
53505408 cb_processed = true ;
53515409 return 0 ;
5352- });
5410+ }, dest_obj );
53535411
53545412 // fetch mtime of the object and other attrs of the object
53555413 // to check for restore_status
0 commit comments