]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: Permission evaluation for Roles.
authorPritha Srivastava <prsrivas@redhat.com>
Wed, 28 Mar 2018 03:39:42 +0000 (09:09 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Mon, 2 Jul 2018 10:12:02 +0000 (15:42 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
src/rgw/rgw_iam_policy.cc
src/rgw/rgw_iam_policy.h
src/rgw/rgw_rest_role.cc
src/rgw/rgw_rest_role.h

index 2eebd750b1b63ccc02e5671f251d1a6d01f0f317..00e9ac693365fb700d6c81d5852b8a259015e9fb 100644 (file)
@@ -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;
 
index 8c2edebef36f26d745f8874e4c9ba774c39c7e82..111084381fd436f66c9e681043277a30bfabd93f 100644 (file)
@@ -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) {
index 60b0efa0e131c2fad0adc9ad6dfcb410442ee67f..6867e0a0f65cc5f010c35f27a79d7ec91acdb354 100644 (file)
 
 #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<string> 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<string> 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();
   }
 }
index df7f00d286954d0e6535f69bbd0d96f8b52238b4..6153c6b21de793ed003272c5680f87379a609857 100644 (file)
@@ -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 */