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