]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/iam: load and evaluate group policies
authorCasey Bodley <cbodley@redhat.com>
Sun, 11 Feb 2024 17:24:05 +0000 (12:24 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:16 +0000 (13:09 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest.cc

index efc18003a5edeb0e01ab41fe7cc4d7c66ee5b096..9991ec57e3659237c403913941adef9da27dc49c 100644 (file)
@@ -353,27 +353,72 @@ get_public_access_conf_from_attr(const map<string, bufferlist>& attrs)
   return boost::none;
 }
 
-vector<Policy> get_iam_user_policy_from_attr(CephContext* cct,
-                        const map<string, bufferlist>& attrs,
-                        const string& tenant) {
-  vector<Policy> policies;
-  if (auto bl = attrs.find(RGW_ATTR_USER_POLICY); bl != attrs.end()) {
-    map<string, string> policy_map;
-    decode(policy_map, bl->second);
-    for (const auto& [name, policy] : policy_map) {
-      policies.emplace_back(cct, tenant, policy, false);
+static void load_inline_policy(CephContext* cct, const bufferlist& bl,
+                               const string& tenant,
+                               std::vector<rgw::IAM::Policy>& policies)
+{
+  map<string, string> policy_map;
+  decode(policy_map, bl);
+  for (const auto& [name, policy] : policy_map) {
+    policies.emplace_back(cct, tenant, policy, false);
+  }
+}
+
+static void load_managed_policy(CephContext* cct, const bufferlist& bl,
+                                const string& tenant,
+                                std::vector<rgw::IAM::Policy>& policies)
+{
+  rgw::IAM::ManagedPolicies policy_set;
+  decode(policy_set, bl);
+  for (const auto& arn : policy_set.arns) {
+    if (auto p = rgw::IAM::get_managed_policy(cct, arn); p) {
+      policies.push_back(std::move(*p));
     }
   }
-  if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
-    rgw::IAM::ManagedPolicies policy_set;
-    decode(policy_set, bl->second);
-    for (const auto& arn : policy_set.arns) {
-      if (auto p = rgw::IAM::get_managed_policy(cct, arn); p) {
-        policies.push_back(std::move(*p));
-      }
+}
+
+static void load_iam_group_policies(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    rgw::sal::Driver* driver,
+                                    const std::string& tenant,
+                                    std::string_view group_id,
+                                    std::vector<rgw::IAM::Policy>& policies)
+{
+  RGWGroupInfo info;
+  rgw::sal::Attrs attrs;
+  RGWObjVersionTracker objv;
+  int r = driver->load_group_by_id(dpp, y, group_id, info, attrs, objv);
+  if (r >= 0) {
+    CephContext* cct = dpp->get_cct();
+    if (auto bl = attrs.find(RGW_ATTR_IAM_POLICY); bl != attrs.end()) {
+      load_inline_policy(cct, bl->second, tenant, policies);
     }
+    if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
+      load_managed_policy(cct, bl->second, tenant, policies);
+    }
+  }
+}
+
+void load_iam_identity_policies(const DoutPrefixProvider* dpp,
+                                optional_yield y,
+                                rgw::sal::Driver* driver,
+                                const RGWUserInfo& info,
+                                const rgw::sal::Attrs& attrs,
+                                std::vector<rgw::IAM::Policy>& policies)
+{
+  // load user policies from user attrs
+  CephContext* cct = dpp->get_cct();
+  if (auto bl = attrs.find(RGW_ATTR_USER_POLICY); bl != attrs.end()) {
+    load_inline_policy(cct, bl->second, info.user_id.tenant, policies);
+  }
+  if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
+    load_managed_policy(cct, bl->second, info.user_id.tenant, policies);
+  }
+
+  // load each group and its policies
+  for (const auto& id : info.group_ids) {
+    load_iam_group_policies(dpp, y, driver, info.user_id.tenant, id, policies);
   }
-  return policies;
 }
 
 static int read_bucket_policy(const DoutPrefixProvider *dpp, 
@@ -639,12 +684,11 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d
     try {
       ret = s->user->read_attrs(dpp, y);
       if (ret == 0) {
-       auto user_policies = get_iam_user_policy_from_attr(s->cct,
-                                                          s->user->get_attrs(),
-                                                          s->user->get_tenant());
-          s->iam_identity_policies.insert(s->iam_identity_policies.end(),
-                                          std::make_move_iterator(user_policies.begin()),
-                                          std::make_move_iterator(user_policies.end()));
+        // load all user and group policies
+        load_iam_identity_policies(dpp, y, driver,
+                                   s->user->get_info(),
+                                   s->user->get_attrs(),
+                                   s->iam_identity_policies);
       } else {
         if (ret == -ENOENT)
           ret = 0;
index dd30734b682099e9adaef8184b8f4e1dff396038..ac2f0ba98cba4f2880c5b56ceb73f3946dbe8a78 100644 (file)
@@ -2070,9 +2070,14 @@ extern int rgw_build_object_policies(const DoutPrefixProvider *dpp, rgw::sal::Dr
                                     req_state *s, bool prefetch_data, optional_yield y);
 extern void rgw_build_iam_environment(rgw::sal::Driver* driver,
                                      req_state* s);
-extern std::vector<rgw::IAM::Policy> get_iam_user_policy_from_attr(CephContext* cct,
-                        const std::map<std::string, bufferlist>& attrs,
-                        const std::string& tenant);
+
+// load all user/group policies
+void load_iam_identity_policies(const DoutPrefixProvider* dpp,
+                                optional_yield y,
+                                rgw::sal::Driver* driver,
+                                const RGWUserInfo& info,
+                                const rgw::sal::Attrs& attrs,
+                                std::vector<rgw::IAM::Policy>& policies);
 
 inline int get_system_versioning_params(req_state *s,
                                        uint64_t *olh_epoch,
index 4185dee4e20e64b3cc9fdd53ed7da07758961d89..b44baf35dfe508b520fcad4684e051c1b4d6411e 100644 (file)
@@ -1878,11 +1878,11 @@ int RGWHandler_REST::init_permissions(RGWOp* op, optional_yield y)
     if (! s->user->get_id().empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) {
       try {
         if (auto ret = s->user->read_attrs(s, y); ! ret) {
-          auto user_policies = get_iam_user_policy_from_attr(s->cct, s->user->get_attrs(), s->user->get_tenant());
-          s->iam_identity_policies.insert(s->iam_identity_policies.end(),
-                                          std::make_move_iterator(user_policies.begin()),
-                                          std::make_move_iterator(user_policies.end()));
-
+          // load all user and group policies
+          load_iam_identity_policies(op, y, driver,
+                                     s->user->get_info(),
+                                     s->user->get_attrs(),
+                                     s->iam_identity_policies);
         }
       } catch (const std::exception& e) {
         ldpp_dout(op, -1) << "Error reading IAM User Policy: " << e.what() << dendl;