From ce882125828716d0e9e4685376697e1a11dad2f7 Mon Sep 17 00:00:00 2001 From: Jing Wenjun Date: Thu, 8 Jun 2017 15:15:28 +0800 Subject: [PATCH] rgw: fix the signature mismatch of FormPost in swift API Fixes: http://tracker.ceph.com/issues/20220 Signed-off-by: Jing Wenjun --- src/rgw/rgw_rest_swift.cc | 63 ++++++++++++++++++++++++++++++++++++++- src/rgw/rgw_rest_swift.h | 2 ++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index f745e8d4913e0..88a2c3368150b 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -1783,6 +1783,14 @@ bool RGWFormPost::is_integral() { const std::string form_signature = get_part_str(ctrl_parts, "signature"); + try { + get_owner_info(s, *s->user); + s->auth.identity = rgw::auth::transform_old_authinfo(s); + } catch (...) { + ldout(s->cct, 5) << "cannot get user_info of account's owner" << dendl; + return false; + } + for (const auto& kv : s->user->temp_url_keys) { const int temp_url_key_num = kv.first; const string& temp_url_key = kv.second; @@ -1815,6 +1823,58 @@ bool RGWFormPost::is_integral() return false; } +void RGWFormPost::get_owner_info(const req_state* const s, + RGWUserInfo& owner_info) const +{ + /* We cannot use req_state::bucket_name because it isn't available + * now. It will be initialized in RGWHandler_REST_SWIFT::postauth_init(). */ + const string& bucket_name = s->init_state.url_bucket; + + /* TempURL in Formpost only requires that bucket name is specified. */ + if (bucket_name.empty()) { + throw -EPERM; + } + + string bucket_tenant; + if (!s->account_name.empty()) { + RGWUserInfo uinfo; + bool found = false; + + const rgw_user uid(s->account_name); + if (uid.tenant.empty()) { + const rgw_user tenanted_uid(uid.id, uid.id); + + if (rgw_get_user_info_by_uid(store, tenanted_uid, uinfo) >= 0) { + /* Succeeded. */ + bucket_tenant = uinfo.user_id.tenant; + found = true; + } + } + + if (!found && rgw_get_user_info_by_uid(store, uid, uinfo) < 0) { + throw -EPERM; + } else { + bucket_tenant = uinfo.user_id.tenant; + } + } + + /* Need to get user info of bucket owner. */ + RGWBucketInfo bucket_info; + int ret = store->get_bucket_info(*static_cast(s->obj_ctx), + bucket_tenant, bucket_name, + bucket_info, nullptr); + if (ret < 0) { + throw ret; + } + + ldout(s->cct, 20) << "temp url user (bucket owner): " << bucket_info.owner + << dendl; + + if (rgw_get_user_info_by_uid(store, bucket_info.owner, owner_info) < 0) { + throw -EPERM; + } +} + int RGWFormPost::get_params() { /* The parentt class extracts boundary info from the Content-Type. */ @@ -1944,8 +2004,9 @@ bool RGWFormPost::is_next_file_to_upload() const auto field_iter = part.fields.find("Content-Disposition"); if (std::end(part.fields) != field_iter) { const auto& params = field_iter->second.params; + const auto& filename_iter = params.find("filename"); - if (std::end(params) != params.find("filename")) { + if (std::end(params) != filename_iter && ! filename_iter->second.empty()) { current_data_part = std::move(part); return true; } diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index 0b1293e286f3c..48d306cde6d1e 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -248,6 +248,8 @@ class RGWFormPost : public RGWPostObj_ObjStore { bool is_next_file_to_upload() override; bool is_integral(); bool is_non_expired(); + void get_owner_info(const req_state* s, + RGWUserInfo& owner_info) const; parts_collection_t ctrl_parts; boost::optional current_data_part; -- 2.39.5