]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rgw/rgw_rest_role.cc
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / rgw / rgw_rest_role.cc
index 386504398fefb4f01d0a86e30ecc2d29813f6a63..7dc772c3f670fa3a96d0d78032d444c15e5e972e 100644 (file)
@@ -1,3 +1,6 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
 #include <errno.h>
 
 #include "common/errno.h"
 
 #define dout_subsys ceph_subsys_rgw
 
-using namespace std;
+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(this,
+                              s,
+                              rgw::ARN(resource_name,
+                                            "role",
+                                             s->user->user_id.tenant, true),
+                                             op)) {
+    return -EACCES;
+  }
+
+  _role = std::move(role);
+
+  return 0;
+}
 
 void RGWRestRole::send_response()
 {
@@ -23,32 +60,41 @@ void RGWRestRole::send_response()
     set_req_state_err(s, op_ret);
   }
   dump_errno(s);
-  end_header(s);
+  end_header(s, this);
 }
 
-int RGWRoleRead::verify_permission()
+int RGWRoleRead::check_caps(RGWUserCaps& caps)
 {
-  if (s->auth.identity->is_anonymous()) {
-    return -EACCES;
-  }
-
-  if (!verify_user_permission(s, RGW_PERM_READ)) {
-    return -EACCES;
-  }
+    return caps.check_cap("roles", RGW_CAP_READ);
+}
 
-  return 0;
+int RGWRoleWrite::check_caps(RGWUserCaps& caps)
+{
+    return caps.check_cap("roles", RGW_CAP_WRITE);
 }
 
-int RGWRoleWrite::verify_permission()
+int RGWCreateRole::verify_permission()
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   }
 
-  if (!verify_user_permission(s, RGW_PERM_WRITE)) {
-    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(this,
+                              s,
+                              rgw::ARN(resource_name,
+                                            "role",
+                                             s->user->user_id.tenant, true),
+                                             get_op())) {
+    return -EACCES;
+  }
   return 0;
 }
 
@@ -57,17 +103,23 @@ int RGWCreateRole::get_params()
   role_name = s->info.args.get("RoleName");
   role_path = s->info.args.get("Path");
   trust_policy = s->info.args.get("AssumeRolePolicyDocument");
+  max_session_duration = s->info.args.get("MaxSessionDuration");
 
   if (role_name.empty() || trust_policy.empty()) {
     ldout(s->cct, 20) << "ERROR: one of role name or assume role policy document is empty"
     << dendl;
     return -EINVAL;
   }
-  JSONParser p;
-  if (!p.parse(trust_policy.c_str(), trust_policy.length())) {
-    ldout(s->cct, 20) << "ERROR: failed to parse assume role policy doc" << dendl;
+
+  bufferlist bl = bufferlist::static_from_string(trust_policy);
+  try {
+    const rgw::IAM::Policy p(s->cct, s->user->user_id.tenant, bl);
+  }
+  catch (rgw::IAM::PolicyParseException& e) {
+    ldout(s->cct, 20) << "failed to parse policy: " << e.what() << dendl;
     return -ERR_MALFORMED_DOC;
   }
+
   return 0;
 }
 
@@ -77,9 +129,8 @@ void RGWCreateRole::execute()
   if (op_ret < 0) {
     return;
   }
-  string uid;
-  s->user->user_id.to_str(uid);
-  RGWRole role(s->cct, store, role_name, role_path, trust_policy, uid);
+  RGWRole role(s->cct, store, role_name, role_path, trust_policy,
+                s->user->user_id.tenant, max_session_duration);
   op_ret = role.create(true);
 
   if (op_ret == -EEXIST) {
@@ -87,9 +138,16 @@ void RGWCreateRole::execute()
   }
 
   if (op_ret == 0) {
-    s->formatter->open_object_section("role");
+    s->formatter->open_object_section("CreateRoleResponse");
+    s->formatter->open_object_section("CreateRoleResult");
+    s->formatter->open_object_section("Role");
     role.dump(s->formatter);
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -111,12 +169,45 @@ void RGWDeleteRole::execute()
   if (op_ret < 0) {
     return;
   }
-  RGWRole role(s->cct, store, role_name);
-  op_ret = role.delete_obj();
+
+  op_ret = _role.delete_obj();
 
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_ROLE_FOUND;
   }
+
+  s->formatter->open_object_section("DeleteRoleResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
+}
+
+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(this,
+                              s,
+                              rgw::ARN(resource_name,
+                                            "role",
+                                             s->user->user_id.tenant, true),
+                                             get_op())) {
+    return -EACCES;
+  }
+  return 0;
 }
 
 int RGWGetRole::get_params()
@@ -137,17 +228,27 @@ void RGWGetRole::execute()
   if (op_ret < 0) {
     return;
   }
-  RGWRole role(s->cct, store, role_name);
+  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;
+    return;
   }
 
+  op_ret = _verify_permission(role);
+
   if (op_ret == 0) {
-    s->formatter->open_object_section("role");
+    s->formatter->open_object_section("GetRoleResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->open_object_section("GetRoleResult");
+    s->formatter->open_object_section("Role");
     role.dump(s->formatter);
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -175,16 +276,35 @@ void RGWModifyRole::execute()
   if (op_ret < 0) {
     return;
   }
-  RGWRole role(s->cct, store, role_name);
-  op_ret = role.get();
-  if (op_ret == -ENOENT) {
-    op_ret = -ERR_NO_ROLE_FOUND;
+
+  _role.update_trust_policy(trust_policy);
+  op_ret = _role.update();
+
+  s->formatter->open_object_section("UpdateAssumeRolePolicyResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
+}
+
+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(this, 
+                              s,
+                              rgw::ARN(),
+                              get_op())) {
+    return -EACCES;
+  }
+
+  return 0;
 }
 
 int RGWListRoles::get_params()
@@ -201,16 +321,23 @@ void RGWListRoles::execute()
     return;
   }
   vector<RGWRole> result;
-  op_ret = RGWRole::get_roles_by_path_prefix(store, s->cct, path_prefix, result);
+  op_ret = RGWRole::get_roles_by_path_prefix(store, s->cct, path_prefix, s->user->user_id.tenant, result);
 
   if (op_ret == 0) {
-    s->formatter->open_array_section("Roles");
+    s->formatter->open_array_section("ListRolesResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->open_array_section("ListRolesResult");
+    s->formatter->open_object_section("Roles");
     for (const auto& it : result) {
-      s->formatter->open_object_section("role");
+      s->formatter->open_object_section("member");
       it.dump(s->formatter);
       s->formatter->close_section();
     }
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -224,12 +351,14 @@ int RGWPutRolePolicy::get_params()
     ldout(s->cct, 20) << "ERROR: One of role name, policy name or perm policy is empty"<< dendl;
     return -EINVAL;
   }
-  JSONParser p;
-  if (!p.parse(perm_policy.c_str(), perm_policy.length())) {
-    ldout(s->cct, 20) << "ERROR: failed to parse perm role policy doc" << dendl;
+  bufferlist bl = bufferlist::static_from_string(perm_policy);
+  try {
+    const rgw::IAM::Policy p(s->cct, s->user->user_id.tenant, bl);
+  }
+  catch (rgw::IAM::PolicyParseException& e) {
+    ldout(s->cct, 20) << "failed to parse policy: " << e.what() << dendl;
     return -ERR_MALFORMED_DOC;
   }
-
   return 0;
 }
 
@@ -240,11 +369,15 @@ void RGWPutRolePolicy::execute()
     return;
   }
 
-  RGWRole role(s->cct, store, role_name);
-  op_ret = role.get();
+  _role.set_perm_policy(policy_name, perm_policy);
+  op_ret = _role.update();
+
   if (op_ret == 0) {
-    role.set_perm_policy(policy_name, perm_policy);
-    op_ret = role.update();
+    s->formatter->open_object_section("PutRolePolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -267,24 +400,23 @@ void RGWGetRolePolicy::execute()
     return;
   }
 
-  RGWRole role(g_ceph_context, store, role_name);
-  op_ret = role.get();
-
+  string perm_policy;
+  op_ret = _role.get_role_policy(policy_name, perm_policy);
   if (op_ret == -ENOENT) {
-    op_ret = -ERR_NO_ROLE_FOUND;
+    op_ret = -ERR_NO_SUCH_ENTITY;
   }
 
   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("GetRolePolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    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();
+    s->formatter->close_section();
   }
 }
 
@@ -306,21 +438,19 @@ void RGWListRolePolicies::execute()
     return;
   }
 
-  RGWRole role(g_ceph_context, store, role_name);
-  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_object_section("ListRolePoliciesResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->open_object_section("ListRolePoliciesResult");
+  s->formatter->open_array_section("PolicyNames");
+  for (const auto& it : policy_names) {
+    s->formatter->dump_string("member", it);
   }
+  s->formatter->close_section();
+  s->formatter->close_section();
+  s->formatter->close_section();
 }
 
 int RGWDeleteRolePolicy::get_params()
@@ -342,21 +472,18 @@ void RGWDeleteRolePolicy::execute()
     return;
   }
 
-  RGWRole role(g_ceph_context, store, role_name);
-  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();
   }
+
+  s->formatter->open_object_section("DeleteRolePoliciesResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
 }