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