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