From 37170a0d4701a8321e5b74da0fe592143c35b55a Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Tue, 10 Oct 2023 17:04:20 +0530 Subject: [PATCH] rgw/iam: adds implementation for iam UpdateOidcProviderThumbprint. This API adds a mechanism to update the thumbprint list of an oidc provider identified by its arn. The existing thumbprint list is completely erased and then the new list is added. fixes: https://tracker.ceph.com/issues/63214 Signed-off-by: Pritha Srivastava --- src/rgw/rgw_auth_s3.cc | 2 + src/rgw/rgw_iam_policy.cc | 4 ++ src/rgw/rgw_iam_policy.h | 1 + src/rgw/rgw_op_type.h | 1 + src/rgw/rgw_rest_iam.cc | 1 + src/rgw/rgw_rest_oidc_provider.cc | 72 +++++++++++++++++++++++++++++++ src/rgw/rgw_rest_oidc_provider.h | 14 +++++- 7 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index d521f60f6b1..412f4bf759a 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -495,6 +495,8 @@ bool is_non_s3_op(RGWOpType op_type) case RGW_OP_DELETE_OIDC_PROVIDER: case RGW_OP_GET_OIDC_PROVIDER: case RGW_OP_LIST_OIDC_PROVIDERS: + case RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER: + case RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT: case RGW_OP_PUBSUB_TOPIC_CREATE: case RGW_OP_PUBSUB_TOPICS_LIST: case RGW_OP_PUBSUB_TOPIC_GET: diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index b45a9ac3f73..068a93c4d95 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -161,6 +161,7 @@ static const actpair actpairs[] = { "iam:GetOIDCProvider", iamGetOIDCProvider}, { "iam:ListOIDCProviders", iamListOIDCProviders}, { "iam:AddClientIdToOIDCProvider", iamAddClientIdToOIDCProvider}, + { "iam:UpdateOIDCProviderThumbprint", iamUpdateOIDCProviderThumbprint}, { "iam:TagRole", iamTagRole}, { "iam:ListRoleTags", iamListRoleTags}, { "iam:UntagRole", iamUntagRole}, @@ -1554,6 +1555,9 @@ const char* action_bit_string(uint64_t action) { case iamAddClientIdToOIDCProvider: return "iam:AddClientIdToOIDCProvider"; + case iamUpdateOIDCProviderThumbprint: + return "iam:UpdateOIDCProviderThumbprint"; + case iamTagRole: return "iam:TagRole"; diff --git a/src/rgw/rgw_iam_policy.h b/src/rgw/rgw_iam_policy.h index 4c452462e4b..1494cbf0b81 100644 --- a/src/rgw/rgw_iam_policy.h +++ b/src/rgw/rgw_iam_policy.h @@ -144,6 +144,7 @@ enum { iamGetOIDCProvider, iamListOIDCProviders, iamAddClientIdToOIDCProvider, + iamUpdateOIDCProviderThumbprint, iamTagRole, iamListRoleTags, iamUntagRole, diff --git a/src/rgw/rgw_op_type.h b/src/rgw/rgw_op_type.h index b9f0b785060..12291d64cb3 100644 --- a/src/rgw/rgw_op_type.h +++ b/src/rgw/rgw_op_type.h @@ -162,5 +162,6 @@ enum RGWOpType { RGW_OP_GET_OIDC_PROVIDER, RGW_OP_LIST_OIDC_PROVIDERS, RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER, + RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT, }; diff --git a/src/rgw/rgw_rest_iam.cc b/src/rgw/rgw_rest_iam.cc index 4c77bc71fa3..adf79e978af 100644 --- a/src/rgw/rgw_rest_iam.cc +++ b/src/rgw/rgw_rest_iam.cc @@ -46,6 +46,7 @@ static const std::unordered_map op_generators = {"GetOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWGetOIDCProvider;}}, {"DeleteOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWDeleteOIDCProvider;}}, {"AddClientIDToOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWAddClientIdToOIDCProvider;}}, + {"UpdateOpenIDConnectProviderThumbprint", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWUpdateOIDCProviderThumbprint;}}, {"TagRole", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWTagRole(bl_post_body);}}, {"ListRoleTags", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWListRoleTags;}}, {"UntagRole", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWUntagRole(bl_post_body);}}, diff --git a/src/rgw/rgw_rest_oidc_provider.cc b/src/rgw/rgw_rest_oidc_provider.cc index d29188bba27..37b5e7edc26 100644 --- a/src/rgw/rgw_rest_oidc_provider.cc +++ b/src/rgw/rgw_rest_oidc_provider.cc @@ -405,3 +405,75 @@ void RGWAddClientIdToOIDCProvider::execute(optional_yield y) s->formatter->close_section(); } } + +RGWUpdateOIDCProviderThumbprint::RGWUpdateOIDCProviderThumbprint() + : RGWRestOIDCProvider(rgw::IAM::iamUpdateOIDCProviderThumbprint, RGW_CAP_WRITE) +{ +} + +int RGWUpdateOIDCProviderThumbprint::init_processing(optional_yield y) +{ + std::string_view account; + if (const auto& acc = s->auth.identity->get_account(); acc) { + account = acc->id; + } else { + account = s->user->get_tenant(); + } + std::string provider_arn = s->info.args.get("OpenIDConnectProviderArn"); + auto ret = validate_provider_arn(provider_arn, account, + resource, url, s->err.message); + if (ret < 0) { + return ret; + } + + auto val_map = s->info.args.get_params(); + /* From AWS documentation here: https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateOpenIDConnectProviderThumbprint.html + The list that you pass with this operation completely replaces the existing list of thumbprints. (The lists are not merged.) */ + for (auto& it : val_map) { + if (it.first.find("ThumbprintList.member.") != string::npos) { + if (it.second.size() > MAX_OIDC_THUMBPRINT_LEN) { + s->err.message = "Thumbprint cannot exceed the maximum length of " + + std::to_string(MAX_OIDC_THUMBPRINT_LEN); + ldpp_dout(this, 20) << "ERROR: Thumbprint exceeds maximum length of " << MAX_OIDC_THUMBPRINT_LEN << dendl; + return -EINVAL; + } + thumbprints.emplace_back(it.second); + } + } + + if (thumbprints.empty()) { + s->err.message = "Missing required element ThumbprintList"; + ldpp_dout(this, 20) << "ERROR: Thumbprints list is empty" << dendl; + return -EINVAL; + } + + return 0; +} + +void RGWUpdateOIDCProviderThumbprint::execute(optional_yield y) +{ + RGWOIDCProviderInfo info; + op_ret = driver->load_oidc_provider(this, y, resource.account, url, info); + + if (op_ret < 0) { + if (op_ret != -ENOENT && op_ret != -EINVAL) { + op_ret = ERR_INTERNAL_ERROR; + } + return; + } + + info.thumbprints = std::move(thumbprints); + + constexpr bool exclusive = false; + op_ret = driver->store_oidc_provider(this, y, info, exclusive); + if (op_ret == 0) { + s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse"); + s->formatter->open_object_section("ResponseMetadata"); + s->formatter->dump_string("RequestId", s->trans_id); + s->formatter->close_section(); + s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse"); + dump_oidc_provider(info, s->formatter); + s->formatter->close_section(); + s->formatter->close_section(); + } +} diff --git a/src/rgw/rgw_rest_oidc_provider.h b/src/rgw/rgw_rest_oidc_provider.h index 9a49ed7dafb..e64243a4e72 100644 --- a/src/rgw/rgw_rest_oidc_provider.h +++ b/src/rgw/rgw_rest_oidc_provider.h @@ -73,4 +73,16 @@ public: void execute(optional_yield y) override; const char* name() const override { return "add_client_id_to_oidc_provider"; } RGWOpType get_type() override { return RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER; } -}; \ No newline at end of file +}; + +class RGWUpdateOIDCProviderThumbprint : public RGWRestOIDCProvider { + std::string url; + std::vector thumbprints; +public: + RGWUpdateOIDCProviderThumbprint(); + + int init_processing(optional_yield y); + void execute(optional_yield y) override; + const char* name() const override { return "update_oidc_provider_thumbprint"; } + RGWOpType get_type() override { return RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT; } +}; -- 2.39.5