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