]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_op.h
bump version to 15.2.8-pve2
[ceph.git] / ceph / src / rgw / rgw_op.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
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 */
12
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>
27 #include <boost/function.hpp>
28
29 #include "common/armor.h"
30 #include "common/mime.h"
31 #include "common/utf8.h"
32 #include "common/ceph_json.h"
33 #include "common/ceph_time.h"
34
35 #include "rgw_common.h"
36 #include "rgw_dmclock.h"
37 #include "rgw_sal.h"
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"
43 #include "rgw_putobj.h"
44 #include "rgw_multi.h"
45 #include "rgw_sal.h"
46
47 #include "rgw_lc.h"
48 #include "rgw_torrent.h"
49 #include "rgw_tag.h"
50 #include "rgw_object_lock.h"
51 #include "cls/lock/cls_lock_client.h"
52 #include "cls/rgw/cls_rgw_client.h"
53 #include "rgw_public_access.h"
54
55 #include "services/svc_sys_obj.h"
56 #include "services/svc_tier_rados.h"
57
58 #include "include/ceph_assert.h"
59
60 using ceph::crypto::SHA1;
61
62 struct req_state;
63 class RGWOp;
64 class RGWRados;
65
66
67 namespace rgw {
68 namespace auth {
69 namespace registry {
70
71 class StrategyRegistry;
72
73 }
74 }
75 }
76
77 int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
78 rgw::sal::RGWRadosStore *store,
79 RGWBucketInfo& bucket_info,
80 map<string, bufferlist>& bucket_attrs,
81 RGWAccessControlPolicy *policy);
82
83 class RGWHandler {
84 protected:
85 rgw::sal::RGWRadosStore* store{nullptr};
86 struct req_state *s{nullptr};
87
88 int do_init_permissions();
89 int do_read_permissions(RGWOp* op, bool only_bucket);
90
91 public:
92 RGWHandler() {}
93 virtual ~RGWHandler();
94
95 virtual int init(rgw::sal::RGWRadosStore* store,
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;
109 virtual int authorize(const DoutPrefixProvider* dpp) = 0;
110 virtual int postauth_init() = 0;
111 virtual int error_handler(int err_no, std::string* error_content);
112 virtual void dump(const string& code, const string& message) const {}
113
114 virtual bool supports_quota() {
115 return true;
116 }
117 };
118
119
120
121 void rgw_bucket_object_pre_exec(struct req_state *s);
122
123 namespace dmc = rgw::dmclock;
124
125 /**
126 * Provide the base class for all ops.
127 */
128 class RGWOp : public DoutPrefixProvider {
129 protected:
130 struct req_state *s;
131 RGWHandler *dialect_handler;
132 rgw::sal::RGWRadosStore *store;
133 RGWCORSConfiguration bucket_cors;
134 bool cors_exist;
135 RGWQuotaInfo bucket_quota;
136 RGWQuotaInfo user_quota;
137 int op_ret;
138 int do_aws4_auth_completion();
139
140 virtual int init_quota();
141
142 public:
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() {
156 if (dialect_handler->supports_quota()) {
157 op_ret = init_quota();
158 if (op_ret < 0)
159 return op_ret;
160 }
161
162 return 0;
163 }
164
165 virtual void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *dialect_handler) {
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. */
187 return dialect_handler->authorize(this);
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 }
197 virtual const char* name() const = 0;
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);
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
213 class RGWDefaultResponseOp : public RGWOp {
214 public:
215 void send_response() override;
216 };
217
218 class RGWGetObj_Filter : public RGWGetDataCB
219 {
220 protected:
221 RGWGetObj_Filter *next{nullptr};
222 public:
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 }
256 };
257
258 class RGWGetObj : public RGWOp {
259 protected:
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;
280 bool ignore_invalid_range;
281 bool range_parsed;
282 bool skip_manifest;
283 bool skip_decrypt{false};
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 */
289 string version_id;
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;
298 uint64_t action = 0;
299
300 bool get_retention;
301 bool get_legal_hold;
302
303 int init_common();
304 public:
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;
330 get_retention = false;
331 get_legal_hold = false;
332 }
333
334 bool prefetch_data() override;
335
336 void set_get_data(bool get_data) {
337 this->get_data = get_data;
338 }
339
340 int verify_permission() override;
341 void pre_exec() override;
342 void execute() override;
343 int parse_range();
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,
350 const off_t end_ofs,
351 bool swift_slo);
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
361 const char* name() const override { return "get_obj"; }
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 */
368 virtual int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter, RGWGetObj_Filter* cb, bufferlist* manifest_bl) {
369 *filter = nullptr;
370 return 0;
371 }
372 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
373 };
374
375 class RGWGetObj_CB : public RGWGetObj_Filter
376 {
377 RGWGetObj *op;
378 public:
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
387 class RGWGetObjTags : public RGWOp {
388 protected:
389 bufferlist tags_bl;
390 bool has_tags{false};
391 public:
392 int verify_permission() override;
393 void execute() override;
394 void pre_exec() override;
395
396 virtual void send_response_data(bufferlist& bl) = 0;
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; }
400
401 };
402
403 class RGWPutObjTags : public RGWOp {
404 protected:
405 bufferlist tags_bl;
406 public:
407 int verify_permission() override;
408 void execute() override;
409
410 virtual void send_response() override = 0;
411 virtual int get_params() = 0;
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; }
415
416 };
417
418 class RGWDeleteObjTags: public RGWOp {
419 public:
420 void pre_exec() override;
421 int verify_permission() override;
422 void execute() override;
423
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;}
427 };
428
429 class RGWGetBucketTags : public RGWOp {
430 protected:
431 bufferlist tags_bl;
432 bool has_tags{false};
433 public:
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
444 class RGWPutBucketTags : public RGWOp {
445 protected:
446 bufferlist tags_bl;
447 bufferlist in_data;
448 public:
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
459 class RGWDeleteBucketTags : public RGWOp {
460 public:
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
470 struct rgw_sync_policy_group;
471
472 class RGWGetBucketReplication : public RGWOp {
473 public:
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
484 class RGWPutBucketReplication : public RGWOp {
485 protected:
486 bufferlist in_data;
487 std::vector<rgw_sync_policy_group> sync_policy_groups;
488 public:
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
499 class RGWDeleteBucketReplication : public RGWOp {
500 protected:
501 virtual void update_sync_policy(rgw_sync_policy_info *policy) = 0;
502 public:
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
512 class RGWBulkDelete : public RGWOp {
513 public:
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:
526 const DoutPrefixProvider * dpp;
527 unsigned int num_deleted;
528 unsigned int num_unfound;
529 std::list<fail_desc_t> failures;
530
531 rgw::sal::RGWRadosStore * const store;
532 req_state * const s;
533
534 public:
535 Deleter(const DoutPrefixProvider* dpp, rgw::sal::RGWRadosStore * const str, req_state * const s)
536 : dpp(dpp),
537 num_deleted(0),
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
565 protected:
566 std::unique_ptr<Deleter> deleter;
567
568 public:
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
581 const char* name() const override { return "bulk_delete"; }
582 RGWOpType get_type() override { return RGW_OP_BULK_DELETE; }
583 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
584 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
585 };
586
587 inline ostream& operator<<(ostream& out, const RGWBulkDelete::acct_path_t &o) {
588 return out << o.bucket_name << "/" << o.obj_key;
589 }
590
591
592 class RGWBulkUploadOp : public RGWOp {
593 boost::optional<RGWSysObjectCtx> dir_ctx;
594
595 protected:
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;
620 virtual void send_response() override = 0;
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,
629 const rgw_obj& obj,
630 std::map<std::string, ceph::bufferlist>& battrs,
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
639 public:
640 RGWBulkUploadOp()
641 : num_created(0) {
642 }
643
644 void init(rgw::sal::RGWRadosStore* const store,
645 struct req_state* const s,
646 RGWHandler* const h) override;
647
648 int verify_permission() override;
649 void pre_exec() override;
650 void execute() override;
651
652 const char* name() const override { return "bulk_upload"; }
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 }
661 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
662 }; /* RGWBulkUploadOp */
663
664
665 class RGWBulkUploadOp::StreamGetter {
666 public:
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
675 class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter {
676 StreamGetter& decoratee;
677
678 protected:
679 StreamGetter& get_decoratee() {
680 return decoratee;
681 }
682
683 public:
684 explicit DecoratedStreamGetter(StreamGetter& decoratee)
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
699 class RGWBulkUploadOp::AlignedStreamGetter
700 : public RGWBulkUploadOp::DecoratedStreamGetter {
701 size_t position;
702 size_t length;
703 size_t alignment;
704
705 public:
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
722 struct 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
729 #define RGW_LIST_BUCKETS_LIMIT_MAX 10000
730
731 class RGWListBuckets : public RGWOp {
732 protected:
733 bool sent_data;
734 std::string marker;
735 std::string end_marker;
736 int64_t limit;
737 uint64_t limit_max;
738 std::map<std::string, ceph::bufferlist> attrs;
739 bool is_truncated;
740
741 RGWUsageStats global_stats;
742 std::map<std::string, RGWUsageStats> policies_stats;
743
744 virtual uint64_t get_default_max() const {
745 return 1000;
746 }
747
748 public:
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) {
754 }
755
756 int verify_permission() override;
757 void execute() override;
758
759 virtual int get_params() = 0;
760 virtual void handle_listing_chunk(rgw::sal::RGWBucketList&& buckets) {
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
764 * instances of RGWBucketList are buffered and finally reversed. */
765 return send_response_data(buckets);
766 }
767 virtual void send_response_begin(bool has_buckets) = 0;
768 virtual void send_response_data(rgw::sal::RGWBucketList& buckets) = 0;
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
775 const char* name() const override { return "list_buckets"; }
776 RGWOpType get_type() override { return RGW_OP_LIST_BUCKETS; }
777 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
778 }; // class RGWListBuckets
779
780 class RGWGetUsage : public RGWOp {
781 protected:
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;
790 map<string, cls_user_bucket_entry> buckets_usage;
791 cls_user_header header;
792 RGWStorageStats stats;
793 public:
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
805 const char* name() const override { return "get_self_usage"; }
806 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
807 };
808
809 class RGWStatAccount : public RGWOp {
810 protected:
811 RGWUsageStats global_stats;
812 std::map<std::string, RGWUsageStats> policies_stats;
813
814 public:
815 RGWStatAccount() = default;
816
817 int verify_permission() override;
818 void execute() override;
819
820 void send_response() override = 0;
821 const char* name() const override { return "stat_account"; }
822 RGWOpType get_type() override { return RGW_OP_STAT_ACCOUNT; }
823 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
824 };
825
826 class RGWListBucket : public RGWOp {
827 protected:
828 rgw::sal::RGWBucket* bucket;
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;
843 bool allow_unordered;
844
845 int shard_id;
846
847 int parse_max_keys();
848
849 public:
850 RGWListBucket() : bucket(nullptr), list_versions(false), max(0),
851 default_max(0), is_truncated(false),
852 allow_unordered(false), shard_id(-1) {}
853 ~RGWListBucket() { delete bucket; }
854 int verify_permission() override;
855 void pre_exec() override;
856 void execute() override;
857
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 }
862 virtual int get_params() = 0;
863 void send_response() override = 0;
864 const char* name() const override { return "list_bucket"; }
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
870 class RGWGetBucketLogging : public RGWOp {
871 public:
872 RGWGetBucketLogging() {}
873 int verify_permission() override;
874 void execute() override { }
875
876 void send_response() override = 0;
877 const char* name() const override { return "get_bucket_logging"; }
878 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOGGING; }
879 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
880 };
881
882 class RGWGetBucketLocation : public RGWOp {
883 public:
884 RGWGetBucketLocation() {}
885 ~RGWGetBucketLocation() override {}
886 int verify_permission() override;
887 void execute() override { }
888
889 void send_response() override = 0;
890 const char* name() const override { return "get_bucket_location"; }
891 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_LOCATION; }
892 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
893 };
894
895 class RGWGetBucketVersioning : public RGWOp {
896 protected:
897 bool versioned{false};
898 bool versioning_enabled{false};
899 bool mfa_enabled{false};
900 public:
901 RGWGetBucketVersioning() = default;
902
903 int verify_permission() override;
904 void pre_exec() override;
905 void execute() override;
906
907 void send_response() override = 0;
908 const char* name() const override { return "get_bucket_versioning"; }
909 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_VERSIONING; }
910 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
911 };
912
913 enum BucketVersionStatus {
914 VersioningStatusInvalid = -1,
915 VersioningNotChanged = 0,
916 VersioningEnabled = 1,
917 VersioningSuspended =2,
918 };
919
920 class RGWSetBucketVersioning : public RGWOp {
921 protected:
922 int versioning_status;
923 bool mfa_set_status{false};
924 bool mfa_status{false};
925 bufferlist in_data;
926 public:
927 RGWSetBucketVersioning() : versioning_status(VersioningNotChanged) {}
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;
936 const char* name() const override { return "set_bucket_versioning"; }
937 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_VERSIONING; }
938 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
939 };
940
941 class RGWGetBucketWebsite : public RGWOp {
942 public:
943 RGWGetBucketWebsite() {}
944
945 int verify_permission() override;
946 void pre_exec() override;
947 void execute() override;
948
949 void send_response() override = 0;
950 const char* name() const override { return "get_bucket_website"; }
951 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_WEBSITE; }
952 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
953 };
954
955 class RGWSetBucketWebsite : public RGWOp {
956 protected:
957 bufferlist in_data;
958 RGWBucketWebsiteConf website_conf;
959 public:
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;
969 const char* name() const override { return "set_bucket_website"; }
970 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
971 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
972 };
973
974 class RGWDeleteBucketWebsite : public RGWOp {
975 public:
976 RGWDeleteBucketWebsite() {}
977
978 int verify_permission() override;
979 void pre_exec() override;
980 void execute() override;
981
982 void send_response() override = 0;
983 const char* name() const override { return "delete_bucket_website"; }
984 RGWOpType get_type() override { return RGW_OP_SET_BUCKET_WEBSITE; }
985 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
986 };
987
988 class RGWStatBucket : public RGWOp {
989 protected:
990 rgw::sal::RGWBucket* bucket;
991
992 public:
993 RGWStatBucket() : bucket(nullptr) {}
994 ~RGWStatBucket() override { delete bucket; }
995
996 int verify_permission() override;
997 void pre_exec() override;
998 void execute() override;
999
1000 void send_response() override = 0;
1001 const char* name() const override { return "stat_bucket"; }
1002 RGWOpType get_type() override { return RGW_OP_STAT_BUCKET; }
1003 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1004 };
1005
1006 class RGWCreateBucket : public RGWOp {
1007 protected:
1008 RGWAccessControlPolicy policy;
1009 string location_constraint;
1010 rgw_placement_rule placement_rule;
1011 RGWBucketInfo info;
1012 obj_version ep_objv;
1013 bool has_cors;
1014 bool relaxed_region_enforcement;
1015 bool obj_lock_enabled;
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
1025 public:
1026 RGWCreateBucket() : has_cors(false), relaxed_region_enforcement(false), obj_lock_enabled(false) {}
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;
1035 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
1036 RGWOp::init(store, s, h);
1037 policy.set_ctx(s->cct);
1038 relaxed_region_enforcement =
1039 s->cct->_conf.get_val<bool>("rgw_relaxed_region_enforcement");
1040 }
1041 virtual int get_params() { return 0; }
1042 void send_response() override = 0;
1043 const char* name() const override { return "create_bucket"; }
1044 RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; }
1045 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1046 };
1047
1048 class RGWDeleteBucket : public RGWOp {
1049 protected:
1050 RGWObjVersionTracker objv_tracker;
1051
1052 public:
1053 RGWDeleteBucket() {}
1054
1055 int verify_permission() override;
1056 void pre_exec() override;
1057 void execute() override;
1058
1059 void send_response() override = 0;
1060 const char* name() const override { return "delete_bucket"; }
1061 RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET; }
1062 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1063 };
1064
1065 struct 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);
1074 encode(path, bl);
1075 encode(etag, bl);
1076 encode(size_bytes, bl);
1077 ENCODE_FINISH(bl);
1078 }
1079
1080 void decode(bufferlist::const_iterator& bl) {
1081 DECODE_START(1, bl);
1082 decode(path, bl);
1083 decode(etag, bl);
1084 decode(size_bytes, bl);
1085 DECODE_FINISH(bl);
1086 }
1087
1088 void decode_json(JSONObj *obj);
1089 };
1090 WRITE_CLASS_ENCODER(rgw_slo_entry)
1091
1092 struct RGWSLOInfo {
1093 vector<rgw_slo_entry> entries;
1094 uint64_t total_size;
1095
1096 /* in memory only */
1097 bufferlist raw_data;
1098
1099 RGWSLOInfo() : total_size(0) {}
1100 ~RGWSLOInfo() {}
1101
1102 void encode(bufferlist& bl) const {
1103 ENCODE_START(1, 1, bl);
1104 encode(entries, bl);
1105 encode(total_size, bl);
1106 ENCODE_FINISH(bl);
1107 }
1108
1109 void decode(bufferlist::const_iterator& bl) {
1110 DECODE_START(1, bl);
1111 decode(entries, bl);
1112 decode(total_size, bl);
1113 DECODE_FINISH(bl);
1114 }
1115 };
1116 WRITE_CLASS_ENCODER(RGWSLOInfo)
1117
1118 class RGWPutObj : public RGWOp {
1119 protected:
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;
1126 std::string copy_source;
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;
1138 std::unique_ptr <RGWObjTags> obj_tags;
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
1149 std::string multipart_upload_id;
1150 std::string multipart_part_str;
1151 int multipart_part_num = 0;
1152
1153 boost::optional<ceph::real_time> delete_at;
1154 //append obj
1155 bool append;
1156 uint64_t position;
1157 uint64_t cur_accounted_size;
1158
1159 //object lock
1160 RGWObjectRetention *obj_retention;
1161 RGWObjectLegalHold *obj_legal_hold;
1162
1163 public:
1164 RGWPutObj() : ofs(0),
1165 supplied_md5_b64(NULL),
1166 supplied_etag(NULL),
1167 if_match(NULL),
1168 if_nomatch(NULL),
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),
1175 olh_epoch(0),
1176 append(false),
1177 position(0),
1178 cur_accounted_size(0),
1179 obj_retention(nullptr),
1180 obj_legal_hold(nullptr) {}
1181
1182 ~RGWPutObj() override {
1183 delete slo_info;
1184 delete obj_retention;
1185 delete obj_legal_hold;
1186 }
1187
1188 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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
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 */
1202 virtual int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
1203 RGWGetObj_Filter* cb,
1204 map<string, bufferlist>& attrs,
1205 bufferlist* manifest_bl) {
1206 *filter = nullptr;
1207 return 0;
1208 }
1209 virtual int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
1210 rgw::putobj::DataProcessor *cb) {
1211 return 0;
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;
1220 const char* name() const override { return "put_obj"; }
1221 RGWOpType get_type() override { return RGW_OP_PUT_OBJ; }
1222 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1223 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
1224 };
1225
1226 class RGWPostObj : public RGWOp {
1227 protected:
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 }
1245 public:
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
1258 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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
1267 virtual int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
1268 rgw::putobj::DataProcessor *cb) {
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;
1274 const char* name() const override { return "post_obj"; }
1275 RGWOpType get_type() override { return RGW_OP_POST_OBJ; }
1276 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1277 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
1278 };
1279
1280 class RGWPutMetadataAccount : public RGWOp {
1281 protected:
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
1293 public:
1294 RGWPutMetadataAccount()
1295 : new_quota_extracted(false),
1296 has_policy(false) {
1297 }
1298
1299 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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);
1313 const char* name() const override { return "put_account_metadata"; }
1314 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_ACCOUNT; }
1315 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1316 };
1317
1318 class RGWPutMetadataBucket : public RGWOp {
1319 protected:
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;
1326 rgw_placement_rule placement_rule;
1327 boost::optional<std::string> swift_ver_location;
1328
1329 public:
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
1338 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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;
1349 const char* name() const override { return "put_bucket_metadata"; }
1350 RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; }
1351 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1352 };
1353
1354 class RGWPutMetadataObject : public RGWOp {
1355 protected:
1356 RGWAccessControlPolicy policy;
1357 boost::optional<ceph::real_time> delete_at;
1358 const char *dlo_manifest;
1359
1360 public:
1361 RGWPutMetadataObject()
1362 : dlo_manifest(NULL)
1363 {}
1364
1365 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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;
1375 const char* name() const override { return "put_obj_metadata"; }
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
1381 class RGWDeleteObj : public RGWOp {
1382 protected:
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;
1389 bool bypass_perm;
1390 bool bypass_governance_mode;
1391
1392 public:
1393 RGWDeleteObj()
1394 : delete_marker(false),
1395 multipart_delete(false),
1396 no_precondition_error(false),
1397 deleter(nullptr),
1398 bypass_perm(true),
1399 bypass_governance_mode(false) {
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;
1409 const char* name() const override { return "delete_obj"; }
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; }
1413 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
1414 };
1415
1416 class RGWCopyObj : public RGWOp {
1417 protected:
1418 RGWAccessControlPolicy dest_policy;
1419 const char *if_mod;
1420 const char *if_unmod;
1421 const char *if_match;
1422 const char *if_nomatch;
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;
1427
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;
1448 string etag;
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
1458 bool need_to_check_storage_class = false;
1459
1460 int init_common();
1461
1462 public:
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
1479 static bool parse_copy_location(const boost::string_view& src,
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
1487 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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
1496 virtual int check_storage_class(const rgw_placement_rule& src_placement) {
1497 return 0;
1498 }
1499
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;
1504 const char* name() const override { return "copy_obj"; }
1505 RGWOpType get_type() override { return RGW_OP_COPY_OBJ; }
1506 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1507 dmc::client_id dmclock_client() override { return dmc::client_id::data; }
1508 };
1509
1510 class RGWGetACLs : public RGWOp {
1511 protected:
1512 string acls;
1513
1514 public:
1515 RGWGetACLs() {}
1516
1517 int verify_permission() override;
1518 void pre_exec() override;
1519 void execute() override;
1520
1521 void send_response() override = 0;
1522 const char* name() const override { return "get_acls"; }
1523 RGWOpType get_type() override { return RGW_OP_GET_ACLS; }
1524 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1525 };
1526
1527 class RGWPutACLs : public RGWOp {
1528 protected:
1529 bufferlist data;
1530 ACLOwner owner;
1531
1532 public:
1533 RGWPutACLs() {}
1534 ~RGWPutACLs() override {}
1535
1536 int verify_permission() override;
1537 void pre_exec() override;
1538 void execute() override;
1539
1540 virtual int get_policy_from_state(rgw::sal::RGWRadosStore *store, struct req_state *s, stringstream& ss) { return 0; }
1541 virtual int get_params() = 0;
1542 void send_response() override = 0;
1543 const char* name() const override { return "put_acls"; }
1544 RGWOpType get_type() override { return RGW_OP_PUT_ACLS; }
1545 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1546 };
1547
1548 class RGWGetLC : public RGWOp {
1549 protected:
1550
1551 public:
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;
1560 const char* name() const override { return "get_lifecycle"; }
1561 RGWOpType get_type() override { return RGW_OP_GET_LC; }
1562 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1563 };
1564
1565 class RGWPutLC : public RGWOp {
1566 protected:
1567 bufferlist data;
1568 const char *content_md5;
1569 string cookie;
1570
1571 public:
1572 RGWPutLC() {
1573 content_md5 = nullptr;
1574 }
1575 ~RGWPutLC() override {}
1576
1577 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *dialect_handler) override {
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;
1593 const char* name() const override { return "put_lifecycle"; }
1594 RGWOpType get_type() override { return RGW_OP_PUT_LC; }
1595 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1596 };
1597
1598 class RGWDeleteLC : public RGWOp {
1599 public:
1600 RGWDeleteLC() = default;
1601 int verify_permission() override;
1602 void pre_exec() override;
1603 void execute() override;
1604
1605 void send_response() override = 0;
1606 const char* name() const override { return "delete_lifecycle"; }
1607 RGWOpType get_type() override { return RGW_OP_DELETE_LC; }
1608 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1609 };
1610
1611 class RGWGetCORS : public RGWOp {
1612 protected:
1613
1614 public:
1615 RGWGetCORS() {}
1616
1617 int verify_permission() override;
1618 void execute() override;
1619
1620 void send_response() override = 0;
1621 const char* name() const override { return "get_cors"; }
1622 RGWOpType get_type() override { return RGW_OP_GET_CORS; }
1623 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1624 };
1625
1626 class RGWPutCORS : public RGWOp {
1627 protected:
1628 bufferlist cors_bl;
1629 bufferlist in_data;
1630
1631 public:
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;
1640 const char* name() const override { return "put_cors"; }
1641 RGWOpType get_type() override { return RGW_OP_PUT_CORS; }
1642 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1643 };
1644
1645 class RGWDeleteCORS : public RGWOp {
1646 protected:
1647
1648 public:
1649 RGWDeleteCORS() {}
1650
1651 int verify_permission() override;
1652 void execute() override;
1653
1654 void send_response() override = 0;
1655 const char* name() const override { return "delete_cors"; }
1656 RGWOpType get_type() override { return RGW_OP_DELETE_CORS; }
1657 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1658 };
1659
1660 class RGWOptionsCORS : public RGWOp {
1661 protected:
1662 RGWCORSRule *rule;
1663 const char *origin, *req_hdrs, *req_meth;
1664
1665 public:
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;
1675 const char* name() const override { return "options_cors"; }
1676 RGWOpType get_type() override { return RGW_OP_OPTIONS_CORS; }
1677 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1678 };
1679
1680 class RGWGetRequestPayment : public RGWOp {
1681 protected:
1682 bool requester_pays;
1683
1684 public:
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;
1692 const char* name() const override { return "get_request_payment"; }
1693 RGWOpType get_type() override { return RGW_OP_GET_REQUEST_PAYMENT; }
1694 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1695 };
1696
1697 class RGWSetRequestPayment : public RGWOp {
1698 protected:
1699 bool requester_pays;
1700 bufferlist in_data;
1701 public:
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;
1711 const char* name() const override { return "set_request_payment"; }
1712 RGWOpType get_type() override { return RGW_OP_SET_REQUEST_PAYMENT; }
1713 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1714 };
1715
1716 class RGWInitMultipart : public RGWOp {
1717 protected:
1718 string upload_id;
1719 RGWAccessControlPolicy policy;
1720 ceph::real_time mtime;
1721
1722 public:
1723 RGWInitMultipart() {}
1724
1725 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
1726 RGWOp::init(store, s, h);
1727 policy.set_ctx(s->cct);
1728 }
1729 int verify_permission() override;
1730 void pre_exec() override;
1731 void execute() override;
1732
1733 virtual int get_params() = 0;
1734 void send_response() override = 0;
1735 const char* name() const override { return "init_multipart"; }
1736 RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; }
1737 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1738 virtual int prepare_encryption(map<string, bufferlist>& attrs) { return 0; }
1739 };
1740
1741 class RGWCompleteMultipart : public RGWOp {
1742 protected:
1743 string upload_id;
1744 string etag;
1745 string version_id;
1746 bufferlist data;
1747
1748 struct MPSerializer {
1749 librados::IoCtx ioctx;
1750 rados::cls::lock::Lock lock;
1751 librados::ObjectWriteOperation op;
1752 std::string oid;
1753 bool locked;
1754
1755 MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
1756 {}
1757
1758 int try_lock(const std::string& oid, utime_t dur);
1759
1760 int unlock() {
1761 return lock.unlock(&ioctx, oid);
1762 }
1763
1764 void clear_locked() {
1765 locked = false;
1766 }
1767 } serializer;
1768
1769 public:
1770 RGWCompleteMultipart() {}
1771 ~RGWCompleteMultipart() override {}
1772
1773 int verify_permission() override;
1774 void pre_exec() override;
1775 void execute() override;
1776 void complete() override;
1777
1778 virtual int get_params() = 0;
1779 void send_response() override = 0;
1780 const char* name() const override { return "complete_multipart"; }
1781 RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
1782 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1783 };
1784
1785 class RGWAbortMultipart : public RGWOp {
1786 public:
1787 RGWAbortMultipart() {}
1788
1789 int verify_permission() override;
1790 void pre_exec() override;
1791 void execute() override;
1792
1793 void send_response() override = 0;
1794 const char* name() const override { return "abort_multipart"; }
1795 RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; }
1796 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1797 };
1798
1799 class RGWListMultipart : public RGWOp {
1800 protected:
1801 string upload_id;
1802 map<uint32_t, RGWUploadPartInfo> parts;
1803 int max_parts;
1804 int marker;
1805 RGWAccessControlPolicy policy;
1806 bool truncated;
1807
1808 public:
1809 RGWListMultipart() {
1810 max_parts = 1000;
1811 marker = 0;
1812 truncated = false;
1813 }
1814
1815 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
1816 RGWOp::init(store, s, h);
1817 policy = RGWAccessControlPolicy(s->cct);
1818 }
1819 int verify_permission() override;
1820 void pre_exec() override;
1821 void execute() override;
1822
1823 virtual int get_params() = 0;
1824 void send_response() override = 0;
1825 const char* name() const override { return "list_multipart"; }
1826 RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
1827 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1828 };
1829
1830 struct RGWMultipartUploadEntry {
1831 rgw_bucket_dir_entry obj;
1832 RGWMPObj mp;
1833
1834 friend std::ostream& operator<<(std::ostream& out,
1835 const RGWMultipartUploadEntry& e) {
1836 constexpr char quote = '"';
1837 return out << "RGWMultipartUploadEntry{ obj.key=" <<
1838 quote << e.obj.key << quote << " mp=" << e.mp << " }";
1839 }
1840 };
1841
1842 class RGWListBucketMultiparts : public RGWOp {
1843 protected:
1844 string prefix;
1845 RGWMPObj marker;
1846 RGWMultipartUploadEntry next_marker;
1847 int max_uploads;
1848 string delimiter;
1849 vector<RGWMultipartUploadEntry> uploads;
1850 map<string, bool> common_prefixes;
1851 bool is_truncated;
1852 int default_max;
1853 bool encode_url {false};
1854
1855 public:
1856 RGWListBucketMultiparts() {
1857 max_uploads = 0;
1858 is_truncated = false;
1859 default_max = 0;
1860 }
1861
1862 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
1863 RGWOp::init(store, s, h);
1864 max_uploads = default_max;
1865 }
1866
1867 int verify_permission() override;
1868 void pre_exec() override;
1869 void execute() override;
1870
1871 virtual int get_params() = 0;
1872 void send_response() override = 0;
1873 const char* name() const override { return "list_bucket_multiparts"; }
1874 RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; }
1875 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1876 };
1877
1878
1879 class RGWGetCrossDomainPolicy : public RGWOp {
1880 public:
1881 RGWGetCrossDomainPolicy() = default;
1882 ~RGWGetCrossDomainPolicy() override = default;
1883
1884 int verify_permission() override {
1885 return 0;
1886 }
1887
1888 void execute() override {
1889 op_ret = 0;
1890 }
1891
1892 const char* name() const override { return "get_crossdomain_policy"; }
1893
1894 RGWOpType get_type() override {
1895 return RGW_OP_GET_CROSS_DOMAIN_POLICY;
1896 }
1897
1898 uint32_t op_mask() override {
1899 return RGW_OP_TYPE_READ;
1900 }
1901 };
1902
1903
1904 class RGWGetHealthCheck : public RGWOp {
1905 public:
1906 RGWGetHealthCheck() = default;
1907 ~RGWGetHealthCheck() override = default;
1908
1909 int verify_permission() override {
1910 return 0;
1911 }
1912
1913 void execute() override;
1914
1915 const char* name() const override { return "get_health_check"; }
1916
1917 RGWOpType get_type() override {
1918 return RGW_OP_GET_HEALTH_CHECK;
1919 }
1920
1921 uint32_t op_mask() override {
1922 return RGW_OP_TYPE_READ;
1923 }
1924 };
1925
1926
1927 class RGWDeleteMultiObj : public RGWOp {
1928 protected:
1929 bufferlist data;
1930 rgw_bucket bucket;
1931 bool quiet;
1932 bool status_dumped;
1933 bool acl_allowed = false;
1934
1935 public:
1936 RGWDeleteMultiObj() {
1937 quiet = false;
1938 status_dumped = false;
1939 }
1940 int verify_permission() override;
1941 void pre_exec() override;
1942 void execute() override;
1943
1944 virtual int get_params() = 0;
1945 virtual void send_status() = 0;
1946 virtual void begin_response() = 0;
1947 virtual void send_partial_response(rgw_obj_key& key, bool delete_marker,
1948 const string& marker_version_id, int ret) = 0;
1949 virtual void end_response() = 0;
1950 const char* name() const override { return "multi_object_delete"; }
1951 RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; }
1952 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1953 };
1954
1955 class RGWInfo: public RGWOp {
1956 public:
1957 RGWInfo() = default;
1958 ~RGWInfo() override = default;
1959
1960 int verify_permission() override { return 0; }
1961 const char* name() const override { return "get info"; }
1962 RGWOpType get_type() override { return RGW_OP_GET_INFO; }
1963 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1964 };
1965
1966 extern int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s);
1967 extern int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *s,
1968 bool prefetch_data);
1969 extern void rgw_build_iam_environment(rgw::sal::RGWRadosStore* store,
1970 struct req_state* s);
1971 extern vector<rgw::IAM::Policy> get_iam_user_policy_from_attr(CephContext* cct,
1972 rgw::sal::RGWRadosStore* store,
1973 map<string, bufferlist>& attrs,
1974 const string& tenant);
1975
1976 static inline int get_system_versioning_params(req_state *s,
1977 uint64_t *olh_epoch,
1978 string *version_id)
1979 {
1980 if (!s->system_request) {
1981 return 0;
1982 }
1983
1984 if (olh_epoch) {
1985 string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
1986 if (!epoch_str.empty()) {
1987 string err;
1988 *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
1989 if (!err.empty()) {
1990 lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
1991 << dendl;
1992 return -EINVAL;
1993 }
1994 }
1995 }
1996
1997 if (version_id) {
1998 *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
1999 }
2000
2001 return 0;
2002 } /* get_system_versioning_params */
2003
2004 static inline void format_xattr(std::string &xattr)
2005 {
2006 /* If the extended attribute is not valid UTF-8, we encode it using
2007 * quoted-printable encoding.
2008 */
2009 if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
2010 (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
2011 static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
2012 static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
2013 static const char MIME_SUFFIX_STR[] = "?=";
2014 static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
2015 int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
2016 char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
2017 strcpy(mime, MIME_PREFIX_STR);
2018 mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
2019 strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
2020 xattr.assign(mime);
2021 delete [] mime;
2022 }
2023 } /* format_xattr */
2024
2025 /**
2026 * Get the HTTP request metadata out of the req_state as a
2027 * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
2028 * s: The request state
2029 * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
2030 * On success returns 0.
2031 * On failure returns a negative error code.
2032 *
2033 */
2034 static inline int rgw_get_request_metadata(CephContext* const cct,
2035 struct req_info& info,
2036 std::map<std::string, ceph::bufferlist>& attrs,
2037 const bool allow_empty_attrs = true)
2038 {
2039 static const std::set<std::string> blacklisted_headers = {
2040 "x-amz-server-side-encryption-customer-algorithm",
2041 "x-amz-server-side-encryption-customer-key",
2042 "x-amz-server-side-encryption-customer-key-md5",
2043 "x-amz-storage-class"
2044 };
2045
2046 size_t valid_meta_count = 0;
2047 for (auto& kv : info.x_meta_map) {
2048 const std::string& name = kv.first;
2049 std::string& xattr = kv.second;
2050
2051 if (blacklisted_headers.count(name) == 1) {
2052 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
2053 continue;
2054 } else if (allow_empty_attrs || !xattr.empty()) {
2055 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
2056 format_xattr(xattr);
2057
2058 std::string attr_name(RGW_ATTR_PREFIX);
2059 attr_name.append(name);
2060
2061 /* Check roughly whether we aren't going behind the limit on attribute
2062 * name. Passing here doesn't guarantee that an OSD will accept that
2063 * as ObjectStore::get_max_attr_name_length() can set the limit even
2064 * lower than the "osd_max_attr_name_len" configurable. */
2065 const auto max_attr_name_len = cct->_conf->rgw_max_attr_name_len;
2066 if (max_attr_name_len && attr_name.length() > max_attr_name_len) {
2067 return -ENAMETOOLONG;
2068 }
2069
2070 /* Similar remarks apply to the check for value size. We're veryfing
2071 * it early at the RGW's side as it's being claimed in /info. */
2072 const auto max_attr_size = cct->_conf->rgw_max_attr_size;
2073 if (max_attr_size && xattr.length() > max_attr_size) {
2074 return -EFBIG;
2075 }
2076
2077 /* Swift allows administrators to limit the number of metadats items
2078 * send _in a single request_. */
2079 const auto max_attrs_num_in_req = cct->_conf->rgw_max_attrs_num_in_req;
2080 if (max_attrs_num_in_req &&
2081 ++valid_meta_count > max_attrs_num_in_req) {
2082 return -E2BIG;
2083 }
2084
2085 auto rval = attrs.emplace(std::move(attr_name), ceph::bufferlist());
2086 /* At the moment the value of the freshly created attribute key-value
2087 * pair is an empty bufferlist. */
2088
2089 ceph::bufferlist& bl = rval.first->second;
2090 bl.append(xattr.c_str(), xattr.size() + 1);
2091 }
2092 }
2093
2094 return 0;
2095 } /* rgw_get_request_metadata */
2096
2097 static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
2098 map<string, bufferlist>& attrs)
2099 {
2100 if (delete_at == boost::none) {
2101 return;
2102 }
2103
2104 bufferlist delatbl;
2105 encode(*delete_at, delatbl);
2106 attrs[RGW_ATTR_DELETE_AT] = delatbl;
2107 } /* encode_delete_at_attr */
2108
2109 static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
2110 {
2111 if (obj_tags == nullptr){
2112 // we assume the user submitted a tag format which we couldn't parse since
2113 // this wouldn't be parsed later by get/put obj tags, lets delete if the
2114 // attr was populated
2115 return;
2116 }
2117
2118 bufferlist tagsbl;
2119 obj_tags->encode(tagsbl);
2120 attrs[RGW_ATTR_TAGS] = tagsbl;
2121 }
2122
2123 static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
2124 map<string, bufferlist>& attrs)
2125 {
2126 string dm = dlo_manifest;
2127
2128 if (dm.find('/') == string::npos) {
2129 return -EINVAL;
2130 }
2131
2132 bufferlist manifest_bl;
2133 manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
2134 attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
2135
2136 return 0;
2137 } /* encode_dlo_manifest_attr */
2138
2139 static inline void complete_etag(MD5& hash, string *etag)
2140 {
2141 char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
2142 char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
2143
2144 hash.Final((unsigned char *)etag_buf);
2145 buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
2146 etag_buf_str);
2147
2148 *etag = etag_buf_str;
2149 } /* complete_etag */
2150
2151 class RGWSetAttrs : public RGWOp {
2152 protected:
2153 map<string, buffer::list> attrs;
2154
2155 public:
2156 RGWSetAttrs() {}
2157 ~RGWSetAttrs() override {}
2158
2159 void emplace_attr(std::string&& key, buffer::list&& bl) {
2160 attrs.emplace(std::move(key), std::move(bl));
2161 }
2162
2163 int verify_permission() override;
2164 void pre_exec() override;
2165 void execute() override;
2166
2167 virtual int get_params() = 0;
2168 void send_response() override = 0;
2169 const char* name() const override { return "set_attrs"; }
2170 RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
2171 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2172 };
2173
2174 class RGWGetObjLayout : public RGWOp {
2175 protected:
2176 RGWObjManifest *manifest{nullptr};
2177 rgw_raw_obj head_obj;
2178
2179 public:
2180 RGWGetObjLayout() {
2181 }
2182
2183 int check_caps(RGWUserCaps& caps) {
2184 return caps.check_cap("admin", RGW_CAP_READ);
2185 }
2186 int verify_permission() override {
2187 return check_caps(s->user->get_info().caps);
2188 }
2189 void pre_exec() override;
2190 void execute() override;
2191
2192 const char* name() const override { return "get_obj_layout"; }
2193 virtual RGWOpType get_type() override { return RGW_OP_GET_OBJ_LAYOUT; }
2194 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2195 };
2196
2197 class RGWPutBucketPolicy : public RGWOp {
2198 bufferlist data;
2199 public:
2200 RGWPutBucketPolicy() = default;
2201 ~RGWPutBucketPolicy() {
2202 }
2203 void send_response() override;
2204 int verify_permission() override;
2205 uint32_t op_mask() override {
2206 return RGW_OP_TYPE_WRITE;
2207 }
2208 void execute() override;
2209 int get_params();
2210 const char* name() const override { return "put_bucket_policy"; }
2211 RGWOpType get_type() override {
2212 return RGW_OP_PUT_BUCKET_POLICY;
2213 }
2214 };
2215
2216 class RGWGetBucketPolicy : public RGWOp {
2217 buffer::list policy;
2218 public:
2219 RGWGetBucketPolicy() = default;
2220 void send_response() override;
2221 int verify_permission() override;
2222 uint32_t op_mask() override {
2223 return RGW_OP_TYPE_READ;
2224 }
2225 void execute() override;
2226 const char* name() const override { return "get_bucket_policy"; }
2227 RGWOpType get_type() override {
2228 return RGW_OP_GET_BUCKET_POLICY;
2229 }
2230 };
2231
2232 class RGWDeleteBucketPolicy : public RGWOp {
2233 public:
2234 RGWDeleteBucketPolicy() = default;
2235 void send_response() override;
2236 int verify_permission() override;
2237 uint32_t op_mask() override {
2238 return RGW_OP_TYPE_WRITE;
2239 }
2240 void execute() override;
2241 int get_params();
2242 const char* name() const override { return "delete_bucket_policy"; }
2243 RGWOpType get_type() override {
2244 return RGW_OP_DELETE_BUCKET_POLICY;
2245 }
2246 };
2247
2248 class RGWPutBucketObjectLock : public RGWOp {
2249 protected:
2250 bufferlist data;
2251 bufferlist obj_lock_bl;
2252 RGWObjectLock obj_lock;
2253 public:
2254 RGWPutBucketObjectLock() = default;
2255 ~RGWPutBucketObjectLock() {}
2256 int verify_permission() override;
2257 void pre_exec() override;
2258 void execute() override;
2259 virtual void send_response() = 0;
2260 virtual int get_params() = 0;
2261 const char* name() const override { return "put_bucket_object_lock"; }
2262 RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_OBJ_LOCK; }
2263 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2264 };
2265
2266 class RGWGetBucketObjectLock : public RGWOp {
2267 public:
2268 int verify_permission() override;
2269 void pre_exec() override;
2270 void execute() override;
2271 virtual void send_response() = 0;
2272 const char* name() const override {return "get_bucket_object_lock"; }
2273 RGWOpType get_type() override { return RGW_OP_GET_BUCKET_OBJ_LOCK; }
2274 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2275 };
2276
2277 class RGWPutObjRetention : public RGWOp {
2278 protected:
2279 bufferlist data;
2280 RGWObjectRetention obj_retention;
2281 bool bypass_perm;
2282 bool bypass_governance_mode;
2283 public:
2284 RGWPutObjRetention():bypass_perm(true), bypass_governance_mode(false) {}
2285 int verify_permission() override;
2286 void pre_exec() override;
2287 void execute() override;
2288 virtual void send_response() override = 0;
2289 virtual int get_params() = 0;
2290 const char* name() const override { return "put_obj_retention"; }
2291 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2292 RGWOpType get_type() override { return RGW_OP_PUT_OBJ_RETENTION; }
2293 };
2294
2295 class RGWGetObjRetention : public RGWOp {
2296 protected:
2297 RGWObjectRetention obj_retention;
2298 public:
2299 int verify_permission() override;
2300 void pre_exec() override;
2301 void execute() override;
2302 virtual void send_response() = 0;
2303 const char* name() const override {return "get_obj_retention"; }
2304 RGWOpType get_type() override { return RGW_OP_GET_OBJ_RETENTION; }
2305 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2306 };
2307
2308 class RGWPutObjLegalHold : public RGWOp {
2309 protected:
2310 bufferlist data;
2311 RGWObjectLegalHold obj_legal_hold;
2312 public:
2313 int verify_permission() override;
2314 void pre_exec() override;
2315 void execute() override;
2316 virtual void send_response() override = 0;
2317 virtual int get_params() = 0;
2318 const char* name() const override { return "put_obj_legal_hold"; }
2319 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2320 RGWOpType get_type() override { return RGW_OP_PUT_OBJ_LEGAL_HOLD; }
2321 };
2322
2323 class RGWGetObjLegalHold : public RGWOp {
2324 protected:
2325 RGWObjectLegalHold obj_legal_hold;
2326 public:
2327 int verify_permission() override;
2328 void pre_exec() override;
2329 void execute() override;
2330 virtual void send_response() = 0;
2331 const char* name() const override {return "get_obj_legal_hold"; }
2332 RGWOpType get_type() override { return RGW_OP_GET_OBJ_LEGAL_HOLD; }
2333 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2334 };
2335
2336
2337 class RGWConfigBucketMetaSearch : public RGWOp {
2338 protected:
2339 std::map<std::string, uint32_t> mdsearch_config;
2340 public:
2341 RGWConfigBucketMetaSearch() {}
2342
2343 int verify_permission() override;
2344 void pre_exec() override;
2345 void execute() override;
2346
2347 virtual int get_params() = 0;
2348 const char* name() const override { return "config_bucket_meta_search"; }
2349 virtual RGWOpType get_type() override { return RGW_OP_CONFIG_BUCKET_META_SEARCH; }
2350 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2351 };
2352
2353 class RGWGetBucketMetaSearch : public RGWOp {
2354 public:
2355 RGWGetBucketMetaSearch() {}
2356
2357 int verify_permission() override;
2358 void pre_exec() override;
2359 void execute() override {}
2360
2361 const char* name() const override { return "get_bucket_meta_search"; }
2362 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_META_SEARCH; }
2363 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2364 };
2365
2366 class RGWDelBucketMetaSearch : public RGWOp {
2367 public:
2368 RGWDelBucketMetaSearch() {}
2369
2370 int verify_permission() override;
2371 void pre_exec() override;
2372 void execute() override;
2373
2374 const char* name() const override { return "delete_bucket_meta_search"; }
2375 virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
2376 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2377 };
2378
2379 class RGWGetClusterStat : public RGWOp {
2380 protected:
2381 struct rados_cluster_stat_t stats_op;
2382 public:
2383 RGWGetClusterStat() {}
2384
2385 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
2386 RGWOp::init(store, s, h);
2387 }
2388 int verify_permission() override {return 0;}
2389 virtual void send_response() override = 0;
2390 virtual int get_params() = 0;
2391 void execute() override;
2392 const char* name() const override { return "get_cluster_stat"; }
2393 dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
2394 };
2395
2396 class RGWGetBucketPolicyStatus : public RGWOp {
2397 protected:
2398 bool isPublic {false};
2399 public:
2400 int verify_permission() override;
2401 const char* name() const override { return "get_bucket_policy_status"; }
2402 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_POLICY_STATUS; }
2403 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2404 void execute() override;
2405 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2406 };
2407
2408 class RGWPutBucketPublicAccessBlock : public RGWOp {
2409 protected:
2410 bufferlist data;
2411 PublicAccessBlockConfiguration access_conf;
2412 public:
2413 int verify_permission() override;
2414 const char* name() const override { return "put_bucket_public_access_block";}
2415 virtual RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK; }
2416 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2417 int get_params();
2418 void execute() override;
2419 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2420 };
2421
2422 class RGWGetBucketPublicAccessBlock : public RGWOp {
2423 protected:
2424 PublicAccessBlockConfiguration access_conf;
2425 public:
2426 int verify_permission() override;
2427 const char* name() const override { return "get_bucket_public_access_block";}
2428 virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_PUBLIC_ACCESS_BLOCK; }
2429 virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
2430 int get_params();
2431 void execute() override;
2432 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2433 };
2434
2435 class RGWDeleteBucketPublicAccessBlock : public RGWOp {
2436 protected:
2437 PublicAccessBlockConfiguration access_conf;
2438 public:
2439 int verify_permission() override;
2440 const char* name() const override { return "delete_bucket_public_access_block";}
2441 virtual RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_PUBLIC_ACCESS_BLOCK; }
2442 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2443 int get_params();
2444 void execute() override;
2445 void send_response() override;
2446 dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
2447 };
2448
2449 static inline int parse_value_and_bound(
2450 const string &input,
2451 int &output,
2452 const long lower_bound,
2453 const long upper_bound,
2454 const long default_val)
2455 {
2456 if (!input.empty()) {
2457 char *endptr;
2458 output = strtol(input.c_str(), &endptr, 10);
2459 if (endptr) {
2460 if (endptr == input.c_str()) return -EINVAL;
2461 while (*endptr && isspace(*endptr)) // ignore white space
2462 endptr++;
2463 if (*endptr) {
2464 return -EINVAL;
2465 }
2466 }
2467 if(output > upper_bound) {
2468 output = upper_bound;
2469 }
2470 if(output < lower_bound) {
2471 output = lower_bound;
2472 }
2473 } else {
2474 output = default_val;
2475 }
2476
2477 return 0;
2478 }
2479
2480 int forward_request_to_master(struct req_state *s, obj_version *objv, rgw::sal::RGWRadosStore *store,
2481 bufferlist& in_data, JSONParser *jp, req_info *forward_info = nullptr);
2482
2483 #endif /* CEPH_RGW_OP_H */