]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Adding a new applier for Roles. 25180/head
authorPritha Srivastava <prsrivas@redhat.com>
Mon, 10 Dec 2018 06:19:06 +0000 (11:49 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Wed, 12 Dec 2018 09:08:38 +0000 (14:38 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
12 files changed:
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.h
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_json_enc.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/rgw/rgw_swift_auth.cc
src/rgw/rgw_swift_auth.h

index e8799c44945065a3ca9fc9c96bd595fdd584d27f..11de9a7791ed5dc6e4a25e9ded48373d3e498f7c 100644 (file)
@@ -535,7 +535,39 @@ 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
+void rgw::auth::RoleApplier::to_str(std::ostream& out) const {
+  out << "rgw::auth::LocalApplier(role name =" << role_name;
+  for (auto policy : role_policies) {
+    out << ", role policy =" << policy;
+  }
+  out << ")";
+}
+
+bool rgw::auth::RoleApplier::is_identity(const idset_t& ids) const {
+  for (auto& p : ids) {
+    string name;
+    string tenant = p.get_tenant();
+    if (tenant.empty()) {
+      name = p.get_id();
+    } else {
+      name = tenant + "$" + p.get_id();
+    }
+    if (p.is_wildcard()) {
+      return true;
+    } else if (p.is_role() && name == role_name) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */
+{
+  /* Load the user id */
+  user_info.user_id = this->user_id;
+}
+
+void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const
 {
   for (auto it : role_policies) {
     try {
@@ -562,7 +594,7 @@ rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const re
     auto apl = \
       apl_factory->create_apl_local(cct, s, user_info,
                                     rgw::auth::LocalApplier::NO_SUBUSER,
-                                    boost::none, boost::none);
+                                    boost::none);
     return result_t::grant(std::move(apl));
   }
 }
index 194ce53ddba23cfef927bed676bd5bd947f0856e..d141479a767b77ecd22196c7d6a2c20cb9aab80f 100644 (file)
@@ -455,7 +455,6 @@ class LocalApplier : public IdentityApplier {
 protected:
   const RGWUserInfo user_info;
   const std::string subuser;
-  vector<std::string> role_policies;
   uint32_t perm_mask;
 
   uint32_t get_perm_mask(const std::string& subuser_name,
@@ -467,13 +466,9 @@ public:
   LocalApplier(CephContext* const cct,
                const RGWUserInfo& user_info,
                std::string subuser,
-               const boost::optional<vector<std::string> >& role_policies,
                const boost::optional<uint32_t>& perm_mask)
     : user_info(user_info),
       subuser(std::move(subuser)) {
-    if (role_policies) {
-      this->role_policies = role_policies.get();
-    }
     if (perm_mask) {
       this->perm_mask = perm_mask.get();
     } else {
@@ -497,7 +492,6 @@ public:
   void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
   uint32_t get_identity_type() const override { return TYPE_RGW; }
   string get_acct_name() const override { return {}; }
-  void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
 
   struct Factory {
     virtual ~Factory() {}
@@ -505,11 +499,54 @@ public:
                                       const req_state* s,
                                       const RGWUserInfo& user_info,
                                       const std::string& subuser,
-                                      const boost::optional<vector<std::string> >& role_policies,
                                       const boost::optional<uint32_t>& perm_mask) const = 0;
     };
 };
 
+class RoleApplier : public IdentityApplier {
+protected:
+  const string role_name;
+  const rgw_user user_id;
+  vector<std::string> role_policies;
+
+public:
+
+  RoleApplier(CephContext* const cct,
+               const string& role_name,
+               const rgw_user& user_id,
+               const vector<std::string>& role_policies)
+    : role_name(role_name),
+      user_id(user_id),
+      role_policies(role_policies) {}
+
+  uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
+    return 0;
+  }
+  bool is_admin_of(const rgw_user& uid) const override {
+    return false;
+  }
+  bool is_owner_of(const rgw_user& uid) const override {
+    return false;
+  }
+  bool is_identity(const idset_t& ids) const override;
+  uint32_t get_perm_mask() const override {
+    return RGW_PERM_NONE;
+  }
+  void to_str(std::ostream& out) const override;
+  void load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const override; /* out */
+  uint32_t get_identity_type() const override { return TYPE_ROLE; }
+  string get_acct_name() const override { return {}; }
+  void modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const override;
+
+  struct Factory {
+    virtual ~Factory() {}
+    virtual aplptr_t create_apl_role( CephContext* cct,
+                                      const req_state* s,
+                                      const string& role_name,
+                                      const rgw_user& user_id,
+                                      const vector<std::string>& role_policies) const = 0;
+    };
+};
 
 /* The anonymous abstract engine. */
 class AnonymousEngine : public Engine {
index f8ea7480be694853276ae9e1882a88ebfec71239..2afbe31c07bcee03c2489bb75cf4a79da54f7483 100644 (file)
@@ -34,7 +34,8 @@ bool is_time_skew_ok(time_t t);
 
 class STSAuthStrategy : public rgw::auth::Strategy,
                         public rgw::auth::RemoteApplier::Factory,
-                        public rgw::auth::LocalApplier::Factory {
+                        public rgw::auth::LocalApplier::Factory,
+                        public rgw::auth::RoleApplier::Factory {
   typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
   RGWRados* const store;
 
@@ -55,13 +56,21 @@ class STSAuthStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser,
-                            const boost::optional<vector<std::string> >& role_policies,
                             const boost::optional<uint32_t>& perm_mask) const override {
     auto apl = rgw::auth::add_sysreq(cct, store, s,
-      rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask));
+      rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask));
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
 
+  aplptr_t create_apl_role(CephContext* const cct,
+                            const req_state* const s,
+                            const string& role_name,
+                            const rgw_user& user_id,
+                            const vector<std::string>& role_policies) const override {
+    auto apl = rgw::auth::add_sysreq(cct, store, s,
+      rgw::auth::RoleApplier(cct, role_name, user_id, role_policies));
+    return aplptr_t(new decltype(apl)(std::move(apl)));
+  }
 public:
   STSAuthStrategy(CephContext* const cct,
                        RGWRados* const store,
@@ -69,7 +78,8 @@ public:
     : store(store),
       sts_engine(cct, store, *ver_abstractor,
                   static_cast<rgw::auth::LocalApplier::Factory*>(this),
-                  static_cast<rgw::auth::RemoteApplier::Factory*>(this)) {
+                  static_cast<rgw::auth::RemoteApplier::Factory*>(this),
+                  static_cast<rgw::auth::RoleApplier::Factory*>(this)) {
       if (cct->_conf->rgw_s3_auth_use_sts) {
         add_engine(Control::SUFFICIENT, sts_engine);
       }
@@ -157,10 +167,9 @@ class AWSAuthStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser,
-                            const boost::optional<vector<std::string> >& role_policies,
                             const boost::optional<uint32_t>& perm_mask) const override {
     auto apl = rgw::auth::add_sysreq(cct, store, s,
-      rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask));
+      rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask));
     /* TODO(rzarzynski): replace with static_ptr. */
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
index afe1f3ada36e11ffc94dac6f0efc4ca30cf0c69b..e1f62cb12a8687038dc31f1a78ebe73b33a963a7 100644 (file)
@@ -1123,10 +1123,6 @@ bool verify_user_permission(const DoutPrefixProvider* dpp,
     return verify_user_permission_no_policy(dpp, s, user_acl, perm);
   }
 
-  if (usr_policy_res == Effect::Pass) {
-    return false;
-  }
-
   return false;
 }
 
@@ -1134,7 +1130,7 @@ bool verify_user_permission_no_policy(const DoutPrefixProvider* dpp, struct req_
                             RGWAccessControlPolicy * const user_acl,
                             const int perm)
 {
-  if (s->user->type == TYPE_ROLE)
+  if (s->auth.identity->get_identity_type() == TYPE_ROLE)
     return false;
 
   /* S3 doesn't support account ACLs. */
index 0a002fd4a25ac3f144d0ad464655f97f9b4c6add..549b3a36f7b3da3b29080f0e288257f2a91fb75a 100644 (file)
@@ -629,7 +629,9 @@ void encode_json(const char *name, const RGWUserCaps& val, Formatter *f);
 
 void decode_json_obj(obj_version& v, JSONObj *obj);
 
-enum RGWUserSourceType
+
+
+enum RGWIdentityType
 {
   TYPE_NONE=0,
   TYPE_RGW=1,
index 1b7f7b2ed6cbdba62e4281e71a0c95b896e2af50..c9f50941111b5580b8a13c01ea5624eb8b155f63 100644 (file)
@@ -478,7 +478,7 @@ void RGWUserInfo::dump(Formatter *f) const
   encode_json("temp_url_keys", temp_url_keys, f);
 
   string user_source_type;
-  switch ((RGWUserSourceType)type) {
+  switch ((RGWIdentityType)type) {
   case TYPE_RGW:
     user_source_type = "rgw";
     break;
index c76cfd0f612278cce7dbfd5ef83db2a18685884f..98869f9a78e3332651fa023c0fbb5448f14795ba 100644 (file)
@@ -572,7 +572,7 @@ int rgw_build_bucket_policies(RGWRados* store, struct req_state* s)
   }
   // We don't need user policies in case of STS token returned by AssumeRole,
   // hence the check for user type
-  if (! s->user->user_id.empty() && s->user->type != TYPE_ROLE) {
+  if (! s->user->user_id.empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) {
     try {
       map<string, bufferlist> uattrs;
       if (ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, uattrs); ! ret) {
index f7142731b41df71862e66ce3ed1a8d97354f8523..4c0130d9d4a1b2e9a1370f9dc73be658d5c4481c 100644 (file)
@@ -1816,7 +1816,7 @@ int RGWHandler_REST::init_permissions(RGWOp* op)
 {
   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->user_id.empty() && s->user->type != TYPE_ROLE) {
+    if (! s->user->user_id.empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) {
       try {
         map<string, bufferlist> uattrs;
         if (auto ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, uattrs); ! ret) {
index 686b5f3700945e3e8ca98a8d4463a62fe4c57e69..b4201765b8e2358a90f658c52aa6fb6d207c4bbb 100644 (file)
@@ -4345,7 +4345,7 @@ rgw::auth::s3::LocalEngine::authenticate(
     return result_t::deny(-ERR_SIGNATURE_NO_MATCH);
   }
 
-  auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser, boost::none, boost::none);
+  auto apl = apl_factory->create_apl_local(cct, s, user_info, k.subuser, boost::none);
   return result_t::grant(std::move(apl), completer_factory(k.key));
 }
 
@@ -4465,7 +4465,9 @@ rgw::auth::s3::STSEngine::authenticate(
 
   // Get all the authorization info
   RGWUserInfo user_info;
+  rgw_user user_id;
   vector<string> role_policies;
+  string role_name;
   if (! token.roleId.empty()) {
     RGWRole role(s->cct, store, token.roleId);
     if (role.get_by_id() < 0) {
@@ -4482,9 +4484,10 @@ rgw::auth::s3::STSEngine::authenticate(
       role_policies.push_back(std::move(token.policy));
     }
     // This is mostly needed to assign the owner of a bucket during its creation
-    user_info.user_id = token.user;
-    user_info.type = token.acct_type;
+    user_id = token.user;
+    role_name = role.get_name();
   }
+
   if (! token.user.empty() && token.acct_type != TYPE_ROLE) {
     // get user info
     int ret = rgw_get_user_info_by_uid(store, token.user, user_info, NULL);
@@ -4498,9 +4501,12 @@ rgw::auth::s3::STSEngine::authenticate(
     auto apl = remote_apl_factory->create_apl_remote(cct, s, get_acl_strategy(),
                                             get_creds_info(token));
     return result_t::grant(std::move(apl), completer_factory(boost::none));
-  } else {
+  } else if (token.acct_type == TYPE_ROLE) {
+    auto apl = role_apl_factory->create_apl_role(cct, s, role_name, user_id, role_policies);
+    return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
+  } else { // This is for all local users of type TYPE_RGW or TYPE_NONE
     string subuser;
-    auto apl = local_apl_factory->create_apl_local(cct, s, user_info, subuser, role_policies, token.perm_mask);
+    auto apl = local_apl_factory->create_apl_local(cct, s, user_info, subuser, token.perm_mask);
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   }
 }
index 1decd9bf59ac617316dfe0e6e49a5840683cc3a5..c425f97c7f3c01b3d33beacfbfd400713233c021 100644 (file)
@@ -892,6 +892,7 @@ class STSEngine : public AWSEngine {
   RGWRados* const store;
   const rgw::auth::LocalApplier::Factory* const local_apl_factory;
   const rgw::auth::RemoteApplier::Factory* const remote_apl_factory;
+  const rgw::auth::RoleApplier::Factory* const role_apl_factory;
 
   using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
   using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
@@ -915,11 +916,13 @@ public:
               RGWRados* const store,
               const VersionAbstractor& ver_abstractor,
               const rgw::auth::LocalApplier::Factory* const local_apl_factory,
-              const rgw::auth::RemoteApplier::Factory* const remote_apl_factory)
+              const rgw::auth::RemoteApplier::Factory* const remote_apl_factory,
+              const rgw::auth::RoleApplier::Factory* const role_apl_factory)
     : AWSEngine(cct, ver_abstractor),
       store(store),
       local_apl_factory(local_apl_factory),
-      remote_apl_factory(remote_apl_factory) {
+      remote_apl_factory(remote_apl_factory),
+      role_apl_factory(role_apl_factory) {
   }
 
   using AWSEngine::authenticate;
@@ -966,10 +969,9 @@ public:
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser,
-                            const boost::optional<vector<std::string> >& role_policies,
                             const boost::optional<uint32_t>& perm_mask) const override {
       return aplptr_t(
-        new rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask));
+        new rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask));
   }
 };
 
index 4acd8fc82608d1ede9d213924243e1d2f643b60f..36248cf492afd4abf31cd4bf8b0b71e2f8cec872 100644 (file)
@@ -434,7 +434,7 @@ ExternalTokenEngine::authenticate(const DoutPrefixProvider* dpp,
 
   auto apl = apl_factory->create_apl_local(cct, s, tmp_uinfo,
                                            extract_swift_subuser(swift_user),
-                                           boost::none, boost::none);
+                                           boost::none);
   return result_t::grant(std::move(apl));
 }
 
@@ -585,7 +585,7 @@ SignedTokenEngine::authenticate(const DoutPrefixProvider* dpp,
 
   auto apl = apl_factory->create_apl_local(cct, s, user_info,
                                            extract_swift_subuser(swift_user),
-                                           boost::none, boost::none);
+                                           boost::none);
   return result_t::grant(std::move(apl));
 }
 
index 5bfd2749a57c49d0576212978f9c273e796f9182..38377764b52e3e090f07e3ba452fba10b06a81d1 100644 (file)
@@ -21,7 +21,7 @@ class TempURLApplier : public rgw::auth::LocalApplier {
 public:
   TempURLApplier(CephContext* const cct,
                  const RGWUserInfo& user_info)
-    : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none, boost::none) {
+    : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) {
   };
 
   void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */
@@ -205,12 +205,11 @@ class DefaultStrategy : public rgw::auth::Strategy,
                             const req_state* const s,
                             const RGWUserInfo& user_info,
                             const std::string& subuser,
-                            const boost::optional<vector<std::string> >& role_policies,
                             const boost::optional<uint32_t>& perm_mask) const override {
     auto apl = \
       rgw::auth::add_3rdparty(store, s->account_name,
         rgw::auth::add_sysreq(cct, store, s,
-          rgw::auth::LocalApplier(cct, user_info, subuser, role_policies, perm_mask)));
+          rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)));
     /* TODO(rzarzynski): replace with static_ptr. */
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }