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