Skip to content

Commit 8e4ddcf

Browse files
committedJan 6, 2025
rgw: fix user rate limit is not enforced w/ global rate limit set
Fixes: https://tracker.ceph.com/issues/68346 Signed-off-by: Mark Kogan <[email protected]>
1 parent 5d63519 commit 8e4ddcf

7 files changed

+113
-83
lines changed
 

‎src/rgw/rgw_auth.cc

+55-31
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ int load_account_and_policies(const DoutPrefixProvider* dpp,
188188

189189
static auto transform_old_authinfo(const RGWUserInfo& user,
190190
std::optional<RGWAccountInfo> account,
191-
std::vector<IAM::Policy> policies)
191+
std::vector<IAM::Policy> policies,
192+
sal::Driver* driver)
192193
-> std::unique_ptr<rgw::auth::Identity>
193194
{
194195
/* This class is not intended for public use. Should be removed altogether
@@ -198,6 +199,7 @@ static auto transform_old_authinfo(const RGWUserInfo& user,
198199
/* For this particular case it's OK to use rgw_user structure to convey
199200
* the identity info as this was the policy for doing that before the
200201
* new auth. */
202+
sal::Driver* driver;
201203
const rgw_user id;
202204
const std::string display_name;
203205
const std::string path;
@@ -208,8 +210,10 @@ static auto transform_old_authinfo(const RGWUserInfo& user,
208210
public:
209211
DummyIdentityApplier(const RGWUserInfo& user,
210212
std::optional<RGWAccountInfo> account,
211-
std::vector<IAM::Policy> policies)
212-
: id(user.user_id),
213+
std::vector<IAM::Policy> policies,
214+
sal::Driver* driver)
215+
: driver(driver),
216+
id(user.user_id),
213217
display_name(user.display_name),
214218
path(user.path),
215219
is_admin(user.admin),
@@ -294,9 +298,9 @@ static auto transform_old_authinfo(const RGWUserInfo& user,
294298
<< ", is_admin=" << is_admin << ")";
295299
}
296300

297-
void load_acct_info(const DoutPrefixProvider* dpp,
298-
RGWUserInfo& user_info) const override {
301+
auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> override {
299302
// noop, this user info was passed in on construction
303+
return driver->get_user(id);
300304
}
301305

302306
void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const {
@@ -307,7 +311,7 @@ static auto transform_old_authinfo(const RGWUserInfo& user,
307311
};
308312

309313
return std::make_unique<DummyIdentityApplier>(
310-
user, std::move(account), std::move(policies));
314+
user, std::move(account), std::move(policies), driver);
311315
}
312316

313317
auto transform_old_authinfo(const DoutPrefixProvider* dpp,
@@ -332,7 +336,7 @@ auto transform_old_authinfo(const DoutPrefixProvider* dpp,
332336
if (policies_) { // return policies to caller if requested
333337
*policies_ = policies;
334338
}
335-
return transform_old_authinfo(info, std::move(account), std::move(policies));
339+
return transform_old_authinfo(info, std::move(account), std::move(policies), driver);
336340
}
337341

338342
} /* namespace auth */
@@ -527,7 +531,7 @@ rgw::auth::Strategy::apply(const DoutPrefixProvider *dpp, const rgw::auth::Strat
527531

528532
/* Account used by a given RGWOp is decoupled from identity employed
529533
* in the authorization phase (RGWOp::verify_permissions). */
530-
applier->load_acct_info(dpp, s->user->get_info());
534+
s->user = applier->load_acct_info(dpp);
531535
s->perm_mask = applier->get_perm_mask();
532536

533537
/* This is the single place where we pass req_state as a pointer
@@ -635,36 +639,36 @@ void rgw::auth::WebIdentityApplier::create_account(const DoutPrefixProvider* dpp
635639
user_info = user->get_info();
636640
}
637641

638-
void rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const {
642+
auto rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> {
639643
rgw_user federated_user;
640644
federated_user.id = this->sub;
641645
federated_user.tenant = role_tenant;
642646
federated_user.ns = "oidc";
643647

648+
std::unique_ptr<rgw::sal::User> user = driver->get_user(federated_user);
644649
if (account) {
645650
// we don't need shadow users for account roles because bucket ownership,
646651
// quota, and stats are tracked by the account instead of the user
647-
user_info.user_id = std::move(federated_user);
652+
RGWUserInfo& user_info = user->get_info();
648653
user_info.display_name = user_name;
649654
user_info.type = TYPE_WEB;
650-
return;
655+
// the user_info.user_id is initialized by driver->get_user(...)
656+
return user;
651657
}
652658

653-
std::unique_ptr<rgw::sal::User> user = driver->get_user(federated_user);
654-
655659
//Check in oidc namespace
656660
if (user->load_user(dpp, null_yield) >= 0) {
657661
/* Succeeded. */
658-
user_info = user->get_info();
659-
return;
662+
// the user_info in user is initialized by user->load_user(...)
663+
return user;
660664
}
661665

662666
user->clear_ns();
663667
//Check for old users which wouldn't have been created in oidc namespace
664668
if (user->load_user(dpp, null_yield) >= 0) {
665669
/* Succeeded. */
666-
user_info = user->get_info();
667-
return;
670+
// the user_info in user is initialized by user->load_user(...)
671+
return user;
668672
}
669673

670674
//Check if user_id.buckets already exists, may have been from the time, when shadow users didnt exist
@@ -675,7 +679,7 @@ void rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider* dpp
675679
last_synced, last_updated);
676680
if (ret < 0 && ret != -ENOENT) {
677681
ldpp_dout(dpp, 0) << "ERROR: reading stats for the user returned error " << ret << dendl;
678-
return;
682+
return user;
679683
}
680684
if (ret == -ENOENT) { /* in case of ENOENT, which means user doesnt have buckets */
681685
//In this case user will be created in oidc namespace
@@ -688,7 +692,8 @@ void rgw::auth::WebIdentityApplier::load_acct_info(const DoutPrefixProvider* dpp
688692
}
689693

690694
ldpp_dout(dpp, 0) << "NOTICE: couldn't map oidc federated user " << federated_user << dendl;
691-
create_account(dpp, federated_user, this->user_name, user_info);
695+
create_account(dpp, federated_user, this->user_name, user->get_info());
696+
return user;
692697
}
693698

694699
void rgw::auth::WebIdentityApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const
@@ -940,7 +945,7 @@ void rgw::auth::RemoteApplier::write_ops_log_entry(rgw_log_entry& entry) const
940945
}
941946

942947
/* TODO(rzarzynski): we need to handle display_name changes. */
943-
void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */
948+
auto rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> /* out */
944949
{
945950
/* It's supposed that RGWRemoteAuthApplier tries to load account info
946951
* that belongs to the authenticated identity. Another policy may be
@@ -979,9 +984,9 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW
979984
(void) load_account_and_policies(dpp, null_yield, driver, user->get_info(),
980985
user->get_attrs(), account, policies);
981986

982-
user_info = std::move(user->get_info());
983987
owner_acct_user = std::move(tenanted_uid);
984-
return;
988+
// the user_info in user is initialized by user->load_user(...)
989+
return user;
985990
}
986991
}
987992

@@ -994,15 +999,16 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW
994999
(void) load_account_and_policies(dpp, null_yield, driver, user->get_info(),
9951000
user->get_attrs(), account, policies);
9961001

997-
user_info = std::move(user->get_info());
9981002
owner_acct_user = acct_user;
999-
return;
1003+
// the user_info in user is initialized by user->load_user(...)
1004+
return user;
10001005
}
10011006

10021007
ldpp_dout(dpp, 0) << "NOTICE: couldn't map swift user " << acct_user << dendl;
1003-
create_account(dpp, acct_user, implicit_tenant, user_info);
1008+
create_account(dpp, acct_user, implicit_tenant, user->get_info());
10041009

10051010
/* Succeeded if we are here (create_account() hasn't throwed). */
1011+
return user;
10061012
}
10071013

10081014
void rgw::auth::RemoteApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
@@ -1102,11 +1108,11 @@ uint32_t rgw::auth::LocalApplier::get_perm_mask(const std::string& subuser_name,
11021108
}
11031109
}
11041110

1105-
void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */
1111+
auto rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> /* out */
11061112
{
11071113
/* Load the account that belongs to the authenticated identity. An extra call
11081114
* to RADOS may be safely skipped in this case. */
1109-
user_info = this->user_info;
1115+
return std::unique_ptr<rgw::sal::User>(user.release());
11101116
}
11111117

11121118
void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
@@ -1125,6 +1131,22 @@ void rgw::auth::LocalApplier::write_ops_log_entry(rgw_log_entry& entry) const
11251131
}
11261132
}
11271133

1134+
rgw::auth::LocalApplier::LocalApplier(CephContext* const cct,
1135+
std::unique_ptr<rgw::sal::User> user,
1136+
std::optional<RGWAccountInfo> account,
1137+
std::vector<IAM::Policy> policies,
1138+
std::string subuser,
1139+
const std::optional<uint32_t>& perm_mask,
1140+
const std::string access_key_id)
1141+
: user_info(user->get_info()),
1142+
user(std::move(user)),
1143+
account(std::move(account)),
1144+
policies(std::move(policies)),
1145+
subuser(std::move(subuser)),
1146+
perm_mask(perm_mask.value_or(RGW_PERM_INVALID)),
1147+
access_key_id(access_key_id) {
1148+
}
1149+
11281150
ACLOwner rgw::auth::RoleApplier::get_aclowner() const
11291151
{
11301152
ACLOwner owner;
@@ -1187,10 +1209,11 @@ bool rgw::auth::RoleApplier::is_identity(const Principal& p) const {
11871209
return false;
11881210
}
11891211

1190-
void rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */
1212+
auto rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> /* out */
11911213
{
11921214
/* Load the user id */
1193-
user_info.user_id = this->token_attrs.user_id;
1215+
std::unique_ptr<rgw::sal::User> user = driver->get_user(this->token_attrs.user_id);
1216+
return user;
11941217
}
11951218

11961219
void rgw::auth::RoleApplier::write_ops_log_entry(rgw_log_entry& entry) const
@@ -1271,9 +1294,10 @@ rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const re
12711294
} else {
12721295
RGWUserInfo user_info;
12731296
rgw_get_anon_user(user_info);
1274-
1297+
std::unique_ptr<rgw::sal::User> user = s->user->clone();
1298+
user->get_info() = user_info;
12751299
auto apl = \
1276-
apl_factory->create_apl_local(cct, s, user_info, std::nullopt, {},
1300+
apl_factory->create_apl_local(cct, s, std::move(user), std::nullopt, {},
12771301
rgw::auth::LocalApplier::NO_SUBUSER,
12781302
std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
12791303
return result_t::grant(std::move(apl));

‎src/rgw/rgw_auth.h

+16-17
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class IdentityApplier : public Identity {
140140
*
141141
* XXX: be aware that the "account" term refers to rgw_user. The naming
142142
* is legacy. */
143-
virtual void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const = 0; /* out */
143+
virtual auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> = 0; /* out */
144144

145145
/* Apply any changes to request state. This method will be most useful for
146146
* TempURL of Swift API. */
@@ -485,7 +485,7 @@ class WebIdentityApplier : public IdentityApplier {
485485

486486
bool is_identity(const Principal& p) const override;
487487

488-
void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override;
488+
auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> override;
489489

490490
uint32_t get_identity_type() const override {
491491
return TYPE_WEB;
@@ -657,7 +657,7 @@ class RemoteApplier : public IdentityApplier {
657657

658658
uint32_t get_perm_mask() const override { return info.perm_mask; }
659659
void to_str(std::ostream& out) const override;
660-
void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
660+
auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> override; /* out */
661661
void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
662662
void write_ops_log_entry(rgw_log_entry& entry) const override;
663663
uint32_t get_identity_type() const override { return info.acct_type; }
@@ -684,14 +684,15 @@ class RemoteApplier : public IdentityApplier {
684684

685685

686686
/* rgw::auth::LocalApplier targets those auth engines that base on the data
687-
* enclosed in the RGWUserInfo control structure. As a side effect of doing
687+
* enclosed in the rgw::sal::User->RGWUserInfo control structure. As a side effect of doing
688688
* the authentication process, they must have it loaded. Leveraging this is
689689
* a way to avoid unnecessary calls to underlying RADOS store. */
690690
class LocalApplier : public IdentityApplier {
691691
using aclspec_t = rgw::auth::Identity::aclspec_t;
692692

693693
protected:
694694
const RGWUserInfo user_info;
695+
mutable std::unique_ptr<rgw::sal::User> user;
695696
const std::optional<RGWAccountInfo> account;
696697
const std::vector<IAM::Policy> policies;
697698
const std::string subuser;
@@ -706,19 +707,12 @@ class LocalApplier : public IdentityApplier {
706707
static const std::string NO_ACCESS_KEY;
707708

708709
LocalApplier(CephContext* const cct,
709-
const RGWUserInfo& user_info,
710+
std::unique_ptr<rgw::sal::User> user,
710711
std::optional<RGWAccountInfo> account,
711712
std::vector<IAM::Policy> policies,
712713
std::string subuser,
713714
const std::optional<uint32_t>& perm_mask,
714-
const std::string access_key_id)
715-
: user_info(user_info),
716-
account(std::move(account)),
717-
policies(std::move(policies)),
718-
subuser(std::move(subuser)),
719-
perm_mask(perm_mask.value_or(RGW_PERM_INVALID)),
720-
access_key_id(access_key_id) {
721-
}
715+
const std::string access_key_id);
722716

723717
ACLOwner get_aclowner() const override;
724718
uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override;
@@ -733,7 +727,7 @@ class LocalApplier : public IdentityApplier {
733727
}
734728
}
735729
void to_str(std::ostream& out) const override;
736-
void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
730+
auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> override; /* out */
737731
void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
738732
uint32_t get_identity_type() const override { return user_info.type; }
739733
std::string get_acct_name() const override { return {}; }
@@ -751,7 +745,7 @@ class LocalApplier : public IdentityApplier {
751745
virtual ~Factory() {}
752746
virtual aplptr_t create_apl_local(CephContext* cct,
753747
const req_state* s,
754-
const RGWUserInfo& user_info,
748+
std::unique_ptr<rgw::sal::User> user,
755749
std::optional<RGWAccountInfo> account,
756750
std::vector<IAM::Policy> policies,
757751
const std::string& subuser,
@@ -780,15 +774,20 @@ class RoleApplier : public IdentityApplier {
780774
std::vector<std::pair<std::string, std::string>> principal_tags;
781775
};
782776
protected:
777+
CephContext* const cct;
778+
rgw::sal::Driver* driver;
783779
Role role;
784780
TokenAttrs token_attrs;
785781

786782
public:
787783

788784
RoleApplier(CephContext* const cct,
785+
rgw::sal::Driver* driver,
789786
const Role& role,
790787
const TokenAttrs& token_attrs)
791-
: role(role),
788+
: cct(cct),
789+
driver(driver),
790+
role(role),
792791
token_attrs(token_attrs) {}
793792

794793
ACLOwner get_aclowner() const override;
@@ -804,7 +803,7 @@ class RoleApplier : public IdentityApplier {
804803
return RGW_PERM_NONE;
805804
}
806805
void to_str(std::ostream& out) const override;
807-
void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
806+
auto load_acct_info(const DoutPrefixProvider* dpp) const -> std::unique_ptr<rgw::sal::User> override; /* out */
808807
uint32_t get_identity_type() const override { return TYPE_ROLE; }
809808
std::string get_acct_name() const override { return {}; }
810809
std::string get_subuser() const override { return {}; }

0 commit comments

Comments
 (0)
Please sign in to comment.