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