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