From 65c80d7e63f12a76857726bab929261717adb75b Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 10 Nov 2023 12:31:11 -0500 Subject: [PATCH] rgw: use rgw_owner in RGWBucketInfo Signed-off-by: Casey Bodley --- src/rgw/driver/d4n/rgw_sal_d4n.cc | 3 +- src/rgw/driver/d4n/rgw_sal_d4n.h | 1 + src/rgw/driver/daos/rgw_sal_daos.cc | 17 ++- src/rgw/driver/daos/rgw_sal_daos.h | 17 ++- src/rgw/driver/dbstore/common/dbstore.cc | 33 ++-- src/rgw/driver/dbstore/common/dbstore.h | 25 ++-- src/rgw/driver/dbstore/sqlite/sqliteDB.cc | 15 +- src/rgw/driver/dbstore/tests/dbstore_tests.cc | 16 +- src/rgw/driver/motr/rgw_sal_motr.cc | 17 ++- src/rgw/driver/motr/rgw_sal_motr.h | 15 +- src/rgw/driver/posix/rgw_sal_posix.cc | 13 +- src/rgw/driver/posix/rgw_sal_posix.h | 13 +- src/rgw/driver/rados/rgw_bucket.cc | 24 ++- src/rgw/driver/rados/rgw_bucket.h | 10 +- src/rgw/driver/rados/rgw_bucket_sync.cc | 9 -- src/rgw/driver/rados/rgw_cr_rados.cc | 2 +- src/rgw/driver/rados/rgw_data_sync.cc | 2 +- src/rgw/driver/rados/rgw_notify.cc | 2 +- src/rgw/driver/rados/rgw_rados.cc | 23 +-- src/rgw/driver/rados/rgw_rados.h | 13 +- src/rgw/driver/rados/rgw_reshard.cc | 2 +- src/rgw/driver/rados/rgw_sal_rados.cc | 65 +++++--- src/rgw/driver/rados/rgw_sal_rados.h | 17 ++- src/rgw/driver/rados/rgw_sync_module_aws.cc | 6 +- src/rgw/driver/rados/rgw_sync_module_es.cc | 6 +- src/rgw/rgw_admin.cc | 20 +-- src/rgw/rgw_auth.cc | 16 +- src/rgw/rgw_common.cc | 45 ++++-- src/rgw/rgw_common.h | 2 +- src/rgw/rgw_crypt.cc | 9 +- src/rgw/rgw_lc.cc | 2 +- src/rgw/rgw_lua_request.cc | 15 +- src/rgw/rgw_op.cc | 141 ++++++++++++------ src/rgw/rgw_quota.cc | 4 +- src/rgw/rgw_rest.cc | 6 +- src/rgw/rgw_rest_s3.cc | 6 +- src/rgw/rgw_rest_swift.cc | 13 +- src/rgw/rgw_sal.h | 27 ++-- src/rgw/rgw_sal_dbstore.cc | 26 ++-- src/rgw/rgw_sal_dbstore.h | 13 +- src/rgw/rgw_sal_filter.cc | 30 ++-- src/rgw/rgw_sal_filter.h | 22 ++- src/rgw/rgw_sal_store.h | 2 +- src/rgw/rgw_swift_auth.cc | 7 +- src/rgw/rgw_user.cc | 2 +- src/test/rgw/test_rgw_lua.cc | 12 +- 46 files changed, 468 insertions(+), 318 deletions(-) diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.cc b/src/rgw/driver/d4n/rgw_sal_d4n.cc index 41c216c178f..1afd6822fe2 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.cc +++ b/src/rgw/driver/d4n/rgw_sal_d4n.cc @@ -111,6 +111,7 @@ int D4NFilterBucket::create(const DoutPrefixProvider* dpp, } int D4NFilterObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -197,7 +198,7 @@ int D4NFilterObject::copy_object(const ACLOwner& owner, } }*/ - return next->copy_object(owner, info, source_zone, + return next->copy_object(owner, remote_user, info, source_zone, nextObject(dest_object), nextBucket(dest_bucket), nextBucket(src_bucket), diff --git a/src/rgw/driver/d4n/rgw_sal_d4n.h b/src/rgw/driver/d4n/rgw_sal_d4n.h index 73b399d46dc..8210496219c 100644 --- a/src/rgw/driver/d4n/rgw_sal_d4n.h +++ b/src/rgw/driver/d4n/rgw_sal_d4n.h @@ -179,6 +179,7 @@ class D4NFilterObject : public FilterObject { virtual ~D4NFilterObject() = default; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, diff --git a/src/rgw/driver/daos/rgw_sal_daos.cc b/src/rgw/driver/daos/rgw_sal_daos.cc index 98e708d645e..765655d7430 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.cc +++ b/src/rgw/driver/daos/rgw_sal_daos.cc @@ -499,8 +499,8 @@ int DaosBucket::read_stats_async( return DAOS_NOT_IMPLEMENTED_LOG(dpp); } -int DaosBucket::sync_user_stats(const DoutPrefixProvider* dpp, - optional_yield y) { +int DaosBucket::sync_owner_stats(const DoutPrefixProvider* dpp, + optional_yield y) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } @@ -508,7 +508,7 @@ int DaosBucket::check_bucket_shards(const DoutPrefixProvider* dpp) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } -int DaosBucket::chown(const DoutPrefixProvider* dpp, User& new_user, +int DaosBucket::chown(const DoutPrefixProvider* dpp, const rgw_owner& new_user, optional_yield y) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } @@ -1207,7 +1207,8 @@ int DaosObject::delete_object(const DoutPrefixProvider* dpp, optional_yield y, } int DaosObject::copy_object( - const ACLOwner& owner, req_info* info, const rgw_zone_id& source_zone, + const ACLOwner& owner, const rgw_user& remote_user, + req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, const rgw_placement_rule& dest_placement, ceph::real_time* src_mtime, ceph::real_time* mtime, @@ -1221,13 +1222,13 @@ int DaosObject::copy_object( return DAOS_NOT_IMPLEMENTED_LOG(dpp); } -int DaosObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, - const DoutPrefixProvider* dpp) { +int DaosObject::swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, + const DoutPrefixProvider* dpp, optional_yield y) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } -int DaosObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) { +int DaosObject::swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) { return DAOS_NOT_IMPLEMENTED_LOG(dpp); } diff --git a/src/rgw/driver/daos/rgw_sal_daos.h b/src/rgw/driver/daos/rgw_sal_daos.h index a01c2c2d0c3..b4f65c5d82f 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.h +++ b/src/rgw/driver/daos/rgw_sal_daos.h @@ -312,10 +312,10 @@ class DaosBucket : public StoreBucket { const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - virtual int sync_user_stats(const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int sync_owner_stats(const DoutPrefixProvider* dpp, + optional_yield y) override; virtual int check_bucket_shards(const DoutPrefixProvider* dpp) override; - virtual int chown(const DoutPrefixProvider* dpp, User& new_user, + virtual int chown(const DoutPrefixProvider* dpp, const rgw_owner& new_user, optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) override; @@ -602,7 +602,8 @@ class DaosObject : public StoreObject { virtual int delete_object(const DoutPrefixProvider* dpp, optional_yield y, uint32_t flags) override; virtual int copy_object( - const ACLOwner& owner, req_info* info, const rgw_zone_id& source_zone, + const ACLOwner& owner, const rgw_user& remote_user, + req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, const rgw_placement_rule& dest_placement, ceph::real_time* src_mtime, ceph::real_time* mtime, @@ -657,10 +658,10 @@ class DaosObject : public StoreObject { Formatter* f) override; /* Swift versioning */ - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, - const DoutPrefixProvider* dpp) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, + const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) override; /* OPs */ virtual std::unique_ptr get_read_op() override; diff --git a/src/rgw/driver/dbstore/common/dbstore.cc b/src/rgw/driver/dbstore/common/dbstore.cc index 5a4ae021ead..d548bc4d8c0 100644 --- a/src/rgw/driver/dbstore/common/dbstore.cc +++ b/src/rgw/driver/dbstore/common/dbstore.cc @@ -474,7 +474,7 @@ out: } int DB::create_bucket(const DoutPrefixProvider *dpp, - const rgw_user& owner, const rgw_bucket& bucket, + const rgw_owner& owner, const rgw_bucket& bucket, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, const std::map& attrs, @@ -502,7 +502,7 @@ int DB::create_bucket(const DoutPrefixProvider *dpp, orig_info.bucket.name = bucket.name; ret = get_bucket_info(dpp, string("name"), "", orig_info, nullptr, nullptr, nullptr); - if (!ret && !orig_info.owner.id.empty()) { + if (!ret && !orig_info.bucket.bucket_id.empty()) { /* already exists. Return the old info */ info = std::move(orig_info); return ret; @@ -543,7 +543,7 @@ int DB::create_bucket(const DoutPrefixProvider *dpp, params.op.bucket.info = info; params.op.bucket.bucket_attrs = attrs; params.op.bucket.mtime = ceph::real_time(); - params.op.user.uinfo.user_id.id = owner.id; + params.op.bucket.owner = to_string(owner); ret = ProcessOp(dpp, "InsertBucket", ¶ms); @@ -576,7 +576,7 @@ out: } int DB::list_buckets(const DoutPrefixProvider *dpp, const std::string& query_str, - rgw_user& user, + std::string& owner, const string& marker, const string& end_marker, uint64_t max, @@ -589,7 +589,7 @@ int DB::list_buckets(const DoutPrefixProvider *dpp, const std::string& query_str DBOpParams params = {}; InitializeParams(dpp, ¶ms); - params.op.user.uinfo.user_id = user; + params.op.bucket.owner = owner; params.op.bucket.min_marker = marker; params.op.bucket.max_marker = end_marker; params.op.list_max_count = max; @@ -619,7 +619,7 @@ int DB::list_buckets(const DoutPrefixProvider *dpp, const std::string& query_str if (query_str == "all") { // userID/OwnerID may have changed. Update it. - user.id = params.op.bucket.info.owner.id; + owner = to_string(params.op.bucket.info.owner); } out: @@ -629,7 +629,7 @@ out: int DB::update_bucket(const DoutPrefixProvider *dpp, const std::string& query_str, RGWBucketInfo& info, bool exclusive, - const rgw_user* powner_id, + const rgw_owner* powner, map* pattrs, ceph::real_time* pmtime, RGWObjVersionTracker* pobjv) @@ -650,7 +650,7 @@ int DB::update_bucket(const DoutPrefixProvider *dpp, const std::string& query_st goto out; } - if (!orig_info.owner.id.empty() && exclusive) { + if (!orig_info.bucket.bucket_id.empty() && exclusive) { /* already exists. Return the old info */ info = std::move(orig_info); @@ -672,17 +672,17 @@ int DB::update_bucket(const DoutPrefixProvider *dpp, const std::string& query_st params.op.bucket.info.bucket.name = info.bucket.name; - if (powner_id) { - params.op.user.uinfo.user_id.id = powner_id->id; + if (powner) { + params.op.bucket.owner = to_string(*powner); } else { - params.op.user.uinfo.user_id.id = orig_info.owner.id; + params.op.bucket.owner = to_string(orig_info.owner); } /* Update version & mtime */ params.op.bucket.bucket_version.ver = ++(bucket_version.ver); if (pmtime) { - params.op.bucket.mtime = *pmtime;; + params.op.bucket.mtime = *pmtime; } else { params.op.bucket.mtime = ceph::real_time(); } @@ -1771,7 +1771,7 @@ int DB::Object::Write::_do_write_meta(const DoutPrefixProvider *dpp, params.op.obj.state.exists = true; params.op.obj.state.size = size; params.op.obj.state.accounted_size = accounted_size; - params.op.obj.owner = target->get_bucket_info().owner.id; + params.op.obj.owner = to_string(target->get_bucket_info().owner); params.op.obj.category = meta.category; if (meta.mtime) { @@ -2201,12 +2201,11 @@ void *DB::GC::entry() { do { std::string& marker = bucket_marker; - rgw_user user; - user.id = user_marker; + std::string owner = user_marker; buckets.clear(); is_truncated = false; - int r = db->list_buckets(dpp, "all", user, marker, string(), + int r = db->list_buckets(dpp, "all", owner, marker, string(), max, false, &buckets, &is_truncated); if (r < 0) { //do nothing? retry later ? @@ -2222,7 +2221,7 @@ void *DB::GC::entry() { ldpp_dout(dpp, 2) << " delete_stale_objs failed for bucket( " << bname <<")" << dendl; } bucket_marker = bname; - user_marker = user.id; + user_marker = owner; /* XXX: If using locks, unlock here and reacquire in the next iteration */ cv.wait_for(lk, std::chrono::milliseconds(100)); diff --git a/src/rgw/driver/dbstore/common/dbstore.h b/src/rgw/driver/dbstore/common/dbstore.h index 8cf6f70f751..3f8191f5a92 100644 --- a/src/rgw/driver/dbstore/common/dbstore.h +++ b/src/rgw/driver/dbstore/common/dbstore.h @@ -35,7 +35,7 @@ struct DBOpUserInfo { struct DBOpBucketInfo { RGWBucketEnt ent; // maybe not needed. not used in create/get_bucket RGWBucketInfo info; - RGWUser* owner = nullptr; + std::string owner; rgw::sal::Attrs bucket_attrs; obj_version bucket_version; ceph::real_time mtime; @@ -482,9 +482,7 @@ class DBOp { BucketVersion INTEGER, \ BucketVersionTag TEXT, \ Mtime BLOB, \ - PRIMARY KEY (BucketName) \ - FOREIGN KEY (OwnerID) \ - REFERENCES '{}' (UserID) ON DELETE CASCADE ON UPDATE CASCADE \n);"; + PRIMARY KEY (BucketName) \n);"; static constexpr std::string_view CreateObjectTableTriggerQ = "CREATE TRIGGER IF NOT EXISTS '{}' \ @@ -931,22 +929,20 @@ class RemoveBucketOp: virtual public DBOp { class GetBucketOp: virtual public DBOp { private: static constexpr std::string_view Query = "SELECT \ - BucketName, BucketTable.Tenant, Marker, BucketID, Size, SizeRounded, CreationTime, \ - Count, BucketTable.PlacementName, BucketTable.PlacementStorageClass, OwnerID, Flags, Zonegroup, \ + BucketName, Tenant, Marker, BucketID, Size, SizeRounded, CreationTime, \ + Count, PlacementName, PlacementStorageClass, OwnerID, Flags, Zonegroup, \ HasInstanceObj, Quota, RequesterPays, HasWebsite, WebsiteConf, \ SwiftVersioning, SwiftVerLocation, \ MdsearchConfig, NewBucketInstanceID, ObjectLock, \ - SyncPolicyInfoGroups, BucketAttrs, BucketVersion, BucketVersionTag, Mtime, NS \ - from '{}' as BucketTable INNER JOIN '{}' ON OwnerID = UserID where BucketName = {}"; + SyncPolicyInfoGroups, BucketAttrs, BucketVersion, BucketVersionTag, Mtime \ + from '{}' where BucketName = {}"; public: virtual ~GetBucketOp() {} static std::string Schema(DBOpPrepareParams ¶ms) { - //return fmt::format(Query, params.op.bucket.bucket_name, - // params.bucket_table, params.user_table); return fmt::format(Query, - params.bucket_table, params.user_table, + params.bucket_table, params.op.bucket.bucket_name); } }; @@ -1596,7 +1592,7 @@ class DB { RGWBucketInfo& info, rgw::sal::Attrs* pattrs, ceph::real_time* pmtime, obj_version* pbucket_version); int create_bucket(const DoutPrefixProvider *dpp, - const rgw_user& owner, const rgw_bucket& bucket, + const rgw_owner& owner, const rgw_bucket& bucket, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, const std::map& attrs, @@ -1611,7 +1607,7 @@ class DB { int remove_bucket(const DoutPrefixProvider *dpp, const RGWBucketInfo info); int list_buckets(const DoutPrefixProvider *dpp, const std::string& query_str, - rgw_user& user, + std::string& owner, const std::string& marker, const std::string& end_marker, uint64_t max, @@ -1620,7 +1616,7 @@ class DB { bool *is_truncated); int update_bucket(const DoutPrefixProvider *dpp, const std::string& query_str, RGWBucketInfo& info, bool exclusive, - const rgw_user* powner_id, std::map* pattrs, + const rgw_owner* powner, std::map* pattrs, ceph::real_time* pmtime, RGWObjVersionTracker* pobjv); uint64_t get_max_head_size() { return ObjHeadSize; } @@ -1909,7 +1905,6 @@ class DB { DB::Object *target; struct DeleteParams { - rgw_user bucket_owner; int versioning_status; ACLOwner obj_owner; /* needed for creation of deletion marker */ uint64_t olh_epoch; diff --git a/src/rgw/driver/dbstore/sqlite/sqliteDB.cc b/src/rgw/driver/dbstore/sqlite/sqliteDB.cc index 81c716c27f1..554d8fe94cf 100644 --- a/src/rgw/driver/dbstore/sqlite/sqliteDB.cc +++ b/src/rgw/driver/dbstore/sqlite/sqliteDB.cc @@ -2,6 +2,7 @@ // vim: ts=8 sw=2 smarttab #include "sqliteDB.h" +#include "rgw_account.h" using namespace std; @@ -421,12 +422,8 @@ static int list_bucket(const DoutPrefixProvider *dpp, DBOpInfo &op, sqlite3_stmt op.bucket.info.placement_rule = op.bucket.ent.placement_rule; op.bucket.info.creation_time = op.bucket.ent.creation_time; - op.bucket.info.owner.id = (const char*)sqlite3_column_text(stmt, OwnerID); - op.bucket.info.owner.tenant = op.bucket.ent.bucket.tenant; - - if (op.name == "GetBucket") { - op.bucket.info.owner.ns = (const char*)sqlite3_column_text(stmt, Bucket_User_NS); - } + const char* owner_id = (const char*)sqlite3_column_text(stmt, OwnerID); + op.bucket.info.owner = parse_owner(owner_id); op.bucket.info.flags = sqlite3_column_int(stmt, Flags); op.bucket.info.zonegroup = (const char*)sqlite3_column_text(stmt, Zonegroup); @@ -1339,7 +1336,7 @@ int SQLInsertBucket::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *para // user_id here is copied as OwnerID in the bucket table. SQL_BIND_INDEX(dpp, stmt, index, p_params.op.user.user_id, sdb); - SQL_BIND_TEXT(dpp, stmt, index, params->op.user.uinfo.user_id.id.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.bucket.owner.c_str(), sdb); SQL_BIND_INDEX(dpp, stmt, index, p_params.op.bucket.bucket_name, sdb); SQL_BIND_TEXT(dpp, stmt, index, params->op.bucket.info.bucket.name.c_str(), sdb); @@ -1567,7 +1564,7 @@ int SQLUpdateBucket::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *para } SQL_BIND_INDEX(dpp, *stmt, index, p_params.op.user.user_id, sdb); - SQL_BIND_TEXT(dpp, *stmt, index, params->op.user.uinfo.user_id.id.c_str(), sdb); + SQL_BIND_TEXT(dpp, *stmt, index, params->op.bucket.owner.c_str(), sdb); SQL_BIND_INDEX(dpp, *stmt, index, p_params.op.bucket.bucket_name, sdb); SQL_BIND_TEXT(dpp, *stmt, index, params->op.bucket.info.bucket.name.c_str(), sdb); @@ -1732,7 +1729,7 @@ int SQLListUserBuckets::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *p if (params->op.query_str != "all") { SQL_BIND_INDEX(dpp, *pstmt, index, p_params.op.user.user_id, sdb); - SQL_BIND_TEXT(dpp, *pstmt, index, params->op.user.uinfo.user_id.id.c_str(), sdb); + SQL_BIND_TEXT(dpp, *pstmt, index, params->op.bucket.owner.c_str(), sdb); } SQL_BIND_INDEX(dpp, *pstmt, index, p_params.op.bucket.min_marker, sdb); diff --git a/src/rgw/driver/dbstore/tests/dbstore_tests.cc b/src/rgw/driver/dbstore/tests/dbstore_tests.cc index 14fe9c37e75..c89addeade1 100644 --- a/src/rgw/driver/dbstore/tests/dbstore_tests.cc +++ b/src/rgw/driver/dbstore/tests/dbstore_tests.cc @@ -96,6 +96,7 @@ namespace { GlobalParams.op.user.uinfo.display_name = user1; GlobalParams.op.user.uinfo.user_id.id = user_id1; GlobalParams.op.bucket.info.bucket.name = bucket1; + GlobalParams.op.bucket.owner = user_id1; GlobalParams.op.obj.state.obj.bucket = GlobalParams.op.bucket.info.bucket; GlobalParams.op.obj.state.obj.key.name = object1; GlobalParams.op.obj.state.obj.key.instance = "inst1"; @@ -444,7 +445,7 @@ TEST_F(DBStoreTest, GetBucket) { ASSERT_EQ(params.op.bucket.info.objv_tracker.read_version.ver, 3); ASSERT_EQ(params.op.bucket.info.objv_tracker.read_version.tag, "read_tag"); ASSERT_EQ(params.op.bucket.mtime, bucket_mtime); - ASSERT_EQ(params.op.bucket.info.owner.id, "user_id1"); + ASSERT_EQ(to_string(params.op.bucket.info.owner), "user_id1"); bufferlist k, k2; string acl; map::iterator it2 = params.op.bucket.bucket_attrs.begin(); @@ -507,7 +508,7 @@ TEST_F(DBStoreTest, GetBucketQueryByName) { ASSERT_EQ(ret, 0); ASSERT_EQ(binfo.bucket.name, "bucket2"); ASSERT_EQ(binfo.bucket.tenant, "tenant"); - ASSERT_EQ(binfo.owner.id, "user_id1"); + ASSERT_EQ(to_string(binfo.owner), "user_id1"); ASSERT_EQ(binfo.objv_tracker.read_version.ver, 1); ASSERT_FALSE(binfo.objv_tracker.read_version.tag.empty()); ASSERT_EQ(binfo.zonegroup, "zid"); @@ -523,14 +524,12 @@ TEST_F(DBStoreTest, GetBucketQueryByName) { TEST_F(DBStoreTest, ListUserBuckets) { struct DBOpParams params = GlobalParams; int ret = -1; - rgw_user owner; + std::string owner = "user_id1"; int max = 2; bool need_stats = true; bool is_truncated = false; RGWUserBuckets ulist; - owner.id = "user_id1"; - marker1 = ""; do { is_truncated = false; @@ -560,8 +559,7 @@ TEST_F(DBStoreTest, ListUserBuckets) { TEST_F(DBStoreTest, BucketChown) { int ret = -1; RGWBucketInfo info; - rgw_user user; - user.id = "user_id2"; + rgw_owner user = rgw_user{"user_id2"}; info.bucket.name = "bucket5"; @@ -581,7 +579,7 @@ TEST_F(DBStoreTest, ListAllBuckets) { TEST_F(DBStoreTest, ListAllBuckets2) { struct DBOpParams params = GlobalParams; int ret = -1; - rgw_user owner; + std::string owner; // empty int max = 2; bool need_stats = true; bool is_truncated = false; @@ -595,7 +593,7 @@ TEST_F(DBStoreTest, ListAllBuckets2) { ASSERT_EQ(ret, 0); cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n"; - cout << "ownerID : " << owner.id << "\n"; + cout << "ownerID : " << owner << "\n"; cout << "marker1 :" << marker1 << "\n"; cout << "is_truncated :" << is_truncated << "\n"; diff --git a/src/rgw/driver/motr/rgw_sal_motr.cc b/src/rgw/driver/motr/rgw_sal_motr.cc index 92c07ff95e4..32ede60d8df 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.cc +++ b/src/rgw/driver/motr/rgw_sal_motr.cc @@ -607,7 +607,7 @@ int MotrBucket::remove(const DoutPrefixProvider *dpp, bool delete_children, opti } // 4. Sync user stats. - ret = this->sync_user_stats(dpp, y); + ret = this->sync_owner_stats(dpp, y); if (ret < 0) { ldout(store->ctx(), 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl; } @@ -808,8 +808,8 @@ int MotrBucket::read_stats_async(const DoutPrefixProvider *dpp, return 0; } -int MotrBucket::sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) +int MotrBucket::sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) { return 0; } @@ -820,7 +820,7 @@ int MotrBucket::check_bucket_shards(const DoutPrefixProvider *dpp, return 0; } -int MotrBucket::chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) +int MotrBucket::chown(const DoutPrefixProvider *dpp, const rgw_owner& new_user, optional_yield y) { // TODO: update bucket with new owner return 0; @@ -1511,6 +1511,7 @@ int MotrObject::delete_object(const DoutPrefixProvider* dpp, optional_yield y, u } int MotrObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -1541,14 +1542,14 @@ int MotrObject::copy_object(const ACLOwner& owner, return 0; } -int MotrObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, - const DoutPrefixProvider* dpp) +int MotrObject::swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, + const DoutPrefixProvider* dpp, optional_yield y) { return 0; } -int MotrObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) +int MotrObject::swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) { return 0; } diff --git a/src/rgw/driver/motr/rgw_sal_motr.h b/src/rgw/driver/motr/rgw_sal_motr.h index 9f7cbd9059d..8865b93be88 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.h +++ b/src/rgw/driver/motr/rgw_sal_motr.h @@ -375,11 +375,11 @@ class MotrBucket : public StoreBucket { virtual int read_stats_async(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) override; + int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) override; int check_bucket_shards(const DoutPrefixProvider *dpp, uint64_t num_objs) override; - virtual int chown(const DoutPrefixProvider *dpp, User& new_user, optional_yield y) override; + virtual int chown(const DoutPrefixProvider *dpp, const rgw_owner& new_user, optional_yield y) override; virtual int put_info(const DoutPrefixProvider *dpp, bool exclusive, ceph::real_time mtime) override; virtual bool is_owner(User* user) override; virtual int check_empty(const DoutPrefixProvider *dpp, optional_yield y) override; @@ -680,6 +680,7 @@ class MotrObject : public StoreObject { optional_yield y, uint32_t flags) override; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -718,10 +719,10 @@ class MotrObject : public StoreObject { virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) override; /* Swift versioning */ - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, - const DoutPrefixProvider* dpp) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, + bool& restored, const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) override; /* OPs */ virtual std::unique_ptr get_read_op() override; diff --git a/src/rgw/driver/posix/rgw_sal_posix.cc b/src/rgw/driver/posix/rgw_sal_posix.cc index c4e753bb3a1..1dc548c360c 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.cc +++ b/src/rgw/driver/posix/rgw_sal_posix.cc @@ -967,8 +967,8 @@ int POSIXBucket::read_stats_async(const DoutPrefixProvider *dpp, return 0; } -int POSIXBucket::sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) +int POSIXBucket::sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) { return 0; } @@ -979,7 +979,7 @@ int POSIXBucket::check_bucket_shards(const DoutPrefixProvider* dpp, return 0; } -int POSIXBucket::chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) +int POSIXBucket::chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) { /* TODO map user to UID/GID, and change it */ return 0; @@ -1488,6 +1488,7 @@ int POSIXObject::delete_object(const DoutPrefixProvider* dpp, } int POSIXObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -1690,14 +1691,14 @@ int POSIXObject::dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y return 0; } -int POSIXObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, +int POSIXObject::swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) { return 0; } -int POSIXObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) +int POSIXObject::swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) { return 0; } diff --git a/src/rgw/driver/posix/rgw_sal_posix.h b/src/rgw/driver/posix/rgw_sal_posix.h index e00f6e74c92..785192afee1 100644 --- a/src/rgw/driver/posix/rgw_sal_posix.h +++ b/src/rgw/driver/posix/rgw_sal_posix.h @@ -196,11 +196,11 @@ public: virtual int read_stats_async(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) override; + virtual int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) override; virtual int check_bucket_shards(const DoutPrefixProvider* dpp, uint64_t num_objs, optional_yield y) override; - virtual int chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) override; + virtual int chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime, optional_yield y) override; virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) override; @@ -321,6 +321,7 @@ public: optional_yield y, uint32_t flags) override; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -367,10 +368,10 @@ public: optional_yield y) override; virtual bool placement_rules_match(rgw_placement_rule& r1, rgw_placement_rule& r2) override; virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) override; - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, + virtual int swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) override; virtual std::unique_ptr get_read_op() override; virtual std::unique_ptr get_delete_op() override; virtual int omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid, diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index 8cde25fc199..5af2230a024 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -1074,7 +1074,7 @@ int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_s auto* rados = radosdriver->getRados()->get_rados_handle(); int r = radosdriver->ctl()->bucket->unlink_bucket(*rados, owner.id, old_bucket->get_info().bucket, y, dpp, false); if (r < 0) { - set_err_msg(err, "could not unlink policy from user " + owner.id.to_str()); + set_err_msg(err, "could not unlink bucket from owner " + to_string(owner.id)); return r; } @@ -3284,11 +3284,12 @@ int RGWBucketCtl::read_buckets_stats(std::vector& buckets, }); } -int RGWBucketCtl::sync_user_stats(const DoutPrefixProvider *dpp, - const rgw_user& user_id, - const RGWBucketInfo& bucket_info, - optional_yield y, - RGWBucketEnt* pent) +int RGWBucketCtl::sync_owner_stats(const DoutPrefixProvider *dpp, + librados::Rados& rados, + const rgw_owner& owner, + const RGWBucketInfo& bucket_info, + optional_yield y, + RGWBucketEnt* pent) { RGWBucketEnt ent; if (!pent) { @@ -3300,7 +3301,16 @@ int RGWBucketCtl::sync_user_stats(const DoutPrefixProvider *dpp, return r; } - return svc.user->flush_bucket_stats(dpp, user_id, *pent, y); + // flush stats to the user/account owner object + const rgw_raw_obj& obj = std::visit(fu2::overload( + [&] (const rgw_user& user) { + return svc.user->get_buckets_obj(user); + }, + [&] (const rgw_account_id& id) { + const RGWZoneParams& zone = svc.zone->get_zone_params(); + return rgwrados::account::get_buckets_obj(zone, id); + }), owner); + return rgwrados::buckets::write_stats(dpp, y, rados, obj, *pent); } int RGWBucketCtl::get_sync_policy_handler(std::optional zone, diff --git a/src/rgw/driver/rados/rgw_bucket.h b/src/rgw/driver/rados/rgw_bucket.h index 52098b839c7..d4acaeb4141 100644 --- a/src/rgw/driver/rados/rgw_bucket.h +++ b/src/rgw/driver/rados/rgw_bucket.h @@ -705,10 +705,12 @@ public: const DoutPrefixProvider *dpp); /* quota related */ - int sync_user_stats(const DoutPrefixProvider *dpp, - const rgw_user& user_id, const RGWBucketInfo& bucket_info, - optional_yield y, - RGWBucketEnt* pent); + int sync_owner_stats(const DoutPrefixProvider *dpp, + librados::Rados& rados, + const rgw_owner& owner, + const RGWBucketInfo& bucket_info, + optional_yield y, + RGWBucketEnt* pent); /* bucket sync */ int get_sync_policy_handler(std::optional zone, diff --git a/src/rgw/driver/rados/rgw_bucket_sync.cc b/src/rgw/driver/rados/rgw_bucket_sync.cc index 6ff76c16a90..dafbb6df46f 100644 --- a/src/rgw/driver/rados/rgw_bucket_sync.cc +++ b/src/rgw/driver/rados/rgw_bucket_sync.cc @@ -768,15 +768,6 @@ RGWBucketSyncPolicyHandler::RGWBucketSyncPolicyHandler(const RGWBucketSyncPolicy bucket_attrs(std::move(_bucket_attrs)) { if (_bucket_info.sync_policy) { sync_policy = *_bucket_info.sync_policy; - - for (auto& entry : sync_policy.groups) { - for (auto& pipe : entry.second.pipes) { - if (pipe.params.mode == rgw_sync_pipe_params::MODE_USER && - pipe.params.user.empty()) { - pipe.params.user = _bucket_info.owner; - } - } - } } legacy_config = parent->legacy_config; bucket = _bucket_info.bucket; diff --git a/src/rgw/driver/rados/rgw_cr_rados.cc b/src/rgw/driver/rados/rgw_cr_rados.cc index 51ebf95197e..396c556926f 100644 --- a/src/rgw/driver/rados/rgw_cr_rados.cc +++ b/src/rgw/driver/rados/rgw_cr_rados.cc @@ -932,7 +932,7 @@ int RGWAsyncRemoveObj::_send_request(const DoutPrefixProvider *dpp) std::unique_ptr del_op = obj->get_delete_op(); - del_op->params.bucket_owner.id = bucket->get_info().owner; + del_op->params.bucket_owner = bucket->get_info().owner; del_op->params.obj_owner = policy.get_owner(); if (del_if_older) { del_op->params.unmod_since = timestamp; diff --git a/src/rgw/driver/rados/rgw_data_sync.cc b/src/rgw/driver/rados/rgw_data_sync.cc index 0796afcfa6f..84e13049319 100644 --- a/src/rgw/driver/rados/rgw_data_sync.cc +++ b/src/rgw/driver/rados/rgw_data_sync.cc @@ -2850,7 +2850,7 @@ int RGWFetchObjFilter_Sync::filter(CephContext *cct, rgw_user& acl_translation_owner = params.dest.acl_translation->owner; if (!acl_translation_owner.empty()) { if (params.mode == rgw_sync_pipe_params::MODE_USER && - acl_translation_owner != dest_bucket_info.owner) { + rgw_owner{acl_translation_owner} != dest_bucket_info.owner) { ldout(cct, 0) << "ERROR: " << __func__ << ": acl translation was requested, but user (" << acl_translation_owner << ") is not dest bucket owner (" << dest_bucket_info.owner << ")" << dendl; return -EPERM; diff --git a/src/rgw/driver/rados/rgw_notify.cc b/src/rgw/driver/rados/rgw_notify.cc index 5a1786ef7ad..357f34e5e53 100644 --- a/src/rgw/driver/rados/rgw_notify.cc +++ b/src/rgw/driver/rados/rgw_notify.cc @@ -921,7 +921,7 @@ static inline void populate_event(reservation_t& res, event.x_amz_id_2 = res.store->getRados()->host_id; // RGW on which the change was made // configurationId is filled from notification configuration event.bucket_name = res.bucket->get_name(); - event.bucket_ownerIdentity = res.bucket->get_owner().id; + event.bucket_ownerIdentity = to_string(res.bucket->get_owner()); const auto region = res.store->get_zone()->get_zonegroup().get_api_name(); rgw::ARN bucket_arn(res.bucket->get_key()); bucket_arn.region = region; diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index 1f079229766..95f05f149a0 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -2300,7 +2300,7 @@ void RGWRados::create_bucket_id(string *bucket_id) int RGWRados::create_bucket(const DoutPrefixProvider* dpp, optional_yield y, const rgw_bucket& bucket, - const rgw_user& owner, + const rgw_owner& owner, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, const RGWZonePlacementInfo* zone_placement, @@ -2854,6 +2854,7 @@ bool RGWRados::swift_versioning_enabled(const RGWBucketInfo& bucket_info) const int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, const ACLOwner& owner, + const rgw_user& remote_user, RGWBucketInfo& bucket_info, const rgw_obj& obj, const DoutPrefixProvider *dpp, @@ -2911,6 +2912,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, r = copy_obj(obj_ctx, owner, + remote_user, NULL, /* req_info *info */ no_zone, dest_obj, @@ -2950,6 +2952,7 @@ int RGWRados::swift_versioning_copy(RGWObjectCtx& obj_ctx, int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, const ACLOwner& owner, + const rgw_user& remote_user, RGWBucketInfo& bucket_info, rgw_obj& obj, bool& restored, @@ -3008,6 +3011,7 @@ int RGWRados::swift_versioning_restore(RGWObjectCtx& obj_ctx, int ret = copy_obj(obj_ctx, owner, + remote_user, nullptr, /* req_info *info */ no_zone, obj, /* dest obj */ @@ -4602,6 +4606,7 @@ int RGWRados::copy_obj_to_remote_dest(const DoutPrefixProvider *dpp, */ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, const ACLOwner& owner, + const rgw_user& remote_user, req_info *info, const rgw_zone_id& source_zone, const rgw_obj& dest_obj, @@ -4660,7 +4665,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, if (remote_src || !source_zone.empty()) { rgw_zone_set_entry source_trace_entry{source_zone.id, std::nullopt}; const req_context rctx{dpp, y, nullptr}; - return fetch_remote_obj(obj_ctx, owner.id, info, source_zone, + return fetch_remote_obj(obj_ctx, remote_user, info, source_zone, dest_obj, src_obj, dest_bucket_info, &src_bucket_info, dest_placement, src_mtime, mtime, mod_ptr, unmod_ptr, high_precision_time, @@ -4737,7 +4742,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx, if (remote_dest) { /* dest is in a different zonegroup, copy it there */ - return copy_obj_to_remote_dest(dpp, astate, attrs, read_op, owner.id, dest_obj, mtime, y); + return copy_obj_to_remote_dest(dpp, astate, attrs, read_op, remote_user, dest_obj, mtime, y); } uint64_t max_chunk_size; @@ -5706,7 +5711,7 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi struct rgw_bucket_dir_entry_meta meta; - meta.owner = params.obj_owner.id.to_str(); + meta.owner = to_string(params.obj_owner.id); meta.owner_display_name = params.obj_owner.display_name; if (real_clock::is_zero(params.mtime)) { @@ -6982,7 +6987,7 @@ int RGWRados::Bucket::UpdateIndex::complete(const DoutPrefixProvider *dpp, int64 if (user_data) ent.meta.user_data = *user_data; - ent.meta.owner = owner.id.to_str(); + ent.meta.owner = to_string(owner.id); ent.meta.owner_display_name = owner.display_name; ent.meta.content_type = content_type; ent.meta.appendable = appendable; @@ -10227,7 +10232,7 @@ int RGWRados::check_disk_state(const DoutPrefixProvider *dpp, object.meta.etag = etag; object.meta.content_type = content_type; object.meta.storage_class = storage_class; - object.meta.owner = owner.id.to_str(); + object.meta.owner = to_string(owner.id); object.meta.owner_display_name = owner.display_name; object.meta.appendable = appendable; @@ -10257,7 +10262,7 @@ int RGWRados::check_disk_state(const DoutPrefixProvider *dpp, list_state.tag = astate->obj_tag.c_str(); } - list_state.meta.owner = owner.id.to_str(); + list_state.meta.owner = to_string(owner.id); list_state.meta.owner_display_name = owner.display_name; list_state.exists = true; @@ -10381,7 +10386,7 @@ int RGWRados::add_bucket_to_reshard(const DoutPrefixProvider *dpp, const RGWBuck cls_rgw_reshard_entry entry; entry.time = real_clock::now(); - entry.tenant = bucket_info.owner.tenant; + entry.tenant = bucket_info.bucket.tenant; entry.bucket_name = bucket_info.bucket.name; entry.bucket_id = bucket_info.bucket.bucket_id; entry.old_num_shards = num_source_shards; @@ -10390,7 +10395,7 @@ int RGWRados::add_bucket_to_reshard(const DoutPrefixProvider *dpp, const RGWBuck return reshard.add(dpp, entry, y); } -int RGWRados::check_quota(const DoutPrefixProvider *dpp, const rgw_user& bucket_owner, rgw_bucket& bucket, +int RGWRados::check_quota(const DoutPrefixProvider *dpp, const rgw_owner& bucket_owner, rgw_bucket& bucket, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only) diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index dd471136a42..481a94a140d 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -633,7 +633,7 @@ public: int create_bucket(const DoutPrefixProvider* dpp, optional_yield y, const rgw_bucket& bucket, - const rgw_user& owner, + const rgw_owner& owner, const std::string& zonegroup_id, const rgw_placement_rule& placement_rule, const RGWZonePlacementInfo* zone_placement, @@ -797,7 +797,7 @@ public: const std::string *ptag; std::list *remove_objs; ceph::real_time set_mtime; - rgw_user bucket_owner; // for quota stats update + rgw_owner bucket_owner; // for quota stats update ACLOwner owner; // owner/owner_display_name for bucket index RGWObjCategory category; int flags; @@ -839,7 +839,7 @@ public: RGWRados::Object *target; struct DeleteParams { - rgw_user bucket_owner; // for quota stats update + rgw_owner bucket_owner; // for quota stats update int versioning_status; // versioning flags defined in enum RGWBucketFlags ACLOwner obj_owner; // needed for creation of deletion marker uint64_t olh_epoch; @@ -1073,12 +1073,14 @@ public: int swift_versioning_copy(RGWObjectCtx& obj_ctx, /* in/out */ const ACLOwner& owner, /* in */ + const rgw_user& remote_user, /* in */ RGWBucketInfo& bucket_info, /* in */ const rgw_obj& obj, /* in */ const DoutPrefixProvider *dpp, /* in */ optional_yield y); /* in */ int swift_versioning_restore(RGWObjectCtx& obj_ctx, /* in/out */ const ACLOwner& owner, /* in */ + const rgw_user& remote_user, /* in */ RGWBucketInfo& bucket_info, /* in */ rgw_obj& obj, /* in/out */ bool& restored, /* out */ @@ -1174,7 +1176,8 @@ public: * Returns: 0 on success, -ERR# otherwise. */ int copy_obj(RGWObjectCtx& obj_ctx, - const ACLOwner& owner, + const ACLOwner& owner, // owner of destination object + const rgw_user& remote_user, // uid for fetch_remote_obj() auth req_info *info, const rgw_zone_id& source_zone, const rgw_obj& dest_obj, @@ -1579,7 +1582,7 @@ public: int fix_tail_obj_locator(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, rgw_obj_key& key, bool fix, bool *need_fix, optional_yield y); - int check_quota(const DoutPrefixProvider *dpp, const rgw_user& bucket_owner, rgw_bucket& bucket, + int check_quota(const DoutPrefixProvider *dpp, const rgw_owner& bucket_owner, rgw_bucket& bucket, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only = false); diff --git a/src/rgw/driver/rados/rgw_reshard.cc b/src/rgw/driver/rados/rgw_reshard.cc index 7a54da7fe7d..c1011bd60a5 100644 --- a/src/rgw/driver/rados/rgw_reshard.cc +++ b/src/rgw/driver/rados/rgw_reshard.cc @@ -1056,7 +1056,7 @@ int RGWReshard::update(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucke cls_rgw_reshard_entry entry; entry.bucket_name = bucket_info.bucket.name; entry.bucket_id = bucket_info.bucket.bucket_id; - entry.tenant = bucket_info.owner.tenant; + entry.tenant = bucket_info.bucket.tenant; int ret = get(dpp, entry); if (ret < 0) { diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index e965a8e233a..a25a4a58d91 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -68,6 +68,7 @@ #include "cls/rgw/cls_rgw_client.h" #include "account.h" +#include "buckets.h" #include "rgw_pubsub.h" #include "topic.h" @@ -335,7 +336,8 @@ int RadosBucket::remove(const DoutPrefixProvider* dpp, } } - ret = store->ctl()->bucket->sync_user_stats(dpp, info.owner, info, y, nullptr); + librados::Rados& rados = *store->getRados()->get_rados_handle(); + ret = store->ctl()->bucket->sync_owner_stats(dpp, rados, info.owner, info, y, nullptr); if (ret < 0) { ldout(store->ctx(), 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl; } @@ -353,14 +355,13 @@ int RadosBucket::remove(const DoutPrefixProvider* dpp, // if bucket has notification definitions associated with it // they should be removed (note that any pending notifications on the bucket are still going to be sent) - const RGWPubSub ps(store, info.owner.tenant, *store->svc()->site); + const RGWPubSub ps(store, info.bucket.tenant, *store->svc()->site); const RGWPubSub::Bucket ps_bucket(ps, this); const auto ps_ret = ps_bucket.remove_notifications(dpp, y); if (ps_ret < 0 && ps_ret != -ENOENT) { ldpp_dout(dpp, -1) << "ERROR: unable to remove notifications from bucket. ret=" << ps_ret << dendl; } - librados::Rados& rados = *store->getRados()->get_rados_handle(); ret = store->ctl()->bucket->unlink_bucket(rados, info.owner, info.bucket, y, dpp, false); if (ret < 0) { @@ -487,7 +488,7 @@ int RadosBucket::remove_bypass_gc(int concurrent_max, bool return ret; } - sync_user_stats(dpp, y, nullptr); + sync_owner_stats(dpp, y, nullptr); if (ret < 0) { ldpp_dout(dpp, 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl; } @@ -551,10 +552,11 @@ int RadosBucket::read_stats_async(const DoutPrefixProvider *dpp, return store->getRados()->get_bucket_stats_async(dpp, get_info(), idx_layout, shard_id, ctx); } -int RadosBucket::sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) +int RadosBucket::sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) { - return store->ctl()->bucket->sync_user_stats(dpp, info.owner, info, y, ent); + librados::Rados& rados = *store->getRados()->get_rados_handle(); + return store->ctl()->bucket->sync_owner_stats(dpp, rados, info.owner, info, y, ent); } int RadosBucket::check_bucket_shards(const DoutPrefixProvider* dpp, @@ -563,18 +565,19 @@ int RadosBucket::check_bucket_shards(const DoutPrefixProvider* dpp, return store->getRados()->check_bucket_shards(info, num_objs, dpp, y); } -int RadosBucket::link(const DoutPrefixProvider* dpp, const rgw_user& new_user, optional_yield y, bool update_entrypoint, RGWObjVersionTracker* objv) +int RadosBucket::link(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, + optional_yield y, bool update_entrypoint, RGWObjVersionTracker* objv) { RGWBucketEntryPoint ep; ep.bucket = info.bucket; - ep.owner = new_user; + ep.owner = new_owner; ep.creation_time = get_creation_time(); ep.linked = true; Attrs ep_attrs; rgw_ep_info ep_data{ep, ep_attrs}; librados::Rados& rados = *store->getRados()->get_rados_handle(); - int r = store->ctl()->bucket->link_bucket(rados, new_user, info.bucket, + int r = store->ctl()->bucket->link_bucket(rados, new_owner, info.bucket, get_creation_time(), y, dpp, update_entrypoint, &ep_data); if (r < 0) @@ -586,14 +589,14 @@ int RadosBucket::link(const DoutPrefixProvider* dpp, const rgw_user& new_user, o return r; } -int RadosBucket::unlink(const DoutPrefixProvider* dpp, const rgw_user& owner, optional_yield y, bool update_entrypoint) +int RadosBucket::unlink(const DoutPrefixProvider* dpp, const rgw_owner& owner, optional_yield y, bool update_entrypoint) { librados::Rados& rados = *store->getRados()->get_rados_handle(); return store->ctl()->bucket->unlink_bucket(rados, owner, info.bucket, y, dpp, update_entrypoint); } -int RadosBucket::chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) +int RadosBucket::chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) { std::string obj_marker; // unlink from the owner, but don't update the entrypoint until link() @@ -642,14 +645,22 @@ int RadosBucket::read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, RGWUsageIter& usage_iter, map& usage) { - return store->getRados()->read_usage(dpp, info.owner, get_name(), start_epoch, + const rgw_user* user = std::get_if(&info.owner); + if (!user) { + return -ENOTSUP; // not supported for account owners + } + return store->getRados()->read_usage(dpp, *user, get_name(), start_epoch, end_epoch, max_entries, is_truncated, usage_iter, usage); } int RadosBucket::trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, optional_yield y) { - return store->getRados()->trim_usage(dpp, info.owner, get_name(), start_epoch, end_epoch, y); + const rgw_user* user = std::get_if(&info.owner); + if (!user) { + return -ENOTSUP; // not supported for account owners + } + return store->getRados()->trim_usage(dpp, *user, get_name(), start_epoch, end_epoch, y); } int RadosBucket::remove_objs_from_index(const DoutPrefixProvider *dpp, std::list& objs_to_unlink) @@ -1092,14 +1103,21 @@ int RadosStore::load_account_stats(const DoutPrefixProvider* dpp, ceph::real_time& last_synced, ceph::real_time& last_updated) { - return -ENOTSUP; + const RGWZoneParams& zone = svc()->zone->get_zone_params(); + const rgw_raw_obj& obj = rgwrados::account::get_buckets_obj(zone, id); + librados::Rados& rados = *getRados()->get_rados_handle(); + return rgwrados::buckets::read_stats(dpp, y, rados, obj, stats, + &last_synced, &last_updated); } int RadosStore::load_account_stats_async(const DoutPrefixProvider* dpp, std::string_view id, boost::intrusive_ptr cb) { - return -ENOTSUP; + const RGWZoneParams& zone = svc()->zone->get_zone_params(); + const rgw_raw_obj& obj = rgwrados::account::get_buckets_obj(zone, id); + librados::Rados& rados = *getRados()->get_rados_handle(); + return rgwrados::buckets::read_stats_async(dpp, rados, obj, std::move(cb)); } std::unique_ptr RadosStore::get_object(const rgw_obj_key& k) @@ -2255,7 +2273,7 @@ RadosObject::RadosDeleteOp::RadosDeleteOp(RadosObject *_source) : int RadosObject::RadosDeleteOp::delete_obj(const DoutPrefixProvider* dpp, optional_yield y, uint32_t flags) { - parent_op.params.bucket_owner = params.bucket_owner.id; + parent_op.params.bucket_owner = params.bucket_owner; parent_op.params.versioning_status = params.versioning_status; parent_op.params.obj_owner = params.obj_owner; parent_op.params.olh_epoch = params.olh_epoch; @@ -2295,6 +2313,7 @@ int RadosObject::delete_object(const DoutPrefixProvider* dpp, } int RadosObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -2324,6 +2343,7 @@ int RadosObject::copy_object(const ACLOwner& owner, { return store->getRados()->copy_obj(*rados_ctx, owner, + remote_user, info, source_zone, dest_object->get_obj(), @@ -2359,22 +2379,23 @@ int RadosObject::RadosReadOp::iterate(const DoutPrefixProvider* dpp, int64_t ofs return parent_op.iterate(dpp, ofs, end, cb, y); } -int RadosObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, +int RadosObject::swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) { rgw_obj obj = get_obj(); return store->getRados()->swift_versioning_restore(*rados_ctx, - owner, + owner, remote_user, bucket->get_info(), obj, restored, dpp, y); } -int RadosObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, optional_yield y) +int RadosObject::swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) { return store->getRados()->swift_versioning_copy(*rados_ctx, - owner, + owner, remote_user, bucket->get_info(), get_obj(), dpp, @@ -2491,7 +2512,7 @@ int RadosMultipartUpload::abort(const DoutPrefixProvider *dpp, CephContext *cct, } std::unique_ptr del_op = meta_obj->get_delete_op(); - del_op->params.bucket_owner.id = bucket->get_info().owner; + del_op->params.bucket_owner = bucket->get_info().owner; del_op->params.versioning_status = 0; if (!remove_objs.empty()) { del_op->params.remove_objs = &remove_objs; diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index 83ba68832b3..5aebda3d32e 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -453,6 +453,7 @@ class RadosObject : public StoreObject { virtual int delete_object(const DoutPrefixProvider* dpp, optional_yield y, uint32_t flags) override; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -514,10 +515,10 @@ class RadosObject : public StoreObject { virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) override; /* Swift versioning */ - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, + virtual int swift_versioning_restore(const ACLOwner& owner, const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int swift_versioning_copy(const ACLOwner& owner, const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) override; /* OPs */ virtual std::unique_ptr get_read_op() override; @@ -601,11 +602,11 @@ class RadosBucket : public StoreBucket { virtual int read_stats_async(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) override; + int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) override; int check_bucket_shards(const DoutPrefixProvider* dpp, uint64_t num_objs, optional_yield y) override; - virtual int chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) override; + virtual int chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime, optional_yield y) override; virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only = false) override; @@ -645,8 +646,8 @@ class RadosBucket : public StoreBucket { optional_yield y, const DoutPrefixProvider *dpp) override; private: - int link(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y, bool update_entrypoint = true, RGWObjVersionTracker* objv = nullptr); - int unlink(const DoutPrefixProvider* dpp, const rgw_user& owner, optional_yield y, bool update_entrypoint = true); + int link(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y, bool update_entrypoint = true, RGWObjVersionTracker* objv = nullptr); + int unlink(const DoutPrefixProvider* dpp, const rgw_owner& owner, optional_yield y, bool update_entrypoint = true); friend class RadosUser; }; diff --git a/src/rgw/driver/rados/rgw_sync_module_aws.cc b/src/rgw/driver/rados/rgw_sync_module_aws.cc index 19be83351e1..9d18bc9472b 100644 --- a/src/rgw/driver/rados/rgw_sync_module_aws.cc +++ b/src/rgw/driver/rados/rgw_sync_module_aws.cc @@ -615,9 +615,9 @@ struct AWSSyncConfig { const rgw_obj_key& obj) { string bucket_str; string owner; - if (!bucket_info.owner.tenant.empty()) { - bucket_str = owner = bucket_info.owner.tenant + "-"; - owner += bucket_info.owner.id; + if (!bucket_info.bucket.tenant.empty()) { + bucket_str = owner = bucket_info.bucket.tenant + "-"; + owner += to_string(bucket_info.owner); } bucket_str += bucket_info.bucket.name; diff --git a/src/rgw/driver/rados/rgw_sync_module_es.cc b/src/rgw/driver/rados/rgw_sync_module_es.cc index e3353dc1fc7..414fbeac4c9 100644 --- a/src/rgw/driver/rados/rgw_sync_module_es.cc +++ b/src/rgw/driver/rados/rgw_sync_module_es.cc @@ -229,7 +229,7 @@ struct ElasticConfig { bool should_handle_operation(RGWBucketInfo& bucket_info) { return index_buckets.exists(bucket_info.bucket.name) && - allow_owners.exists(bucket_info.owner.to_str()); + allow_owners.exists(to_string(bucket_info.owner)); } }; @@ -501,12 +501,12 @@ struct es_obj_metadata { const RGWAccessControlList& acl = policy.get_acl(); - permissions.insert(policy.get_owner().id.to_str()); + permissions.insert(to_string(policy.get_owner().id)); for (const auto& acliter : acl.get_grant_map()) { const ACLGrant& grant = acliter.second; const auto* user = grant.get_user(); if (user && (grant.get_permission().get_permissions() & RGW_PERM_READ) != 0) { - permissions.insert(user->id.to_str()); + permissions.insert(to_string(user->id)); } } } else if (attr_name == RGW_ATTR_TAGS) { diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 64e7018037e..e693d1288de 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -3181,8 +3181,6 @@ class SyncPolicyContext rgw_sync_policy_info *policy{nullptr}; - std::optional owner; - public: SyncPolicyContext(rgw::sal::ConfigStore* cfgstore, std::optional _bucket) @@ -3208,8 +3206,6 @@ public: return ret; } - owner = bucket->get_info().owner; - if (!bucket->get_info().sync_policy) { rgw_sync_policy_info new_policy; bucket->get_info().set_sync_policy(std::move(new_policy)); @@ -3242,10 +3238,6 @@ public: rgw_sync_policy_info& get_policy() { return *policy; } - - std::optional& get_owner() { - return owner; - } }; void resolve_zone_id_opt(std::optional& zone_name, std::optional& zone_id) @@ -7445,7 +7437,7 @@ int main(int argc, const char **argv) return -r; } formatter->dump_string("bucket_id", entry.bucket_id); - formatter->dump_string("bucket_owner", entry.bucket_owner.to_str()); + formatter->dump_string("bucket_owner", to_string(entry.bucket_owner)); formatter->dump_string("bucket", entry.bucket); uint64_t agg_time = 0; @@ -8894,7 +8886,7 @@ next: cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = bucket->sync_user_stats(dpp(), null_yield, nullptr); + ret = bucket->sync_owner_stats(dpp(), null_yield, nullptr); if (ret < 0) { cerr << "ERROR: could not sync bucket stats: " << cpp_strerror(-ret) << std::endl; @@ -10013,11 +10005,9 @@ next: if (!rgw::sal::User::empty(user)) { pipe->params.user = user->get_id(); - } else if (pipe->params.user.empty()) { - auto owner = sync_policy_ctx.get_owner(); - if (owner) { - pipe->params.user = *owner; - } + } else if (pipe->params.mode == rgw_sync_pipe_params::MODE_USER) { + cerr << "ERROR: missing --uid for --mode=user" << std::endl; + return EINVAL; } ret = sync_policy_ctx.write_policy(); diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 6e9029f4c53..d8a16fba3f2 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -77,8 +77,12 @@ transform_old_authinfo(CephContext* const cct, ACLOwner get_aclowner() const { ACLOwner owner; - owner.id = id; - owner.display_name = display_name; + if (!account_id.empty()) { + owner.id.emplace(account_id); + } else { + owner.id = id; + owner.display_name = display_name; + } return owner; } @@ -793,8 +797,12 @@ const std::string rgw::auth::LocalApplier::NO_ACCESS_KEY; ACLOwner rgw::auth::LocalApplier::get_aclowner() const { ACLOwner owner; - owner.id = user_info.user_id; - owner.display_name = user_info.display_name; + if (!user_info.account_id.empty()) { + owner.id = user_info.account_id; + } else { + owner.id = user_info.user_id; + owner.display_name = user_info.display_name; + } return owner; } diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 7a0bec1271b..f334bdbca21 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -10,6 +10,7 @@ #include "json_spirit/json_spirit.h" #include "common/ceph_json.h" #include "common/Formatter.h" +#include "common/versioned_variant.h" #include "rgw_op.h" #include "rgw_common.h" @@ -2261,9 +2262,19 @@ RGWBucketInfo::~RGWBucketInfo() } void RGWBucketInfo::encode(bufferlist& bl) const { - ENCODE_START(23, 4, bl); + // rgw_owner is now encoded at the end. if the owner is a user, duplicate the + // encoding of its id/tenant/ns in the existing locations for backward compat. + // otherwise, encode empty strings there + const rgw_user* user = std::get_if(&owner); + std::string empty; + + ENCODE_START(24, 4, bl); encode(bucket, bl); - encode(owner.id, bl); + if (user) { + encode(user->id, bl); + } else { + encode(empty, bl); + } encode(flags, bl); encode(zonegroup, bl); uint64_t ct = real_clock::to_time_t(creation_time); @@ -2272,7 +2283,11 @@ void RGWBucketInfo::encode(bufferlist& bl) const { encode(has_instance_obj, bl); encode(quota, bl); encode(requester_pays, bl); - encode(owner.tenant, bl); + if (user) { + encode(user->tenant, bl); + } else { + encode(empty, bl); + } encode(has_website, bl); if (has_website) { encode(website_conf, bl); @@ -2294,17 +2309,24 @@ void RGWBucketInfo::encode(bufferlist& bl) const { encode(*sync_policy, bl); } encode(layout, bl); - encode(owner.ns, bl); + if (user) { + encode(user->ns, bl); + } else { + encode(empty, bl); + } + ceph::versioned_variant::encode(owner, bl); // v24 + ENCODE_FINISH(bl); } void RGWBucketInfo::decode(bufferlist::const_iterator& bl) { - DECODE_START_LEGACY_COMPAT_LEN_32(23, 4, 4, bl); + rgw_user user; + DECODE_START_LEGACY_COMPAT_LEN_32(24, 4, 4, bl); decode(bucket, bl); if (struct_v >= 2) { string s; decode(s, bl); - owner.from_str(s); + user.from_str(s); } if (struct_v >= 3) decode(flags, bl); @@ -2330,7 +2352,7 @@ void RGWBucketInfo::decode(bufferlist::const_iterator& bl) { if (struct_v >= 12) decode(requester_pays, bl); if (struct_v >= 13) - decode(owner.tenant, bl); + decode(user.tenant, bl); if (struct_v >= 14) { decode(has_website, bl); if (has_website) { @@ -2374,7 +2396,12 @@ void RGWBucketInfo::decode(bufferlist::const_iterator& bl) { decode(layout, bl); } if (struct_v >= 23) { - decode(owner.ns, bl); + decode(user.ns, bl); + } + if (struct_v >= 24) { + ceph::versioned_variant::decode(owner, bl); + } else { + owner = std::move(user); // user was decoded piecewise above } if (layout.logs.empty() && @@ -2493,7 +2520,7 @@ void RGWBucketInfo::dump(Formatter *f) const encode_json("bucket", bucket, f); utime_t ut(creation_time); encode_json("creation_time", ut, f); - encode_json("owner", owner.to_str(), f); + encode_json("owner", owner, f); encode_json("flags", flags, f); encode_json("zonegroup", zonegroup, f); encode_json("placement_rule", placement_rule, f); diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index f28a09e398d..1e3d5e07bae 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -964,7 +964,7 @@ class RGWSI_Zone; struct RGWBucketInfo { rgw_bucket bucket; - rgw_user owner; + rgw_owner owner; uint32_t flags{0}; std::string zonegroup; ceph::real_time creation_time; diff --git a/src/rgw/rgw_crypt.cc b/src/rgw/rgw_crypt.cc index 085fda0a44b..58874bf22b9 100644 --- a/src/rgw/rgw_crypt.cc +++ b/src/rgw/rgw_crypt.cc @@ -13,6 +13,7 @@ #include #include #include "include/ceph_assert.h" +#include "include/function2.hpp" #include "crypto/crypto_accel.h" #include "crypto/crypto_plugin.h" #include "rgw/rgw_kms.h" @@ -964,7 +965,13 @@ std::string expand_key_name(req_state *s, const std::string_view&t) continue; } if (t.compare(i+1, 8, "owner_id") == 0) { - r.append(s->bucket->get_info().owner.id); + r.append(std::visit(fu2::overload( + [] (const rgw_user& user_id) -> const std::string& { + return user_id.id; + }, + [] (const rgw_account_id& account_id) -> const std::string& { + return account_id; + }), s->bucket->get_info().owner)); i += 9; continue; } diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index f8b4c9cc96c..7ae42cdfb70 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -597,7 +597,7 @@ static int remove_expired_obj(const DoutPrefixProvider* dpp, = obj->get_bucket()->get_info().versioning_status(); del_op->params.obj_owner.id = rgw_user{meta.owner}; del_op->params.obj_owner.display_name = meta.owner_display_name; - del_op->params.bucket_owner.id = bucket_info.owner; + del_op->params.bucket_owner = bucket_info.owner; del_op->params.unmod_since = meta.mtime; // notification supported only for RADOS driver for now diff --git a/src/rgw/rgw_lua_request.cc b/src/rgw/rgw_lua_request.cc index d430620ac0d..4119d8f93a5 100644 --- a/src/rgw/rgw_lua_request.cc +++ b/src/rgw/rgw_lua_request.cc @@ -303,8 +303,19 @@ struct BucketMetaTable : public EmptyMetaTable { } else if (strcasecmp(index, "PlacementRule") == 0) { create_metatable(L, name, index, false, &(bucket->get_info().placement_rule)); } else if (strcasecmp(index, "User") == 0) { - create_metatable(L, name, index, false, - const_cast(&bucket->get_owner())); + const rgw_owner& owner = bucket->get_owner(); + if (const rgw_user* u = std::get_if(&owner); u) { + create_metatable(L, name, index, false, const_cast(u)); + } else { + lua_pushnil(L); + } + } else if (strcasecmp(index, "Account") == 0) { + const rgw_owner& owner = bucket->get_owner(); + if (const rgw_account_id* a = std::get_if(&owner); a) { + pushstring(L, *a); + } else { + lua_pushnil(L); + } } else { return error_unknown_field(L, index, name); } diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 0cf888b7fff..04f432c4303 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -265,7 +265,7 @@ static int get_user_policy_from_attr(const DoutPrefixProvider *dpp, int rgw_op_get_bucket_policy_from_attr(const DoutPrefixProvider *dpp, CephContext *cct, rgw::sal::Driver* driver, - const rgw_user& bucket_owner, + const rgw_owner& bucket_owner, map& bucket_attrs, RGWAccessControlPolicy& policy, optional_yield y) @@ -278,13 +278,7 @@ int rgw_op_get_bucket_policy_from_attr(const DoutPrefixProvider *dpp, return ret; } else { ldpp_dout(dpp, 0) << "WARNING: couldn't find acl header for bucket, generating default" << dendl; - std::unique_ptr user = driver->get_user(bucket_owner); - /* object exists, but policy is broken */ - int r = user->load_user(dpp, y); - if (r < 0) - return r; - - policy.create_default(user->get_id(), user->get_display_name()); + policy.create_default(bucket_owner, ""); } return 0; } @@ -486,6 +480,42 @@ static int read_obj_policy(const DoutPrefixProvider *dpp, return ret; } +// try to read swift account acls from the owning user +static int get_swift_owner_account_acl(const DoutPrefixProvider* dpp, + optional_yield y, + rgw::sal::Driver* driver, + const ACLOwner& owner, + RGWAccessControlPolicy& policy) +{ + // only rgw_user owners support swift acls + const rgw_user* uid = std::get_if(&owner.id); + if (uid == nullptr) { + return 0; + } + if (uid->empty()) { + return 0; + } + + std::unique_ptr user = driver->get_user(*uid); + int ret = user->read_attrs(dpp, y); + if (!ret) { + ret = get_user_policy_from_attr(dpp, dpp->get_cct(), + user->get_attrs(), policy); + } + if (-ENOENT == ret) { + /* In already existing clusters users won't have ACL. In such case + * assuming that only account owner has the rights seems to be + * reasonable. That allows to have only one verification logic. + * NOTE: there is small compatibility kludge for global, empty tenant: + * 1. if we try to reach an existing bucket, its owner is considered + * as account owner. + * 2. otherwise account owner is identity stored in s->owner. */ + policy.create_default(owner.id, owner.display_name); + ret = 0; + } + return ret; +} + /** * Get the AccessControlPolicy for an user, bucket or object off of disk. * s: The req_state to draw information from. @@ -588,24 +618,8 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d /* handle user ACL only for those APIs which support it */ if (s->dialect == "swift" && !s->user->get_id().empty()) { - std::unique_ptr acl_user = driver->get_user(acct_acl_user->id); - - ret = acl_user->read_attrs(dpp, y); - if (!ret) { - ret = get_user_policy_from_attr(dpp, s->cct, acl_user->get_attrs(), s->user_acl); - } - if (-ENOENT == ret) { - /* In already existing clusters users won't have ACL. In such case - * assuming that only account owner has the rights seems to be - * reasonable. That allows to have only one verification logic. - * NOTE: there is small compatibility kludge for global, empty tenant: - * 1. if we try to reach an existing bucket, its owner is considered - * as account owner. - * 2. otherwise account owner is identity stored in s->user->user_id. */ - s->user_acl.create_default(acct_acl_user->id, - acct_acl_user->display_name); - ret = 0; - } else if (ret < 0) { + ret = get_swift_owner_account_acl(dpp, y, driver, *acct_acl_user, s->user_acl); + if (ret < 0) { ldpp_dout(dpp, 0) << "NOTICE: couldn't get user attrs for handling ACL " "(user_id=" << s->user->get_id() << ", ret=" << ret << ")" << dendl; return ret; @@ -1412,6 +1426,34 @@ int RGWOp::do_aws4_auth_completion() return 0; } +static int get_owner_quota_info(DoutPrefixProvider* dpp, + optional_yield y, + rgw::sal::Driver* driver, + const rgw_owner& owner, + RGWQuota& quotas) +{ + return std::visit(fu2::overload( + [&] (const rgw_user& uid) { + auto user = driver->get_user(uid); + int r = user->load_user(dpp, y); + if (r >= 0) { + quotas = user->get_info().quota; + } + return r; + }, + [&] (const rgw_account_id& account_id) { + RGWAccountInfo info; + rgw::sal::Attrs attrs; // ignored + RGWObjVersionTracker objv; // ignored + int r = driver->load_account_by_id(dpp, y, account_id, info, attrs, objv); + if (r >= 0) { + // no bucket quota + quotas.user_quota = info.quota; + } + return r; + }), owner); +} + int RGWOp::init_quota() { /* no quota enforcement for system requests */ @@ -1428,30 +1470,29 @@ int RGWOp::init_quota() return 0; } - std::unique_ptr owner_user = - driver->get_user(s->bucket->get_info().owner); - rgw::sal::User* user; + RGWQuota user_quotas; - if (s->user->get_id() == s->bucket_owner.id) { - user = s->user.get(); + if (s->owner.id == s->bucket_owner.id) { + user_quotas = s->user->get_info().quota; } else { - int r = owner_user->load_user(this, s->yield); - if (r < 0) + // consult the bucket owner's quota + int r = get_owner_quota_info(this, s->yield, driver, + s->bucket_owner.id, user_quotas); + if (r < 0) { return r; - user = owner_user.get(); - + } } driver->get_quota(quota); if (s->bucket->get_info().quota.enabled) { quota.bucket_quota = s->bucket->get_info().quota; - } else if (user->get_info().quota.bucket_quota.enabled) { - quota.bucket_quota = user->get_info().quota.bucket_quota; + } else if (user_quotas.bucket_quota.enabled) { + quota.bucket_quota = user_quotas.bucket_quota; } - if (user->get_info().quota.user_quota.enabled) { - quota.user_quota = user->get_info().quota.user_quota; + if (user_quotas.user_quota.enabled) { + quota.user_quota = user_quotas.user_quota; } return 0; @@ -3585,7 +3626,7 @@ void RGWCreateBucket::execute(optional_yield y) op_ret = s->bucket->load_bucket(this, y); if (op_ret < 0) { return; - } else if (s->bucket->get_owner() != s->user->get_id()) { + } else if (!s->auth.identity->is_owner_of(s->bucket->get_owner())) { /* New bucket doesn't belong to the account we're operating on. */ op_ret = -EEXIST; return; @@ -3679,7 +3720,7 @@ void RGWDeleteBucket::execute(optional_yield y) } } - op_ret = s->bucket->sync_user_stats(this, y, nullptr); + op_ret = s->bucket->sync_owner_stats(this, y, nullptr); if ( op_ret < 0) { ldpp_dout(this, 1) << "WARNING: failed to sync user stats before bucket delete: op_ret= " << op_ret << dendl; } @@ -4191,7 +4232,8 @@ void RGWPutObj::execute(optional_yield y) /* Handle object versioning of Swift API. */ if (! multipart) { - op_ret = s->object->swift_versioning_copy(s->owner, this, s->yield); + op_ret = s->object->swift_versioning_copy(s->owner, s->user->get_id(), + this, s->yield); if (op_ret < 0) { return; } @@ -5323,7 +5365,8 @@ void RGWDeleteObj::execute(optional_yield y) s->object->set_atomic(); bool ver_restored = false; - op_ret = s->object->swift_versioning_restore(s->owner, ver_restored, this, y); + op_ret = s->object->swift_versioning_restore(s->owner, s->user->get_id(), + ver_restored, this, y); if (op_ret < 0) { return; } @@ -5341,7 +5384,7 @@ void RGWDeleteObj::execute(optional_yield y) std::unique_ptr del_op = s->object->get_delete_op(); del_op->params.obj_owner = s->owner; - del_op->params.bucket_owner = s->bucket_owner; + del_op->params.bucket_owner = s->bucket_owner.id; del_op->params.versioning_status = s->bucket->get_info().versioning_status(); del_op->params.unmod_since = unmod_since; del_op->params.high_precision_time = s->system_request; @@ -5799,12 +5842,14 @@ void RGWCopyObj::execute(optional_yield y) /* Handle object versioning of Swift API. In case of copying to remote this * should fail gently (op_ret == 0) as the dst_obj will not exist here. */ - op_ret = s->object->swift_versioning_copy(s->owner, this, s->yield); + op_ret = s->object->swift_versioning_copy(s->owner, s->user->get_id(), + this, s->yield); if (op_ret < 0) { return; } op_ret = s->src_object->copy_object(s->owner, + s->user->get_id(), &s->info, source_zone, s->object.get(), @@ -6012,7 +6057,7 @@ void RGWPutACLs::execute(optional_yield y) if (op_ret < 0) return; - if (!existing_owner.id.empty() && + if (!existing_owner.empty() && existing_owner.id != new_policy.get_owner().id) { s->err.message = "Cannot modify ACL Owner"; op_ret = -EPERM; @@ -7261,7 +7306,7 @@ void RGWDeleteMultiObj::handle_individual_object(const rgw_obj_key& o, optional_ std::unique_ptr del_op = obj->get_delete_op(); del_op->params.versioning_status = obj->get_bucket()->get_info().versioning_status(); del_op->params.obj_owner = s->owner; - del_op->params.bucket_owner = s->bucket_owner; + del_op->params.bucket_owner = s->bucket_owner.id; del_op->params.marker_version_id = version_id; op_ret = del_op->delete_obj(this, y, rgw::sal::FLAG_LOG_OP); @@ -7436,7 +7481,7 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path, optional_yie std::unique_ptr del_op = obj->get_delete_op(); del_op->params.versioning_status = obj->get_bucket()->get_info().versioning_status(); del_op->params.obj_owner = bowner; - del_op->params.bucket_owner = bucket_owner; + del_op->params.bucket_owner = bucket_owner.id; ret = del_op->delete_obj(dpp, y, rgw::sal::FLAG_LOG_OP); if (ret < 0) { diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc index b0f58c09695..ca9eb6a2294 100644 --- a/src/rgw/rgw_quota.cc +++ b/src/rgw/rgw_quota.cc @@ -596,9 +596,9 @@ int RGWOwnerStatsCache::sync_bucket(const rgw_owner& owner, const rgw_bucket& b, } RGWBucketEnt ent; - r = bucket->sync_user_stats(dpp, y, &ent); + r = bucket->sync_owner_stats(dpp, y, &ent); if (r < 0) { - ldpp_dout(dpp, 0) << "ERROR: sync_user_stats() for bucket=" << bucket << " returned " << r << dendl; + ldpp_dout(dpp, 0) << "ERROR: sync_owner_stats() for bucket=" << bucket << " returned " << r << dendl; return r; } diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 3a4abaabd20..56d2e4925f1 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -505,7 +505,9 @@ void dump_owner(req_state *s, const std::string& id, const string& name, section = "Owner"; s->formatter->open_object_section(section); s->formatter->dump_string("ID", id); - s->formatter->dump_string("DisplayName", name); + if (!name.empty()) { + s->formatter->dump_string("DisplayName", name); + } s->formatter->close_section(); } @@ -588,7 +590,7 @@ void end_header(req_state* s, RGWOp* op, const char *content_type, dump_trans_id(s); if ((!s->is_err()) && s->bucket && - (s->bucket->get_info().owner != s->user->get_id()) && + (!s->auth.identity->is_owner_of(s->bucket->get_info().owner)) && (s->bucket->get_info().requester_pays)) { dump_header(s, "x-amz-request-charged", "requester"); } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 495651f89d6..0f77c2f9b01 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2349,9 +2349,9 @@ static void dump_bucket_metadata(req_state *s, rgw::sal::Bucket* bucket, dump_header(s, "X-RGW-Bytes-Used", static_cast(stats.size)); // only bucket's owner is allowed to get the quota settings of the account - if (bucket->get_owner() == s->user->get_id()) { - auto user_info = s->user->get_info(); - auto bucket_quota = s->bucket->get_info().quota; // bucket quota + if (s->auth.identity->is_owner_of(bucket->get_owner())) { + const auto& user_info = s->user->get_info(); + const auto& bucket_quota = s->bucket->get_info().quota; // bucket quota dump_header(s, "X-RGW-Quota-User-Size", static_cast(user_info.quota.user_quota.max_size)); dump_header(s, "X-RGW-Quota-User-Objects", static_cast(user_info.quota.user_quota.max_objects)); dump_header(s, "X-RGW-Quota-Max-Buckets", static_cast(user_info.max_buckets)); diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index f6bb52e2d1a..fe366acf856 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2227,10 +2227,17 @@ void RGWFormPost::get_owner_info(const req_state* const s, throw ret; } - ldpp_dout(this, 20) << "temp url user (bucket owner): " << bucket->get_info().owner - << dendl; + const rgw_owner& owner = bucket->get_owner(); + const rgw_user* uid = std::get_if(&owner); + if (!uid) { + ldpp_dout(this, 20) << "bucket " << *bucket << " is not owned by a user " + "so has no temp url keys" << dendl; + throw -EPERM; + } + + ldpp_dout(this, 20) << "temp url user (bucket owner): " << *uid << dendl; - user = driver->get_user(bucket->get_info().owner); + user = driver->get_user(*uid); if (user->load_user(s, s->yield) < 0) { throw -EPERM; } diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 02c7b3c9048..5a496105132 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -738,7 +738,7 @@ class Bucket { /// Input parameters for create(). struct CreateParams { - rgw_user owner; + rgw_owner owner; std::string zonegroup_id; rgw_placement_rule placement_rule; // zone placement is optional on buckets created for another zonegroup @@ -772,18 +772,18 @@ class Bucket { const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr cb) = 0; /** Sync this bucket's stats to the owning user's stats in the backing store */ - virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* optional_ent) = 0; + virtual int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* optional_ent) = 0; /** Check if this bucket needs resharding, and schedule it if it does */ virtual int check_bucket_shards(const DoutPrefixProvider* dpp, uint64_t num_objs, optional_yield y) = 0; /** Change the owner of this bucket in the backing store. Current owner must be set. Does not * change ownership of the objects in the bucket. */ - virtual int chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) = 0; + virtual int chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) = 0; /** Store the cached bucket info into the backing store */ virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime, optional_yield y) = 0; /** Get the owner of this bucket */ - virtual const rgw_user& get_owner() const = 0; + virtual const rgw_owner& get_owner() const = 0; /** Check in the backing store if this bucket is empty */ virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) = 0; /** Check if the given size fits within the quota */ @@ -965,8 +965,8 @@ class Object { */ struct DeleteOp { struct Params { - ACLOwner bucket_owner; - ACLOwner obj_owner; + rgw_owner bucket_owner; //< bucket owner for usage/quota accounting + ACLOwner obj_owner; //< acl owner for delete marker if necessary int versioning_status{0}; uint64_t olh_epoch{0}; std::string marker_version_id; @@ -1000,7 +1000,7 @@ class Object { optional_yield y, uint32_t flags) = 0; /** Copy an this object to another object. */ - virtual int copy_object(const ACLOwner& owner, + virtual int copy_object(const ACLOwner& owner, const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -1122,10 +1122,15 @@ class Object { virtual rgw_obj get_obj(void) const = 0; /** Restore the previous swift version of this object */ - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, /* out */ - const DoutPrefixProvider* dpp, optional_yield y) = 0; + virtual int swift_versioning_restore(const ACLOwner& owner, + const rgw_user& remote_user, + bool& restored, + const DoutPrefixProvider* dpp, + optional_yield y) = 0; /** Copy the current version of a swift object to the configured destination bucket*/ - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, + virtual int swift_versioning_copy(const ACLOwner& owner, + const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) = 0; /** Get a new ReadOp for this object */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index ee5f5a1f2eb..fd7a268fb7a 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -39,7 +39,8 @@ namespace rgw::sal { RGWUserBuckets ulist; bool is_truncated = false; - int ret = store->getDB()->list_buckets(dpp, "", info.user_id, marker, + std::string owner = info.user_id.to_str(); + int ret = store->getDB()->list_buckets(dpp, "", owner, marker, end_marker, max, need_stats, &ulist, &is_truncated); if (ret < 0) return ret; @@ -226,8 +227,8 @@ namespace rgw::sal { return 0; } - int DBBucket::sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) + int DBBucket::sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) { return 0; } @@ -238,7 +239,7 @@ namespace rgw::sal { return 0; } - int DBBucket::chown(const DoutPrefixProvider *dpp, const rgw_user& new_owner, optional_yield y) + int DBBucket::chown(const DoutPrefixProvider *dpp, const rgw_owner& new_owner, optional_yield y) { int ret; @@ -702,7 +703,6 @@ namespace rgw::sal { int DBObject::DBDeleteOp::delete_obj(const DoutPrefixProvider* dpp, optional_yield y, uint32_t flags) { - parent_op.params.bucket_owner = params.bucket_owner.id; parent_op.params.versioning_status = params.versioning_status; parent_op.params.obj_owner = params.obj_owner; parent_op.params.olh_epoch = params.olh_epoch; @@ -732,13 +732,13 @@ namespace rgw::sal { DB::Object del_target(store->getDB(), bucket->get_info(), get_obj()); DB::Object::Delete del_op(&del_target); - del_op.params.bucket_owner = bucket->get_info().owner; del_op.params.versioning_status = bucket->get_info().versioning_status(); return del_op.delete_obj(dpp); } int DBObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -774,14 +774,16 @@ namespace rgw::sal { return parent_op.iterate(dpp, ofs, end, cb); } - int DBObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, + int DBObject::swift_versioning_restore(const ACLOwner& owner, + const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) { return 0; } - int DBObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) + int DBObject::swift_versioning_copy(const ACLOwner& owner, + const rgw_user& remote_user, + const DoutPrefixProvider* dpp, optional_yield y) { return 0; } @@ -794,7 +796,7 @@ namespace rgw::sal { int ret; std::unique_ptr del_op = meta_obj->get_delete_op(); - del_op->params.bucket_owner.id = bucket->get_info().owner; + del_op->params.bucket_owner = bucket->get_info().owner; del_op->params.versioning_status = 0; // Since the data objects are associated with meta obj till @@ -834,7 +836,7 @@ namespace rgw::sal { DB::Object::Write obj_op(&op_target); /* Create meta object */ - obj_op.meta.owner = owner.id; + obj_op.meta.owner = to_string(owner.id); obj_op.meta.category = RGWObjCategory::MultiMeta; obj_op.meta.flags = PUT_OBJ_CREATE_EXCL; obj_op.meta.mtime = &mtime; @@ -1013,7 +1015,7 @@ namespace rgw::sal { DB::Object::Write obj_op(&op_target); ret = obj_op.prepare(dpp); - obj_op.meta.owner = owner.id; + obj_op.meta.owner = to_string(owner.id); obj_op.meta.flags = PUT_OBJ_CREATE; obj_op.meta.category = RGWObjCategory::Main; obj_op.meta.modify_tail = true; diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index aa971d1cdf0..8df568e3c9d 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -158,11 +158,11 @@ protected: std::string *max_marker = nullptr, bool *syncstopped = nullptr) override; virtual int read_stats_async(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) override; + int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) override; int check_bucket_shards(const DoutPrefixProvider *dpp, uint64_t num_objs, optional_yield y) override; - virtual int chown(const DoutPrefixProvider *dpp, const rgw_user& new_owner, optional_yield y) override; + virtual int chown(const DoutPrefixProvider *dpp, const rgw_owner& new_owner, optional_yield y) override; virtual int put_info(const DoutPrefixProvider *dpp, bool exclusive, ceph::real_time mtime, optional_yield y) override; virtual int check_empty(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only = false) override; @@ -547,6 +547,7 @@ protected: optional_yield y, uint32_t flags) override; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -587,9 +588,11 @@ protected: virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) override; /* Swift versioning */ - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, + virtual int swift_versioning_restore(const ACLOwner& owner, + const rgw_user& remote_user, bool& restored, const DoutPrefixProvider* dpp, optional_yield y) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, + virtual int swift_versioning_copy(const ACLOwner& owner, + const rgw_user& remote_user, const DoutPrefixProvider* dpp, optional_yield y) override; /* OPs */ diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 78dfc9f28aa..358f3a9ae38 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -682,10 +682,10 @@ int FilterBucket::read_stats_async(const DoutPrefixProvider *dpp, return next->read_stats_async(dpp, idx_layout, shard_id, ctx); } -int FilterBucket::sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) +int FilterBucket::sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) { - return next->sync_user_stats(dpp, y, ent); + return next->sync_owner_stats(dpp, y, ent); } int FilterBucket::check_bucket_shards(const DoutPrefixProvider* dpp, @@ -694,7 +694,7 @@ int FilterBucket::check_bucket_shards(const DoutPrefixProvider* dpp, return next->check_bucket_shards(dpp, num_objs, y); } -int FilterBucket::chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, optional_yield y) +int FilterBucket::chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) { return next->chown(dpp, new_owner, y); } @@ -705,7 +705,7 @@ int FilterBucket::put_info(const DoutPrefixProvider* dpp, bool exclusive, return next->put_info(dpp, exclusive, _mtime, y); } -const rgw_user& FilterBucket::get_owner() const +const rgw_owner& FilterBucket::get_owner() const { return next->get_owner(); } @@ -825,6 +825,7 @@ int FilterObject::delete_object(const DoutPrefixProvider* dpp, } int FilterObject::copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, @@ -852,7 +853,7 @@ int FilterObject::copy_object(const ACLOwner& owner, const DoutPrefixProvider* dpp, optional_yield y) { - return next->copy_object(owner, info, source_zone, + return next->copy_object(owner, remote_user, info, source_zone, nextObject(dest_object), nextBucket(dest_bucket), nextBucket(src_bucket), @@ -957,16 +958,21 @@ void FilterObject::set_bucket(Bucket* b) next->set_bucket(nextBucket(b)); }; -int FilterObject::swift_versioning_restore(const ACLOwner& owner, bool& restored, - const DoutPrefixProvider* dpp, optional_yield y) +int FilterObject::swift_versioning_restore(const ACLOwner& owner, + const rgw_user& remote_user, + bool& restored, + const DoutPrefixProvider* dpp, + optional_yield y) { - return next->swift_versioning_restore(owner, restored, dpp, y); + return next->swift_versioning_restore(owner, remote_user, restored, dpp, y); } -int FilterObject::swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) +int FilterObject::swift_versioning_copy(const ACLOwner& owner, + const rgw_user& remote_user, + const DoutPrefixProvider* dpp, + optional_yield y) { - return next->swift_versioning_copy(owner, dpp, y); + return next->swift_versioning_copy(owner, remote_user, dpp, y); } std::unique_ptr FilterObject::get_read_op() diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index 5c4e6327245..d896f999923 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -486,15 +486,15 @@ public: virtual int read_stats_async(const DoutPrefixProvider *dpp, const bucket_index_layout_generation& idx_layout, int shard_id, boost::intrusive_ptr ctx) override; - int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y, - RGWBucketEnt* ent) override; + int sync_owner_stats(const DoutPrefixProvider *dpp, optional_yield y, + RGWBucketEnt* ent) override; int check_bucket_shards(const DoutPrefixProvider* dpp, uint64_t num_objs, optional_yield y) override; - virtual int chown(const DoutPrefixProvider* dpp, const rgw_user& new_owner, + virtual int chown(const DoutPrefixProvider* dpp, const rgw_owner& new_owner, optional_yield y) override; virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime, optional_yield y) override; - virtual const rgw_user& get_owner() const override; + virtual const rgw_owner& get_owner() const override; virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuota& quota, uint64_t obj_size, optional_yield y, @@ -625,6 +625,7 @@ public: optional_yield y, uint32_t flags) override; virtual int copy_object(const ACLOwner& owner, + const rgw_user& remote_user, req_info* info, const rgw_zone_id& source_zone, rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, rgw::sal::Bucket* src_bucket, @@ -712,10 +713,15 @@ public: virtual bool have_instance(void) override { return next->have_instance(); } virtual void clear_instance() override { return next->clear_instance(); } - virtual int swift_versioning_restore(const ACLOwner& owner, bool& restored, /* out */ - const DoutPrefixProvider* dpp, optional_yield y) override; - virtual int swift_versioning_copy(const ACLOwner& owner, const DoutPrefixProvider* dpp, - optional_yield y) override; + virtual int swift_versioning_restore(const ACLOwner& owner, + const rgw_user& remote_user, + bool& restored, + const DoutPrefixProvider* dpp, + optional_yield y) override; + virtual int swift_versioning_copy(const ACLOwner& owner, + const rgw_user& remote_user, + const DoutPrefixProvider* dpp, + optional_yield y) override; virtual std::unique_ptr get_read_op() override; virtual std::unique_ptr get_delete_op() override; diff --git a/src/rgw/rgw_sal_store.h b/src/rgw/rgw_sal_store.h index 1ba44bc02ec..8bfff802526 100644 --- a/src/rgw/rgw_sal_store.h +++ b/src/rgw/rgw_sal_store.h @@ -135,7 +135,7 @@ class StoreBucket : public Bucket { virtual Attrs& get_attrs(void) override { return attrs; } virtual int set_attrs(Attrs a) override { attrs = a; return 0; } - virtual const rgw_user& get_owner() const override { return info.owner; }; + virtual const rgw_owner& get_owner() const override { return info.owner; } virtual bool empty() const override { return info.bucket.name.empty(); } virtual const std::string& get_name() const override { return info.bucket.name; } virtual const std::string& get_tenant() const override { return info.bucket.tenant; } diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index aa31adc1d0a..9edf257b6b8 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -124,11 +124,16 @@ void TempURLEngine::get_owner_info(const DoutPrefixProvider* dpp, const req_stat throw ret; } + const rgw_user* uid = std::get_if(&bucket->get_info().owner); + if (!uid) { + throw -EPERM; + } + ldpp_dout(dpp, 20) << "temp url user (bucket owner): " << bucket->get_info().owner << dendl; std::unique_ptr user; - user = driver->get_user(bucket->get_info().owner); + user = driver->get_user(*uid); if (user->load_user(dpp, s->yield) < 0) { throw -EPERM; } diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index 02403e5f342..d77b50a1117 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -35,7 +35,7 @@ int rgw_user_sync_all_stats(const DoutPrefixProvider *dpp, rgw::sal::Driver* dri ldpp_dout(dpp, 0) << "ERROR: could not read bucket info: bucket=" << bucket << " ret=" << ret << dendl; continue; } - ret = bucket->sync_user_stats(dpp, y, &ent); + ret = bucket->sync_owner_stats(dpp, y, &ent); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: could not sync bucket stats: ret=" << ret << dendl; return ret; diff --git a/src/test/rgw/test_rgw_lua.cc b/src/test/rgw/test_rgw_lua.cc index ed60fb9ec1f..57bfc08ea35 100644 --- a/src/test/rgw/test_rgw_lua.cc +++ b/src/test/rgw/test_rgw_lua.cc @@ -367,8 +367,7 @@ TEST(TestRGWLua, Bucket) info.bucket.name = "myname"; info.bucket.marker = "mymarker"; info.bucket.bucket_id = "myid"; - info.owner.id = "myuser"; - info.owner.tenant = "mytenant"; + info.owner = rgw_user{"mytenant", "myuser"}; s.bucket.reset(new sal::RadosBucket(nullptr, info)); const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); @@ -672,8 +671,7 @@ TEST(TestRGWLua, Acl) end assert(Request.UserAcl.Owner.DisplayName == "jack black", Request.UserAcl.Owner.DisplayName) - assert(Request.UserAcl.Owner.User.Id == "black", Request.UserAcl.Owner.User.Id) - assert(Request.UserAcl.Owner.User.Tenant == "jack", Request.UserAcl.Owner.User.Tenant) + assert(Request.UserAcl.Owner.User == "jack$black", Request.UserAcl.Owner.User) assert(#Request.UserAcl.Grants == 7) print_grant("", Request.UserAcl.Grants[""]) for k, v in pairs(Request.UserAcl.Grants) do @@ -735,8 +733,7 @@ TEST(TestRGWLua, UseFunction) const std::string script = R"( function print_owner(owner) print("Owner Display Name: " .. owner.DisplayName) - print("Owner Id: " .. owner.User.Id) - print("Owner Tenanet: " .. owner.User.Tenant) + print("Owner Id: " .. owner.User) end print_owner(Request.ObjectOwner) @@ -1586,8 +1583,7 @@ TEST(TestRGWLua, DifferentContextUser) s.user.reset(new sal::RadosUser(nullptr, rgw_user("tenant1", "user1"))); RGWBucketInfo info; info.bucket.name = "bucket1"; - info.owner.id = "user2"; - info.owner.tenant = "tenant2"; + info.owner = rgw_user{"tenant2", "user2"}; s.bucket.reset(new sal::RadosBucket(nullptr, info)); const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); -- 2.39.5