]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_op.h
import 15.2.4
[ceph.git] / ceph / src / rgw / rgw_op.h
CommitLineData
31f18b77 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
11fdf7f2 3
7c673cae
FG
4/**
5 * All operations via the rados gateway are carried out by
6 * small classes known as RGWOps. This class contains a req_state
7 * and each possible command is a subclass of this with a defined
8 * execute() method that does whatever the subclass name implies.
9 * These subclasses must be further subclassed (by interface type)
10 * to provide additional virtual methods such as send_response or get_params.
11 */
11fdf7f2 12
7c673cae
FG
13#ifndef CEPH_RGW_OP_H
14#define CEPH_RGW_OP_H
15
16#include <limits.h>
17
18#include <array>
19#include <memory>
20#include <string>
21#include <set>
22#include <map>
23#include <vector>
24
25#include <boost/optional.hpp>
26#include <boost/utility/in_place_factory.hpp>
31f18b77 27#include <boost/function.hpp>
7c673cae
FG
28
29#include "common/armor.h"
30#include "common/mime.h"
31#include "common/utf8.h"
32#include "common/ceph_json.h"
7c673cae
FG
33#include "common/ceph_time.h"
34
35#include "rgw_common.h"
11fdf7f2 36#include "rgw_dmclock.h"
9f95a23c 37#include "rgw_sal.h"
7c673cae
FG
38#include "rgw_user.h"
39#include "rgw_bucket.h"
40#include "rgw_acl.h"
41#include "rgw_cors.h"
42#include "rgw_quota.h"
11fdf7f2 43#include "rgw_putobj.h"
9f95a23c
TL
44#include "rgw_multi.h"
45#include "rgw_sal.h"
7c673cae
FG
46
47#include "rgw_lc.h"
48#include "rgw_torrent.h"
224ce89b 49#include "rgw_tag.h"
eafe8130 50#include "rgw_object_lock.h"
3efd9988
FG
51#include "cls/lock/cls_lock_client.h"
52#include "cls/rgw/cls_rgw_client.h"
9f95a23c 53#include "rgw_public_access.h"
7c673cae 54
11fdf7f2 55#include "services/svc_sys_obj.h"
9f95a23c 56#include "services/svc_tier_rados.h"
11fdf7f2
TL
57
58#include "include/ceph_assert.h"
7c673cae 59
7c673cae
FG
60using ceph::crypto::SHA1;
61
62struct req_state;
63class RGWOp;
9f95a23c 64class RGWRados;
7c673cae
FG
65
66
67namespace rgw {
68namespace auth {
69namespace registry {
70
71class StrategyRegistry;
72
73}
74}
75}
76
11fdf7f2 77int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
9f95a23c 78 rgw::sal::RGWRadosStore *store,
11fdf7f2
TL
79 RGWBucketInfo& bucket_info,
80 map<string, bufferlist>& bucket_attrs,
81 RGWAccessControlPolicy *policy);
7c673cae
FG
82
83class RGWHandler {
84protected:
9f95a23c
TL
85 rgw::sal::RGWRadosStore* store{nullptr};
86 struct req_state *s{nullptr};
7c673cae
FG
87
88 int do_init_permissions();
89 int do_read_permissions(RGWOp* op, bool only_bucket);
90
91public:
9f95a23c 92 RGWHandler() {}
7c673cae
FG
93 virtual ~RGWHandler();
94
9f95a23c 95 virtual int init(rgw::sal::RGWRadosStore* store,
7c673cae
FG
96 struct req_state* _s,
97 rgw::io::BasicClient* cio);
98
99 virtual int init_permissions(RGWOp*) {
100 return 0;
101 }
102
103 virtual int retarget(RGWOp* op, RGWOp** new_op) {
104 *new_op = op;
105 return 0;
106 }
107
108 virtual int read_permissions(RGWOp* op) = 0;
11fdf7f2 109 virtual int authorize(const DoutPrefixProvider* dpp) = 0;
7c673cae
FG
110 virtual int postauth_init() = 0;
111 virtual int error_handler(int err_no, std::string* error_content);
31f18b77 112 virtual void dump(const string& code, const string& message) const {}
11fdf7f2
TL
113
114 virtual bool supports_quota() {
115 return true;
116 }
7c673cae
FG
117};
118
119
31f18b77
FG
120
121void rgw_bucket_object_pre_exec(struct req_state *s);
122
11fdf7f2
TL
123namespace dmc = rgw::dmclock;
124
7c673cae
FG
125/**
126 * Provide the base class for all ops.
127 */
11fdf7f2 128class RGWOp : public DoutPrefixProvider {
7c673cae
FG
129protected:
130 struct req_state *s;
131 RGWHandler *dialect_handler;
9f95a23c 132 rgw::sal::RGWRadosStore *store;
7c673cae
FG
133 RGWCORSConfiguration bucket_cors;
134 bool cors_exist;
135 RGWQuotaInfo bucket_quota;
136 RGWQuotaInfo user_quota;
137 int op_ret;
7c673cae
FG
138 int do_aws4_auth_completion();
139
140 virtual int init_quota();
b32b8144 141
7c673cae
FG
142public:
143 RGWOp()
144 : s(nullptr),
145 dialect_handler(nullptr),
146 store(nullptr),
147 cors_exist(false),
148 op_ret(0) {
149 }
150
151 virtual ~RGWOp() = default;
152
153 int get_ret() const { return op_ret; }
154
155 virtual int init_processing() {
11fdf7f2
TL
156 if (dialect_handler->supports_quota()) {
157 op_ret = init_quota();
158 if (op_ret < 0)
159 return op_ret;
160 }
7c673cae
FG
161
162 return 0;
163 }
164
9f95a23c 165 virtual void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *dialect_handler) {
7c673cae
FG
166 this->store = store;
167 this->s = s;
168 this->dialect_handler = dialect_handler;
169 }
170 int read_bucket_cors();
171 bool generate_cors_headers(string& origin, string& method, string& headers, string& exp_headers, unsigned *max_age);
172
173 virtual int verify_params() { return 0; }
174 virtual bool prefetch_data() { return false; }
175
176 /* Authenticate requester -- verify its identity.
177 *
178 * NOTE: typically the procedure is common across all operations of the same
179 * dialect (S3, Swift API). However, there are significant exceptions in
180 * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
181 * different, specific authentication schema driving the need for per-op
182 * authentication. The alternative is to duplicate parts of the method-
183 * dispatch logic in RGWHandler::authorize() and pollute it with a lot
184 * of special cases. */
185 virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
186 /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
11fdf7f2 187 return dialect_handler->authorize(this);
7c673cae
FG
188 }
189 virtual int verify_permission() = 0;
190 virtual int verify_op_mask();
191 virtual void pre_exec() {}
192 virtual void execute() = 0;
193 virtual void send_response() {}
194 virtual void complete() {
195 send_response();
196 }
11fdf7f2 197 virtual const char* name() const = 0;
7c673cae
FG
198 virtual RGWOpType get_type() { return RGW_OP_UNKNOWN; }
199
200 virtual uint32_t op_mask() { return 0; }
201
202 virtual int error_handler(int err_no, string *error_content);
11fdf7f2
TL
203
204 // implements DoutPrefixProvider
205 std::ostream& gen_prefix(std::ostream& out) const override;
206 CephContext* get_cct() const override { return s->cct; }
207 unsigned get_subsys() const override { return ceph_subsys_rgw; }
208
209 virtual dmc::client_id dmclock_client() { return dmc::client_id::metadata; }
210 virtual dmc::Cost dmclock_cost() { return 1; }
211};
212
213class RGWDefaultResponseOp : public RGWOp {
214public:
215 void send_response() override;
216};
217
218class RGWGetObj_Filter : public RGWGetDataCB
219{
220protected:
221 RGWGetObj_Filter *next{nullptr};
222public:
223 RGWGetObj_Filter() {}
224 explicit RGWGetObj_Filter(RGWGetObj_Filter *next): next(next) {}
225 ~RGWGetObj_Filter() override {}
226 /**
227 * Passes data through filter.
228 * Filter can modify content of bl.
229 * When bl_len == 0 , it means 'flush
230 */
231 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override {
232 if (next) {
233 return next->handle_data(bl, bl_ofs, bl_len);
234 }
235 return 0;
236 }
237 /**
238 * Flushes any cached data. Used by RGWGetObjFilter.
239 * Return logic same as handle_data.
240 */
241 virtual int flush() {
242 if (next) {
243 return next->flush();
244 }
245 return 0;
246 }
247 /**
248 * Allows filter to extend range required for successful filtering
249 */
250 virtual int fixup_range(off_t& ofs, off_t& end) {
251 if (next) {
252 return next->fixup_range(ofs, end);
253 }
254 return 0;
255 }
7c673cae
FG
256};
257
258class RGWGetObj : public RGWOp {
259protected:
260 seed torrent; // get torrent
261 const char *range_str;
262 const char *if_mod;
263 const char *if_unmod;
264 const char *if_match;
265 const char *if_nomatch;
266 uint32_t mod_zone_id;
267 uint64_t mod_pg_ver;
268 off_t ofs;
269 uint64_t total_len;
270 off_t start;
271 off_t end;
272 ceph::real_time mod_time;
273 ceph::real_time lastmod;
274 ceph::real_time unmod_time;
275 ceph::real_time *mod_ptr;
276 ceph::real_time *unmod_ptr;
277 map<string, bufferlist> attrs;
278 bool get_data;
279 bool partial_content;
28e407b8 280 bool ignore_invalid_range;
7c673cae
FG
281 bool range_parsed;
282 bool skip_manifest;
181888fb 283 bool skip_decrypt{false};
7c673cae
FG
284 rgw_obj obj;
285 utime_t gc_invalidate_time;
286 bool is_slo;
287 string lo_etag;
288 bool rgwx_stat; /* extended rgw stat operation */
31f18b77 289 string version_id;
7c673cae
FG
290
291 // compression attrs
292 RGWCompressionInfo cs_info;
293 off_t first_block, last_block;
294 off_t q_ofs, q_len;
295 bool first_data;
296 uint64_t cur_ofs;
297 bufferlist waiting;
31f18b77 298 uint64_t action = 0;
7c673cae 299
eafe8130
TL
300 bool get_retention;
301 bool get_legal_hold;
302
7c673cae
FG
303 int init_common();
304public:
305 RGWGetObj() {
306 range_str = NULL;
307 if_mod = NULL;
308 if_unmod = NULL;
309 if_match = NULL;
310 if_nomatch = NULL;
311 mod_zone_id = 0;
312 mod_pg_ver = 0;
313 start = 0;
314 ofs = 0;
315 total_len = 0;
316 end = -1;
317 mod_ptr = NULL;
318 unmod_ptr = NULL;
319 get_data = false;
320 partial_content = false;
321 range_parsed = false;
322 skip_manifest = false;
323 is_slo = false;
324 first_block = 0;
325 last_block = 0;
326 q_ofs = 0;
327 q_len = 0;
328 first_data = true;
329 cur_ofs = 0;
eafe8130
TL
330 get_retention = false;
331 get_legal_hold = false;
7c673cae
FG
332 }
333
334 bool prefetch_data() override;
335
336 void set_get_data(bool get_data) {
337 this->get_data = get_data;
338 }
28e407b8 339
7c673cae
FG
340 int verify_permission() override;
341 void pre_exec() override;
342 void execute() override;
28e407b8 343 int parse_range();
31f18b77
FG
344 int read_user_manifest_part(
345 rgw_bucket& bucket,
346 const rgw_bucket_dir_entry& ent,
347 RGWAccessControlPolicy * const bucket_acl,
348 const boost::optional<rgw::IAM::Policy>& bucket_policy,
349 const off_t start_ofs,
11fdf7f2
TL
350 const off_t end_ofs,
351 bool swift_slo);
7c673cae
FG
352 int handle_user_manifest(const char *prefix);
353 int handle_slo_manifest(bufferlist& bl);
354
355 int get_data_cb(bufferlist& bl, off_t ofs, off_t len);
356
357 virtual int get_params() = 0;
358 virtual int send_response_data_error() = 0;
359 virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) = 0;
360
11fdf7f2 361 const char* name() const override { return "get_obj"; }
7c673cae
FG
362 RGWOpType get_type() override { return RGW_OP_GET_OBJ; }
363 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
364 virtual bool need_object_expiration() { return false; }
365 /**
366 * calculates filter used to decrypt RGW objects data
367 */
11fdf7f2 368 virtual int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter, RGWGetObj_Filter* cb, bufferlist* manifest_bl) {
7c673cae
FG
369 *filter = nullptr;
370 return 0;
371 }
11fdf7f2 372 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
373};
374
11fdf7f2 375class RGWGetObj_CB : public RGWGetObj_Filter
7c673cae
FG
376{
377 RGWGetObj *op;
378public:
379 explicit RGWGetObj_CB(RGWGetObj *_op) : op(_op) {}
380 ~RGWGetObj_CB() override {}
381
382 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override {
383 return op->get_data_cb(bl, bl_ofs, bl_len);
384 }
385};
386
224ce89b
WB
387class RGWGetObjTags : public RGWOp {
388 protected:
389 bufferlist tags_bl;
390 bool has_tags{false};
391 public:
11fdf7f2
TL
392 int verify_permission() override;
393 void execute() override;
394 void pre_exec() override;
224ce89b
WB
395
396 virtual void send_response_data(bufferlist& bl) = 0;
11fdf7f2
TL
397 const char* name() const override { return "get_obj_tags"; }
398 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
399 RGWOpType get_type() override { return RGW_OP_GET_OBJ_TAGGING; }
224ce89b
WB
400
401};
402
403class RGWPutObjTags : public RGWOp {
404 protected:
405 bufferlist tags_bl;
406 public:
11fdf7f2
TL
407 int verify_permission() override;
408 void execute() override;
224ce89b 409
11fdf7f2 410 virtual void send_response() override = 0;
224ce89b 411 virtual int get_params() = 0;
11fdf7f2
TL
412 const char* name() const override { return "put_obj_tags"; }
413 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
414 RGWOpType get_type() override { return RGW_OP_PUT_OBJ_TAGGING; }
224ce89b
WB
415
416};
417
418class RGWDeleteObjTags: public RGWOp {
419 public:
11fdf7f2
TL
420 void pre_exec() override;
421 int verify_permission() override;
422 void execute() override;
224ce89b 423
11fdf7f2
TL
424 const char* name() const override { return "delete_obj_tags"; }
425 virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
426 RGWOpType get_type() override { return RGW_OP_DELETE_OBJ_TAGGING;}
224ce89b
WB
427};
428
9f95a23c
TL
429class RGWGetBucketTags : public RGWOp {
430protected:
431 bufferlist tags_bl;
432 bool has_tags{false};
433public:
434 int verify_permission() override;
435 void execute() override;
436 void pre_exec() override;
437
438 virtual void send_response_data(bufferlist& bl) = 0;
439 const char* name() const override { return "get_bucket_tags"; }
440 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
441 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_TAGGING; }
442};
443
444class RGWPutBucketTags : public RGWOp {
445protected:
446 bufferlist tags_bl;
447 bufferlist in_data;
448public:
449 int verify_permission() override;
450 void execute() override;
451
452 virtual void send_response() override = 0;
453 virtual int get_params() = 0;
454 const char* name() const override { return "put_bucket_tags"; }
455 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
456 RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_TAGGING; }
457};
458
459class RGWDeleteBucketTags : public RGWOp {
460public:
461 void pre_exec() override;
462 int verify_permission() override;
463 void execute() override;
464
465 const char* name() const override { return "delete_bucket_tags"; }
466 virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
467 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_TAGGING;}
468};
469
470struct rgw_sync_policy_group;
471
472class RGWGetBucketReplication : public RGWOp {
473public:
474 int verify_permission() override;
475 void execute() override;
476 void pre_exec() override;
477
478 virtual void send_response_data() = 0;
479 const char* name() const override { return "get_bucket_replication"; }
480 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
481 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_REPLICATION; }
482};
483
484class RGWPutBucketReplication : public RGWOp {
485protected:
486 bufferlist in_data;
487 std::vector<rgw_sync_policy_group> sync_policy_groups;
488public:
489 int verify_permission() override;
490 void execute() override;
491
492 virtual void send_response() override = 0;
493 virtual int get_params() = 0;
494 const char* name() const override { return "put_bucket_replication"; }
495 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
496 RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_REPLICATION; }
497};
498
499class RGWDeleteBucketReplication : public RGWOp {
500protected:
501 virtual void update_sync_policy(rgw_sync_policy_info *policy) = 0;
502public:
503 void pre_exec() override;
504 int verify_permission() override;
505 void execute() override;
506
507 const char* name() const override { return "delete_bucket_replication"; }
508 virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
509 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_REPLICATION;}
510};
511
7c673cae
FG
512class RGWBulkDelete : public RGWOp {
513public:
514 struct acct_path_t {
515 std::string bucket_name;
516 rgw_obj_key obj_key;
517 };
518
519 struct fail_desc_t {
520 int err;
521 acct_path_t path;
522 };
523
524 class Deleter {
525 protected:
11fdf7f2 526 const DoutPrefixProvider * dpp;
7c673cae
FG
527 unsigned int num_deleted;
528 unsigned int num_unfound;
529 std::list<fail_desc_t> failures;
530
9f95a23c 531 rgw::sal::RGWRadosStore * const store;
7c673cae
FG
532 req_state * const s;
533
534 public:
9f95a23c 535 Deleter(const DoutPrefixProvider* dpp, rgw::sal::RGWRadosStore * const str, req_state * const s)
11fdf7f2
TL
536 : dpp(dpp),
537 num_deleted(0),
7c673cae
FG
538 num_unfound(0),
539 store(str),
540 s(s) {
541 }
542
543 unsigned int get_num_deleted() const {
544 return num_deleted;
545 }
546
547 unsigned int get_num_unfound() const {
548 return num_unfound;
549 }
550
551 const std::list<fail_desc_t> get_failures() const {
552 return failures;
553 }
554
555 bool verify_permission(RGWBucketInfo& binfo,
556 map<string, bufferlist>& battrs,
557 ACLOwner& bucket_owner /* out */);
558 bool delete_single(const acct_path_t& path);
559 bool delete_chunk(const std::list<acct_path_t>& paths);
560 };
561 /* End of Deleter subclass */
562
563 static const size_t MAX_CHUNK_ENTRIES = 1024;
564
565protected:
566 std::unique_ptr<Deleter> deleter;
567
568public:
569 RGWBulkDelete()
570 : deleter(nullptr) {
571 }
572
573 int verify_permission() override;
574 void pre_exec() override;
575 void execute() override;
576
577 virtual int get_data(std::list<acct_path_t>& items,
578 bool * is_truncated) = 0;
579 void send_response() override = 0;
580
11fdf7f2 581 const char* name() const override { return "bulk_delete"; }
7c673cae
FG
582 RGWOpType get_type() override { return RGW_OP_BULK_DELETE; }
583 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
11fdf7f2 584 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
585};
586
587inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
588 return out << o.bucket_name << "/" << o.obj_key;
589}
590
591
592class RGWBulkUploadOp : public RGWOp {
11fdf7f2 593 boost::optional<RGWSysObjectCtx> dir_ctx;
7c673cae
FG
594
595protected:
596 class fail_desc_t {
597 public:
598 fail_desc_t(const int err, std::string path)
599 : err(err),
600 path(std::move(path)) {
601 }
602
603 const int err;
604 const std::string path;
605 };
606
607 static constexpr std::array<int, 2> terminal_errors = {
608 { -EACCES, -EPERM }
609 };
610
611 /* FIXME: boost::container::small_vector<fail_desc_t, 4> failures; */
612 std::vector<fail_desc_t> failures;
613 size_t num_created;
614
615 class StreamGetter;
616 class DecoratedStreamGetter;
617 class AlignedStreamGetter;
618
619 virtual std::unique_ptr<StreamGetter> create_stream() = 0;
11fdf7f2 620 virtual void send_response() override = 0;
7c673cae
FG
621
622 boost::optional<std::pair<std::string, rgw_obj_key>>
623 parse_path(const boost::string_ref& path);
624
625 std::pair<std::string, std::string>
626 handle_upload_path(struct req_state *s);
627
628 bool handle_file_verify_permission(RGWBucketInfo& binfo,
31f18b77
FG
629 const rgw_obj& obj,
630 std::map<std::string, ceph::bufferlist>& battrs,
7c673cae
FG
631 ACLOwner& bucket_owner /* out */);
632 int handle_file(boost::string_ref path,
633 size_t size,
634 AlignedStreamGetter& body);
635
636 int handle_dir_verify_permission();
637 int handle_dir(boost::string_ref path);
638
639public:
640 RGWBulkUploadOp()
641 : num_created(0) {
642 }
643
9f95a23c 644 void init(rgw::sal::RGWRadosStore* const store,
7c673cae 645 struct req_state* const s,
11fdf7f2 646 RGWHandler* const h) override;
7c673cae
FG
647
648 int verify_permission() override;
649 void pre_exec() override;
650 void execute() override;
651
11fdf7f2 652 const char* name() const override { return "bulk_upload"; }
7c673cae
FG
653
654 RGWOpType get_type() override {
655 return RGW_OP_BULK_UPLOAD;
656 }
657
658 uint32_t op_mask() override {
659 return RGW_OP_TYPE_WRITE;
660 }
11fdf7f2 661 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
662}; /* RGWBulkUploadOp */
663
664
665class RGWBulkUploadOp::StreamGetter {
666public:
667 StreamGetter() = default;
668 virtual ~StreamGetter() = default;
669
670 virtual ssize_t get_at_most(size_t want, ceph::bufferlist& dst) = 0;
671 virtual ssize_t get_exactly(size_t want, ceph::bufferlist& dst) = 0;
672}; /* End of nested subclass StreamGetter */
673
674
675class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
676 StreamGetter& decoratee;
677
678protected:
679 StreamGetter& get_decoratee() {
680 return decoratee;
681 }
682
683public:
11fdf7f2 684 explicit DecoratedStreamGetter(StreamGetter& decoratee)
7c673cae
FG
685 : decoratee(decoratee) {
686 }
687 virtual ~DecoratedStreamGetter() = default;
688
689 ssize_t get_at_most(const size_t want, ceph::bufferlist& dst) override {
690 return get_decoratee().get_at_most(want, dst);
691 }
692
693 ssize_t get_exactly(const size_t want, ceph::bufferlist& dst) override {
694 return get_decoratee().get_exactly(want, dst);
695 }
696}; /* RGWBulkUploadOp::DecoratedStreamGetter */
697
698
699class RGWBulkUploadOp::AlignedStreamGetter
700 : public RGWBulkUploadOp::DecoratedStreamGetter {
701 size_t position;
702 size_t length;
703 size_t alignment;
704
705public:
706 template <typename U>
707 AlignedStreamGetter(const size_t position,
708 const size_t length,
709 const size_t alignment,
710 U&& decoratee)
711 : DecoratedStreamGetter(std::forward<U>(decoratee)),
712 position(position),
713 length(length),
714 alignment(alignment) {
715 }
716 virtual ~AlignedStreamGetter();
717 ssize_t get_at_most(size_t want, ceph::bufferlist& dst) override;
718 ssize_t get_exactly(size_t want, ceph::bufferlist& dst) override;
719}; /* RGWBulkUploadOp::AlignedStreamGetter */
720
721
3efd9988
FG
722struct RGWUsageStats {
723 uint64_t bytes_used = 0;
724 uint64_t bytes_used_rounded = 0;
725 uint64_t buckets_count = 0;
726 uint64_t objects_count = 0;
727};
728
7c673cae
FG
729#define RGW_LIST_BUCKETS_LIMIT_MAX 10000
730
731class RGWListBuckets : public RGWOp {
732protected:
733 bool sent_data;
3efd9988
FG
734 std::string marker;
735 std::string end_marker;
7c673cae
FG
736 int64_t limit;
737 uint64_t limit_max;
3efd9988 738 std::map<std::string, ceph::bufferlist> attrs;
7c673cae
FG
739 bool is_truncated;
740
3efd9988
FG
741 RGWUsageStats global_stats;
742 std::map<std::string, RGWUsageStats> policies_stats;
743
7c673cae
FG
744 virtual uint64_t get_default_max() const {
745 return 1000;
746 }
747
748public:
3efd9988
FG
749 RGWListBuckets()
750 : sent_data(false),
751 limit(RGW_LIST_BUCKETS_LIMIT_MAX),
752 limit_max(RGW_LIST_BUCKETS_LIMIT_MAX),
753 is_truncated(false) {
7c673cae
FG
754 }
755
756 int verify_permission() override;
757 void execute() override;
758
759 virtual int get_params() = 0;
9f95a23c 760 virtual void handle_listing_chunk(rgw::sal::RGWBucketList&& buckets) {
3efd9988
FG
761 /* The default implementation, used by e.g. S3, just generates a new
762 * part of listing and sends it client immediately. Swift can behave
763 * differently: when the reverse option is requested, all incoming
9f95a23c 764 * instances of RGWBucketList are buffered and finally reversed. */
3efd9988
FG
765 return send_response_data(buckets);
766 }
7c673cae 767 virtual void send_response_begin(bool has_buckets) = 0;
9f95a23c 768 virtual void send_response_data(rgw::sal::RGWBucketList& buckets) = 0;
7c673cae
FG
769 virtual void send_response_end() = 0;
770 void send_response() override {}
771
772 virtual bool should_get_stats() { return false; }
773 virtual bool supports_account_metadata() { return false; }
774
11fdf7f2 775 const char* name() const override { return "list_buckets"; }
7c673cae
FG
776 RGWOpType get_type() override { return RGW_OP_LIST_BUCKETS; }
777 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1adf2230 778}; // class RGWListBuckets
7c673cae
FG
779
780class RGWGetUsage : public RGWOp {
781protected:
782 bool sent_data;
783 string start_date;
784 string end_date;
785 int show_log_entries;
786 int show_log_sum;
787 map<string, bool> categories;
788 map<rgw_user_bucket, rgw_usage_log_entry> usage;
789 map<string, rgw_usage_log_entry> summary_map;
c07f9fc5 790 map<string, cls_user_bucket_entry> buckets_usage;
7c673cae 791 cls_user_header header;
9f95a23c 792 RGWStorageStats stats;
7c673cae
FG
793public:
794 RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
795 }
796
797 int verify_permission() override;
798 void execute() override;
799
800 virtual int get_params() = 0;
801 void send_response() override {}
802
803 virtual bool should_get_stats() { return false; }
804
9f95a23c 805 const char* name() const override { return "get_self_usage"; }
7c673cae
FG
806 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
807};
808
809class RGWStatAccount : public RGWOp {
810protected:
3efd9988
FG
811 RGWUsageStats global_stats;
812 std::map<std::string, RGWUsageStats> policies_stats;
7c673cae
FG
813
814public:
3efd9988 815 RGWStatAccount() = default;
7c673cae
FG
816
817 int verify_permission() override;
818 void execute() override;
819
820 void send_response() override = 0;
11fdf7f2 821 const char* name() const override { return "stat_account"; }
7c673cae
FG
822 RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; }
823 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
824};
825
826class RGWListBucket : public RGWOp {
827protected:
9f95a23c 828 rgw::sal::RGWBucket* bucket;
7c673cae
FG
829 string prefix;
830 rgw_obj_key marker;
831 rgw_obj_key next_marker;
832 rgw_obj_key end_marker;
833 string max_keys;
834 string delimiter;
835 string encoding_type;
836 bool list_versions;
837 int max;
838 vector<rgw_bucket_dir_entry> objs;
839 map<string, bool> common_prefixes;
840
841 int default_max;
842 bool is_truncated;
1adf2230 843 bool allow_unordered;
7c673cae
FG
844
845 int shard_id;
846
847 int parse_max_keys();
848
849public:
9f95a23c 850 RGWListBucket() : bucket(nullptr), list_versions(false), max(0),
1adf2230
AA
851 default_max(0), is_truncated(false),
852 allow_unordered(false), shard_id(-1) {}
9f95a23c 853 ~RGWListBucket() { delete bucket; }
7c673cae
FG
854 int verify_permission() override;
855 void pre_exec() override;
856 void execute() override;
857
9f95a23c
TL
858 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
859 RGWOp::init(store, s, h);
860 bucket = new rgw::sal::RGWRadosBucket(store, *s->user, s->bucket);
861 }
7c673cae
FG
862 virtual int get_params() = 0;
863 void send_response() override = 0;
11fdf7f2 864 const char* name() const override { return "list_bucket"; }
7c673cae
FG
865 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET; }
866 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
867 virtual bool need_container_stats() { return false; }
868};
869
870class RGWGetBucketLogging : public RGWOp {
871public:
872 RGWGetBucketLogging() {}
873 int verify_permission() override;
874 void execute() override { }
875
876 void send_response() override = 0;
11fdf7f2 877 const char* name() const override { return "get_bucket_logging"; }
7c673cae
FG
878 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOGGING; }
879 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
880};
881
882class RGWGetBucketLocation : public RGWOp {
883public:
884 RGWGetBucketLocation() {}
885 ~RGWGetBucketLocation() override {}
886 int verify_permission() override;
887 void execute() override { }
888
889 void send_response() override = 0;
11fdf7f2 890 const char* name() const override { return "get_bucket_location"; }
3efd9988 891 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOCATION; }
7c673cae
FG
892 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
893};
894
895class RGWGetBucketVersioning : public RGWOp {
896protected:
11fdf7f2
TL
897 bool versioned{false};
898 bool versioning_enabled{false};
899 bool mfa_enabled{false};
7c673cae 900public:
11fdf7f2 901 RGWGetBucketVersioning() = default;
7c673cae
FG
902
903 int verify_permission() override;
904 void pre_exec() override;
905 void execute() override;
906
907 void send_response() override = 0;
11fdf7f2 908 const char* name() const override { return "get_bucket_versioning"; }
7c673cae
FG
909 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_VERSIONING; }
910 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
911};
912
11fdf7f2
TL
913enum BucketVersionStatus {
914 VersioningStatusInvalid = -1,
915 VersioningNotChanged = 0,
916 VersioningEnabled = 1,
917 VersioningSuspended =2,
918};
919
7c673cae
FG
920class RGWSetBucketVersioning : public RGWOp {
921protected:
11fdf7f2
TL
922 int versioning_status;
923 bool mfa_set_status{false};
924 bool mfa_status{false};
7c673cae
FG
925 bufferlist in_data;
926public:
11fdf7f2 927 RGWSetBucketVersioning() : versioning_status(VersioningNotChanged) {}
7c673cae
FG
928
929 int verify_permission() override;
930 void pre_exec() override;
931 void execute() override;
932
933 virtual int get_params() { return 0; }
934
935 void send_response() override = 0;
11fdf7f2 936 const char* name() const override { return "set_bucket_versioning"; }
7c673cae
FG
937 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_VERSIONING; }
938 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
939};
940
941class RGWGetBucketWebsite : public RGWOp {
942public:
943 RGWGetBucketWebsite() {}
944
945 int verify_permission() override;
946 void pre_exec() override;
947 void execute() override;
948
949 void send_response() override = 0;
11fdf7f2 950 const char* name() const override { return "get_bucket_website"; }
7c673cae
FG
951 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_WEBSITE; }
952 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
953};
954
955class RGWSetBucketWebsite : public RGWOp {
956protected:
31f18b77 957 bufferlist in_data;
7c673cae
FG
958 RGWBucketWebsiteConf website_conf;
959public:
960 RGWSetBucketWebsite() {}
961
962 int verify_permission() override;
963 void pre_exec() override;
964 void execute() override;
965
966 virtual int get_params() { return 0; }
967
968 void send_response() override = 0;
11fdf7f2 969 const char* name() const override { return "set_bucket_website"; }
7c673cae
FG
970 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
971 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
972};
973
974class RGWDeleteBucketWebsite : public RGWOp {
975public:
976 RGWDeleteBucketWebsite() {}
977
978 int verify_permission() override;
979 void pre_exec() override;
980 void execute() override;
981
982 void send_response() override = 0;
11fdf7f2 983 const char* name() const override { return "delete_bucket_website"; }
7c673cae
FG
984 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
985 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
986};
987
988class RGWStatBucket : public RGWOp {
989protected:
9f95a23c 990 rgw::sal::RGWBucket* bucket;
7c673cae
FG
991
992public:
9f95a23c
TL
993 RGWStatBucket() : bucket(nullptr) {}
994 ~RGWStatBucket() override { delete bucket; }
7c673cae
FG
995
996 int verify_permission() override;
997 void pre_exec() override;
998 void execute() override;
999
1000 void send_response() override = 0;
11fdf7f2 1001 const char* name() const override { return "stat_bucket"; }
7c673cae
FG
1002 RGWOpType get_type() override { return RGW_OP_STAT_BUCKET; }
1003 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1004};
1005
1006class RGWCreateBucket : public RGWOp {
1007protected:
1008 RGWAccessControlPolicy policy;
1009 string location_constraint;
11fdf7f2 1010 rgw_placement_rule placement_rule;
7c673cae
FG
1011 RGWBucketInfo info;
1012 obj_version ep_objv;
1013 bool has_cors;
11fdf7f2 1014 bool relaxed_region_enforcement;
eafe8130 1015 bool obj_lock_enabled;
7c673cae
FG
1016 RGWCORSConfiguration cors_config;
1017 boost::optional<std::string> swift_ver_location;
1018 map<string, buffer::list> attrs;
1019 set<string> rmattr_names;
1020
1021 bufferlist in_data;
1022
1023 virtual bool need_metadata_upload() const { return false; }
1024
1025public:
eafe8130 1026 RGWCreateBucket() : has_cors(false), relaxed_region_enforcement(false), obj_lock_enabled(false) {}
7c673cae
FG
1027
1028 void emplace_attr(std::string&& key, buffer::list&& bl) {
1029 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1030 }
1031
1032 int verify_permission() override;
1033 void pre_exec() override;
1034 void execute() override;
9f95a23c 1035 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1036 RGWOp::init(store, s, h);
1037 policy.set_ctx(s->cct);
11fdf7f2
TL
1038 relaxed_region_enforcement =
1039 s->cct->_conf.get_val<bool>("rgw_relaxed_region_enforcement");
7c673cae
FG
1040 }
1041 virtual int get_params() { return 0; }
1042 void send_response() override = 0;
11fdf7f2 1043 const char* name() const override { return "create_bucket"; }
7c673cae
FG
1044 RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; }
1045 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1046};
1047
1048class RGWDeleteBucket : public RGWOp {
1049protected:
1050 RGWObjVersionTracker objv_tracker;
1051
1052public:
1053 RGWDeleteBucket() {}
1054
1055 int verify_permission() override;
1056 void pre_exec() override;
1057 void execute() override;
1058
1059 void send_response() override = 0;
11fdf7f2 1060 const char* name() const override { return "delete_bucket"; }
7c673cae
FG
1061 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET; }
1062 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1063};
1064
1065struct rgw_slo_entry {
1066 string path;
1067 string etag;
1068 uint64_t size_bytes;
1069
1070 rgw_slo_entry() : size_bytes(0) {}
1071
1072 void encode(bufferlist& bl) const {
1073 ENCODE_START(1, 1, bl);
11fdf7f2
TL
1074 encode(path, bl);
1075 encode(etag, bl);
1076 encode(size_bytes, bl);
7c673cae
FG
1077 ENCODE_FINISH(bl);
1078 }
1079
11fdf7f2 1080 void decode(bufferlist::const_iterator& bl) {
7c673cae 1081 DECODE_START(1, bl);
11fdf7f2
TL
1082 decode(path, bl);
1083 decode(etag, bl);
1084 decode(size_bytes, bl);
7c673cae
FG
1085 DECODE_FINISH(bl);
1086 }
1087
1088 void decode_json(JSONObj *obj);
1089};
1090WRITE_CLASS_ENCODER(rgw_slo_entry)
1091
1092struct RGWSLOInfo {
1093 vector<rgw_slo_entry> entries;
1094 uint64_t total_size;
1095
1096 /* in memory only */
11fdf7f2 1097 bufferlist raw_data;
7c673cae 1098
11fdf7f2
TL
1099 RGWSLOInfo() : total_size(0) {}
1100 ~RGWSLOInfo() {}
7c673cae
FG
1101
1102 void encode(bufferlist& bl) const {
1103 ENCODE_START(1, 1, bl);
11fdf7f2
TL
1104 encode(entries, bl);
1105 encode(total_size, bl);
7c673cae
FG
1106 ENCODE_FINISH(bl);
1107 }
1108
11fdf7f2 1109 void decode(bufferlist::const_iterator& bl) {
7c673cae 1110 DECODE_START(1, bl);
11fdf7f2
TL
1111 decode(entries, bl);
1112 decode(total_size, bl);
7c673cae
FG
1113 DECODE_FINISH(bl);
1114 }
1115};
1116WRITE_CLASS_ENCODER(RGWSLOInfo)
1117
1118class RGWPutObj : public RGWOp {
7c673cae
FG
1119protected:
1120 seed torrent;
1121 off_t ofs;
1122 const char *supplied_md5_b64;
1123 const char *supplied_etag;
1124 const char *if_match;
1125 const char *if_nomatch;
3a9019d9 1126 std::string copy_source;
7c673cae
FG
1127 const char *copy_source_range;
1128 RGWBucketInfo copy_source_bucket_info;
1129 string copy_source_tenant_name;
1130 string copy_source_bucket_name;
1131 string copy_source_object_name;
1132 string copy_source_version_id;
1133 off_t copy_source_range_fst;
1134 off_t copy_source_range_lst;
1135 string etag;
1136 bool chunked_upload;
1137 RGWAccessControlPolicy policy;
224ce89b 1138 std::unique_ptr <RGWObjTags> obj_tags;
7c673cae
FG
1139 const char *dlo_manifest;
1140 RGWSLOInfo *slo_info;
1141 map<string, bufferlist> attrs;
1142 ceph::real_time mtime;
1143 uint64_t olh_epoch;
1144 string version_id;
1145 bufferlist bl_aux;
1146 map<string, string> crypt_http_responses;
1147 string user_data;
1148
11fdf7f2
TL
1149 std::string multipart_upload_id;
1150 std::string multipart_part_str;
1151 int multipart_part_num = 0;
1152
7c673cae 1153 boost::optional<ceph::real_time> delete_at;
11fdf7f2
TL
1154 //append obj
1155 bool append;
1156 uint64_t position;
1157 uint64_t cur_accounted_size;
7c673cae 1158
eafe8130
TL
1159 //object lock
1160 RGWObjectRetention *obj_retention;
1161 RGWObjectLegalHold *obj_legal_hold;
1162
7c673cae
FG
1163public:
1164 RGWPutObj() : ofs(0),
1165 supplied_md5_b64(NULL),
1166 supplied_etag(NULL),
1167 if_match(NULL),
1168 if_nomatch(NULL),
7c673cae
FG
1169 copy_source_range(NULL),
1170 copy_source_range_fst(0),
1171 copy_source_range_lst(0),
1172 chunked_upload(0),
1173 dlo_manifest(NULL),
1174 slo_info(NULL),
11fdf7f2
TL
1175 olh_epoch(0),
1176 append(false),
1177 position(0),
eafe8130
TL
1178 cur_accounted_size(0),
1179 obj_retention(nullptr),
1180 obj_legal_hold(nullptr) {}
7c673cae
FG
1181
1182 ~RGWPutObj() override {
1183 delete slo_info;
eafe8130
TL
1184 delete obj_retention;
1185 delete obj_legal_hold;
7c673cae
FG
1186 }
1187
9f95a23c 1188 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1189 RGWOp::init(store, s, h);
1190 policy.set_ctx(s->cct);
1191 }
1192
1193 void emplace_attr(std::string&& key, buffer::list&& bl) {
1194 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1195 }
1196
7c673cae
FG
1197 int verify_permission() override;
1198 void pre_exec() override;
1199 void execute() override;
1200
1201 /* this is for cases when copying data from other object */
11fdf7f2
TL
1202 virtual int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
1203 RGWGetObj_Filter* cb,
7c673cae
FG
1204 map<string, bufferlist>& attrs,
1205 bufferlist* manifest_bl) {
1206 *filter = nullptr;
1207 return 0;
1208 }
11fdf7f2
TL
1209 virtual int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
1210 rgw::putobj::DataProcessor *cb) {
1211 return 0;
7c673cae
FG
1212 }
1213
1214 int get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len);
1215 int get_data(const off_t fst, const off_t lst, bufferlist& bl);
1216
1217 virtual int get_params() = 0;
1218 virtual int get_data(bufferlist& bl) = 0;
1219 void send_response() override = 0;
11fdf7f2 1220 const char* name() const override { return "put_obj"; }
7c673cae
FG
1221 RGWOpType get_type() override { return RGW_OP_PUT_OBJ; }
1222 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
11fdf7f2 1223 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
1224};
1225
7c673cae
FG
1226class RGWPostObj : public RGWOp {
1227protected:
1228 off_t min_len;
1229 off_t max_len;
1230 int len;
1231 off_t ofs;
1232 const char *supplied_md5_b64;
1233 const char *supplied_etag;
1234 string etag;
1235 RGWAccessControlPolicy policy;
1236 map<string, bufferlist> attrs;
1237 boost::optional<ceph::real_time> delete_at;
1238
1239 /* Must be called after get_data() or the result is undefined. */
1240 virtual std::string get_current_filename() const = 0;
1241 virtual std::string get_current_content_type() const = 0;
1242 virtual bool is_next_file_to_upload() {
1243 return false;
1244 }
1245public:
1246 RGWPostObj() : min_len(0),
1247 max_len(LLONG_MAX),
1248 len(0),
1249 ofs(0),
1250 supplied_md5_b64(nullptr),
1251 supplied_etag(nullptr) {
1252 }
1253
1254 void emplace_attr(std::string&& key, buffer::list&& bl) {
1255 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1256 }
1257
9f95a23c 1258 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1259 RGWOp::init(store, s, h);
1260 policy.set_ctx(s->cct);
1261 }
1262
1263 int verify_permission() override;
1264 void pre_exec() override;
1265 void execute() override;
1266
11fdf7f2
TL
1267 virtual int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
1268 rgw::putobj::DataProcessor *cb) {
7c673cae
FG
1269 return 0;
1270 }
1271 virtual int get_params() = 0;
1272 virtual int get_data(ceph::bufferlist& bl, bool& again) = 0;
1273 void send_response() override = 0;
11fdf7f2 1274 const char* name() const override { return "post_obj"; }
7c673cae
FG
1275 RGWOpType get_type() override { return RGW_OP_POST_OBJ; }
1276 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
11fdf7f2 1277 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
1278};
1279
1280class RGWPutMetadataAccount : public RGWOp {
1281protected:
1282 std::set<std::string> rmattr_names;
1283 std::map<std::string, bufferlist> attrs, orig_attrs;
1284 std::map<int, std::string> temp_url_keys;
1285 RGWQuotaInfo new_quota;
1286 bool new_quota_extracted;
1287
1288 RGWObjVersionTracker acct_op_tracker;
1289
1290 RGWAccessControlPolicy policy;
1291 bool has_policy;
1292
1293public:
1294 RGWPutMetadataAccount()
1295 : new_quota_extracted(false),
1296 has_policy(false) {
1297 }
1298
9f95a23c 1299 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1300 RGWOp::init(store, s, h);
1301 policy.set_ctx(s->cct);
1302 }
1303 int init_processing() override;
1304 int verify_permission() override;
1305 void pre_exec() override { }
1306 void execute() override;
1307
1308 virtual int get_params() = 0;
1309 void send_response() override = 0;
1310 virtual void filter_out_temp_url(map<string, bufferlist>& add_attrs,
1311 const set<string>& rmattr_names,
1312 map<int, string>& temp_url_keys);
11fdf7f2 1313 const char* name() const override { return "put_account_metadata"; }
7c673cae
FG
1314 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_ACCOUNT; }
1315 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1316};
1317
1318class RGWPutMetadataBucket : public RGWOp {
1319protected:
1320 map<string, buffer::list> attrs;
1321 set<string> rmattr_names;
1322 bool has_policy, has_cors;
1323 uint32_t policy_rw_mask;
1324 RGWAccessControlPolicy policy;
1325 RGWCORSConfiguration cors_config;
11fdf7f2 1326 rgw_placement_rule placement_rule;
7c673cae
FG
1327 boost::optional<std::string> swift_ver_location;
1328
1329public:
1330 RGWPutMetadataBucket()
1331 : has_policy(false), has_cors(false), policy_rw_mask(0)
1332 {}
1333
1334 void emplace_attr(std::string&& key, buffer::list&& bl) {
1335 attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
1336 }
1337
9f95a23c 1338 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1339 RGWOp::init(store, s, h);
1340 policy.set_ctx(s->cct);
1341 }
1342
1343 int verify_permission() override;
1344 void pre_exec() override;
1345 void execute() override;
1346
1347 virtual int get_params() = 0;
1348 void send_response() override = 0;
11fdf7f2 1349 const char* name() const override { return "put_bucket_metadata"; }
7c673cae
FG
1350 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; }
1351 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1352};
1353
1354class RGWPutMetadataObject : public RGWOp {
1355protected:
1356 RGWAccessControlPolicy policy;
7c673cae
FG
1357 boost::optional<ceph::real_time> delete_at;
1358 const char *dlo_manifest;
1359
1360public:
1361 RGWPutMetadataObject()
1362 : dlo_manifest(NULL)
1363 {}
1364
9f95a23c 1365 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1366 RGWOp::init(store, s, h);
1367 policy.set_ctx(s->cct);
1368 }
1369 int verify_permission() override;
1370 void pre_exec() override;
1371 void execute() override;
1372
1373 virtual int get_params() = 0;
1374 void send_response() override = 0;
11fdf7f2 1375 const char* name() const override { return "put_obj_metadata"; }
7c673cae
FG
1376 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_OBJECT; }
1377 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1378 virtual bool need_object_expiration() { return false; }
1379};
1380
1381class RGWDeleteObj : public RGWOp {
1382protected:
1383 bool delete_marker;
1384 bool multipart_delete;
1385 string version_id;
1386 ceph::real_time unmod_since; /* if unmodified since */
1387 bool no_precondition_error;
1388 std::unique_ptr<RGWBulkDelete::Deleter> deleter;
eafe8130
TL
1389 bool bypass_perm;
1390 bool bypass_governance_mode;
7c673cae
FG
1391
1392public:
1393 RGWDeleteObj()
1394 : delete_marker(false),
1395 multipart_delete(false),
1396 no_precondition_error(false),
eafe8130
TL
1397 deleter(nullptr),
1398 bypass_perm(true),
1399 bypass_governance_mode(false) {
7c673cae
FG
1400 }
1401
1402 int verify_permission() override;
1403 void pre_exec() override;
1404 void execute() override;
1405 int handle_slo_manifest(bufferlist& bl);
1406
1407 virtual int get_params() { return 0; }
1408 void send_response() override = 0;
11fdf7f2 1409 const char* name() const override { return "delete_obj"; }
7c673cae
FG
1410 RGWOpType get_type() override { return RGW_OP_DELETE_OBJ; }
1411 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1412 virtual bool need_object_expiration() { return false; }
11fdf7f2 1413 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
1414};
1415
1416class RGWCopyObj : public RGWOp {
1417protected:
1418 RGWAccessControlPolicy dest_policy;
1419 const char *if_mod;
1420 const char *if_unmod;
1421 const char *if_match;
1422 const char *if_nomatch;
494da23a
TL
1423 // Required or it is not a copy operation
1424 std::string_view copy_source;
1425 // Not actually required
1426 std::optional<std::string_view> md_directive;
11fdf7f2 1427
7c673cae
FG
1428 off_t ofs;
1429 off_t len;
1430 off_t end;
1431 ceph::real_time mod_time;
1432 ceph::real_time unmod_time;
1433 ceph::real_time *mod_ptr;
1434 ceph::real_time *unmod_ptr;
1435 map<string, buffer::list> attrs;
1436 string src_tenant_name, src_bucket_name;
1437 rgw_bucket src_bucket;
1438 rgw_obj_key src_object;
1439 string dest_tenant_name, dest_bucket_name;
1440 rgw_bucket dest_bucket;
1441 string dest_object;
1442 ceph::real_time src_mtime;
1443 ceph::real_time mtime;
1444 RGWRados::AttrsMod attrs_mod;
1445 RGWBucketInfo src_bucket_info;
1446 RGWBucketInfo dest_bucket_info;
1447 string source_zone;
11fdf7f2 1448 string etag;
7c673cae
FG
1449
1450 off_t last_ofs;
1451
1452 string version_id;
1453 uint64_t olh_epoch;
1454
1455 boost::optional<ceph::real_time> delete_at;
1456 bool copy_if_newer;
1457
11fdf7f2
TL
1458 bool need_to_check_storage_class = false;
1459
7c673cae
FG
1460 int init_common();
1461
1462public:
1463 RGWCopyObj() {
1464 if_mod = NULL;
1465 if_unmod = NULL;
1466 if_match = NULL;
1467 if_nomatch = NULL;
1468 ofs = 0;
1469 len = 0;
1470 end = -1;
1471 mod_ptr = NULL;
1472 unmod_ptr = NULL;
1473 attrs_mod = RGWRados::ATTRSMOD_NONE;
1474 last_ofs = 0;
1475 olh_epoch = 0;
1476 copy_if_newer = false;
1477 }
1478
3a9019d9 1479 static bool parse_copy_location(const boost::string_view& src,
7c673cae
FG
1480 string& bucket_name,
1481 rgw_obj_key& object);
1482
1483 void emplace_attr(std::string&& key, buffer::list&& bl) {
1484 attrs.emplace(std::move(key), std::move(bl));
1485 }
1486
9f95a23c 1487 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1488 RGWOp::init(store, s, h);
1489 dest_policy.set_ctx(s->cct);
1490 }
1491 int verify_permission() override;
1492 void pre_exec() override;
1493 void execute() override;
1494 void progress_cb(off_t ofs);
1495
11fdf7f2
TL
1496 virtual int check_storage_class(const rgw_placement_rule& src_placement) {
1497 return 0;
1498 }
1499
7c673cae
FG
1500 virtual int init_dest_policy() { return 0; }
1501 virtual int get_params() = 0;
1502 virtual void send_partial_response(off_t ofs) {}
1503 void send_response() override = 0;
11fdf7f2 1504 const char* name() const override { return "copy_obj"; }
7c673cae
FG
1505 RGWOpType get_type() override { return RGW_OP_COPY_OBJ; }
1506 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
11fdf7f2 1507 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
7c673cae
FG
1508};
1509
1510class RGWGetACLs : public RGWOp {
1511protected:
1512 string acls;
1513
1514public:
1515 RGWGetACLs() {}
1516
1517 int verify_permission() override;
1518 void pre_exec() override;
1519 void execute() override;
1520
1521 void send_response() override = 0;
11fdf7f2 1522 const char* name() const override { return "get_acls"; }
7c673cae
FG
1523 RGWOpType get_type() override { return RGW_OP_GET_ACLS; }
1524 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1525};
1526
1527class RGWPutACLs : public RGWOp {
1528protected:
11fdf7f2 1529 bufferlist data;
7c673cae
FG
1530 ACLOwner owner;
1531
1532public:
11fdf7f2
TL
1533 RGWPutACLs() {}
1534 ~RGWPutACLs() override {}
7c673cae
FG
1535
1536 int verify_permission() override;
1537 void pre_exec() override;
1538 void execute() override;
1539
9f95a23c 1540 virtual int get_policy_from_state(rgw::sal::RGWRadosStore *store, struct req_state *s, stringstream& ss) { return 0; }
7c673cae
FG
1541 virtual int get_params() = 0;
1542 void send_response() override = 0;
11fdf7f2 1543 const char* name() const override { return "put_acls"; }
7c673cae
FG
1544 RGWOpType get_type() override { return RGW_OP_PUT_ACLS; }
1545 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1546};
1547
1548class RGWGetLC : public RGWOp {
1549protected:
1550
1551public:
1552 RGWGetLC() { }
1553 ~RGWGetLC() override { }
1554
1555 int verify_permission() override;
1556 void pre_exec() override;
1557 void execute() override = 0;
1558
1559 void send_response() override = 0;
11fdf7f2 1560 const char* name() const override { return "get_lifecycle"; }
d2e6a577 1561 RGWOpType get_type() override { return RGW_OP_GET_LC; }
7c673cae
FG
1562 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1563};
1564
1565class RGWPutLC : public RGWOp {
1566protected:
11fdf7f2 1567 bufferlist data;
b32b8144 1568 const char *content_md5;
7c673cae
FG
1569 string cookie;
1570
1571public:
1572 RGWPutLC() {
b32b8144 1573 content_md5 = nullptr;
7c673cae 1574 }
11fdf7f2 1575 ~RGWPutLC() override {}
7c673cae 1576
9f95a23c 1577 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *dialect_handler) override {
7c673cae
FG
1578#define COOKIE_LEN 16
1579 char buf[COOKIE_LEN + 1];
1580
1581 RGWOp::init(store, s, dialect_handler);
1582 gen_rand_alphanumeric(s->cct, buf, sizeof(buf) - 1);
1583 cookie = buf;
1584 }
1585
1586 int verify_permission() override;
1587 void pre_exec() override;
1588 void execute() override;
1589
1590// virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
1591 virtual int get_params() = 0;
1592 void send_response() override = 0;
11fdf7f2 1593 const char* name() const override { return "put_lifecycle"; }
d2e6a577 1594 RGWOpType get_type() override { return RGW_OP_PUT_LC; }
7c673cae
FG
1595 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1596};
1597
1598class RGWDeleteLC : public RGWOp {
7c673cae 1599public:
9f95a23c 1600 RGWDeleteLC() = default;
7c673cae
FG
1601 int verify_permission() override;
1602 void pre_exec() override;
1603 void execute() override;
1604
1605 void send_response() override = 0;
11fdf7f2 1606 const char* name() const override { return "delete_lifecycle"; }
d2e6a577 1607 RGWOpType get_type() override { return RGW_OP_DELETE_LC; }
7c673cae
FG
1608 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1609};
1610
1611class RGWGetCORS : public RGWOp {
1612protected:
1613
1614public:
1615 RGWGetCORS() {}
1616
1617 int verify_permission() override;
1618 void execute() override;
1619
1620 void send_response() override = 0;
11fdf7f2 1621 const char* name() const override { return "get_cors"; }
7c673cae
FG
1622 RGWOpType get_type() override { return RGW_OP_GET_CORS; }
1623 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1624};
1625
1626class RGWPutCORS : public RGWOp {
1627protected:
1628 bufferlist cors_bl;
31f18b77 1629 bufferlist in_data;
7c673cae
FG
1630
1631public:
1632 RGWPutCORS() {}
1633 ~RGWPutCORS() override {}
1634
1635 int verify_permission() override;
1636 void execute() override;
1637
1638 virtual int get_params() = 0;
1639 void send_response() override = 0;
11fdf7f2 1640 const char* name() const override { return "put_cors"; }
7c673cae
FG
1641 RGWOpType get_type() override { return RGW_OP_PUT_CORS; }
1642 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1643};
1644
1645class RGWDeleteCORS : public RGWOp {
1646protected:
1647
1648public:
1649 RGWDeleteCORS() {}
1650
1651 int verify_permission() override;
1652 void execute() override;
1653
1654 void send_response() override = 0;
11fdf7f2 1655 const char* name() const override { return "delete_cors"; }
7c673cae
FG
1656 RGWOpType get_type() override { return RGW_OP_DELETE_CORS; }
1657 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1658};
1659
1660class RGWOptionsCORS : public RGWOp {
1661protected:
1662 RGWCORSRule *rule;
1663 const char *origin, *req_hdrs, *req_meth;
1664
1665public:
1666 RGWOptionsCORS() : rule(NULL), origin(NULL),
1667 req_hdrs(NULL), req_meth(NULL) {
1668 }
1669
1670 int verify_permission() override {return 0;}
1671 int validate_cors_request(RGWCORSConfiguration *cc);
1672 void execute() override;
1673 void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age);
1674 void send_response() override = 0;
11fdf7f2 1675 const char* name() const override { return "options_cors"; }
7c673cae
FG
1676 RGWOpType get_type() override { return RGW_OP_OPTIONS_CORS; }
1677 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1678};
1679
1680class RGWGetRequestPayment : public RGWOp {
1681protected:
1682 bool requester_pays;
1683
1684public:
1685 RGWGetRequestPayment() : requester_pays(0) {}
1686
1687 int verify_permission() override;
1688 void pre_exec() override;
1689 void execute() override;
1690
1691 void send_response() override = 0;
11fdf7f2 1692 const char* name() const override { return "get_request_payment"; }
7c673cae
FG
1693 RGWOpType get_type() override { return RGW_OP_GET_REQUEST_PAYMENT; }
1694 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1695};
1696
1697class RGWSetRequestPayment : public RGWOp {
1698protected:
1699 bool requester_pays;
494da23a 1700 bufferlist in_data;
7c673cae
FG
1701public:
1702 RGWSetRequestPayment() : requester_pays(false) {}
1703
1704 int verify_permission() override;
1705 void pre_exec() override;
1706 void execute() override;
1707
1708 virtual int get_params() { return 0; }
1709
1710 void send_response() override = 0;
11fdf7f2 1711 const char* name() const override { return "set_request_payment"; }
7c673cae
FG
1712 RGWOpType get_type() override { return RGW_OP_SET_REQUEST_PAYMENT; }
1713 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1714};
1715
1716class RGWInitMultipart : public RGWOp {
1717protected:
1718 string upload_id;
1719 RGWAccessControlPolicy policy;
1720
1721public:
1722 RGWInitMultipart() {}
1723
9f95a23c 1724 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1725 RGWOp::init(store, s, h);
1726 policy.set_ctx(s->cct);
1727 }
1728 int verify_permission() override;
1729 void pre_exec() override;
1730 void execute() override;
1731
1732 virtual int get_params() = 0;
1733 void send_response() override = 0;
11fdf7f2 1734 const char* name() const override { return "init_multipart"; }
7c673cae
FG
1735 RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; }
1736 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1737 virtual int prepare_encryption(map<string, bufferlist>& attrs) { return 0; }
1738};
1739
1740class RGWCompleteMultipart : public RGWOp {
1741protected:
1742 string upload_id;
1743 string etag;
11fdf7f2
TL
1744 string version_id;
1745 bufferlist data;
7c673cae 1746
3efd9988
FG
1747 struct MPSerializer {
1748 librados::IoCtx ioctx;
1749 rados::cls::lock::Lock lock;
1750 librados::ObjectWriteOperation op;
1751 std::string oid;
1752 bool locked;
1753
1754 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1755 {}
1756
1757 int try_lock(const std::string& oid, utime_t dur);
1758
1759 int unlock() {
1760 return lock.unlock(&ioctx, oid);
1761 }
1762
1763 void clear_locked() {
1764 locked = false;
1765 }
1766 } serializer;
1767
7c673cae 1768public:
11fdf7f2
TL
1769 RGWCompleteMultipart() {}
1770 ~RGWCompleteMultipart() override {}
7c673cae
FG
1771
1772 int verify_permission() override;
1773 void pre_exec() override;
1774 void execute() override;
3efd9988 1775 void complete() override;
7c673cae
FG
1776
1777 virtual int get_params() = 0;
1778 void send_response() override = 0;
11fdf7f2 1779 const char* name() const override { return "complete_multipart"; }
7c673cae
FG
1780 RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
1781 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1782};
1783
1784class RGWAbortMultipart : public RGWOp {
1785public:
1786 RGWAbortMultipart() {}
1787
1788 int verify_permission() override;
1789 void pre_exec() override;
1790 void execute() override;
1791
1792 void send_response() override = 0;
11fdf7f2 1793 const char* name() const override { return "abort_multipart"; }
7c673cae
FG
1794 RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; }
1795 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1796};
1797
1798class RGWListMultipart : public RGWOp {
1799protected:
1800 string upload_id;
1801 map<uint32_t, RGWUploadPartInfo> parts;
1802 int max_parts;
1803 int marker;
1804 RGWAccessControlPolicy policy;
1805 bool truncated;
1806
1807public:
1808 RGWListMultipart() {
1809 max_parts = 1000;
1810 marker = 0;
1811 truncated = false;
1812 }
1813
9f95a23c 1814 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1815 RGWOp::init(store, s, h);
1816 policy = RGWAccessControlPolicy(s->cct);
1817 }
1818 int verify_permission() override;
1819 void pre_exec() override;
1820 void execute() override;
1821
1822 virtual int get_params() = 0;
1823 void send_response() override = 0;
11fdf7f2 1824 const char* name() const override { return "list_multipart"; }
7c673cae
FG
1825 RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
1826 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1827};
1828
1829struct RGWMultipartUploadEntry {
1830 rgw_bucket_dir_entry obj;
1831 RGWMPObj mp;
e306af50
TL
1832
1833 friend std::ostream& operator<<(std::ostream& out,
1834 const RGWMultipartUploadEntry& e) {
1835 constexpr char quote = '"';
1836 return out << "RGWMultipartUploadEntry{ obj.key=" <<
1837 quote << e.obj.key << quote << " mp=" << e.mp << " }";
1838 }
7c673cae
FG
1839};
1840
1841class RGWListBucketMultiparts : public RGWOp {
1842protected:
1843 string prefix;
1844 RGWMPObj marker;
1845 RGWMultipartUploadEntry next_marker;
1846 int max_uploads;
1847 string delimiter;
1848 vector<RGWMultipartUploadEntry> uploads;
1849 map<string, bool> common_prefixes;
1850 bool is_truncated;
1851 int default_max;
9f95a23c 1852 bool encode_url {false};
7c673cae
FG
1853
1854public:
1855 RGWListBucketMultiparts() {
1856 max_uploads = 0;
1857 is_truncated = false;
1858 default_max = 0;
1859 }
1860
9f95a23c 1861 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
7c673cae
FG
1862 RGWOp::init(store, s, h);
1863 max_uploads = default_max;
1864 }
1865
1866 int verify_permission() override;
1867 void pre_exec() override;
1868 void execute() override;
1869
1870 virtual int get_params() = 0;
1871 void send_response() override = 0;
11fdf7f2 1872 const char* name() const override { return "list_bucket_multiparts"; }
7c673cae
FG
1873 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; }
1874 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1875};
1876
1877
1878class RGWGetCrossDomainPolicy : public RGWOp {
1879public:
1880 RGWGetCrossDomainPolicy() = default;
1881 ~RGWGetCrossDomainPolicy() override = default;
1882
1883 int verify_permission() override {
1884 return 0;
1885 }
1886
1887 void execute() override {
1888 op_ret = 0;
1889 }
1890
11fdf7f2 1891 const char* name() const override { return "get_crossdomain_policy"; }
7c673cae
FG
1892
1893 RGWOpType get_type() override {
1894 return RGW_OP_GET_CROSS_DOMAIN_POLICY;
1895 }
1896
1897 uint32_t op_mask() override {
1898 return RGW_OP_TYPE_READ;
1899 }
1900};
1901
1902
1903class RGWGetHealthCheck : public RGWOp {
1904public:
1905 RGWGetHealthCheck() = default;
1906 ~RGWGetHealthCheck() override = default;
1907
1908 int verify_permission() override {
1909 return 0;
1910 }
1911
1912 void execute() override;
1913
11fdf7f2 1914 const char* name() const override { return "get_health_check"; }
7c673cae
FG
1915
1916 RGWOpType get_type() override {
1917 return RGW_OP_GET_HEALTH_CHECK;
1918 }
1919
1920 uint32_t op_mask() override {
1921 return RGW_OP_TYPE_READ;
1922 }
1923};
1924
1925
1926class RGWDeleteMultiObj : public RGWOp {
1927protected:
11fdf7f2 1928 bufferlist data;
7c673cae
FG
1929 rgw_bucket bucket;
1930 bool quiet;
1931 bool status_dumped;
31f18b77 1932 bool acl_allowed = false;
7c673cae
FG
1933
1934public:
1935 RGWDeleteMultiObj() {
7c673cae
FG
1936 quiet = false;
1937 status_dumped = false;
1938 }
1939 int verify_permission() override;
1940 void pre_exec() override;
1941 void execute() override;
1942
1943 virtual int get_params() = 0;
1944 virtual void send_status() = 0;
1945 virtual void begin_response() = 0;
1946 virtual void send_partial_response(rgw_obj_key& key, bool delete_marker,
1947 const string& marker_version_id, int ret) = 0;
1948 virtual void end_response() = 0;
11fdf7f2 1949 const char* name() const override { return "multi_object_delete"; }
7c673cae
FG
1950 RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; }
1951 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1952};
1953
1954class RGWInfo: public RGWOp {
1955public:
1956 RGWInfo() = default;
1957 ~RGWInfo() override = default;
1958
1959 int verify_permission() override { return 0; }
11fdf7f2 1960 const char* name() const override { return "get info"; }
7c673cae
FG
1961 RGWOpType get_type() override { return RGW_OP_GET_INFO; }
1962 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1963};
1964
9f95a23c
TL
1965extern int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s);
1966extern int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *s,
31f18b77 1967 bool prefetch_data);
9f95a23c 1968extern void rgw_build_iam_environment(rgw::sal::RGWRadosStore* store,
11fdf7f2
TL
1969 struct req_state* s);
1970extern vector<rgw::IAM::Policy> get_iam_user_policy_from_attr(CephContext* cct,
9f95a23c 1971 rgw::sal::RGWRadosStore* store,
11fdf7f2
TL
1972 map<string, bufferlist>& attrs,
1973 const string& tenant);
7c673cae
FG
1974
1975static inline int get_system_versioning_params(req_state *s,
1976 uint64_t *olh_epoch,
1977 string *version_id)
1978{
1979 if (!s->system_request) {
1980 return 0;
1981 }
1982
1983 if (olh_epoch) {
1984 string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
1985 if (!epoch_str.empty()) {
1986 string err;
1987 *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
1988 if (!err.empty()) {
1989 lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
1990 << dendl;
1991 return -EINVAL;
1992 }
1993 }
1994 }
1995
1996 if (version_id) {
1997 *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
1998 }
1999
2000 return 0;
2001} /* get_system_versioning_params */
2002
2003static inline void format_xattr(std::string &xattr)
2004{
2005 /* If the extended attribute is not valid UTF-8, we encode it using
2006 * quoted-printable encoding.
2007 */
2008 if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
2009 (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
2010 static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
2011 static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
2012 static const char MIME_SUFFIX_STR[] = "?=";
2013 static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
2014 int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
2015 char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
2016 strcpy(mime, MIME_PREFIX_STR);
2017 mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
2018 strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
2019 xattr.assign(mime);
2020 delete [] mime;
2021 }
2022} /* format_xattr */
2023
2024/**
2025 * Get the HTTP request metadata out of the req_state as a
2026 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
2027 * s: The request state
2028 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
3efd9988
FG
2029 * On success returns 0.
2030 * On failure returns a negative error code.
7c673cae
FG
2031 *
2032 */
3efd9988
FG
2033static inline int rgw_get_request_metadata(CephContext* const cct,
2034 struct req_info& info,
2035 std::map<std::string, ceph::bufferlist>& attrs,
2036 const bool allow_empty_attrs = true)
7c673cae
FG
2037{
2038 static const std::set<std::string> blacklisted_headers = {
2039 "x-amz-server-side-encryption-customer-algorithm",
2040 "x-amz-server-side-encryption-customer-key",
11fdf7f2
TL
2041 "x-amz-server-side-encryption-customer-key-md5",
2042 "x-amz-storage-class"
7c673cae 2043 };
3efd9988
FG
2044
2045 size_t valid_meta_count = 0;
2046 for (auto& kv : info.x_meta_map) {
2047 const std::string& name = kv.first;
2048 std::string& xattr = kv.second;
2049
7c673cae
FG
2050 if (blacklisted_headers.count(name) == 1) {
2051 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
2052 continue;
3efd9988 2053 } else if (allow_empty_attrs || !xattr.empty()) {
7c673cae
FG
2054 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
2055 format_xattr(xattr);
3efd9988
FG
2056
2057 std::string attr_name(RGW_ATTR_PREFIX);
7c673cae 2058 attr_name.append(name);
3efd9988
FG
2059
2060 /* Check roughly whether we aren't going behind the limit on attribute
2061 * name. Passing here doesn't guarantee that an OSD will accept that
2062 * as ObjectStore::get_max_attr_name_length() can set the limit even
2063 * lower than the "osd_max_attr_name_len" configurable. */
eafe8130 2064 const auto max_attr_name_len = cct->_conf->rgw_max_attr_name_len;
3efd9988
FG
2065 if (max_attr_name_len && attr_name.length() > max_attr_name_len) {
2066 return -ENAMETOOLONG;
2067 }
2068
2069 /* Similar remarks apply to the check for value size. We're veryfing
2070 * it early at the RGW's side as it's being claimed in /info. */
eafe8130 2071 const auto max_attr_size = cct->_conf->rgw_max_attr_size;
3efd9988
FG
2072 if (max_attr_size && xattr.length() > max_attr_size) {
2073 return -EFBIG;
2074 }
2075
2076 /* Swift allows administrators to limit the number of metadats items
2077 * send _in a single request_. */
eafe8130
TL
2078 const auto max_attrs_num_in_req = cct->_conf->rgw_max_attrs_num_in_req;
2079 if (max_attrs_num_in_req &&
2080 ++valid_meta_count > max_attrs_num_in_req) {
3efd9988
FG
2081 return -E2BIG;
2082 }
2083
2084 auto rval = attrs.emplace(std::move(attr_name), ceph::bufferlist());
2085 /* At the moment the value of the freshly created attribute key-value
2086 * pair is an empty bufferlist. */
2087
2088 ceph::bufferlist& bl = rval.first->second;
7c673cae
FG
2089 bl.append(xattr.c_str(), xattr.size() + 1);
2090 }
2091 }
3efd9988
FG
2092
2093 return 0;
7c673cae
FG
2094} /* rgw_get_request_metadata */
2095
2096static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
2097 map<string, bufferlist>& attrs)
2098{
2099 if (delete_at == boost::none) {
2100 return;
2101 }
2102
2103 bufferlist delatbl;
11fdf7f2 2104 encode(*delete_at, delatbl);
7c673cae
FG
2105 attrs[RGW_ATTR_DELETE_AT] = delatbl;
2106} /* encode_delete_at_attr */
2107
224ce89b
WB
2108static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
2109{
2110 if (obj_tags == nullptr){
2111 // we assume the user submitted a tag format which we couldn't parse since
2112 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2113 // attr was populated
2114 return;
2115 }
2116
2117 bufferlist tagsbl;
2118 obj_tags->encode(tagsbl);
2119 attrs[RGW_ATTR_TAGS] = tagsbl;
2120}
2121
7c673cae
FG
2122static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
2123 map<string, bufferlist>& attrs)
2124{
2125 string dm = dlo_manifest;
2126
2127 if (dm.find('/') == string::npos) {
2128 return -EINVAL;
2129 }
2130
2131 bufferlist manifest_bl;
2132 manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
2133 attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
2134
2135 return 0;
2136} /* encode_dlo_manifest_attr */
2137
2138static inline void complete_etag(MD5& hash, string *etag)
2139{
2140 char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
2141 char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
2142
11fdf7f2 2143 hash.Final((unsigned char *)etag_buf);
7c673cae
FG
2144 buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
2145 etag_buf_str);
2146
2147 *etag = etag_buf_str;
2148} /* complete_etag */
2149
2150class RGWSetAttrs : public RGWOp {
2151protected:
2152 map<string, buffer::list> attrs;
2153
2154public:
2155 RGWSetAttrs() {}
2156 ~RGWSetAttrs() override {}
2157
2158 void emplace_attr(std::string&& key, buffer::list&& bl) {
2159 attrs.emplace(std::move(key), std::move(bl));
2160 }
2161
2162 int verify_permission() override;
2163 void pre_exec() override;
2164 void execute() override;
2165
2166 virtual int get_params() = 0;
2167 void send_response() override = 0;
11fdf7f2 2168 const char* name() const override { return "set_attrs"; }
7c673cae
FG
2169 RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
2170 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2171};
2172
2173class RGWGetObjLayout : public RGWOp {
2174protected:
2175 RGWObjManifest *manifest{nullptr};
2176 rgw_raw_obj head_obj;
2177
2178public:
2179 RGWGetObjLayout() {
2180 }
2181
2182 int check_caps(RGWUserCaps& caps) {
2183 return caps.check_cap("admin", RGW_CAP_READ);
2184 }
11fdf7f2 2185 int verify_permission() override {
9f95a23c 2186 return check_caps(s->user->get_info().caps);
7c673cae 2187 }
11fdf7f2
TL
2188 void pre_exec() override;
2189 void execute() override;
7c673cae 2190
11fdf7f2
TL
2191 const char* name() const override { return "get_obj_layout"; }
2192 virtual RGWOpType get_type() override { return RGW_OP_GET_OBJ_LAYOUT; }
2193 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
7c673cae
FG
2194};
2195
31f18b77 2196class RGWPutBucketPolicy : public RGWOp {
11fdf7f2 2197 bufferlist data;
31f18b77
FG
2198public:
2199 RGWPutBucketPolicy() = default;
2200 ~RGWPutBucketPolicy() {
31f18b77
FG
2201 }
2202 void send_response() override;
2203 int verify_permission() override;
2204 uint32_t op_mask() override {
2205 return RGW_OP_TYPE_WRITE;
2206 }
2207 void execute() override;
2208 int get_params();
11fdf7f2 2209 const char* name() const override { return "put_bucket_policy"; }
31f18b77
FG
2210 RGWOpType get_type() override {
2211 return RGW_OP_PUT_BUCKET_POLICY;
2212 }
2213};
7c673cae 2214
31f18b77
FG
2215class RGWGetBucketPolicy : public RGWOp {
2216 buffer::list policy;
2217public:
2218 RGWGetBucketPolicy() = default;
2219 void send_response() override;
2220 int verify_permission() override;
2221 uint32_t op_mask() override {
2222 return RGW_OP_TYPE_READ;
2223 }
2224 void execute() override;
11fdf7f2 2225 const char* name() const override { return "get_bucket_policy"; }
31f18b77
FG
2226 RGWOpType get_type() override {
2227 return RGW_OP_GET_BUCKET_POLICY;
2228 }
2229};
2230
2231class RGWDeleteBucketPolicy : public RGWOp {
2232public:
2233 RGWDeleteBucketPolicy() = default;
2234 void send_response() override;
2235 int verify_permission() override;
2236 uint32_t op_mask() override {
2237 return RGW_OP_TYPE_WRITE;
2238 }
2239 void execute() override;
2240 int get_params();
11fdf7f2 2241 const char* name() const override { return "delete_bucket_policy"; }
31f18b77
FG
2242 RGWOpType get_type() override {
2243 return RGW_OP_DELETE_BUCKET_POLICY;
2244 }
2245};
2246
eafe8130
TL
2247class RGWPutBucketObjectLock : public RGWOp {
2248protected:
2249 bufferlist data;
2250 bufferlist obj_lock_bl;
2251 RGWObjectLock obj_lock;
2252public:
2253 RGWPutBucketObjectLock() = default;
2254 ~RGWPutBucketObjectLock() {}
2255 int verify_permission() override;
2256 void pre_exec() override;
2257 void execute() override;
2258 virtual void send_response() = 0;
2259 virtual int get_params() = 0;
2260 const char* name() const override { return "put_bucket_object_lock"; }
2261 RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_OBJ_LOCK; }
2262 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2263};
2264
2265class RGWGetBucketObjectLock : public RGWOp {
2266public:
2267 int verify_permission() override;
2268 void pre_exec() override;
2269 void execute() override;
2270 virtual void send_response() = 0;
2271 const char* name() const override {return "get_bucket_object_lock"; }
2272 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_OBJ_LOCK; }
2273 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2274};
2275
2276class RGWPutObjRetention : public RGWOp {
2277protected:
2278 bufferlist data;
2279 RGWObjectRetention obj_retention;
2280 bool bypass_perm;
2281 bool bypass_governance_mode;
2282public:
2283 RGWPutObjRetention():bypass_perm(true), bypass_governance_mode(false) {}
2284 int verify_permission() override;
2285 void pre_exec() override;
2286 void execute() override;
2287 virtual void send_response() override = 0;
2288 virtual int get_params() = 0;
2289 const char* name() const override { return "put_obj_retention"; }
2290 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2291 RGWOpType get_type() override { return RGW_OP_PUT_OBJ_RETENTION; }
2292};
2293
2294class RGWGetObjRetention : public RGWOp {
2295protected:
2296 RGWObjectRetention obj_retention;
2297public:
2298 int verify_permission() override;
2299 void pre_exec() override;
2300 void execute() override;
2301 virtual void send_response() = 0;
2302 const char* name() const override {return "get_obj_retention"; }
2303 RGWOpType get_type() override { return RGW_OP_GET_OBJ_RETENTION; }
2304 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2305};
2306
2307class RGWPutObjLegalHold : public RGWOp {
2308protected:
2309 bufferlist data;
2310 RGWObjectLegalHold obj_legal_hold;
2311public:
2312 int verify_permission() override;
2313 void pre_exec() override;
2314 void execute() override;
2315 virtual void send_response() override = 0;
2316 virtual int get_params() = 0;
2317 const char* name() const override { return "put_obj_legal_hold"; }
2318 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2319 RGWOpType get_type() override { return RGW_OP_PUT_OBJ_LEGAL_HOLD; }
2320};
2321
2322class RGWGetObjLegalHold : public RGWOp {
2323protected:
2324 RGWObjectLegalHold obj_legal_hold;
2325public:
2326 int verify_permission() override;
2327 void pre_exec() override;
2328 void execute() override;
2329 virtual void send_response() = 0;
2330 const char* name() const override {return "get_obj_legal_hold"; }
2331 RGWOpType get_type() override { return RGW_OP_GET_OBJ_LEGAL_HOLD; }
2332 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2333};
2334
31f18b77
FG
2335
2336class RGWConfigBucketMetaSearch : public RGWOp {
2337protected:
2338 std::map<std::string, uint32_t> mdsearch_config;
2339public:
2340 RGWConfigBucketMetaSearch() {}
2341
11fdf7f2
TL
2342 int verify_permission() override;
2343 void pre_exec() override;
2344 void execute() override;
31f18b77
FG
2345
2346 virtual int get_params() = 0;
11fdf7f2
TL
2347 const char* name() const override { return "config_bucket_meta_search"; }
2348 virtual RGWOpType get_type() override { return RGW_OP_CONFIG_BUCKET_META_SEARCH; }
2349 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
31f18b77
FG
2350};
2351
2352class RGWGetBucketMetaSearch : public RGWOp {
2353public:
2354 RGWGetBucketMetaSearch() {}
2355
11fdf7f2
TL
2356 int verify_permission() override;
2357 void pre_exec() override;
2358 void execute() override {}
31f18b77 2359
11fdf7f2
TL
2360 const char* name() const override { return "get_bucket_meta_search"; }
2361 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_META_SEARCH; }
2362 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
31f18b77
FG
2363};
2364
2365class RGWDelBucketMetaSearch : public RGWOp {
2366public:
2367 RGWDelBucketMetaSearch() {}
2368
11fdf7f2
TL
2369 int verify_permission() override;
2370 void pre_exec() override;
2371 void execute() override;
31f18b77 2372
11fdf7f2 2373 const char* name() const override { return "delete_bucket_meta_search"; }
31f18b77 2374 virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
11fdf7f2 2375 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
31f18b77 2376};
7c673cae 2377
28e407b8
AA
2378class RGWGetClusterStat : public RGWOp {
2379protected:
2380 struct rados_cluster_stat_t stats_op;
2381public:
2382 RGWGetClusterStat() {}
2383
9f95a23c 2384 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
28e407b8
AA
2385 RGWOp::init(store, s, h);
2386 }
2387 int verify_permission() override {return 0;}
11fdf7f2 2388 virtual void send_response() override = 0;
28e407b8
AA
2389 virtual int get_params() = 0;
2390 void execute() override;
11fdf7f2
TL
2391 const char* name() const override { return "get_cluster_stat"; }
2392 dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
28e407b8
AA
2393};
2394
9f95a23c
TL
2395class RGWGetBucketPolicyStatus : public RGWOp {
2396protected:
2397 bool isPublic {false};
2398public:
2399 int verify_permission() override;
2400 const char* name() const override { return "get_bucket_policy_status"; }
2401 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_POLICY_STATUS; }
2402 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2403 void execute() override;
2404 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2405};
2406
2407class RGWPutBucketPublicAccessBlock : public RGWOp {
2408protected:
2409 bufferlist data;
2410 PublicAccessBlockConfiguration access_conf;
2411public:
2412 int verify_permission() override;
2413 const char* name() const override { return "put_bucket_public_access_block";}
2414 virtual RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK; }
2415 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2416 int get_params();
2417 void execute() override;
2418 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2419};
2420
2421class RGWGetBucketPublicAccessBlock : public RGWOp {
2422protected:
2423 PublicAccessBlockConfiguration access_conf;
2424public:
2425 int verify_permission() override;
2426 const char* name() const override { return "get_bucket_public_access_block";}
2427 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_PUBLIC_ACCESS_BLOCK; }
2428 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2429 int get_params();
2430 void execute() override;
2431 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2432};
2433
2434class RGWDeleteBucketPublicAccessBlock : public RGWOp {
2435protected:
2436 PublicAccessBlockConfiguration access_conf;
2437public:
2438 int verify_permission() override;
2439 const char* name() const override { return "delete_bucket_public_access_block";}
2440 virtual RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_PUBLIC_ACCESS_BLOCK; }
2441 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2442 int get_params();
2443 void execute() override;
2444 void send_response() override;
2445 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2446};
2447
f64942e4
AA
2448static inline int parse_value_and_bound(
2449 const string &input,
2450 int &output,
2451 const long lower_bound,
2452 const long upper_bound,
2453 const long default_val)
2454{
2455 if (!input.empty()) {
2456 char *endptr;
2457 output = strtol(input.c_str(), &endptr, 10);
2458 if (endptr) {
2459 if (endptr == input.c_str()) return -EINVAL;
2460 while (*endptr && isspace(*endptr)) // ignore white space
2461 endptr++;
2462 if (*endptr) {
2463 return -EINVAL;
2464 }
2465 }
2466 if(output > upper_bound) {
2467 output = upper_bound;
2468 }
2469 if(output < lower_bound) {
2470 output = lower_bound;
2471 }
2472 } else {
2473 output = default_val;
2474 }
2475
2476 return 0;
2477}
28e407b8 2478
9f95a23c
TL
2479int forward_request_to_master(struct req_state *s, obj_version *objv, rgw::sal::RGWRadosStore *store,
2480 bufferlist& in_data, JSONParser *jp, req_info *forward_info = nullptr);
28e407b8 2481
7c673cae 2482#endif /* CEPH_RGW_OP_H */