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