]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/auth: pass user policies into identities
authorCasey Bodley <cbodley@redhat.com>
Mon, 4 Mar 2024 21:10:17 +0000 (16:10 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:16 +0000 (13:09 -0400)
loading user policies in rgw_build_bucket_policies() doesn't work for
PostObj requests because we haven't authenticated yet at that point

instead, auth engines load/parse policies when they load the user info.
policies are passed into the auth identities and applied to req_state
via modify_request_state() similar to how RoleApplier handles role
policy

this also moves the load_iam_identity_policies() into rgw_auth.cc for
use by transform_old_authinfo()

Signed-off-by: Casey Bodley <cbodley@redhat.com>
14 files changed:
src/rgw/driver/rados/rgw_data_sync.cc
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.h
src/rgw/rgw_lib.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_process.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h
src/rgw/rgw_swift_auth.cc
src/rgw/rgw_swift_auth.h

index 77e676c81a0185314560756a640588e011827e78..dbea56d4de78e8fa0d65edbbb125719db217ca24 100644 (file)
@@ -2614,7 +2614,6 @@ class RGWUserPermHandler {
   rgw_user uid;
 
   struct _info {
-    RGWUserInfo user_info;
     rgw::IAM::Environment env;
     std::unique_ptr<rgw::auth::Identity> identity;
     RGWAccessControlPolicy user_acl;
@@ -2638,28 +2637,23 @@ class RGWUserPermHandler {
                                         uid(handler->uid),
                                         info(handler->info) {}
     int operate() override {
-      auto user_ctl = sync_env->driver->getRados()->ctl.user;
-
-      ret = user_ctl->get_info_by_uid(sync_env->dpp, uid, &info->user_info, null_yield);
+      auto user = sync_env->driver->get_user(uid);
+      ret = user->load_user(sync_env->dpp, null_yield);
       if (ret < 0) {
         return ret;
       }
 
       auto result = rgw::auth::transform_old_authinfo(
-          sync_env->dpp, null_yield, sync_env->driver, info->user_info);
+          sync_env->dpp, null_yield, sync_env->driver, user.get());
       if (!result) {
         return result.error();
       }
       info->identity = std::move(result).value();
 
-      map<string, bufferlist> uattrs;
-
-      ret = user_ctl->get_attrs_by_uid(sync_env->dpp, uid, &uattrs, null_yield);
-      if (ret == 0) {
-        ret = RGWUserPermHandler::policy_from_attrs(sync_env->cct, uattrs, &info->user_acl);
-      }
+      ret = RGWUserPermHandler::policy_from_attrs(
+          sync_env->cct, user->get_attrs(), &info->user_acl);
       if (ret == -ENOENT) {
-        info->user_acl.create_default(uid, info->user_info.display_name);
+        info->user_acl.create_default(uid, user->get_display_name());
       }
 
       return 0;
index b01451f047e2442465ac2fb353ba26a3d6ad9d04..6fe40836036262770ca9fcf4f7188d0428954537 100644 (file)
@@ -82,14 +82,119 @@ static bool match_account_or_tenant(const std::optional<RGWAccountInfo>& account
       || (tenant == expected);
 }
 
-auto transform_old_authinfo(const RGWUserInfo& user,
-                            std::optional<RGWAccountInfo> account)
+static void load_inline_policy(CephContext* cct, const bufferlist& bl,
+                               const string* tenant,
+                               std::vector<rgw::IAM::Policy>& policies)
+{
+  map<string, string> policy_map;
+  using ceph::decode;
+  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,
+                                std::vector<rgw::IAM::Policy>& policies)
+{
+  rgw::IAM::ManagedPolicies policy_set;
+  using ceph::decode;
+  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));
+    }
+  }
+}
+
+static int load_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) {
+    return r;
+  }
+
+  CephContext* cct = dpp->get_cct();
+  if (auto i = attrs.find(RGW_ATTR_IAM_POLICY); i != attrs.end()) {
+    load_inline_policy(cct, i->second, tenant, policies);
+  }
+  if (auto i = attrs.find(RGW_ATTR_MANAGED_POLICY); i != attrs.end()) {
+    load_managed_policy(cct, i->second, policies);
+  }
+  return 0;
+}
+
+int load_account_and_policies(const DoutPrefixProvider* dpp,
+                              optional_yield y,
+                              sal::Driver* driver,
+                              const RGWUserInfo& info,
+                              const sal::Attrs& attrs,
+                              std::optional<RGWAccountInfo>& account,
+                              std::vector<IAM::Policy>& policies)
+{
+  if (!info.account_id.empty()) {
+    account.emplace();
+    rgw::sal::Attrs attrs; // ignored
+    RGWObjVersionTracker objv; // ignored
+    int r = driver->load_account_by_id(dpp, y, info.account_id,
+                                       *account, attrs, objv);
+    if (r < 0) {
+      ldpp_dout(dpp, 1) << "ERROR: failed to load account "
+          << info.account_id << " for user " << info.user_id
+          << ": " << cpp_strerror(r) << dendl;
+      return r;
+    }
+  }
+
+  // non-account identity policy is restricted to the current tenant
+  const std::string* policy_tenant = info.account_id.empty()
+      ? &info.user_id.tenant : nullptr;
+
+  // 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, policy_tenant, policies);
+  }
+  if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
+    load_managed_policy(cct, bl->second, policies);
+  }
+
+  // load each group and its policies
+  for (const auto& id : info.group_ids) {
+    int r = load_group_policies(dpp, y, driver, policy_tenant, id, policies);
+    if (r == -ENOENT) {
+      // in multisite, metadata sync may race to replicate the user before its
+      // group. ignore ENOENT here so we don't reject all the user's requests
+      // in the meantime
+      ldpp_dout(dpp, 1) << "WARNING: skipping nonexistent group id " << id
+          << " for user " << info.user_id << ": " << cpp_strerror(r) << dendl;
+    } else if (r < 0) {
+      ldpp_dout(dpp, 1) << "ERROR: failed to load group id " << id
+          << " for user " << info.user_id << ": " << cpp_strerror(r) << dendl;
+      return r;
+    }
+  }
+
+  return 0;
+}
+
+static auto transform_old_authinfo(const RGWUserInfo& user,
+                                   std::optional<RGWAccountInfo> account,
+                                   std::vector<IAM::Policy> policies)
   -> std::unique_ptr<rgw::auth::Identity>
 {
   /* This class is not intended for public use. Should be removed altogether
    * with this function after moving all our APIs to the new authentication
    * infrastructure. */
-  class DummyIdentityApplier : public rgw::auth::Identity {
+  class DummyIdentityApplier : public rgw::auth::IdentityApplier {
     /* For this particular case it's OK to use rgw_user structure to convey
      * the identity info as this was the policy for doing that before the
      * new auth. */
@@ -99,15 +204,18 @@ auto transform_old_authinfo(const RGWUserInfo& user,
     const bool is_admin;
     const uint32_t type;
     const std::optional<RGWAccountInfo> account;
+    const std::vector<IAM::Policy> policies;
   public:
     DummyIdentityApplier(const RGWUserInfo& user,
-                         std::optional<RGWAccountInfo> account)
+                         std::optional<RGWAccountInfo> account,
+                         std::vector<IAM::Policy> policies)
       : id(user.user_id),
         display_name(user.display_name),
         path(user.path),
         is_admin(user.admin),
         type(user.type),
-        account(std::move(account))
+        account(std::move(account)),
+        policies(std::move(policies))
     {}
 
     ACLOwner get_aclowner() const {
@@ -176,33 +284,42 @@ auto transform_old_authinfo(const RGWUserInfo& user,
       out << "RGWDummyIdentityApplier(auth_id=" << id
           << ", is_admin=" << is_admin << ")";
     }
+
+    void load_acct_info(const DoutPrefixProvider* dpp,
+                        RGWUserInfo& user_info) const override {
+      // noop, this user info was passed in on construction
+    }
+
+    void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const {
+      // copy our identity policies into req_state
+      s->iam_identity_policies.insert(s->iam_identity_policies.end(),
+                                      policies.begin(), policies.end());
+    }
   };
 
-  return std::make_unique<DummyIdentityApplier>(user, std::move(account));
+  return std::make_unique<DummyIdentityApplier>(
+      user, std::move(account), std::move(policies));
 }
 
 auto transform_old_authinfo(const DoutPrefixProvider* dpp,
                             optional_yield y,
-                            rgw::sal::Driver* driver,
-                            const RGWUserInfo& user)
+                            sal::Driver* driver,
+                            sal::User* user)
   -> tl::expected<std::unique_ptr<Identity>, int>
 {
+  const RGWUserInfo& info = user->get_info();
+  const sal::Attrs& attrs = user->get_attrs();
+
   std::optional<RGWAccountInfo> account;
-  if (!user.account_id.empty()) {
-    account.emplace();
-    rgw::sal::Attrs attrs; // ignored
-    RGWObjVersionTracker objv; // ignored
-    int r = driver->load_account_by_id(dpp, y, user.account_id,
-                                       *account, attrs, objv);
-    if (r < 0) {
-      ldpp_dout(dpp, 1) << "ERROR: failed to load account "
-          << user.account_id << " for user " << user.user_id
-          << ": " << cpp_strerror(r) << dendl;
-      return tl::unexpected(r);
-    }
+  std::vector<IAM::Policy> policies;
+
+  int r = load_account_and_policies(dpp, y, driver, info, attrs,
+                                    account, policies);
+  if (r < 0) {
+    return tl::unexpected(r);
   }
 
-  return transform_old_authinfo(user, std::move(account));
+  return transform_old_authinfo(info, std::move(account), std::move(policies));
 }
 
 } /* namespace auth */
@@ -626,9 +743,13 @@ const std::string rgw::auth::RemoteApplier::AuthInfo::NO_ACCESS_KEY;
 ACLOwner rgw::auth::RemoteApplier::get_aclowner() const
 {
   ACLOwner owner;
-  // TODO: handle account ownership
-  owner.id = info.acct_user;
-  owner.display_name = info.acct_name;
+  if (account) {
+    owner.id = account->id;
+    owner.display_name = account->name;
+  } else {
+    owner.id = info.acct_user;
+    owner.display_name = info.acct_name;
+  }
   return owner;
 }
 
@@ -822,7 +943,10 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW
 
     if (user->load_user(dpp, null_yield) >= 0) {
       /* Succeeded. */
-      user_info = user->get_info();
+      (void) load_account_and_policies(dpp, null_yield, driver, user->get_info(),
+                                       user->get_attrs(), account, policies);
+
+      user_info = std::move(user->get_info());
       return;
     }
   }
@@ -833,7 +957,10 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW
        ;       /* suppress lookup for id used by "other" protocol */
   else if (user->load_user(dpp, null_yield) >= 0) {
     /* Succeeded. */
-    user_info = user->get_info();
+    (void) load_account_and_policies(dpp, null_yield, driver, user->get_info(),
+                                     user->get_attrs(), account, policies);
+
+    user_info = std::move(user->get_info());
     return;
   }
 
@@ -843,6 +970,13 @@ void rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp, RGW
   /* Succeeded if we are here (create_account() hasn't throwed). */
 }
 
+void rgw::auth::RemoteApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
+{
+  // copy our identity policies into req_state
+  s->iam_identity_policies.insert(s->iam_identity_policies.end(),
+                                  policies.begin(), policies.end());
+}
+
 /* rgw::auth::LocalApplier */
 /* static declaration */
 const std::string rgw::auth::LocalApplier::NO_SUBUSER;
@@ -940,6 +1074,13 @@ void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWU
   user_info = this->user_info;
 }
 
+void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
+{
+  // copy our identity policies into req_state
+  s->iam_identity_policies.insert(s->iam_identity_policies.end(),
+                                  policies.begin(), policies.end());
+}
+
 void rgw::auth::LocalApplier::write_ops_log_entry(rgw_log_entry& entry) const
 {
   entry.access_key_id = access_key_id;
@@ -1086,7 +1227,7 @@ rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const re
     rgw_get_anon_user(user_info);
 
     auto apl = \
-      apl_factory->create_apl_local(cct, s, user_info, std::nullopt,
+      apl_factory->create_apl_local(cct, s, user_info, std::nullopt, {},
                                     rgw::auth::LocalApplier::NO_SUBUSER,
                                     std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
     return result_t::grant(std::move(apl));
index 0e7eabe0c9fddf728a74c0065d6311465557d27f..90e60374550a1b7692222e2ab684beb5388eb34f 100644 (file)
@@ -98,18 +98,23 @@ inline std::ostream& operator<<(std::ostream& out,
 }
 
 
-// Return an identity for the given user and account.
-auto transform_old_authinfo(const RGWUserInfo& user,
-                            std::optional<RGWAccountInfo> account)
-  -> std::unique_ptr<rgw::auth::Identity>;
-
-// Return an identity for the given user, loading its account if necessary.
+// Return an identity for the given user after loading its account and policies.
 auto transform_old_authinfo(const DoutPrefixProvider* dpp,
                             optional_yield y,
-                            rgw::sal::Driver* driver,
-                            const RGWUserInfo& user)
+                            sal::Driver* driver,
+                            sal::User* user)
   -> tl::expected<std::unique_ptr<Identity>, int>;
 
+// Load the user account and all user/group policies. May throw
+// PolicyParseException on malformed policy.
+int load_account_and_policies(const DoutPrefixProvider* dpp,
+                              optional_yield y,
+                              sal::Driver* driver,
+                              const RGWUserInfo& info,
+                              const sal::Attrs& attrs,
+                              std::optional<RGWAccountInfo>& account,
+                              std::vector<IAM::Policy>& policies);
+
 
 /* Interface for classes applying changes to request state/RADOS store
  * imposed by a particular rgw::auth::Engine.
@@ -609,6 +614,10 @@ protected:
   const rgw::auth::ImplicitTenants& implicit_tenant_context;
   const rgw::auth::ImplicitTenants::implicit_tenant_flag_bits implicit_tenant_bit;
 
+  // account and policies are loaded by load_acct_info()
+  mutable std::optional<RGWAccountInfo> account;
+  mutable std::vector<IAM::Policy> policies;
+
   virtual void create_account(const DoutPrefixProvider* dpp,
                               const rgw_user& acct_user,
                               bool implicit_tenant,
@@ -638,6 +647,7 @@ public:
   uint32_t get_perm_mask() const override { return info.perm_mask; }
   void to_str(std::ostream& out) const override;
   void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
+  void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
   void write_ops_log_entry(rgw_log_entry& entry) const override;
   uint32_t get_identity_type() const override { return info.acct_type; }
   std::string get_acct_name() const override { return info.acct_name; }
@@ -669,6 +679,7 @@ class LocalApplier : public IdentityApplier {
 protected:
   const RGWUserInfo user_info;
   const std::optional<RGWAccountInfo> account;
+  const std::vector<IAM::Policy> policies;
   const std::string subuser;
   uint32_t perm_mask;
   const std::string access_key_id;
@@ -683,11 +694,13 @@ public:
   LocalApplier(CephContext* const cct,
                const RGWUserInfo& user_info,
                std::optional<RGWAccountInfo> account,
+               std::vector<IAM::Policy> policies,
                std::string subuser,
                const std::optional<uint32_t>& perm_mask,
                const std::string access_key_id)
     : user_info(user_info),
       account(std::move(account)),
+      policies(std::move(policies)),
       subuser(std::move(subuser)),
       perm_mask(perm_mask.value_or(RGW_PERM_INVALID)),
       access_key_id(access_key_id) {
@@ -707,6 +720,7 @@ public:
   }
   void to_str(std::ostream& out) const override;
   void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
+  void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
   uint32_t get_identity_type() const override { return user_info.type; }
   std::string get_acct_name() const override { return {}; }
   std::string get_subuser() const override { return subuser; }
@@ -722,6 +736,7 @@ public:
                                       const req_state* s,
                                       const RGWUserInfo& user_info,
                                       std::optional<RGWAccountInfo> account,
+                                      std::vector<IAM::Policy> policies,
                                       const std::string& subuser,
                                       const std::optional<uint32_t>& perm_mask,
                                       const std::string& access_key_id) const = 0;
index c7cde7c04969df4975ac545b7f117cf749c806bf..e1fe5163f025d290e7e51a5d1b5994f67be7f1ad 100644 (file)
@@ -57,12 +57,13 @@ class STSAuthStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             std::optional<RGWAccountInfo> account,
+                            std::vector<IAM::Policy> policies,
                             const std::string& subuser,
                             const std::optional<uint32_t>& perm_mask,
                             const std::string& access_key_id) const override {
     auto apl = rgw::auth::add_sysreq(cct, driver, s,
-      rgw::auth::LocalApplier(cct, user_info, std::move(account),
-                              subuser, perm_mask, access_key_id));
+      LocalApplier(cct, user_info, std::move(account), std::move(policies),
+                   subuser, perm_mask, access_key_id));
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
 
@@ -177,12 +178,13 @@ class AWSAuthStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             std::optional<RGWAccountInfo> account,
+                            std::vector<IAM::Policy> policies,
                             const std::string& subuser,
                             const std::optional<uint32_t>& perm_mask,
                             const std::string& access_key_id) const override {
     auto apl = rgw::auth::add_sysreq(cct, driver, s,
-      rgw::auth::LocalApplier(cct, user_info, std::move(account),
-                              subuser, perm_mask, access_key_id));
+      LocalApplier(cct, user_info, std::move(account), std::move(policies),
+                   subuser, perm_mask, access_key_id));
     /* TODO(rzarzynski): replace with static_ptr. */
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
index 85763e1a2671cd72e10aa72d733f070a8b99d256..665a03b62792192e2c11d1b233edd65602f0052e 100644 (file)
@@ -247,8 +247,14 @@ namespace rgw {
       /* FIXME: remove this after switching all handlers to the new
        * authentication infrastructure. */
       if (! s->auth.identity) {
-       s->auth.identity = rgw::auth::transform_old_authinfo(
-            io->get_user(), std::nullopt);
+        auto result = rgw::auth::transform_old_authinfo(
+            op, null_yield, env.driver, s->user.get());
+        if (!result) {
+          ret = result.error();
+          abort_req(s, op, ret);
+          goto done;
+        }
+       s->auth.identity = std::move(result).value();
       }
 
       ldpp_dout(s, 2) << "reading op permissions" << dendl;
@@ -378,8 +384,14 @@ namespace rgw {
     /* FIXME: remove this after switching all handlers to the new authentication
      * infrastructure. */
     if (! s->auth.identity) {
-      s->auth.identity = rgw::auth::transform_old_authinfo(
-          io_ctx.get_user(), std::nullopt);
+      auto result = rgw::auth::transform_old_authinfo(
+          op, null_yield, env.driver, s->user.get());
+      if (!result) {
+        ret = result.error();
+        abort_req(s, op, ret);
+        goto done;
+      }
+      s->auth.identity = std::move(result).value();
     }
 
     ldpp_dout(s, 2) << "reading op permissions" << dendl;
index 15bdf13c2f87a823e358822cfe6b3f1a2a6af43d..f30077ea484760e5639ae83c38b34adfda2594ea 100644 (file)
@@ -355,77 +355,6 @@ get_public_access_conf_from_attr(const map<string, bufferlist>& attrs)
   return boost::none;
 }
 
-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,
-                                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));
-    }
-  }
-}
-
-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, 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)
-{
-  // non-account identity policy is restricted to the current tenant
-  const std::string* policy_tenant = info.account_id.empty()
-      ? &info.user_id.tenant : nullptr;
-
-  // 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, policy_tenant, policies);
-  }
-  if (auto bl = attrs.find(RGW_ATTR_MANAGED_POLICY); bl != attrs.end()) {
-    load_managed_policy(cct, bl->second, policies);
-  }
-
-  // load each group and its policies
-  for (const auto& id : info.group_ids) {
-    load_iam_group_policies(dpp, y, driver, policy_tenant, id, policies);
-  }
-}
-
 static int read_bucket_policy(const DoutPrefixProvider *dpp, 
                               rgw::sal::Driver* driver,
                               req_state *s,
@@ -683,29 +612,6 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d
       return ret;
     }
   }
-  // We don't need user policies in case of STS token returned by AssumeRole,
-  // hence the check for user type
-  if (! s->user->get_id().empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) {
-    try {
-      ret = s->user->read_attrs(dpp, y);
-      if (ret == 0) {
-        // 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;
-        else ret = -EACCES;
-      }
-    } catch (const std::exception& e) {
-      ldpp_dout(dpp, -1) << "Error reading IAM User Policy: " << e.what() << dendl;
-      if (!s->system_request) {
-        ret = -EACCES;
-      }
-    }
-  }
 
   try {
     s->iam_policy = get_iam_policy_from_attr(s->cct, s->bucket_attrs);
index 016a6f38dd39bae65c92b369bbf326ea483979e3..9302017fc3efd54720eac7bea6c2c6bdae95846d 100644 (file)
@@ -2071,14 +2071,6 @@ extern int rgw_build_object_policies(const DoutPrefixProvider *dpp, rgw::sal::Dr
 extern void rgw_build_iam_environment(rgw::sal::Driver* driver,
                                      req_state* s);
 
-// 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,
                                        std::string *version_id)
index 7a7f70fa30d8448ef24a93485d60273b7600ed1b..10e544b577df17017649b57ea8dc3db569019d33 100644 (file)
@@ -367,7 +367,7 @@ int process_request(const RGWProcessEnv& penv,
      * infrastructure. */
     if (nullptr == s->auth.identity) {
       auto result = rgw::auth::transform_old_authinfo(
-          op, yield, driver, s->user->get_info());
+          op, yield, driver, s->user.get());
       if (!result) {
         abort_early(s, op, result.error(), handler, yield);
         goto done;
index b44baf35dfe508b520fcad4684e051c1b4d6411e..020309038eb3c39ba62b17d584733228e8a51d56 100644 (file)
@@ -1874,20 +1874,6 @@ static http_op op_from_method(const char *method)
 int RGWHandler_REST::init_permissions(RGWOp* op, optional_yield y)
 {
   if (op->get_type() == RGW_OP_CREATE_BUCKET) {
-    // We don't need user policies in case of STS token returned by AssumeRole, hence the check for user type
-    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) {
-          // 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;
-      }
-    }
     rgw_build_iam_environment(driver, s);
     return 0;
   }
index f88474c27e3a940bedf9777976154452e53be865..a9a6c3699d0d2e54c74e1d33a44b99d9f21ed986 100644 (file)
@@ -6292,18 +6292,11 @@ rgw::auth::s3::LocalEngine::authenticate(
   }*/
 
   std::optional<RGWAccountInfo> account;
-  if (!user->get_info().account_id.empty()) {
-    account.emplace();
-    rgw::sal::Attrs attrs; // ignored
-    RGWObjVersionTracker objv; // ignored
-    int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
-                                       *account, attrs, objv);
-    if (r < 0) {
-      ldpp_dout(dpp, 1) << "ERROR: failed to load account "
-          << user->get_info().account_id << " for user " << *user
-          << ": " << cpp_strerror(r) << dendl;
-      return result_t::deny(-EPERM);
-    }
+  std::vector<IAM::Policy> policies;
+  int ret = load_account_and_policies(dpp, y, driver, user->get_info(),
+                                      user->get_attrs(), account, policies);
+  if (ret < 0) {
+    return result_t::deny(-EPERM);
   }
 
   const auto iter = user->get_info().access_keys.find(access_key_id);
@@ -6315,8 +6308,9 @@ rgw::auth::s3::LocalEngine::authenticate(
 
   /* Ignore signature for HTTP OPTIONS */
   if (s->op_type == RGW_OP_OPTIONS_CORS) {
-    auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account),
-                                             k.subuser, std::nullopt, access_key_id);
+    auto apl = apl_factory->create_apl_local(
+        cct, s, user->get_info(), std::move(account), std::move(policies),
+        k.subuser, std::nullopt, access_key_id);
     return result_t::grant(std::move(apl), completer_factory(k.key));
   }
 
@@ -6335,8 +6329,9 @@ rgw::auth::s3::LocalEngine::authenticate(
     return result_t::reject(-ERR_SIGNATURE_NO_MATCH);
   }
 
-  auto apl = apl_factory->create_apl_local(cct, s, user->get_info(), std::move(account),
-                                           k.subuser, std::nullopt, access_key_id);
+  auto apl = apl_factory->create_apl_local(
+      cct, s, user->get_info(), std::move(account), std::move(policies),
+      k.subuser, std::nullopt, access_key_id);
   return result_t::grant(std::move(apl), completer_factory(k.key));
 }
 
@@ -6535,24 +6530,17 @@ rgw::auth::s3::STSEngine::authenticate(
     }
 
     std::optional<RGWAccountInfo> account;
-    if (!user->get_info().account_id.empty()) {
-      account.emplace();
-      rgw::sal::Attrs attrs; // ignored
-      RGWObjVersionTracker objv; // ignored
-      int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
-                                         *account, attrs, objv);
-      if (r < 0) {
-        ldpp_dout(dpp, 1) << "ERROR: failed to load account "
-            << user->get_info().account_id << " for user " << *user
-            << ": " << cpp_strerror(r) << dendl;
-        return result_t::deny(-EPERM);
-      }
+    std::vector<IAM::Policy> policies;
+    ret = load_account_and_policies(dpp, y, driver, user->get_info(),
+                                    user->get_attrs(), account, policies);
+    if (ret < 0) {
+      return result_t::deny(-EPERM);
     }
 
     string subuser;
-    auto apl = local_apl_factory->create_apl_local(cct, s, user->get_info(),
-                                                   std::move(account), subuser,
-                                                   token.perm_mask, std::string(_access_key_id));
+    auto apl = local_apl_factory->create_apl_local(
+        cct, s, user->get_info(), std::move(account), std::move(policies),
+        subuser, token.perm_mask, std::string(_access_key_id));
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   }
 }
index 129726f0584f86022ac1e0ae55923bd02a7e87ac..fa92f2ec88561c83232b1eb23689dcb6d924fdba 100644 (file)
@@ -2137,9 +2137,13 @@ bool RGWFormPost::is_integral()
   bool r = false;
 
   try {
-    get_owner_info(s, s->user->get_info());
-    s->auth.identity = rgw::auth::transform_old_authinfo(
-        s->user->get_info(), std::nullopt);
+    s->user = get_owner_info(s);
+    auto result = rgw::auth::transform_old_authinfo(
+        this, s->yield, driver, s->user.get());
+    if (!result) {
+      return false;
+    }
+    s->auth.identity = std::move(result).value();
   } catch (...) {
     ldpp_dout(this, 5) << "cannot get user_info of account's owner" << dendl;
     return false;
@@ -2180,8 +2184,8 @@ bool RGWFormPost::is_integral()
   return r;
 }
 
-void RGWFormPost::get_owner_info(const req_state* const s,
-                                   RGWUserInfo& owner_info) const
+auto RGWFormPost::get_owner_info(const req_state* const s) const
+  -> std::unique_ptr<rgw::sal::User>
 {
   /* We cannot use req_state::bucket_name because it isn't available
    * now. It will be initialized in RGWHandler_REST_SWIFT::postauth_init(). */
@@ -2243,7 +2247,7 @@ void RGWFormPost::get_owner_info(const req_state* const s,
     throw -EPERM;
   }
 
-  owner_info = user->get_info();
+  return user;
 }
 
 int RGWFormPost::get_params(optional_yield y)
index 154a069d73ffa5728a534f886a4024711d1661b9..18c80aea402586bf9e2f99d5e50b8281ab92d2c5 100644 (file)
@@ -254,8 +254,7 @@ class RGWFormPost : public RGWPostObj_ObjStore {
   bool is_next_file_to_upload() override;
   bool is_integral();
   bool is_non_expired();
-  void get_owner_info(const req_state* s,
-                      RGWUserInfo& owner_info) const;
+  std::unique_ptr<rgw::sal::User> get_owner_info(const req_state* s) const;
 
   parts_collection_t ctrl_parts;
   boost::optional<post_form_part> current_data_part;
index f191d3628af99371a52bab80c798277483e5bc4e..af60a0e275d224d0bddf6af98260962b41c3b6bb 100644 (file)
@@ -514,24 +514,17 @@ ExternalTokenEngine::authenticate(const DoutPrefixProvider* dpp,
   }
 
   std::optional<RGWAccountInfo> account;
-  if (!user->get_info().account_id.empty()) {
-    account.emplace();
-    rgw::sal::Attrs attrs; // ignored
-    RGWObjVersionTracker objv; // ignored
-    int r = driver->load_account_by_id(dpp, y, user->get_info().account_id,
-                                       *account, attrs, objv);
-    if (r < 0) {
-      ldpp_dout(dpp, 1) << "ERROR: failed to load account "
-          << user->get_info().account_id << " for user " << *user
-          << ": " << cpp_strerror(r) << dendl;
-      return result_t::deny(-EPERM);
-    }
+  std::vector<IAM::Policy> policies;
+  ret = load_account_and_policies(dpp, y, driver, user->get_info(),
+                                  user->get_attrs(), account, policies);
+  if (ret < 0) {
+    return result_t::deny(-EPERM);
   }
 
-  auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
-                                           std::move(account),
-                                           extract_swift_subuser(swift_user),
-                                           std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
+  auto apl = apl_factory->create_apl_local(
+      cct, s, user->get_info(), std::move(account),
+      std::move(policies), extract_swift_subuser(swift_user),
+      std::nullopt, LocalApplier::NO_ACCESS_KEY);
   return result_t::grant(std::move(apl));
 }
 
@@ -650,18 +643,11 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp,
   }
 
   std::optional<RGWAccountInfo> account;
-  if (!user->get_info().account_id.empty()) {
-    account.emplace();
-    rgw::sal::Attrs attrs; // ignored
-    RGWObjVersionTracker objv; // ignored
-    int r = driver->load_account_by_id(dpp, s->yield, user->get_info().account_id,
-                                       *account, attrs, objv);
-    if (r < 0) {
-      ldpp_dout(dpp, 1) << "ERROR: failed to load account "
-          << user->get_info().account_id << " for user " << *user
-          << ": " << cpp_strerror(r) << dendl;
-      return result_t::deny(-EPERM);
-    }
+  std::vector<IAM::Policy> policies;
+  ret = load_account_and_policies(dpp, s->yield, driver, user->get_info(),
+                                  user->get_attrs(), account, policies);
+  if (ret < 0) {
+    return result_t::deny(-EPERM);
   }
 
   ldpp_dout(dpp, 10) << "swift_user=" << swift_user << dendl;
@@ -698,10 +684,10 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp,
     return result_t::deny(-EPERM);
   }
 
-  auto apl = apl_factory->create_apl_local(cct, s, user->get_info(),
-                                           std::move(account),
-                                           extract_swift_subuser(swift_user),
-                                           std::nullopt, rgw::auth::LocalApplier::NO_ACCESS_KEY);
+  auto apl = apl_factory->create_apl_local(
+      cct, s, user->get_info(), std::move(account),
+      std::move(policies), extract_swift_subuser(swift_user),
+      std::nullopt, LocalApplier::NO_ACCESS_KEY);
   return result_t::grant(std::move(apl));
 }
 
index c5435556fd2a734fb3a46a8420c50cb6f2e0cbfa..9049c54f5ca6f0411242d33c3cc516fc650fca7a 100644 (file)
@@ -24,7 +24,7 @@ class TempURLApplier : public rgw::auth::LocalApplier {
 public:
   TempURLApplier(CephContext* const cct,
                  const RGWUserInfo& user_info)
-    : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER,
+    : LocalApplier(cct, user_info, std::nullopt, {}, LocalApplier::NO_SUBUSER,
                    std::nullopt, LocalApplier::NO_ACCESS_KEY)
   {}
 
@@ -156,7 +156,7 @@ class SwiftAnonymousApplier : public rgw::auth::LocalApplier {
   public:
     SwiftAnonymousApplier(CephContext* const cct,
                           const RGWUserInfo& user_info)
-      : LocalApplier(cct, user_info, std::nullopt, LocalApplier::NO_SUBUSER,
+      : LocalApplier(cct, user_info, std::nullopt, {}, LocalApplier::NO_SUBUSER,
                      std::nullopt, LocalApplier::NO_ACCESS_KEY) {
     }
     bool is_admin_of(const rgw_owner& o) const {return false;}
@@ -240,14 +240,15 @@ class DefaultStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             std::optional<RGWAccountInfo> account,
+                            std::vector<IAM::Policy> policies,
                             const std::string& subuser,
                             const std::optional<uint32_t>& perm_mask,
                             const std::string& access_key_id) const override {
     auto apl = \
       rgw::auth::add_3rdparty(driver, rgw_user(s->account_name),
         rgw::auth::add_sysreq(cct, driver, s,
-          rgw::auth::LocalApplier(cct, user_info, std::move(account),
-                                  subuser, perm_mask, access_key_id)));
+          LocalApplier(cct, user_info, std::move(account), std::move(policies),
+                       subuser, perm_mask, access_key_id)));
     /* TODO(rzarzynski): replace with static_ptr. */
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }