]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_op.h
dc554a37b714b00583b51773c796cb28e3620699
[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
1721 public:
1722 RGWInitMultipart() {}
1723
1724 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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;
1734 const char* name() const override { return "init_multipart"; }
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
1740 class RGWCompleteMultipart : public RGWOp {
1741 protected:
1742 string upload_id;
1743 string etag;
1744 string version_id;
1745 bufferlist data;
1746
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
1768 public:
1769 RGWCompleteMultipart() {}
1770 ~RGWCompleteMultipart() override {}
1771
1772 int verify_permission() override;
1773 void pre_exec() override;
1774 void execute() override;
1775 void complete() override;
1776
1777 virtual int get_params() = 0;
1778 void send_response() override = 0;
1779 const char* name() const override { return "complete_multipart"; }
1780 RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
1781 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
1782 };
1783
1784 class RGWAbortMultipart : public RGWOp {
1785 public:
1786 RGWAbortMultipart() {}
1787
1788 int verify_permission() override;
1789 void pre_exec() override;
1790 void execute() override;
1791
1792 void send_response() override = 0;
1793 const char* name() const override { return "abort_multipart"; }
1794 RGWOpType get_type() override { return RGW_OP_ABORT_MULTIPART; }
1795 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1796 };
1797
1798 class RGWListMultipart : public RGWOp {
1799 protected:
1800 string upload_id;
1801 map<uint32_t, RGWUploadPartInfo> parts;
1802 int max_parts;
1803 int marker;
1804 RGWAccessControlPolicy policy;
1805 bool truncated;
1806
1807 public:
1808 RGWListMultipart() {
1809 max_parts = 1000;
1810 marker = 0;
1811 truncated = false;
1812 }
1813
1814 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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;
1824 const char* name() const override { return "list_multipart"; }
1825 RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
1826 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1827 };
1828
1829 struct RGWMultipartUploadEntry {
1830 rgw_bucket_dir_entry obj;
1831 RGWMPObj mp;
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 }
1839 };
1840
1841 class RGWListBucketMultiparts : public RGWOp {
1842 protected:
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;
1852 bool encode_url {false};
1853
1854 public:
1855 RGWListBucketMultiparts() {
1856 max_uploads = 0;
1857 is_truncated = false;
1858 default_max = 0;
1859 }
1860
1861 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
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;
1872 const char* name() const override { return "list_bucket_multiparts"; }
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
1878 class RGWGetCrossDomainPolicy : public RGWOp {
1879 public:
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
1891 const char* name() const override { return "get_crossdomain_policy"; }
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
1903 class RGWGetHealthCheck : public RGWOp {
1904 public:
1905 RGWGetHealthCheck() = default;
1906 ~RGWGetHealthCheck() override = default;
1907
1908 int verify_permission() override {
1909 return 0;
1910 }
1911
1912 void execute() override;
1913
1914 const char* name() const override { return "get_health_check"; }
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
1926 class RGWDeleteMultiObj : public RGWOp {
1927 protected:
1928 bufferlist data;
1929 rgw_bucket bucket;
1930 bool quiet;
1931 bool status_dumped;
1932 bool acl_allowed = false;
1933
1934 public:
1935 RGWDeleteMultiObj() {
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;
1949 const char* name() const override { return "multi_object_delete"; }
1950 RGWOpType get_type() override { return RGW_OP_DELETE_MULTI_OBJ; }
1951 uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
1952 };
1953
1954 class RGWInfo: public RGWOp {
1955 public:
1956 RGWInfo() = default;
1957 ~RGWInfo() override = default;
1958
1959 int verify_permission() override { return 0; }
1960 const char* name() const override { return "get info"; }
1961 RGWOpType get_type() override { return RGW_OP_GET_INFO; }
1962 uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
1963 };
1964
1965 extern int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s);
1966 extern int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *s,
1967 bool prefetch_data);
1968 extern void rgw_build_iam_environment(rgw::sal::RGWRadosStore* store,
1969 struct req_state* s);
1970 extern vector<rgw::IAM::Policy> get_iam_user_policy_from_attr(CephContext* cct,
1971 rgw::sal::RGWRadosStore* store,
1972 map<string, bufferlist>& attrs,
1973 const string& tenant);
1974
1975 static 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
2003 static 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>
2029 * On success returns 0.
2030 * On failure returns a negative error code.
2031 *
2032 */
2033 static 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)
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",
2041 "x-amz-server-side-encryption-customer-key-md5",
2042 "x-amz-storage-class"
2043 };
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
2050 if (blacklisted_headers.count(name) == 1) {
2051 lsubdout(cct, rgw, 10) << "skipping x>> " << name << dendl;
2052 continue;
2053 } else if (allow_empty_attrs || !xattr.empty()) {
2054 lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
2055 format_xattr(xattr);
2056
2057 std::string attr_name(RGW_ATTR_PREFIX);
2058 attr_name.append(name);
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. */
2064 const auto max_attr_name_len = cct->_conf->rgw_max_attr_name_len;
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. */
2071 const auto max_attr_size = cct->_conf->rgw_max_attr_size;
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_. */
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) {
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;
2089 bl.append(xattr.c_str(), xattr.size() + 1);
2090 }
2091 }
2092
2093 return 0;
2094 } /* rgw_get_request_metadata */
2095
2096 static 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;
2104 encode(*delete_at, delatbl);
2105 attrs[RGW_ATTR_DELETE_AT] = delatbl;
2106 } /* encode_delete_at_attr */
2107
2108 static 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
2122 static 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
2138 static 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
2143 hash.Final((unsigned char *)etag_buf);
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
2150 class RGWSetAttrs : public RGWOp {
2151 protected:
2152 map<string, buffer::list> attrs;
2153
2154 public:
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;
2168 const char* name() const override { return "set_attrs"; }
2169 RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
2170 uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2171 };
2172
2173 class RGWGetObjLayout : public RGWOp {
2174 protected:
2175 RGWObjManifest *manifest{nullptr};
2176 rgw_raw_obj head_obj;
2177
2178 public:
2179 RGWGetObjLayout() {
2180 }
2181
2182 int check_caps(RGWUserCaps& caps) {
2183 return caps.check_cap("admin", RGW_CAP_READ);
2184 }
2185 int verify_permission() override {
2186 return check_caps(s->user->get_info().caps);
2187 }
2188 void pre_exec() override;
2189 void execute() override;
2190
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; }
2194 };
2195
2196 class RGWPutBucketPolicy : public RGWOp {
2197 bufferlist data;
2198 public:
2199 RGWPutBucketPolicy() = default;
2200 ~RGWPutBucketPolicy() {
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();
2209 const char* name() const override { return "put_bucket_policy"; }
2210 RGWOpType get_type() override {
2211 return RGW_OP_PUT_BUCKET_POLICY;
2212 }
2213 };
2214
2215 class RGWGetBucketPolicy : public RGWOp {
2216 buffer::list policy;
2217 public:
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;
2225 const char* name() const override { return "get_bucket_policy"; }
2226 RGWOpType get_type() override {
2227 return RGW_OP_GET_BUCKET_POLICY;
2228 }
2229 };
2230
2231 class RGWDeleteBucketPolicy : public RGWOp {
2232 public:
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();
2241 const char* name() const override { return "delete_bucket_policy"; }
2242 RGWOpType get_type() override {
2243 return RGW_OP_DELETE_BUCKET_POLICY;
2244 }
2245 };
2246
2247 class RGWPutBucketObjectLock : public RGWOp {
2248 protected:
2249 bufferlist data;
2250 bufferlist obj_lock_bl;
2251 RGWObjectLock obj_lock;
2252 public:
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
2265 class RGWGetBucketObjectLock : public RGWOp {
2266 public:
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
2276 class RGWPutObjRetention : public RGWOp {
2277 protected:
2278 bufferlist data;
2279 RGWObjectRetention obj_retention;
2280 bool bypass_perm;
2281 bool bypass_governance_mode;
2282 public:
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
2294 class RGWGetObjRetention : public RGWOp {
2295 protected:
2296 RGWObjectRetention obj_retention;
2297 public:
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
2307 class RGWPutObjLegalHold : public RGWOp {
2308 protected:
2309 bufferlist data;
2310 RGWObjectLegalHold obj_legal_hold;
2311 public:
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
2322 class RGWGetObjLegalHold : public RGWOp {
2323 protected:
2324 RGWObjectLegalHold obj_legal_hold;
2325 public:
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
2335
2336 class RGWConfigBucketMetaSearch : public RGWOp {
2337 protected:
2338 std::map<std::string, uint32_t> mdsearch_config;
2339 public:
2340 RGWConfigBucketMetaSearch() {}
2341
2342 int verify_permission() override;
2343 void pre_exec() override;
2344 void execute() override;
2345
2346 virtual int get_params() = 0;
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; }
2350 };
2351
2352 class RGWGetBucketMetaSearch : public RGWOp {
2353 public:
2354 RGWGetBucketMetaSearch() {}
2355
2356 int verify_permission() override;
2357 void pre_exec() override;
2358 void execute() override {}
2359
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; }
2363 };
2364
2365 class RGWDelBucketMetaSearch : public RGWOp {
2366 public:
2367 RGWDelBucketMetaSearch() {}
2368
2369 int verify_permission() override;
2370 void pre_exec() override;
2371 void execute() override;
2372
2373 const char* name() const override { return "delete_bucket_meta_search"; }
2374 virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
2375 virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
2376 };
2377
2378 class RGWGetClusterStat : public RGWOp {
2379 protected:
2380 struct rados_cluster_stat_t stats_op;
2381 public:
2382 RGWGetClusterStat() {}
2383
2384 void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
2385 RGWOp::init(store, s, h);
2386 }
2387 int verify_permission() override {return 0;}
2388 virtual void send_response() override = 0;
2389 virtual int get_params() = 0;
2390 void execute() override;
2391 const char* name() const override { return "get_cluster_stat"; }
2392 dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
2393 };
2394
2395 class RGWGetBucketPolicyStatus : public RGWOp {
2396 protected:
2397 bool isPublic {false};
2398 public:
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
2407 class RGWPutBucketPublicAccessBlock : public RGWOp {
2408 protected:
2409 bufferlist data;
2410 PublicAccessBlockConfiguration access_conf;
2411 public:
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
2421 class RGWGetBucketPublicAccessBlock : public RGWOp {
2422 protected:
2423 PublicAccessBlockConfiguration access_conf;
2424 public:
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
2434 class RGWDeleteBucketPublicAccessBlock : public RGWOp {
2435 protected:
2436 PublicAccessBlockConfiguration access_conf;
2437 public:
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
2448 static 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 }
2478
2479 int 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);
2481
2482 #endif /* CEPH_RGW_OP_H */