formatter->flush(cout);
}
-static void show_role_info(RGWRole& role, Formatter* formatter)
+static void show_role_info(rgw::sal::RGWRole* role, Formatter* formatter)
{
formatter->open_object_section("role");
- role.dump(formatter);
+ role->dump(formatter);
formatter->close_section();
formatter->flush(cout);
}
-static void show_roles_info(vector<RGWRole>& roles, Formatter* formatter)
+static void show_roles_info(vector<std::unique_ptr<rgw::sal::RGWRole>>& roles, Formatter* formatter)
{
formatter->open_array_section("Roles");
for (const auto& it : roles) {
formatter->open_object_section("role");
- it.dump(formatter);
+ it->dump(formatter);
formatter->close_section();
}
formatter->close_section();
cerr << "failed to parse policy: " << e.what() << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, path, assume_role_doc, tenant);
- ret = role.create(dpp(), true, null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant, path, assume_role_doc);
+ ret = role->create(dpp(), true, null_yield);
if (ret < 0) {
return -ret;
}
- show_role_info(role, formatter.get());
+ show_role_info(role.get(), formatter.get());
return 0;
}
case OPT::ROLE_DELETE:
cerr << "ERROR: empty role name" << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.delete_obj(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->delete_obj(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
cerr << "ERROR: empty role name" << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
- show_role_info(role, formatter.get());
+ show_role_info(role.get(), formatter.get());
return 0;
}
case OPT::ROLE_MODIFY:
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
- role.update_trust_policy(assume_role_doc);
- ret = role.update(null_yield);
+ role->update_trust_policy(assume_role_doc);
+ ret = role->update(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
}
case OPT::ROLE_LIST:
{
- vector<RGWRole> result;
- ret = RGWRole::get_roles_by_path_prefix(dpp(), store, g_ceph_context, path_prefix, tenant, result, null_yield);
+ vector<std::unique_ptr<rgw::sal::RGWRole>> result;
+ ret = store->get_roles(dpp(), null_yield, path_prefix, tenant, result);
if (ret < 0) {
return -ret;
}
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
- role.set_perm_policy(policy_name, perm_policy_doc);
- ret = role.update(null_yield);
+ role->set_perm_policy(policy_name, perm_policy_doc);
+ ret = role->update(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
cerr << "ERROR: Role name is empty" << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
- std::vector<string> policy_names = role.get_role_policy_names();
+ std::vector<string> policy_names = role->get_role_policy_names();
show_policy_names(policy_names, formatter.get());
return 0;
}
cerr << "ERROR: policy name is empty" << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- int ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ int ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
string perm_policy;
- ret = role.get_role_policy(policy_name, perm_policy);
+ ret = role->get_role_policy(dpp(), policy_name, perm_policy);
if (ret < 0) {
return -ret;
}
cerr << "ERROR: policy name is empty" << std::endl;
return -EINVAL;
}
- RGWRole role(g_ceph_context, store, role_name, tenant);
- ret = role.get(dpp(), null_yield);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name, tenant);
+ ret = role->get(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
- ret = role.delete_policy(policy_name);
+ ret = role->delete_policy(dpp(), policy_name);
if (ret < 0) {
return -ret;
}
- ret = role.update(null_yield);
+ ret = role->update(dpp(), null_yield);
if (ret < 0) {
return -ret;
}
cerr << "ERROR: invalid script context: " << *str_script_ctx << ". must be one of: preRequest, postRequest" << std::endl;
return EINVAL;
}
- rc = rgw::lua::write_script(store, tenant, null_yield, script_ctx, script);
+ rc = rgw::lua::write_script(dpp(), store, tenant, null_yield, script_ctx, script);
if (rc < 0) {
cerr << "ERROR: failed to put script. error: " << rc << std::endl;
return -rc;
cerr << "ERROR: invalid script context: " << *str_script_ctx << ". must be one of: preRequest, postRequest" << std::endl;
return EINVAL;
}
- const auto rc = rgw::lua::delete_script(store, tenant, null_yield, script_ctx);
+ const auto rc = rgw::lua::delete_script(dpp(), store, tenant, null_yield, script_ctx);
if (rc < 0) {
cerr << "ERROR: failed to remove script. error: " << rc << std::endl;
return -rc;
int read_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, std::string& script)
{
- RGWObjVersionTracker objv_tracker;
+ auto lua_script = store->get_lua_script_manager();
- rgw_raw_obj obj(store->get_zone()->get_params().log_pool, script_oid(ctx, tenant));
-
- bufferlist bl;
-
- const auto rc = store->get_system_obj(
- dpp,
- obj.pool,
- obj.oid,
- bl,
- &objv_tracker,
- nullptr,
- y,
- nullptr,
- nullptr);
-
- if (rc < 0) {
- return rc;
- }
-
- auto iter = bl.cbegin();
- try {
- ceph::decode(script, iter);
- } catch (buffer::error& err) {
- return -EIO;
- }
-
- return 0;
+ return lua_script->get(dpp, y, script_oid(ctx, tenant), script);
}
-int write_script(rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script)
+int write_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script)
{
- RGWObjVersionTracker objv_tracker;
-
- rgw_raw_obj obj(store->get_zone()->get_params().log_pool, script_oid(ctx, tenant));
-
- bufferlist bl;
- ceph::encode(script, bl);
+ auto lua_script = store->get_lua_script_manager();
- const auto rc = store->put_system_obj(
- obj.pool,
- obj.oid,
- bl,
- false,
- &objv_tracker,
- real_time(),
- y);
-
- if (rc < 0) {
- return rc;
- }
-
- return 0;
+ return lua_script->put(dpp, y, script_oid(ctx, tenant), script);
}
-int delete_script(rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx)
+int delete_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx)
{
- RGWObjVersionTracker objv_tracker;
-
- rgw_raw_obj obj(store->get_zone()->get_params().log_pool, script_oid(ctx, tenant));
+ auto lua_script = store->get_lua_script_manager();
- const auto rc = store->delete_system_obj(
- obj.pool,
- obj.oid,
- &objv_tracker,
- y);
-
- if (rc < 0 && rc != -ENOENT) {
- return rc;
- }
-
- return 0;
+ return lua_script->del(dpp, y, script_oid(ctx, tenant));
}
#ifdef WITH_RADOSGW_LUA_PACKAGES
bool verify(const std::string& script, std::string& err_msg);
// store a lua script in a context
-int write_script(rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script);
+int write_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, const std::string& script);
// read the stored lua script from a context
int read_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx, std::string& script);
// delete the stored lua script from a context
-int delete_script(rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx);
+int delete_script(const DoutPrefixProvider *dpp, rgw::sal::Store* store, const std::string& tenant, optional_yield y, context ctx);
#ifdef WITH_RADOSGW_LUA_PACKAGES
#include <set>
#define dout_subsys ceph_subsys_rgw
+namespace rgw { namespace sal {
+
const string RGWOIDCProvider::oidc_url_oid_prefix = "oidc_url.";
const string RGWOIDCProvider::oidc_arn_prefix = "arn:aws:iam::";
-int RGWOIDCProvider::store_url(const string& url, bool exclusive,
- optional_yield y)
-{
- using ceph::encode;
- string oid = tenant + get_url_oid_prefix() + url;
-
- bufferlist bl;
- encode(*this, bl);
- return store->put_system_obj(store->get_zone()->get_params().oidc_pool, oid,
- bl, exclusive, NULL, real_time(), y);
-}
-
int RGWOIDCProvider::get_tenant_url_from_arn(string& tenant, string& url)
{
auto provider_arn = rgw::ARN::parse(arn);
{
int ret;
- if (! validate_input()) {
+ if (! validate_input(dpp)) {
return -EINVAL;
}
sprintf(buf + strlen(buf),".%dZ",(int)tv.tv_usec/1000);
creation_date.assign(buf, strlen(buf));
- auto& pool = store->get_zone()->get_params().oidc_pool;
- ret = store_url(idp_url, exclusive, y);
+ ret = store_url(dpp, idp_url, exclusive, y);
if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: storing role info in pool: " << pool.name << ": "
+ ldpp_dout(dpp, 0) << "ERROR: storing role info in OIDC pool: "
<< provider_url << ": " << cpp_strerror(-ret) << dendl;
return ret;
}
return 0;
}
-int RGWOIDCProvider::delete_obj(optional_yield y)
-{
- auto& pool = store->get_zone()->get_params().oidc_pool;
-
- string url, tenant;
- auto ret = get_tenant_url_from_arn(tenant, url);
- if (ret < 0) {
- ldout(cct, 0) << "ERROR: failed to parse arn" << dendl;
- return -EINVAL;
- }
-
- if (this->tenant != tenant) {
- ldout(cct, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
- << tenant << ": " << dendl;
- return -EINVAL;
- }
-
- // Delete url
- string oid = tenant + get_url_oid_prefix() + url;
- ret = store->delete_system_obj(pool, oid, NULL, y);
- if (ret < 0) {
- ldout(cct, 0) << "ERROR: deleting oidc url from pool: " << pool.name << ": "
- << provider_url << ": " << cpp_strerror(-ret) << dendl;
- }
-
- return ret;
-}
-
int RGWOIDCProvider::get(const DoutPrefixProvider *dpp)
{
string url, tenant;
JSONDecoder::decode_json("OpenIDConnectProviderArn", arn, obj);
}
-int RGWOIDCProvider::read_url(const DoutPrefixProvider *dpp, const string& url, const string& tenant)
-{
- auto& pool = store->get_zone()->get_params().oidc_pool;
- string oid = tenant + get_url_oid_prefix() + url;
- bufferlist bl;
-
- int ret = store->get_system_obj(dpp, pool, oid, bl, NULL, NULL, null_yield);
- if (ret < 0) {
- return ret;
- }
-
- try {
- using ceph::decode;
- auto iter = bl.cbegin();
- decode(*this, iter);
- } catch (buffer::error& err) {
- ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
- ": " << url << dendl;
- return -EIO;
- }
-
- return 0;
-}
-
-bool RGWOIDCProvider::validate_input()
+bool RGWOIDCProvider::validate_input(const DoutPrefixProvider *dpp)
{
if (provider_url.length() > MAX_OIDC_URL_LEN) {
- ldout(cct, 0) << "ERROR: Invalid length of url " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid length of url " << dendl;
return false;
}
if (client_ids.size() > MAX_OIDC_NUM_CLIENT_IDS) {
- ldout(cct, 0) << "ERROR: Invalid number of client ids " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid number of client ids " << dendl;
return false;
}
}
if (thumbprints.size() > MAX_OIDC_NUM_THUMBPRINTS) {
- ldout(cct, 0) << "ERROR: Invalid number of thumbprints " << thumbprints.size() << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid number of thumbprints " << thumbprints.size() << dendl;
return false;
}
return true;
}
-int RGWOIDCProvider::get_providers(const DoutPrefixProvider *dpp,
- rgw::sal::Store* store,
- const string& tenant,
- vector<RGWOIDCProvider>& providers)
-{
- auto pool = store->get_zone()->get_params().oidc_pool;
- string prefix = tenant + oidc_url_oid_prefix;
-
- //Get the filtered objects
- list<string> result;
- bool is_truncated;
- RGWListRawObjsCtx ctx;
- do {
- list<string> oids;
- int r = store->list_raw_objects(pool, prefix, 1000, ctx, oids, &is_truncated);
- if (r < 0) {
- ldpp_dout(dpp, 0) << "ERROR: listing filtered objects failed: " << pool.name << ": "
- << prefix << ": " << cpp_strerror(-r) << dendl;
- return r;
- }
- for (const auto& iter : oids) {
- RGWOIDCProvider provider(store->ctx(), store);
- bufferlist bl;
-
- int ret = store->get_system_obj(dpp, pool, iter, bl, NULL, NULL, null_yield);
- if (ret < 0) {
- return ret;
- }
-
- try {
- using ceph::decode;
- auto iter = bl.cbegin();
- decode(provider, iter);
- } catch (buffer::error& err) {
- ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
- ": " << iter << dendl;
- return -EIO;
- }
-
- providers.push_back(std::move(provider));
- }
- } while (is_truncated);
-
- return 0;
-}
-
const string& RGWOIDCProvider::get_url_oid_prefix()
{
return oidc_url_oid_prefix;
}
+
+} } // namespace rgw::sal
#include "rgw/rgw_sal.h"
+namespace rgw { namespace sal {
class RGWOIDCProvider
{
- using string = std::string;
- static const string oidc_url_oid_prefix;
- static const string oidc_arn_prefix;
+public:
+ static const std::string oidc_url_oid_prefix;
+ static const std::string oidc_arn_prefix;
static constexpr int MAX_OIDC_NUM_CLIENT_IDS = 100;
static constexpr int MAX_OIDC_CLIENT_ID_LEN = 255;
static constexpr int MAX_OIDC_NUM_THUMBPRINTS = 5;
static constexpr int MAX_OIDC_THUMBPRINT_LEN = 40;
static constexpr int MAX_OIDC_URL_LEN = 255;
- CephContext *cct;
- rgw::sal::Store* store;
- string id;
- string provider_url;
- string arn;
- string creation_date;
- string tenant;
- vector<string> client_ids;
- vector<string> thumbprints;
-
- int get_tenant_url_from_arn(string& tenant, string& url);
- int store_url(const string& url, bool exclusive, optional_yield y);
- int read_url(const DoutPrefixProvider *dpp, const string& url, const string& tenant);
- bool validate_input();
+protected:
+ std::string id;
+ std::string provider_url;
+ std::string arn;
+ std::string creation_date;
+ std::string tenant;
+ vector<std::string> client_ids;
+ vector<std::string> thumbprints;
+
+ int get_tenant_url_from_arn(std::string& tenant, std::string& url);
+ virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) = 0;
+ virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant) = 0;
+ bool validate_input(const DoutPrefixProvider *dpp);
public:
- RGWOIDCProvider(CephContext *cct,
- rgw::sal::Store* store,
- string provider_url,
- string tenant,
- vector<string> client_ids,
- vector<string> thumbprints)
- : cct(cct),
- store(store),
- provider_url(std::move(provider_url)),
+ void set_arn(std::string _arn) {
+ arn = _arn;
+ }
+ void set_url(std::string _provider_url) {
+ provider_url = _provider_url;
+ }
+ void set_tenant(std::string _tenant) {
+ tenant = _tenant;
+ }
+ void set_client_ids(std::vector<std::string>& _client_ids) {
+ client_ids = std::move(_client_ids);
+ }
+ void set_thumbprints(std::vector<std::string>& _thumbprints) {
+ thumbprints = std::move(_thumbprints);
+ }
+
+ RGWOIDCProvider(std::string provider_url,
+ std::string tenant,
+ vector<std::string> client_ids,
+ vector<std::string> thumbprints)
+ : provider_url(std::move(provider_url)),
tenant(std::move(tenant)),
client_ids(std::move(client_ids)),
thumbprints(std::move(thumbprints)) {
}
- RGWOIDCProvider(CephContext *cct,
- rgw::sal::Store* store,
- string arn,
- string tenant)
- : cct(cct),
- store(store),
- arn(std::move(arn)),
+ RGWOIDCProvider( std::string arn,
+ std::string tenant)
+ : arn(std::move(arn)),
tenant(std::move(tenant)) {
}
- RGWOIDCProvider(CephContext *cct,
- rgw::sal::Store* store,
- string tenant)
- : cct(cct),
- store(store),
- tenant(std::move(tenant)) {}
-
- RGWOIDCProvider(CephContext *cct,
- rgw::sal::Store* store)
- : cct(cct),
- store(store) {}
+ RGWOIDCProvider(std::string tenant)
+ : tenant(std::move(tenant)) {}
RGWOIDCProvider() {}
- ~RGWOIDCProvider() = default;
+ virtual ~RGWOIDCProvider() = default;
void encode(bufferlist& bl) const {
ENCODE_START(3, 1, bl);
DECODE_FINISH(bl);
}
- const string& get_provider_url() const { return provider_url; }
- const string& get_arn() const { return arn; }
- const string& get_create_date() const { return creation_date; }
- const vector<string>& get_client_ids() const { return client_ids;}
- const vector<string>& get_thumbprints() const { return thumbprints; }
+ const std::string& get_provider_url() const { return provider_url; }
+ const std::string& get_arn() const { return arn; }
+ const std::string& get_create_date() const { return creation_date; }
+ const vector<std::string>& get_client_ids() const { return client_ids;}
+ const vector<std::string>& get_thumbprints() const { return thumbprints; }
int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
- int delete_obj(optional_yield y);
+ virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) = 0;
int get(const DoutPrefixProvider *dpp);
void dump(Formatter *f) const;
void dump_all(Formatter *f) const;
void decode_json(JSONObj *obj);
- static const string& get_url_oid_prefix();
- static int get_providers(const DoutPrefixProvider *dpp,
- rgw::sal::Store* store,
- const string& tenant,
- vector<RGWOIDCProvider>& providers);
+ static const std::string& get_url_oid_prefix();
};
WRITE_CLASS_ENCODER(RGWOIDCProvider)
+
+} } // namespace rgw::sal
#endif /* CEPH_RGW_OIDC_PROVIDER_H */
return;
}
- RGWOIDCProvider provider(s->cct, store, provider_url,
- s->user->get_tenant(), client_ids, thumbprints);
- op_ret = provider.create(s, true, y);
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
+ provider->set_url(provider_url);
+ provider->set_tenant(s->user->get_tenant());
+ provider->set_client_ids(client_ids);
+ provider->set_thumbprints(thumbprints);
+ op_ret = provider->create(s, true, y);
if (op_ret == 0) {
s->formatter->open_object_section("CreateOpenIDConnectProviderResponse");
s->formatter->open_object_section("CreateOpenIDConnectProviderResult");
- provider.dump(s->formatter);
+ provider->dump(s->formatter);
s->formatter->close_section();
s->formatter->open_object_section("ResponseMetadata");
s->formatter->dump_string("RequestId", s->trans_id);
void RGWDeleteOIDCProvider::execute(optional_yield y)
{
- RGWOIDCProvider provider(s->cct, store, provider_arn, s->user->get_tenant());
- op_ret = provider.delete_obj(y);
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
+ provider->set_arn(provider_arn);
+ provider->set_tenant(s->user->get_tenant());
+ op_ret = provider->delete_obj(this, y);
if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
op_ret = ERR_INTERNAL_ERROR;
void RGWGetOIDCProvider::execute(optional_yield y)
{
- RGWOIDCProvider provider(s->cct, store, provider_arn, s->user->get_tenant());
- op_ret = provider.get(s);
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
+ provider->set_arn(provider_arn);
+ provider->set_tenant(s->user->get_tenant());
+ op_ret = provider->get(s);
if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
op_ret = ERR_INTERNAL_ERROR;
s->formatter->dump_string("RequestId", s->trans_id);
s->formatter->close_section();
s->formatter->open_object_section("GetOpenIDConnectProviderResult");
- provider.dump_all(s->formatter);
+ provider->dump_all(s->formatter);
s->formatter->close_section();
s->formatter->close_section();
}
void RGWListOIDCProviders::execute(optional_yield y)
{
- vector<RGWOIDCProvider> result;
- op_ret = RGWOIDCProvider::get_providers(s, store, s->user->get_tenant(), result);
+ vector<std::unique_ptr<rgw::sal::RGWOIDCProvider>> result;
+ op_ret = store->get_oidc_providers(s, s->user->get_tenant(), result);
if (op_ret == 0) {
s->formatter->open_array_section("ListOpenIDConnectProvidersResponse");
s->formatter->open_array_section("OpenIDConnectProviderList");
for (const auto& it : result) {
s->formatter->open_object_section("Arn");
- auto& arn = it.get_arn();
+ auto& arn = it->get_arn();
ldpp_dout(s, 0) << "ARN: " << arn << dendl;
s->formatter->dump_string("Arn", arn);
s->formatter->close_section();
}
string role_name = s->info.args.get("RoleName");
- RGWRole role(s->cct, store, role_name, s->user->get_tenant());
- if (op_ret = role.get(s, y); op_ret < 0) {
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+ s->user->get_tenant());
+ if (op_ret = role->get(s, y); op_ret < 0) {
if (op_ret == -ENOENT) {
op_ret = -ERR_NO_ROLE_FOUND;
}
return ret;
}
- string resource_name = role.get_path() + role_name;
+ string resource_name = role->get_path() + role_name;
uint64_t op = get_op();
if (!verify_user_permission(this,
s,
if (op_ret < 0) {
return;
}
- RGWRole role(s->cct, store, role_name, role_path, trust_policy,
- s->user->get_tenant(), max_session_duration);
- op_ret = role.create(s, true, y);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+ s->user->get_tenant(),
+ role_path,
+ trust_policy,
+ max_session_duration);
+ op_ret = role->create(s, true, y);
if (op_ret == -EEXIST) {
op_ret = -ERR_ROLE_EXISTS;
s->formatter->open_object_section("CreateRoleResponse");
s->formatter->open_object_section("CreateRoleResult");
s->formatter->open_object_section("Role");
- role.dump(s->formatter);
+ role->dump(s->formatter);
s->formatter->close_section();
s->formatter->close_section();
s->formatter->open_object_section("ResponseMetadata");
return;
}
- op_ret = _role.delete_obj(s, y);
+ op_ret = _role->delete_obj(s, y);
if (op_ret == -ENOENT) {
op_ret = -ERR_NO_ROLE_FOUND;
return 0;
}
-int RGWGetRole::_verify_permission(const RGWRole& role)
+int RGWGetRole::_verify_permission(const rgw::sal::RGWRole* role)
{
if (s->auth.identity->is_anonymous()) {
return -EACCES;
return ret;
}
- string resource_name = role.get_path() + role.get_name();
+ string resource_name = role->get_path() + role->get_name();
if (!verify_user_permission(this,
s,
rgw::ARN(resource_name,
if (op_ret < 0) {
return;
}
- RGWRole role(s->cct, store, role_name, s->user->get_tenant());
- op_ret = role.get(s, y);
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(role_name,
+ s->user->get_tenant());
+ op_ret = role->get(s, y);
if (op_ret == -ENOENT) {
op_ret = -ERR_NO_ROLE_FOUND;
return;
}
- op_ret = _verify_permission(role);
+ op_ret = _verify_permission(role.get());
if (op_ret == 0) {
s->formatter->open_object_section("GetRoleResponse");
s->formatter->close_section();
s->formatter->open_object_section("GetRoleResult");
s->formatter->open_object_section("Role");
- role.dump(s->formatter);
+ role->dump(s->formatter);
s->formatter->close_section();
s->formatter->close_section();
s->formatter->close_section();
return;
}
- _role.update_trust_policy(trust_policy);
- op_ret = _role.update(y);
+ _role->update_trust_policy(trust_policy);
+ op_ret = _role->update(this, y);
s->formatter->open_object_section("UpdateAssumeRolePolicyResponse");
s->formatter->open_object_section("ResponseMetadata");
if (op_ret < 0) {
return;
}
- vector<RGWRole> result;
- op_ret = RGWRole::get_roles_by_path_prefix(s, store, s->cct, path_prefix, s->user->get_tenant(), result, y);
+ vector<std::unique_ptr<rgw::sal::RGWRole>> result;
+ op_ret = store->get_roles(s, y, path_prefix, s->user->get_tenant(), result);
if (op_ret == 0) {
s->formatter->open_array_section("ListRolesResponse");
s->formatter->open_object_section("Roles");
for (const auto& it : result) {
s->formatter->open_object_section("member");
- it.dump(s->formatter);
+ it->dump(s->formatter);
s->formatter->close_section();
}
s->formatter->close_section();
return;
}
- _role.set_perm_policy(policy_name, perm_policy);
- op_ret = _role.update(y);
+ _role->set_perm_policy(policy_name, perm_policy);
+ op_ret = _role->update(this, y);
if (op_ret == 0) {
s->formatter->open_object_section("PutRolePolicyResponse");
}
string perm_policy;
- op_ret = _role.get_role_policy(policy_name, perm_policy);
+ op_ret = _role->get_role_policy(this, policy_name, perm_policy);
if (op_ret == -ENOENT) {
op_ret = -ERR_NO_SUCH_ENTITY;
}
return;
}
- std::vector<string> policy_names = _role.get_role_policy_names();
+ 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);
return;
}
- op_ret = _role.delete_policy(policy_name);
+ op_ret = _role->delete_policy(this, policy_name);
if (op_ret == -ENOENT) {
op_ret = -ERR_NO_ROLE_FOUND;
}
if (op_ret == 0) {
- op_ret = _role.update(y);
+ op_ret = _role->update(this, y);
}
s->formatter->open_object_section("DeleteRolePoliciesResponse");
string perm_policy;
string path_prefix;
string max_session_duration;
- RGWRole _role;
+ std::unique_ptr<rgw::sal::RGWRole> _role;
public:
int verify_permission(optional_yield y) override;
void send_response() override;
};
class RGWGetRole : public RGWRoleRead {
- int _verify_permission(const RGWRole& role);
+ int _verify_permission(const rgw::sal::RGWRole* role);
public:
RGWGetRole() = default;
int verify_permission(optional_yield y) override;
string role_id;
rgw::auth::RoleApplier::Role r;
if (! token.roleId.empty()) {
- RGWRole role(s->cct, store, token.roleId);
- if (role.get_by_id(dpp, y) < 0) {
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(token.roleId);
+ if (role->get_by_id(dpp, y) < 0) {
return result_t::deny(-EPERM);
}
r.id = token.roleId;
- r.name = role.get_name();
- r.tenant = role.get_tenant();
+ r.name = role->get_name();
+ r.tenant = role->get_tenant();
- vector<string> role_policy_names = role.get_role_policy_names();
+ vector<string> role_policy_names = role->get_role_policy_names();
for (auto& policy_name : role_policy_names) {
string perm_policy;
- if (int ret = role.get_role_policy(policy_name, perm_policy); ret == 0) {
+ if (int ret = role->get_role_policy(dpp, policy_name, perm_policy); ret == 0) {
r.role_policies.push_back(std::move(perm_policy));
}
}
return tenant;
}
-boost::optional<RGWOIDCProvider>
+std::unique_ptr<rgw::sal::RGWOIDCProvider>
WebTokenEngine::get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss) const
{
string tenant = get_role_tenant(role_arn);
}
auto provider_arn = rgw::ARN(idp_url, "oidc-provider", tenant);
string p_arn = provider_arn.to_string();
- RGWOIDCProvider provider(cct, store, p_arn, tenant);
- auto ret = provider.get(dpp);
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
+ provider->set_arn(p_arn);
+ provider->set_tenant(tenant);
+ auto ret = provider->get(dpp);
if (ret < 0) {
- return boost::none;
+ return nullptr;
}
- return provider;
+ return std::move(provider);
}
bool
ldpp_dout(this, 0) << "failed to get role info using role arn: " << rArn << dendl;
return ret;
}
- string policy = role.get_assume_role_policy();
+ string policy = role->get_assume_role_policy();
buffer::list bl = buffer::list::static_from_string(policy);
//Parse the policy
bool is_cert_valid(const vector<string>& thumbprints, const string& cert) const;
- boost::optional<RGWOIDCProvider> get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss) const;
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss) const;
std::string get_role_tenant(const string& role_arn) const;
#define dout_subsys ceph_subsys_rgw
+namespace rgw { namespace sal {
const string RGWRole::role_name_oid_prefix = "role_names.";
const string RGWRole::role_oid_prefix = "roles.";
const string RGWRole::role_path_oid_prefix = "role_paths.";
const string RGWRole::role_arn_prefix = "arn:aws:iam::";
-int RGWRole::store_info(bool exclusive, optional_yield y)
-{
- using ceph::encode;
- string oid = get_info_oid_prefix() + id;
-
- bufferlist bl;
- encode(*this, bl);
-
- return store->put_system_obj(store->get_zone()->get_params().roles_pool, oid,
- bl, exclusive, NULL, real_time(), y, NULL);
-}
-
-int RGWRole::store_name(bool exclusive, optional_yield y)
-{
- RGWNameToId nameToId;
- nameToId.obj_id = id;
-
- string oid = tenant + get_names_oid_prefix() + name;
-
- bufferlist bl;
- using ceph::encode;
- encode(nameToId, bl);
-
- return store->put_system_obj(store->get_zone()->get_params().roles_pool, oid,
- bl, exclusive, NULL, real_time(), y, NULL);
-}
-
-int RGWRole::store_path(bool exclusive, optional_yield y)
-{
- string oid = tenant + get_path_oid_prefix() + path + get_info_oid_prefix() + id;
-
- bufferlist bl;
- return store->put_system_obj(store->get_zone()->get_params().roles_pool, oid,
- bl, exclusive, NULL, real_time(), y, NULL);
-}
-
-int RGWRole::create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
-{
- int ret;
-
- if (! validate_input()) {
- return -EINVAL;
- }
-
- /* check to see the name is not used */
- ret = read_id(dpp, name, tenant, id, y);
- if (exclusive && ret == 0) {
- ldpp_dout(dpp, 0) << "ERROR: name " << name << " already in use for role id "
- << id << dendl;
- return -EEXIST;
- } else if ( ret < 0 && ret != -ENOENT) {
- ldpp_dout(dpp, 0) << "failed reading role id " << id << ": "
- << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- /* create unique id */
- uuid_d new_uuid;
- char uuid_str[37];
- new_uuid.generate_random();
- new_uuid.print(uuid_str);
- id = uuid_str;
-
- //arn
- arn = role_arn_prefix + tenant + ":role" + path + name;
-
- // Creation time
- real_clock::time_point t = real_clock::now();
-
- struct timeval tv;
- real_clock::to_timeval(t, tv);
-
- char buf[30];
- struct tm result;
- gmtime_r(&tv.tv_sec, &result);
- strftime(buf,30,"%Y-%m-%dT%H:%M:%S", &result);
- sprintf(buf + strlen(buf),".%dZ",(int)tv.tv_usec/1000);
- creation_date.assign(buf, strlen(buf));
-
- auto& pool = store->get_zone()->get_params().roles_pool;
- ret = store_info(exclusive, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: storing role info in pool: " << pool.name << ": "
- << id << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- ret = store_name(exclusive, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: storing role name in pool: " << pool.name << ": "
- << name << ": " << cpp_strerror(-ret) << dendl;
-
- //Delete the role info that was stored in the previous call
- string oid = get_info_oid_prefix() + id;
- int info_ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (info_ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: cleanup of role id from pool: " << pool.name << ": "
- << id << ": " << cpp_strerror(-info_ret) << dendl;
- }
- return ret;
- }
-
- ret = store_path(exclusive, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: storing role path in pool: " << pool.name << ": "
- << path << ": " << cpp_strerror(-ret) << dendl;
- //Delete the role info that was stored in the previous call
- string oid = get_info_oid_prefix() + id;
- int info_ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (info_ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: cleanup of role id from pool: " << pool.name << ": "
- << id << ": " << cpp_strerror(-info_ret) << dendl;
- }
- //Delete role name that was stored in previous call
- oid = tenant + get_names_oid_prefix() + name;
- int name_ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (name_ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: cleanup of role name from pool: " << pool.name << ": "
- << name << ": " << cpp_strerror(-name_ret) << dendl;
- }
- return ret;
- }
- return 0;
-}
-
-int RGWRole::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
-{
- auto& pool = store->get_zone()->get_params().roles_pool;
-
- int ret = read_name(dpp, y);
- if (ret < 0) {
- return ret;
- }
-
- ret = read_info(dpp, y);
- if (ret < 0) {
- return ret;
- }
-
- if (! perm_policy_map.empty()) {
- return -ERR_DELETE_CONFLICT;
- }
-
- // Delete id
- string oid = get_info_oid_prefix() + id;
- ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: deleting role id from pool: " << pool.name << ": "
- << id << ": " << cpp_strerror(-ret) << dendl;
- }
-
- // Delete name
- oid = tenant + get_names_oid_prefix() + name;
- ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: deleting role name from pool: " << pool.name << ": "
- << name << ": " << cpp_strerror(-ret) << dendl;
- }
-
- // Delete path
- oid = tenant + get_path_oid_prefix() + path + get_info_oid_prefix() + id;
- ret = store->delete_system_obj(pool, oid, nullptr, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: deleting role path from pool: " << pool.name << ": "
- << path << ": " << cpp_strerror(-ret) << dendl;
- }
- return ret;
-}
-
int RGWRole::get(const DoutPrefixProvider *dpp, optional_yield y)
{
int ret = read_name(dpp, y);
return 0;
}
-int RGWRole::update(optional_yield y)
+int RGWRole::update(const DoutPrefixProvider *dpp, optional_yield y)
{
- auto& pool = store->get_zone()->get_params().roles_pool;
-
- int ret = store_info(false, y);
+ int ret = store_info(dpp, false, y);
if (ret < 0) {
- ldout(cct, 0) << "ERROR: storing info in pool: " << pool.name << ": "
+ ldpp_dout(dpp, 0) << "ERROR: storing info in Role pool: "
<< id << ": " << cpp_strerror(-ret) << dendl;
return ret;
}
return policy_names;
}
-int RGWRole::get_role_policy(const string& policy_name, string& perm_policy)
+int RGWRole::get_role_policy(const DoutPrefixProvider* dpp, const string& policy_name, string& perm_policy)
{
const auto it = perm_policy_map.find(policy_name);
if (it == perm_policy_map.end()) {
- ldout(cct, 0) << "ERROR: Policy name: " << policy_name << " not found" << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Policy name: " << policy_name << " not found" << dendl;
return -ENOENT;
} else {
perm_policy = it->second;
return 0;
}
-int RGWRole::delete_policy(const string& policy_name)
+int RGWRole::delete_policy(const DoutPrefixProvider* dpp, const string& policy_name)
{
const auto& it = perm_policy_map.find(policy_name);
if (it == perm_policy_map.end()) {
- ldout(cct, 0) << "ERROR: Policy name: " << policy_name << " not found" << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Policy name: " << policy_name << " not found" << dendl;
return -ENOENT;
} else {
perm_policy_map.erase(it);
JSONDecoder::decode_json("assume_role_policy_document", trust_policy, obj);
}
-int RGWRole::read_id(const DoutPrefixProvider *dpp, const string& role_name, const string& tenant, string& role_id, optional_yield y)
-{
- auto& pool = store->get_zone()->get_params().roles_pool;
- string oid = tenant + get_names_oid_prefix() + role_name;
- bufferlist bl;
-
- int ret = store->get_system_obj(dpp, pool, oid, bl, NULL, NULL, y);
- if (ret < 0) {
- return ret;
- }
-
- RGWNameToId nameToId;
- try {
- auto iter = bl.cbegin();
- using ceph::decode;
- decode(nameToId, iter);
- } catch (buffer::error& err) {
- ldpp_dout(dpp, 0) << "ERROR: failed to decode role from pool: " << pool.name << ": "
- << role_name << dendl;
- return -EIO;
- }
- role_id = nameToId.obj_id;
- return 0;
-}
-
-int RGWRole::read_info(const DoutPrefixProvider *dpp, optional_yield y)
-{
- auto& pool = store->get_zone()->get_params().roles_pool;
- string oid = get_info_oid_prefix() + id;
- bufferlist bl;
-
- int ret = store->get_system_obj(dpp, pool, oid, bl, NULL, NULL, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: failed reading role info from pool: " << pool.name <<
- ": " << id << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- try {
- using ceph::decode;
- auto iter = bl.cbegin();
- decode(*this, iter);
- } catch (buffer::error& err) {
- ldpp_dout(dpp, 0) << "ERROR: failed to decode role info from pool: " << pool.name <<
- ": " << id << dendl;
- return -EIO;
- }
-
- return 0;
-}
-
-int RGWRole::read_name(const DoutPrefixProvider *dpp, optional_yield y)
-{
- auto& pool = store->get_zone()->get_params().roles_pool;
- string oid = tenant + get_names_oid_prefix() + name;
- bufferlist bl;
-
- int ret = store->get_system_obj(dpp, pool, oid, bl, NULL, NULL, y);
- if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: failed reading role name from pool: " << pool.name << ": "
- << name << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- RGWNameToId nameToId;
- try {
- using ceph::decode;
- auto iter = bl.cbegin();
- decode(nameToId, iter);
- } catch (buffer::error& err) {
- ldpp_dout(dpp, 0) << "ERROR: failed to decode role name from pool: " << pool.name << ": "
- << name << dendl;
- return -EIO;
- }
- id = nameToId.obj_id;
- return 0;
-}
-
-bool RGWRole::validate_input()
+bool RGWRole::validate_input(const DoutPrefixProvider* dpp)
{
if (name.length() > MAX_ROLE_NAME_LEN) {
- ldout(cct, 0) << "ERROR: Invalid name length " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid name length " << dendl;
return false;
}
if (path.length() > MAX_PATH_NAME_LEN) {
- ldout(cct, 0) << "ERROR: Invalid path length " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid path length " << dendl;
return false;
}
std::regex regex_name("[A-Za-z0-9:=,.@-]+");
if (! std::regex_match(name, regex_name)) {
- ldout(cct, 0) << "ERROR: Invalid chars in name " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid chars in name " << dendl;
return false;
}
std::regex regex_path("(/[!-~]+/)|(/)");
if (! std::regex_match(path,regex_path)) {
- ldout(cct, 0) << "ERROR: Invalid chars in path " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid chars in path " << dendl;
return false;
}
if (max_session_duration < SESSION_DURATION_MIN ||
max_session_duration > SESSION_DURATION_MAX) {
- ldout(cct, 0) << "ERROR: Invalid session duration, should be between 3600 and 43200 seconds " << dendl;
+ ldpp_dout(dpp, 0) << "ERROR: Invalid session duration, should be between 3600 and 43200 seconds " << dendl;
return false;
}
return true;
this->trust_policy = trust_policy;
}
-int RGWRole::get_roles_by_path_prefix(const DoutPrefixProvider *dpp,
- rgw::sal::Store* store,
- CephContext *cct,
- const string& path_prefix,
- const string& tenant,
- vector<RGWRole>& roles,
- optional_yield y)
-{
- auto pool = store->get_zone()->get_params().roles_pool;
- string prefix;
-
- // List all roles if path prefix is empty
- if (! path_prefix.empty()) {
- prefix = tenant + role_path_oid_prefix + path_prefix;
- } else {
- prefix = tenant + role_path_oid_prefix;
- }
-
- //Get the filtered objects
- list<string> result;
- bool is_truncated;
- RGWListRawObjsCtx ctx;
- do {
- list<string> oids;
- int r = store->list_raw_objects(pool, prefix, 1000, ctx, oids, &is_truncated);
- if (r < 0) {
- ldpp_dout(dpp, 0) << "ERROR: listing filtered objects failed: " << pool.name << ": "
- << prefix << ": " << cpp_strerror(-r) << dendl;
- return r;
- }
- for (const auto& iter : oids) {
- result.push_back(iter.substr(role_path_oid_prefix.size()));
- }
- } while (is_truncated);
-
- for (const auto& it : result) {
- //Find the role oid prefix from the end
- size_t pos = it.rfind(role_oid_prefix);
- if (pos == string::npos) {
- continue;
- }
- // Split the result into path and info_oid + id
- string path = it.substr(0, pos);
-
- /*Make sure that prefix is part of path (False results could've been returned)
- because of the role info oid + id appended to the path)*/
- if(path_prefix.empty() || path.find(path_prefix) != string::npos) {
- //Get id from info oid prefix + id
- string id = it.substr(pos + role_oid_prefix.length());
-
- RGWRole role(cct, store);
- role.set_id(id);
- int ret = role.read_info(dpp, y);
- if (ret < 0) {
- return ret;
- }
- roles.push_back(std::move(role));
- }
- }
-
- return 0;
-}
-
const string& RGWRole::get_names_oid_prefix()
{
return role_name_oid_prefix;
{
return role_path_oid_prefix;
}
+
+} } // namespace rgw::sal
#include "rgw/rgw_rados.h"
-namespace rgw { namespace sal { class Store; } }
+namespace rgw { namespace sal {
class RGWRole
{
- using string = std::string;
- static const string role_name_oid_prefix;
- static const string role_oid_prefix;
- static const string role_path_oid_prefix;
- static const string role_arn_prefix;
+public:
+ static const std::string role_name_oid_prefix;
+ static const std::string role_oid_prefix;
+ static const std::string role_path_oid_prefix;
+ static const std::string role_arn_prefix;
static constexpr int MAX_ROLE_NAME_LEN = 64;
static constexpr int MAX_PATH_NAME_LEN = 512;
static constexpr uint64_t SESSION_DURATION_MIN = 3600; // in seconds
static constexpr uint64_t SESSION_DURATION_MAX = 43200; // in seconds
-
- CephContext *cct;
- rgw::sal::Store* store;
- string id;
- string name;
- string path;
- string arn;
- string creation_date;
- string trust_policy;
- map<string, string> perm_policy_map;
- string tenant;
+protected:
+
+ std::string id;
+ std::string name;
+ std::string path;
+ std::string arn;
+ std::string creation_date;
+ std::string trust_policy;
+ map<std::string, std::string> perm_policy_map;
+ std::string tenant;
uint64_t max_session_duration;
- int store_info(bool exclusive, optional_yield y);
- int store_name(bool exclusive, optional_yield y);
- int store_path(bool exclusive, optional_yield y);
- int read_id(const DoutPrefixProvider *dpp, const string& role_name, const string& tenant, string& role_id, optional_yield y);
- int read_name(const DoutPrefixProvider *dpp, optional_yield y);
- int read_info(const DoutPrefixProvider *dpp, optional_yield y);
- bool validate_input();
+public:
+ virtual int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) = 0;
+ virtual int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) = 0;
+ virtual int store_path(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) = 0;
+ virtual int read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y) = 0;
+ virtual int read_name(const DoutPrefixProvider *dpp, optional_yield y) = 0;
+ virtual int read_info(const DoutPrefixProvider *dpp, optional_yield y) = 0;
+ bool validate_input(const DoutPrefixProvider* dpp);
void extract_name_tenant(const std::string& str);
-public:
- RGWRole(CephContext *cct,
- rgw::sal::Store* store,
- string name,
- string path,
- string trust_policy,
- string tenant,
- string max_session_duration_str="")
- : cct(cct),
- store(store),
- name(std::move(name)),
+ RGWRole(std::string name,
+ std::string tenant,
+ std::string path="",
+ std::string trust_policy="",
+ std::string max_session_duration_str="")
+ : name(std::move(name)),
path(std::move(path)),
trust_policy(std::move(trust_policy)),
tenant(std::move(tenant)) {
}
}
- RGWRole(CephContext *cct,
- rgw::sal::Store* store,
- string name,
- string tenant)
- : cct(cct),
- store(store),
- name(std::move(name)),
- tenant(std::move(tenant)) {
- extract_name_tenant(this->name);
- }
-
- RGWRole(CephContext *cct,
- rgw::sal::Store* store,
- string id)
- : cct(cct),
- store(store),
- id(std::move(id)) {}
-
- RGWRole(CephContext *cct,
- rgw::sal::Store* store)
- : cct(cct),
- store(store) {}
-
- RGWRole() {}
+ RGWRole(std::string id) : id(std::move(id)) {}
- ~RGWRole() = default;
+ virtual ~RGWRole() = default;
void encode(bufferlist& bl) const {
ENCODE_START(3, 1, bl);
DECODE_FINISH(bl);
}
- const string& get_id() const { return id; }
- const string& get_name() const { return name; }
- const string& get_tenant() const { return tenant; }
- const string& get_path() const { return path; }
- const string& get_create_date() const { return creation_date; }
- const string& get_assume_role_policy() const { return trust_policy;}
+ const std::string& get_id() const { return id; }
+ const std::string& get_name() const { return name; }
+ const std::string& get_tenant() const { return tenant; }
+ const std::string& get_path() const { return path; }
+ const std::string& get_create_date() const { return creation_date; }
+ const std::string& get_assume_role_policy() const { return trust_policy;}
const uint64_t& get_max_session_duration() const { return max_session_duration; }
- void set_id(const string& id) { this->id = id; }
+ void set_id(const std::string& id) { this->id = id; }
- int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
- int delete_obj(const DoutPrefixProvider *dpp, optional_yield y);
+ virtual int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) = 0;
+ virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) = 0;
int get(const DoutPrefixProvider *dpp, optional_yield y);
int get_by_id(const DoutPrefixProvider *dpp, optional_yield y);
- int update(optional_yield y);
- void update_trust_policy(string& trust_policy);
- void set_perm_policy(const string& policy_name, const string& perm_policy);
- vector<string> get_role_policy_names();
- int get_role_policy(const string& policy_name, string& perm_policy);
- int delete_policy(const string& policy_name);
+ int update(const DoutPrefixProvider *dpp, optional_yield y);
+ void update_trust_policy(std::string& trust_policy);
+ void set_perm_policy(const std::string& policy_name, const std::string& perm_policy);
+ vector<std::string> get_role_policy_names();
+ int get_role_policy(const DoutPrefixProvider* dpp, const std::string& policy_name, std::string& perm_policy);
+ int delete_policy(const DoutPrefixProvider* dpp, const std::string& policy_name);
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
- static const string& get_names_oid_prefix();
- static const string& get_info_oid_prefix();
- static const string& get_path_oid_prefix();
- static int get_roles_by_path_prefix(const DoutPrefixProvider *dpp,
- rgw::sal::Store* store,
- CephContext *cct,
- const string& path_prefix,
- const string& tenant,
- vector<RGWRole>& roles,
- optional_yield y);
+ static const std::string& get_names_oid_prefix();
+ static const std::string& get_info_oid_prefix();
+ static const std::string& get_path_oid_prefix();
};
WRITE_CLASS_ENCODER(RGWRole)
+} } // namespace rgw::sal
#endif /* CEPH_RGW_ROLE_H */
class GCChain;
class Writer;
class Zone;
+class LuaScriptManager;
+class RGWOIDCProvider;
+class RGWRole;
enum AttrsMod {
ATTRSMOD_NONE = 0,
virtual int register_to_service_map(const std::string& daemon_type,
const map<std::string, std::string>& meta) = 0;
virtual void get_quota(RGWQuotaInfo& bucket_quota, RGWQuotaInfo& user_quota) = 0;
- virtual int list_raw_objects(const rgw_pool& pool, const std::string& prefix_filter,
- int max, RGWListRawObjsCtx& ctx, std::list<std::string>& oids,
- bool* is_truncated) = 0;
virtual int set_buckets_enabled(const DoutPrefixProvider* dpp, vector<rgw_bucket>& buckets, bool enabled) = 0;
virtual uint64_t get_new_req_id() = 0;
virtual int get_sync_policy_handler(const DoutPrefixProvider* dpp,
map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0;
virtual int trim_all_usage(uint64_t start_epoch, uint64_t end_epoch) = 0;
virtual int get_config_key_val(std::string name, bufferlist* bl) = 0;
- virtual int put_system_obj(const rgw_pool& pool, const std::string& oid,
- bufferlist& data, bool exclusive,
- RGWObjVersionTracker* objv_tracker, real_time set_mtime,
- optional_yield y, map<std::string, bufferlist>* pattrs = nullptr) = 0;
- virtual int get_system_obj(const DoutPrefixProvider* dpp,
- const rgw_pool& pool, const std::string& key,
- bufferlist& bl,
- RGWObjVersionTracker* objv_tracker, real_time* pmtime,
- optional_yield y, map<std::string, bufferlist>* pattrs = nullptr,
- rgw_cache_entry_info* cache_info = nullptr,
- boost::optional<obj_version> refresh_version = boost::none) = 0;
- virtual int delete_system_obj(const rgw_pool& pool, const std::string& oid,
- RGWObjVersionTracker* objv_tracker, optional_yield y) = 0;
virtual int meta_list_keys_init(const std::string& section, const std::string& marker, void** phandle) = 0;
virtual int meta_list_keys_next(void* handle, int max, list<std::string>& keys, bool* truncated) = 0;
virtual void meta_list_keys_complete(void* handle) = 0;
virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) = 0;
virtual const RGWSyncModuleInstanceRef& get_sync_module() = 0;
virtual std::string get_host_id() = 0;
+ virtual std::unique_ptr<LuaScriptManager> get_lua_script_manager() = 0;
+ virtual std::unique_ptr<RGWRole> get_role(std::string name,
+ std::string tenant,
+ std::string path="",
+ std::string trust_policy="",
+ std::string max_session_duration_str="") = 0;
+ virtual std::unique_ptr<RGWRole> get_role(std::string id) = 0;
+ virtual int get_roles(const DoutPrefixProvider *dpp,
+ optional_yield y,
+ const std::string& path_prefix,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWRole>>& roles) = 0;
+ virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() = 0;
+ virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWOIDCProvider>>& providers) = 0;
virtual void finalize(void) = 0;
virtual const std::string& get_current_period_id() = 0;
};
+class LuaScriptManager {
+protected:
+ std::string script;
+
+public:
+ virtual ~LuaScriptManager() = default;
+
+ virtual int get(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) = 0;
+ virtual int put(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) = 0;
+ virtual int del(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) = 0;
+};
+
} } // namespace rgw::sal
class StoreManager {
user_quota = svc()->quota->get_user_quota();
}
-int RadosStore::list_raw_objects(const rgw_pool& pool, const std::string& prefix_filter,
- int max, RGWListRawObjsCtx& ctx, list<std::string>& oids,
- bool* is_truncated)
-{
- return rados->list_raw_objects(pool, prefix_filter, max, ctx, oids, is_truncated);
-}
-
int RadosStore::set_buckets_enabled(const DoutPrefixProvider* dpp, vector<rgw_bucket>& buckets, bool enabled)
{
return rados->set_buckets_enabled(buckets, enabled, dpp);
return svc()->config_key->get(name, true, bl);
}
-int RadosStore::put_system_obj(const rgw_pool& pool, const std::string& oid,
- bufferlist& data, bool exclusive,
- RGWObjVersionTracker* objv_tracker, real_time set_mtime,
- optional_yield y, map<std::string, bufferlist>* pattrs)
-{
- auto obj_ctx = svc()->sysobj->init_obj_ctx();
- return rgw_put_system_obj(obj_ctx, pool, oid, data, exclusive, objv_tracker, set_mtime, y, pattrs);
-}
-
-int RadosStore::get_system_obj(const DoutPrefixProvider* dpp,
- const rgw_pool& pool, const std::string& key,
- bufferlist& bl,
- RGWObjVersionTracker* objv_tracker, real_time* pmtime,
- optional_yield y, map<std::string, bufferlist>* pattrs,
- rgw_cache_entry_info* cache_info,
- boost::optional<obj_version> refresh_version)
-{
- auto obj_ctx = svc()->sysobj->init_obj_ctx();
- return rgw_get_system_obj(obj_ctx, pool, key, bl, objv_tracker, pmtime, y, dpp, pattrs, cache_info, refresh_version);
-}
-
-int RadosStore::delete_system_obj(const rgw_pool& pool, const std::string& oid,
- RGWObjVersionTracker* objv_tracker, optional_yield y)
-{
- return rgw_delete_system_obj(svc()->sysobj, pool, oid, objv_tracker, y);
-}
-
int RadosStore::meta_list_keys_init(const std::string& section, const std::string& marker, void** phandle)
{
return ctl()->meta.mgr->list_keys_init(section, marker, phandle);
rados->finalize();
}
+std::unique_ptr<LuaScriptManager> RadosStore::get_lua_script_manager()
+{
+ return std::unique_ptr<LuaScriptManager>(new RadosLuaScriptManager(this));
+}
+
+std::unique_ptr<RGWRole> RadosStore::get_role(std::string name,
+ std::string tenant,
+ std::string path,
+ std::string trust_policy,
+ std::string max_session_duration_str)
+{
+ return std::unique_ptr<RGWRole>(new RadosRole(this, name, tenant, path, trust_policy, max_session_duration_str));
+}
+
+std::unique_ptr<RGWRole> RadosStore::get_role(std::string id)
+{
+ return std::unique_ptr<RGWRole>(new RadosRole(this, id));
+}
+
+int RadosStore::get_roles(const DoutPrefixProvider *dpp,
+ optional_yield y,
+ const std::string& path_prefix,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWRole>>& roles)
+{
+ auto pool = get_zone()->get_params().roles_pool;
+ std::string prefix;
+
+ // List all roles if path prefix is empty
+ if (! path_prefix.empty()) {
+ prefix = tenant + RGWRole::role_path_oid_prefix + path_prefix;
+ } else {
+ prefix = tenant + RGWRole::role_path_oid_prefix;
+ }
+
+ //Get the filtered objects
+ list<std::string> result;
+ bool is_truncated;
+ RGWListRawObjsCtx ctx;
+ do {
+ list<std::string> oids;
+ int r = rados->list_raw_objects(pool, prefix, 1000, ctx, oids, &is_truncated);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: listing filtered objects failed: "
+ << prefix << ": " << cpp_strerror(-r) << dendl;
+ return r;
+ }
+ for (const auto& iter : oids) {
+ result.push_back(iter.substr(RGWRole::role_path_oid_prefix.size()));
+ }
+ } while (is_truncated);
+
+ for (const auto& it : result) {
+ //Find the role oid prefix from the end
+ size_t pos = it.rfind(RGWRole::role_oid_prefix);
+ if (pos == std::string::npos) {
+ continue;
+ }
+ // Split the result into path and info_oid + id
+ std::string path = it.substr(0, pos);
+
+ /*Make sure that prefix is part of path (False results could've been returned)
+ because of the role info oid + id appended to the path)*/
+ if(path_prefix.empty() || path.find(path_prefix) != std::string::npos) {
+ //Get id from info oid prefix + id
+ std::string id = it.substr(pos + RGWRole::role_oid_prefix.length());
+
+ std::unique_ptr<rgw::sal::RGWRole> role = get_role(id);
+ int ret = role->read_info(dpp, y);
+ if (ret < 0) {
+ return ret;
+ }
+ roles.push_back(std::move(role));
+ }
+ }
+
+ return 0;
+}
+
+std::unique_ptr<RGWOIDCProvider> RadosStore::get_oidc_provider()
+{
+ return std::unique_ptr<RGWOIDCProvider>(new RadosOIDCProvider(this));
+}
+
+int RadosStore::get_oidc_providers(const DoutPrefixProvider *dpp,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWOIDCProvider>>& providers)
+{
+ std::string prefix = tenant + RGWOIDCProvider::oidc_url_oid_prefix;
+ auto pool = zone.get_params().oidc_pool;
+ auto obj_ctx = svc()->sysobj->init_obj_ctx();
+
+ //Get the filtered objects
+ list<std::string> result;
+ bool is_truncated;
+ RGWListRawObjsCtx ctx;
+ do {
+ list<std::string> oids;
+ int r = rados->list_raw_objects(pool, prefix, 1000, ctx, oids, &is_truncated);
+ if (r < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: listing filtered objects failed: OIDC pool: "
+ << pool.name << ": " << prefix << ": " << cpp_strerror(-r) << dendl;
+ return r;
+ }
+ for (const auto& iter : oids) {
+ std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = get_oidc_provider();
+ bufferlist bl;
+
+ r = rgw_get_system_obj(obj_ctx, pool, iter, bl, nullptr, nullptr, null_yield, dpp);
+ if (r < 0) {
+ return r;
+ }
+
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(*provider, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: "
+ << pool.name << ": " << iter << dendl;
+ return -EIO;
+ }
+
+ providers.push_back(std::move(provider));
+ }
+ } while (is_truncated);
+
+ return 0;
+}
+
int RadosStore::get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx* ioctx)
{
return rados->get_obj_head_ioctx(bucket_info, obj, ioctx);
return store->svc()->zone->get_current_period_id();
}
+int RadosLuaScriptManager::get(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ bufferlist bl;
+
+ int r = rgw_get_system_obj(obj_ctx, pool, key, bl, nullptr, nullptr, y, dpp);
+ if (r < 0) {
+ return r;
+ }
+
+ auto iter = bl.cbegin();
+ try {
+ ceph::decode(script, iter);
+ } catch (buffer::error& err) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int RadosLuaScriptManager::put(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ bufferlist bl;
+ ceph::encode(script, bl);
+
+ int r = rgw_put_system_obj(obj_ctx, pool, key, bl, false, nullptr, real_time(), y);
+ if (r < 0) {
+ return r;
+ }
+
+ return 0;
+}
+
+int RadosLuaScriptManager::del(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key)
+{
+ int r = rgw_delete_system_obj(store->svc()->sysobj, pool, key, nullptr, y);
+ if (r < 0 && r != -ENOENT) {
+ return r;
+ }
+
+ return 0;
+}
+
+int RadosOIDCProvider::store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = tenant + get_url_oid_prefix() + url;
+
+ bufferlist bl;
+ using ceph::encode;
+ encode(*this, bl);
+ return rgw_put_system_obj(obj_ctx, store->get_zone()->get_params().oidc_pool, oid, bl, exclusive, nullptr, real_time(), y);
+}
+
+int RadosOIDCProvider::read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ auto& pool = store->get_zone()->get_params().oidc_pool;
+ std::string oid = tenant + get_url_oid_prefix() + url;
+ bufferlist bl;
+
+ int ret = rgw_get_system_obj(obj_ctx, pool, oid, bl, nullptr, nullptr, null_yield, dpp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(*this, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
+ ": " << url << dendl;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int RadosOIDCProvider::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
+{
+ auto& pool = store->get_zone()->get_params().oidc_pool;
+
+ std::string url, tenant;
+ auto ret = get_tenant_url_from_arn(tenant, url);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to parse arn" << dendl;
+ return -EINVAL;
+ }
+
+ if (this->tenant != tenant) {
+ ldpp_dout(dpp, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
+ << tenant << ": " << dendl;
+ return -EINVAL;
+ }
+
+ // Delete url
+ std::string oid = tenant + get_url_oid_prefix() + url;
+ ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: deleting oidc url from pool: " << pool.name << ": "
+ << provider_url << ": " << cpp_strerror(-ret) << dendl;
+ }
+
+ return ret;
+}
+
+int RadosRole::store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
+{
+ using ceph::encode;
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = get_info_oid_prefix() + id;
+
+ bufferlist bl;
+ encode(*this, bl);
+
+ return rgw_put_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, exclusive, nullptr, real_time(), y);
+}
+
+int RadosRole::store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ RGWNameToId nameToId;
+ nameToId.obj_id = id;
+
+ std::string oid = tenant + get_names_oid_prefix() + name;
+
+ bufferlist bl;
+ using ceph::encode;
+ encode(nameToId, bl);
+
+ return rgw_put_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, exclusive, nullptr, real_time(), y);
+}
+
+int RadosRole::store_path(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = tenant + get_path_oid_prefix() + path + get_info_oid_prefix() + id;
+
+ bufferlist bl;
+
+ return rgw_put_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, exclusive, nullptr, real_time(), y);
+}
+
+int RadosRole::read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = tenant + get_names_oid_prefix() + role_name;
+ bufferlist bl;
+
+ int ret = rgw_get_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, nullptr, nullptr, null_yield, dpp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ RGWNameToId nameToId;
+ try {
+ auto iter = bl.cbegin();
+ using ceph::decode;
+ decode(nameToId, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode role from Role pool: " << role_name << dendl;
+ return -EIO;
+ }
+ role_id = nameToId.obj_id;
+ return 0;
+}
+
+int RadosRole::read_name(const DoutPrefixProvider *dpp, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = tenant + get_names_oid_prefix() + name;
+ bufferlist bl;
+
+ int ret = rgw_get_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, nullptr, nullptr, null_yield, dpp);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed reading role name from Role pool: " << name <<
+ ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ RGWNameToId nameToId;
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(nameToId, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode role name from Role pool: " << name << dendl;
+ return -EIO;
+ }
+ id = nameToId.obj_id;
+ return 0;
+}
+
+int RadosRole::read_info(const DoutPrefixProvider *dpp, optional_yield y)
+{
+ auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
+ std::string oid = get_info_oid_prefix() + id;
+ bufferlist bl;
+
+ int ret = rgw_get_system_obj(obj_ctx, store->get_zone()->get_params().roles_pool, oid, bl, nullptr, nullptr, null_yield, dpp);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: failed reading role info from Role pool: " << id << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ try {
+ using ceph::decode;
+ auto iter = bl.cbegin();
+ decode(*this, iter);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode role info from Role pool: " << id << dendl;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
+{
+ int ret;
+
+ if (! validate_input(dpp)) {
+ return -EINVAL;
+ }
+
+ /* check to see the name is not used */
+ ret = read_id(dpp, name, tenant, id, y);
+ if (exclusive && ret == 0) {
+ ldpp_dout(dpp, 0) << "ERROR: name " << name << " already in use for role id "
+ << id << dendl;
+ return -EEXIST;
+ } else if ( ret < 0 && ret != -ENOENT) {
+ ldpp_dout(dpp, 0) << "failed reading role id " << id << ": "
+ << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ /* create unique id */
+ uuid_d new_uuid;
+ char uuid_str[37];
+ new_uuid.generate_random();
+ new_uuid.print(uuid_str);
+ id = uuid_str;
+
+ //arn
+ arn = role_arn_prefix + tenant + ":role" + path + name;
+
+ // Creation time
+ real_clock::time_point t = real_clock::now();
+
+ struct timeval tv;
+ real_clock::to_timeval(t, tv);
+
+ char buf[30];
+ struct tm result;
+ gmtime_r(&tv.tv_sec, &result);
+ strftime(buf,30,"%Y-%m-%dT%H:%M:%S", &result);
+ sprintf(buf + strlen(buf),".%dZ",(int)tv.tv_usec/1000);
+ creation_date.assign(buf, strlen(buf));
+
+ auto& pool = store->get_zone()->get_params().roles_pool;
+ ret = store_info(dpp, exclusive, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: storing role info in Role pool: "
+ << id << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ ret = store_name(dpp, exclusive, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: storing role name in Role pool: "
+ << name << ": " << cpp_strerror(-ret) << dendl;
+
+ //Delete the role info that was stored in the previous call
+ std::string oid = get_info_oid_prefix() + id;
+ int info_ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (info_ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: cleanup of role id from Role pool: "
+ << id << ": " << cpp_strerror(-info_ret) << dendl;
+ }
+ return ret;
+ }
+
+ ret = store_path(dpp, exclusive, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: storing role path in Role pool: "
+ << path << ": " << cpp_strerror(-ret) << dendl;
+ //Delete the role info that was stored in the previous call
+ std::string oid = get_info_oid_prefix() + id;
+ int info_ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (info_ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: cleanup of role id from Role pool: "
+ << id << ": " << cpp_strerror(-info_ret) << dendl;
+ }
+ //Delete role name that was stored in previous call
+ oid = tenant + get_names_oid_prefix() + name;
+ int name_ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (name_ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: cleanup of role name from Role pool: "
+ << name << ": " << cpp_strerror(-name_ret) << dendl;
+ }
+ return ret;
+ }
+ return 0;
+}
+
+int RadosRole::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
+{
+ auto& pool = store->get_zone()->get_params().roles_pool;
+
+ int ret = read_name(dpp, y);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = read_info(dpp, y);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (! perm_policy_map.empty()) {
+ return -ERR_DELETE_CONFLICT;
+ }
+
+ // Delete id
+ std::string oid = get_info_oid_prefix() + id;
+ ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: deleting role id from Role pool: "
+ << id << ": " << cpp_strerror(-ret) << dendl;
+ }
+
+ // Delete name
+ oid = tenant + get_names_oid_prefix() + name;
+ ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: deleting role name from Role pool: "
+ << name << ": " << cpp_strerror(-ret) << dendl;
+ }
+
+ // Delete path
+ oid = tenant + get_path_oid_prefix() + path + get_info_oid_prefix() + id;
+ ret = rgw_delete_system_obj(store->svc()->sysobj, pool, oid, nullptr, y);
+ if (ret < 0) {
+ ldpp_dout(dpp, 0) << "ERROR: deleting role path from Role pool: "
+ << path << ": " << cpp_strerror(-ret) << dendl;
+ }
+ return ret;
+}
+
+
} // namespace rgw::sal
extern "C" {
#include "rgw_sal.h"
#include "rgw_rados.h"
#include "rgw_notify.h"
+#include "rgw_oidc_provider.h"
+#include "rgw_role.h"
#include "cls/lock/cls_lock_client.h"
namespace rgw { namespace sal {
virtual int register_to_service_map(const std::string& daemon_type,
const map<std::string, std::string>& meta) override;
virtual void get_quota(RGWQuotaInfo& bucket_quota, RGWQuotaInfo& user_quota) override;
- virtual int list_raw_objects(const rgw_pool& pool, const std::string& prefix_filter,
- int max, RGWListRawObjsCtx& ctx, std::list<std::string>& oids,
- bool* is_truncated) override;
virtual int set_buckets_enabled(const DoutPrefixProvider* dpp, vector<rgw_bucket>& buckets, bool enabled) override;
virtual uint64_t get_new_req_id() override { return rados->get_new_req_id(); }
virtual int get_sync_policy_handler(const DoutPrefixProvider* dpp,
map<rgw_user_bucket, rgw_usage_log_entry>& usage) override;
virtual int trim_all_usage(uint64_t start_epoch, uint64_t end_epoch) override;
virtual int get_config_key_val(std::string name, bufferlist* bl) override;
- virtual int put_system_obj(const rgw_pool& pool, const std::string& oid,
- bufferlist& data, bool exclusive,
- RGWObjVersionTracker* objv_tracker, real_time set_mtime,
- optional_yield y, map<std::string, bufferlist> *pattrs = nullptr)
- override;
- virtual int get_system_obj(const DoutPrefixProvider* dpp,
- const rgw_pool& pool, const std::string& key,
- bufferlist& bl,
- RGWObjVersionTracker* objv_tracker, real_time* pmtime,
- optional_yield y, map<std::string, bufferlist> *pattrs = nullptr,
- rgw_cache_entry_info* cache_info = nullptr,
- boost::optional<obj_version> refresh_version = boost::none) override;
- virtual int delete_system_obj(const rgw_pool& pool, const std::string& oid,
- RGWObjVersionTracker* objv_tracker, optional_yield y) override;
virtual int meta_list_keys_init(const std::string& section, const std::string& marker, void** phandle) override;
virtual int meta_list_keys_next(void* handle, int max, list<std::string>& keys, bool* truncated) override;
virtual void meta_list_keys_complete(void* handle) override;
virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) override;
virtual const RGWSyncModuleInstanceRef& get_sync_module() { return rados->get_sync_module(); }
virtual std::string get_host_id() { return rados->host_id; }
+ virtual std::unique_ptr<LuaScriptManager> get_lua_script_manager() override;
+ virtual std::unique_ptr<RGWRole> get_role(string name,
+ string tenant,
+ string path="",
+ string trust_policy="",
+ string max_session_duration_str="") override;
+ virtual std::unique_ptr<RGWRole> get_role(std::string id) override;
+ virtual int get_roles(const DoutPrefixProvider *dpp,
+ optional_yield y,
+ const std::string& path_prefix,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWRole>>& roles) override;
+ virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
+ virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
+ const std::string& tenant,
+ vector<std::unique_ptr<RGWOIDCProvider>>& providers) override;
virtual void finalize(void) override;
virtual int drain() override;
};
+class RadosLuaScriptManager : public LuaScriptManager {
+ RadosStore* store;
+ rgw_pool pool;
+
+public:
+ RadosLuaScriptManager(RadosStore* _s) : store(_s)
+ {
+ pool = store->get_zone()->get_params().log_pool;
+ }
+ virtual ~RadosLuaScriptManager() = default;
+
+ virtual int get(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) override;
+ virtual int put(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) override;
+ virtual int del(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) override;
+};
+
+class RadosOIDCProvider : public RGWOIDCProvider {
+ RadosStore* store;
+public:
+ RadosOIDCProvider(RadosStore* _store) : store(_store) {}
+ ~RadosOIDCProvider() = default;
+
+ virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override;
+ virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant) override;
+ virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override;
+ void encode(bufferlist& bl) const {
+ RGWOIDCProvider::encode(bl);
+ }
+ void decode(bufferlist::const_iterator& bl) {
+ RGWOIDCProvider::decode(bl);
+ }
+};
+
+class RadosRole : public RGWRole {
+ RadosStore* store;
+public:
+ RadosRole(RadosStore* _store, std::string name,
+ std::string tenant,
+ std::string path,
+ std::string trust_policy,
+ std::string max_session_duration) : RGWRole(name, tenant, path, trust_policy, max_session_duration), store(_store) {}
+ RadosRole(RadosStore* _store, std::string id) : RGWRole(id), store(_store) {}
+ ~RadosRole() = default;
+
+ virtual int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override;
+ virtual int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override;
+ virtual int store_path(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override;
+ virtual int read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y) override;
+ virtual int read_name(const DoutPrefixProvider *dpp, optional_yield y) override;
+ virtual int read_info(const DoutPrefixProvider *dpp, optional_yield y) override;
+ virtual int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override;
+ virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override;
+};
+
} } // namespace rgw::sal
+
+WRITE_CLASS_ENCODER(rgw::sal::RadosOIDCProvider)
return AssumeRoleRequestBase::validate_input();
}
-std::tuple<int, RGWRole> STSService::getRoleInfo(const DoutPrefixProvider *dpp,
+std::tuple<int, rgw::sal::RGWRole*> STSService::getRoleInfo(const DoutPrefixProvider *dpp,
const string& arn,
optional_yield y)
{
if (auto r_arn = rgw::ARN::parse(arn); r_arn) {
auto pos = r_arn->resource.find_last_of('/');
string roleName = r_arn->resource.substr(pos + 1);
- RGWRole role(cct, store, roleName, r_arn->account);
- if (int ret = role.get(dpp, y); ret < 0) {
+ std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(roleName, r_arn->account);
+ if (int ret = role->get(dpp, y); ret < 0) {
if (ret == -ENOENT) {
ldpp_dout(dpp, 0) << "Role doesn't exist: " << roleName << dendl;
ret = -ERR_NO_ROLE_FOUND;
}
- return make_tuple(ret, this->role);
+ return make_tuple(ret, nullptr);
} else {
auto path_pos = r_arn->resource.find('/');
string path;
} else {
path = r_arn->resource.substr(path_pos, ((pos - path_pos) + 1));
}
- string r_path = role.get_path();
+ string r_path = role->get_path();
if (path != r_path) {
ldpp_dout(dpp, 0) << "Invalid Role ARN: Path in ARN does not match with the role path: " << path << " " << r_path << dendl;
- return make_tuple(-EACCES, this->role);
+ return make_tuple(-EACCES, nullptr);
}
this->role = std::move(role);
- return make_tuple(0, this->role);
+ return make_tuple(0, this->role.get());
}
} else {
ldpp_dout(dpp, 0) << "Invalid role arn: " << arn << dendl;
- return make_tuple(-EINVAL, this->role);
+ return make_tuple(-EINVAL, nullptr);
}
}
return response;
}
- string roleId = role.get_id();
- uint64_t roleMaxSessionDuration = role.get_max_session_duration();
+ string roleId = role->get_id();
+ uint64_t roleMaxSessionDuration = role->get_max_session_duration();
req.setMaxDuration(roleMaxSessionDuration);
//Validate input
return response;
}
- string roleId = role.get_id();
- uint64_t roleMaxSessionDuration = role.get_max_session_duration();
+ string roleId = role->get_id();
+ uint64_t roleMaxSessionDuration = role->get_max_session_duration();
req.setMaxDuration(roleMaxSessionDuration);
//Validate input
CephContext* cct;
rgw::sal::Store* store;
rgw_user user_id;
- RGWRole role;
+ std::unique_ptr<rgw::sal::RGWRole> role;
rgw::auth::Identity* identity;
int storeARN(const DoutPrefixProvider *dpp, string& arn, optional_yield y);
public:
STSService(CephContext* cct, rgw::sal::Store* store, rgw_user user_id,
rgw::auth::Identity* identity)
: cct(cct), store(store), user_id(user_id), identity(identity) {}
- std::tuple<int, RGWRole> getRoleInfo(const DoutPrefixProvider *dpp, const string& arn, optional_yield y);
+ std::tuple<int, rgw::sal::RGWRole*> getRoleInfo(const DoutPrefixProvider *dpp, const string& arn, optional_yield y);
AssumeRoleResponse assumeRole(const DoutPrefixProvider *dpp, AssumeRoleRequest& req, optional_yield y);
GetSessionTokenResponse getSessionToken(GetSessionTokenRequest& req);
AssumeRoleWithWebIdentityResponse assumeRoleWithWebIdentity(AssumeRoleWithWebIdentityRequest& req);