From: Pritha Srivastava Date: Wed, 28 Mar 2018 03:39:42 +0000 (+0530) Subject: rgw: Permission evaluation for Roles. X-Git-Tag: v14.0.1~335^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6bb890a2e6412954bf637cf5f2ab904bbed22d15;p=ceph-ci.git rgw: Permission evaluation for Roles. Signed-off-by: Pritha Srivastava --- diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index 2eebd750b1b..00e9ac69336 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -456,7 +456,18 @@ static const actpair actpairs[] = { "s3:RestoreObject", s3RestoreObject }, { "iam:PutUserPolicy", iamPutUserPolicy }, { "iam:GetUserPolicy", iamGetUserPolicy }, - { "iam:DeleteUserPolicy", iamDeleteUserPolicy }}; + { "iam:DeleteUserPolicy", iamDeleteUserPolicy }, + { "iam:ListUserPolicies", iamListUserPolicies }, + { "iam:CreateRole", iamCreateRole}, + { "iam:DeleteRole", iamDeleteRole}, + { "iam:GetRole", iamGetRole}, + { "iam:ModifyRole", iamModifyRole}, + { "iam:ListRoles", iamListRoles}, + { "iam:PutRolePolicy", iamPutRolePolicy}, + { "iam:GetRolePolicy", iamGetRolePolicy}, + { "iam:ListRolePolicies", iamListRolePolicies}, + { "iam:DeleteRolePolicy", iamDeleteRolePolicy}, +}; struct PolicyParser; diff --git a/src/rgw/rgw_iam_policy.h b/src/rgw/rgw_iam_policy.h index 8c2edebef36..111084381fd 100644 --- a/src/rgw/rgw_iam_policy.h +++ b/src/rgw/rgw_iam_policy.h @@ -97,12 +97,21 @@ static constexpr std::uint64_t s3PutObjectVersionTagging = 1ULL << 52; static constexpr std::uint64_t s3DeleteObjectVersionTagging = 1ULL << 53; static constexpr std::uint64_t s3Count = 54; static constexpr std::uint64_t s3All = (1ULL << s3Count) - 1; - static constexpr std::uint64_t iamPutUserPolicy = 1ULL << 56; static constexpr std::uint64_t iamGetUserPolicy = 1ULL << 57; static constexpr std::uint64_t iamDeleteUserPolicy = 1ULL << 58; static constexpr std::uint64_t iamListUserPolicies = 1ULL << 59; +static constexpr std::uint64_t iamCreateRole = 1ULL << 60; +static constexpr std::uint64_t iamDeleteRole = 1ULL << 61; +static constexpr std::uint64_t iamModifyRole = 1ULL << 62; +static constexpr std::uint64_t iamGetRole = 1ULL << 63; +static constexpr std::uint64_t iamListRoles = 3ULL; +static constexpr std::uint64_t iamPutRolePolicy = 5ULL; +static constexpr std::uint64_t iamGetRolePolicy = 6ULL; +static constexpr std::uint64_t iamListRolePolicies = 7ULL; +static constexpr std::uint64_t iamDeleteRolePolicy = 9ULL; + namespace { inline int op_to_perm(std::uint64_t op) { switch (op) { diff --git a/src/rgw/rgw_rest_role.cc b/src/rgw/rgw_rest_role.cc index 60b0efa0e13..6867e0a0f65 100644 --- a/src/rgw/rgw_rest_role.cc +++ b/src/rgw/rgw_rest_role.cc @@ -17,6 +17,41 @@ #define dout_subsys ceph_subsys_rgw +int RGWRestRole::verify_permission() +{ + if (s->auth.identity->is_anonymous()) { + return -EACCES; + } + + string role_name = s->info.args.get("RoleName"); + RGWRole role(s->cct, store, role_name, s->user->user_id.tenant); + if (op_ret = role.get(); op_ret < 0) { + if (op_ret == -ENOENT) { + op_ret = -ERR_NO_ROLE_FOUND; + } + return op_ret; + } + + if (int ret = check_caps(s->user->caps); ret == 0) { + _role = std::move(role); + return ret; + } + + string resource_name = role.get_path() + role_name; + uint64_t op = get_op(); + if (!verify_user_permission(s, + rgw::IAM::ARN(resource_name, + "role", + s->user->user_id.tenant), + op)) { + return -EACCES; + } + + _role = std::move(role); + + return 0; +} + void RGWRestRole::send_response() { if (op_ret) { @@ -26,13 +61,6 @@ void RGWRestRole::send_response() end_header(s); } -int RGWRestRole::verify_permission() -{ - int ret = check_caps(s->user->caps); - ldout(s->cct, 0) << "INFO: verify_permissions ret" << ret << dendl; - return ret; -} - int RGWRoleRead::check_caps(RGWUserCaps& caps) { return caps.check_cap("roles", RGW_CAP_READ); @@ -43,6 +71,30 @@ int RGWRoleWrite::check_caps(RGWUserCaps& caps) return caps.check_cap("roles", RGW_CAP_WRITE); } +int RGWCreateRole::verify_permission() +{ + if (s->auth.identity->is_anonymous()) { + return -EACCES; + } + + if (int ret = check_caps(s->user->caps); ret == 0) { + return ret; + } + + string role_name = s->info.args.get("RoleName"); + string role_path = s->info.args.get("Path"); + + string resource_name = role_path + role_name; + if (!verify_user_permission(s, + rgw::IAM::ARN(resource_name, + "role", + s->user->user_id.tenant), + get_op())) { + return -EACCES; + } + return 0; +} + int RGWCreateRole::get_params() { role_name = s->info.args.get("RoleName"); @@ -100,14 +152,40 @@ void RGWDeleteRole::execute() if (op_ret < 0) { return; } - RGWRole role(s->cct, store, role_name, s->user->user_id.tenant); - op_ret = role.delete_obj(); + + op_ret = _role.delete_obj(); if (op_ret == -ENOENT) { op_ret = -ERR_NO_ROLE_FOUND; } } +int RGWGetRole::verify_permission() +{ + return 0; +} + +int RGWGetRole::_verify_permission(const RGWRole& role) +{ + if (s->auth.identity->is_anonymous()) { + return -EACCES; + } + + if (int ret = check_caps(s->user->caps); ret == 0) { + return ret; + } + + string resource_name = role.get_path() + role.get_name(); + if (!verify_user_permission(s, + rgw::IAM::ARN(resource_name, + "role", + s->user->user_id.tenant), + get_op())) { + return -EACCES; + } + return 0; +} + int RGWGetRole::get_params() { role_name = s->info.args.get("RoleName"); @@ -131,8 +209,11 @@ void RGWGetRole::execute() if (op_ret == -ENOENT) { op_ret = -ERR_NO_ROLE_FOUND; + return; } + op_ret = _verify_permission(role); + if (op_ret == 0) { s->formatter->open_object_section("role"); role.dump(s->formatter); @@ -164,16 +245,29 @@ void RGWModifyRole::execute() if (op_ret < 0) { return; } - RGWRole role(s->cct, store, role_name, s->user->user_id.tenant); - op_ret = role.get(); - if (op_ret == -ENOENT) { - op_ret = -ERR_NO_ROLE_FOUND; + + _role.update_trust_policy(trust_policy); + op_ret = _role.update(); + +} + +int RGWListRoles::verify_permission() +{ + if (s->auth.identity->is_anonymous()) { + return -EACCES; } - if (op_ret == 0) { - role.update_trust_policy(trust_policy); - op_ret = role.update(); + if (int ret = check_caps(s->user->caps); ret == 0) { + return ret; + } + + if (!verify_user_permission(s, + rgw::IAM::ARN(), + get_op())) { + return -EACCES; } + + return 0; } int RGWListRoles::get_params() @@ -229,12 +323,8 @@ void RGWPutRolePolicy::execute() return; } - RGWRole role(s->cct, store, role_name, s->user->user_id.tenant); - op_ret = role.get(); - if (op_ret == 0) { - role.set_perm_policy(policy_name, perm_policy); - op_ret = role.update(); - } + _role.set_perm_policy(policy_name, perm_policy); + op_ret = _role.update(); } int RGWGetRolePolicy::get_params() @@ -256,24 +346,14 @@ void RGWGetRolePolicy::execute() return; } - RGWRole role(g_ceph_context, store, role_name, s->user->user_id.tenant); - op_ret = role.get(); - - if (op_ret == -ENOENT) { - op_ret = -ERR_NO_ROLE_FOUND; - } - + string perm_policy; + op_ret = _role.get_role_policy(policy_name, perm_policy); if (op_ret == 0) { - string perm_policy; - op_ret = role.get_role_policy(policy_name, perm_policy); - - if (op_ret == 0) { - s->formatter->open_object_section("GetRolePolicyResult"); - s->formatter->dump_string("PolicyName", policy_name); - s->formatter->dump_string("RoleName", role_name); - s->formatter->dump_string("Permission policy", perm_policy); - s->formatter->close_section(); - } + s->formatter->open_object_section("GetRolePolicyResult"); + s->formatter->dump_string("PolicyName", policy_name); + s->formatter->dump_string("RoleName", role_name); + s->formatter->dump_string("Permission policy", perm_policy); + s->formatter->close_section(); } } @@ -295,21 +375,12 @@ void RGWListRolePolicies::execute() return; } - RGWRole role(g_ceph_context, store, role_name, s->user->user_id.tenant); - op_ret = role.get(); - - if (op_ret == -ENOENT) { - op_ret = -ERR_NO_ROLE_FOUND; - } - - if (op_ret == 0) { - std::vector policy_names = role.get_role_policy_names(); - s->formatter->open_array_section("PolicyNames"); - for (const auto& it : policy_names) { - s->formatter->dump_string("member", it); - } - s->formatter->close_section(); + std::vector policy_names = _role.get_role_policy_names(); + s->formatter->open_array_section("PolicyNames"); + for (const auto& it : policy_names) { + s->formatter->dump_string("member", it); } + s->formatter->close_section(); } int RGWDeleteRolePolicy::get_params() @@ -331,21 +402,12 @@ void RGWDeleteRolePolicy::execute() return; } - RGWRole role(g_ceph_context, store, role_name, s->user->user_id.tenant); - op_ret = role.get(); - + op_ret = _role.delete_policy(policy_name); if (op_ret == -ENOENT) { op_ret = -ERR_NO_ROLE_FOUND; } if (op_ret == 0) { - op_ret = role.delete_policy(policy_name); - if (op_ret == -ENOENT) { - op_ret = -ERR_NO_ROLE_FOUND; - } - - if (op_ret == 0) { - op_ret = role.update(); - } + op_ret = _role.update(); } } diff --git a/src/rgw/rgw_rest_role.h b/src/rgw/rgw_rest_role.h index df7f00d2869..6153c6b21de 100644 --- a/src/rgw/rgw_rest_role.h +++ b/src/rgw/rgw_rest_role.h @@ -3,6 +3,8 @@ #ifndef CEPH_RGW_REST_ROLE_H #define CEPH_RGW_REST_ROLE_H +#include "rgw_role.h" + class RGWRestRole : public RGWRESTOp { protected: string role_name; @@ -11,10 +13,11 @@ protected: string policy_name; string perm_policy; string path_prefix; - + RGWRole _role; public: int verify_permission() override; void send_response() override; + virtual uint64_t get_op() = 0; }; class RGWRoleRead : public RGWRestRole { @@ -32,10 +35,12 @@ public: class RGWCreateRole : public RGWRoleWrite { public: RGWCreateRole() = default; + int verify_permission() override; void execute() override; int get_params(); const char* name() const override { return "create_role"; } RGWOpType get_type() override { return RGW_OP_CREATE_ROLE; } + uint64_t get_op() { return rgw::IAM::iamCreateRole; } }; class RGWDeleteRole : public RGWRoleWrite { @@ -45,15 +50,19 @@ public: int get_params(); const char* name() const override { return "delete_role"; } RGWOpType get_type() override { return RGW_OP_DELETE_ROLE; } + uint64_t get_op() { return rgw::IAM::iamDeleteRole; } }; class RGWGetRole : public RGWRoleRead { + int _verify_permission(const RGWRole& role); public: RGWGetRole() = default; + int verify_permission() override; void execute() override; int get_params(); const char* name() const override { return "get_role"; } RGWOpType get_type() override { return RGW_OP_GET_ROLE; } + uint64_t get_op() { return rgw::IAM::iamGetRole; } }; class RGWModifyRole : public RGWRoleWrite { @@ -63,15 +72,18 @@ public: int get_params(); const char* name() const override { return "modify_role"; } RGWOpType get_type() override { return RGW_OP_MODIFY_ROLE; } + uint64_t get_op() { return rgw::IAM::iamModifyRole; } }; class RGWListRoles : public RGWRoleRead { public: RGWListRoles() = default; + int verify_permission() override; void execute() override; int get_params(); const char* name() const override { return "list_roles"; } RGWOpType get_type() override { return RGW_OP_LIST_ROLES; } + uint64_t get_op() { return rgw::IAM::iamListRoles; } }; class RGWPutRolePolicy : public RGWRoleWrite { @@ -81,6 +93,7 @@ public: int get_params(); const char* name() const override { return "put_role_policy"; } RGWOpType get_type() override { return RGW_OP_PUT_ROLE_POLICY; } + uint64_t get_op() { return rgw::IAM::iamPutRolePolicy; } }; class RGWGetRolePolicy : public RGWRoleRead { @@ -90,6 +103,7 @@ public: int get_params(); const char* name() const override { return "get_role_policy"; } RGWOpType get_type() override { return RGW_OP_GET_ROLE_POLICY; } + uint64_t get_op() { return rgw::IAM::iamGetRolePolicy; } }; class RGWListRolePolicies : public RGWRoleRead { @@ -99,6 +113,7 @@ public: int get_params(); const char* name() const override { return "list_role_policies"; } RGWOpType get_type() override { return RGW_OP_LIST_ROLE_POLICIES; } + uint64_t get_op() { return rgw::IAM::iamListRolePolicies; } }; class RGWDeleteRolePolicy : public RGWRoleWrite { @@ -108,6 +123,7 @@ public: int get_params(); const char* name() const override { return "delete_role_policy"; } RGWOpType get_type() override { return RGW_OP_DELETE_ROLE_POLICY; } + uint64_t get_op() { return rgw::IAM::iamDeleteRolePolicy; } }; #endif /* CEPH_RGW_REST_ROLE_H */