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