]>
Commit | Line | Data |
---|---|---|
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 |
63 | using ceph::crypto::SHA1; |
64 | ||
65 | struct req_state; | |
66 | class RGWOp; | |
9f95a23c | 67 | class RGWRados; |
20effc67 | 68 | class RGWMultiCompleteUpload; |
7c673cae FG |
69 | |
70 | ||
71 | namespace rgw { | |
72 | namespace auth { | |
73 | namespace registry { | |
74 | ||
75 | class StrategyRegistry; | |
76 | ||
77 | } | |
78 | } | |
79 | } | |
80 | ||
1e59de90 | 81 | int 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 | |
89 | class RGWHandler { | |
90 | protected: | |
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 | |
97 | public: | |
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 | 127 | void rgw_bucket_object_pre_exec(req_state *s); |
31f18b77 | 128 | |
11fdf7f2 TL |
129 | namespace dmc = rgw::dmclock; |
130 | ||
1e59de90 | 131 | std::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 | ||
135 | template <class T> | |
136 | int 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 | 175 | class RGWOp : public DoutPrefixProvider { |
7c673cae | 176 | protected: |
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 |
213 | public: |
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 | ||
287 | class RGWDefaultResponseOp : public RGWOp { | |
288 | public: | |
289 | void send_response() override; | |
290 | }; | |
291 | ||
292 | class RGWGetObj_Filter : public RGWGetDataCB | |
293 | { | |
294 | protected: | |
295 | RGWGetObj_Filter *next{nullptr}; | |
296 | public: | |
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 | ||
332 | class RGWGetObj : public RGWOp { | |
333 | protected: | |
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(); |
379 | public: | |
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 | 455 | class RGWGetObj_CB : public RGWGetObj_Filter |
7c673cae FG |
456 | { |
457 | RGWGetObj *op; | |
458 | public: | |
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 |
467 | class 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 | ||
483 | class 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 | ||
498 | class 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 |
509 | class RGWGetBucketTags : public RGWOp { |
510 | protected: | |
511 | bufferlist tags_bl; | |
512 | bool has_tags{false}; | |
513 | public: | |
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 | ||
524 | class RGWPutBucketTags : public RGWOp { | |
525 | protected: | |
526 | bufferlist tags_bl; | |
527 | bufferlist in_data; | |
528 | public: | |
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 | ||
539 | class RGWDeleteBucketTags : public RGWOp { | |
540 | public: | |
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 | ||
550 | struct rgw_sync_policy_group; | |
551 | ||
552 | class RGWGetBucketReplication : public RGWOp { | |
553 | public: | |
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 | ||
564 | class RGWPutBucketReplication : public RGWOp { | |
565 | protected: | |
566 | bufferlist in_data; | |
567 | std::vector<rgw_sync_policy_group> sync_policy_groups; | |
568 | public: | |
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 | ||
579 | class RGWDeleteBucketReplication : public RGWOp { | |
580 | protected: | |
581 | virtual void update_sync_policy(rgw_sync_policy_info *policy) = 0; | |
582 | public: | |
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 |
592 | class RGWBulkDelete : public RGWOp { |
593 | public: | |
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 | ||
646 | protected: | |
647 | std::unique_ptr<Deleter> deleter; | |
648 | ||
649 | public: | |
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 | 668 | inline 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 | ||
673 | class RGWBulkUploadOp : public RGWOp { | |
7c673cae FG |
674 | protected: |
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 | |
720 | public: | |
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 | ||
746 | class RGWBulkUploadOp::StreamGetter { | |
747 | public: | |
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 | ||
756 | class RGWBulkUploadOp::DecoratedStreamGetter : public StreamGetter { | |
757 | StreamGetter& decoratee; | |
758 | ||
759 | protected: | |
760 | StreamGetter& get_decoratee() { | |
761 | return decoratee; | |
762 | } | |
763 | ||
764 | public: | |
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 | ||
780 | class RGWBulkUploadOp::AlignedStreamGetter | |
781 | : public RGWBulkUploadOp::DecoratedStreamGetter { | |
782 | size_t position; | |
783 | size_t length; | |
784 | size_t alignment; | |
785 | ||
786 | public: | |
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 |
803 | struct 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 | ||
812 | class RGWListBuckets : public RGWOp { | |
813 | protected: | |
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 | ||
828 | public: | |
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 | |
860 | class RGWGetUsage : public RGWOp { | |
861 | protected: | |
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 |
873 | public: |
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 | ||
889 | class RGWStatAccount : public RGWOp { | |
890 | protected: | |
3efd9988 FG |
891 | RGWUsageStats global_stats; |
892 | std::map<std::string, RGWUsageStats> policies_stats; | |
7c673cae FG |
893 | |
894 | public: | |
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 | ||
906 | class RGWListBucket : public RGWOp { | |
907 | protected: | |
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 | ||
928 | public: | |
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 | ||
947 | class RGWGetBucketLogging : public RGWOp { | |
948 | public: | |
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 | ||
959 | class RGWGetBucketLocation : public RGWOp { | |
960 | public: | |
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 | ||
972 | class RGWGetBucketVersioning : public RGWOp { | |
973 | protected: | |
11fdf7f2 TL |
974 | bool versioned{false}; |
975 | bool versioning_enabled{false}; | |
976 | bool mfa_enabled{false}; | |
7c673cae | 977 | public: |
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 |
990 | enum BucketVersionStatus { |
991 | VersioningStatusInvalid = -1, | |
992 | VersioningNotChanged = 0, | |
993 | VersioningEnabled = 1, | |
994 | VersioningSuspended =2, | |
995 | }; | |
996 | ||
7c673cae FG |
997 | class RGWSetBucketVersioning : public RGWOp { |
998 | protected: | |
11fdf7f2 TL |
999 | int versioning_status; |
1000 | bool mfa_set_status{false}; | |
1001 | bool mfa_status{false}; | |
7c673cae FG |
1002 | bufferlist in_data; |
1003 | public: | |
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 | ||
1018 | class RGWGetBucketWebsite : public RGWOp { | |
1019 | public: | |
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 | ||
1032 | class RGWSetBucketWebsite : public RGWOp { | |
1033 | protected: | |
31f18b77 | 1034 | bufferlist in_data; |
7c673cae FG |
1035 | RGWBucketWebsiteConf website_conf; |
1036 | public: | |
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 | ||
1051 | class RGWDeleteBucketWebsite : public RGWOp { | |
1052 | public: | |
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 | ||
1065 | class RGWStatBucket : public RGWOp { | |
1066 | protected: | |
20effc67 | 1067 | std::unique_ptr<rgw::sal::Bucket> bucket; |
7c673cae FG |
1068 | |
1069 | public: | |
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 | ||
1080 | class RGWCreateBucket : public RGWOp { | |
1081 | protected: | |
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 | ||
1099 | public: | |
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 | ||
1122 | class RGWDeleteBucket : public RGWOp { | |
1123 | protected: | |
1124 | RGWObjVersionTracker objv_tracker; | |
1125 | ||
1126 | public: | |
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 | ||
1139 | struct 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 | }; | |
1164 | WRITE_CLASS_ENCODER(rgw_slo_entry) | |
1165 | ||
1166 | struct 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 | }; | |
1190 | WRITE_CLASS_ENCODER(RGWSLOInfo) | |
1191 | ||
1192 | class RGWPutObj : public RGWOp { | |
7c673cae FG |
1193 | protected: |
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 |
1238 | public: |
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 |
1307 | class RGWPostObj : public RGWOp { |
1308 | protected: | |
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 | } | |
1326 | public: | |
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 | ||
1361 | class RGWPutMetadataAccount : public RGWOp { | |
1362 | protected: | |
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 | ||
1372 | public: | |
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 | ||
1397 | class RGWPutMetadataBucket : public RGWOp { | |
1398 | protected: | |
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 | ||
1408 | public: | |
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 | ||
1433 | class RGWPutMetadataObject : public RGWOp { | |
1434 | protected: | |
1435 | RGWAccessControlPolicy policy; | |
7c673cae FG |
1436 | boost::optional<ceph::real_time> delete_at; |
1437 | const char *dlo_manifest; | |
1438 | ||
1439 | public: | |
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 | ||
1460 | class RGWDeleteObj : public RGWOp { | |
1461 | protected: | |
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 | |
1471 | public: | |
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 | ||
1495 | class RGWCopyObj : public RGWOp { | |
1496 | protected: | |
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 | ||
1538 | public: | |
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 | ||
1595 | class RGWGetACLs : public RGWOp { | |
1596 | protected: | |
20effc67 | 1597 | std::string acls; |
7c673cae FG |
1598 | |
1599 | public: | |
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 | ||
1612 | class RGWPutACLs : public RGWOp { | |
1613 | protected: | |
11fdf7f2 | 1614 | bufferlist data; |
7c673cae FG |
1615 | ACLOwner owner; |
1616 | ||
1617 | public: | |
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 | ||
1633 | class RGWGetLC : public RGWOp { | |
1634 | protected: | |
1e59de90 | 1635 | |
7c673cae FG |
1636 | public: |
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 | ||
1650 | class RGWPutLC : public RGWOp { | |
1651 | protected: | |
11fdf7f2 | 1652 | bufferlist data; |
b32b8144 | 1653 | const char *content_md5; |
20effc67 | 1654 | std::string cookie; |
7c673cae FG |
1655 | |
1656 | public: | |
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 | ||
1683 | class RGWDeleteLC : public RGWOp { | |
7c673cae | 1684 | public: |
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 | ||
1696 | class RGWGetCORS : public RGWOp { | |
1697 | protected: | |
1698 | ||
1699 | public: | |
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 | ||
1711 | class RGWPutCORS : public RGWOp { | |
1712 | protected: | |
1713 | bufferlist cors_bl; | |
31f18b77 | 1714 | bufferlist in_data; |
7c673cae FG |
1715 | |
1716 | public: | |
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 | ||
1730 | class RGWDeleteCORS : public RGWOp { | |
1731 | protected: | |
1732 | ||
1733 | public: | |
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 | ||
1745 | class RGWOptionsCORS : public RGWOp { | |
1746 | protected: | |
1747 | RGWCORSRule *rule; | |
1748 | const char *origin, *req_hdrs, *req_meth; | |
1749 | ||
1750 | public: | |
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 |
1765 | class RGWPutBucketEncryption : public RGWOp { |
1766 | protected: | |
1767 | RGWBucketEncryptionConfig bucket_encryption_conf; | |
1768 | bufferlist data; | |
1769 | public: | |
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 | ||
1781 | class RGWGetBucketEncryption : public RGWOp { | |
1782 | protected: | |
1783 | RGWBucketEncryptionConfig bucket_encryption_conf; | |
1784 | public: | |
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 | ||
1795 | class RGWDeleteBucketEncryption : public RGWOp { | |
1796 | protected: | |
1797 | RGWBucketEncryptionConfig bucket_encryption_conf; | |
1798 | public: | |
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 |
1809 | class RGWGetRequestPayment : public RGWOp { |
1810 | protected: | |
1811 | bool requester_pays; | |
1812 | ||
1813 | public: | |
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 | ||
1826 | class RGWSetRequestPayment : public RGWOp { | |
1827 | protected: | |
1828 | bool requester_pays; | |
494da23a | 1829 | bufferlist in_data; |
7c673cae FG |
1830 | public: |
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 | ||
1845 | class RGWInitMultipart : public RGWOp { | |
1846 | protected: | |
20effc67 | 1847 | std::string upload_id; |
7c673cae | 1848 | RGWAccessControlPolicy policy; |
f6b5b4d7 | 1849 | ceph::real_time mtime; |
20effc67 | 1850 | jspan multipart_trace; |
7c673cae FG |
1851 | |
1852 | public: | |
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 | ||
1871 | class RGWCompleteMultipart : public RGWOp { | |
1872 | protected: | |
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 | 1885 | public: |
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 | ||
1902 | class RGWAbortMultipart : public RGWOp { | |
20effc67 TL |
1903 | protected: |
1904 | jspan multipart_trace; | |
7c673cae FG |
1905 | public: |
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 | ||
1918 | class RGWListMultipart : public RGWOp { | |
1919 | protected: | |
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 | |
1928 | public: | |
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 |
1950 | class RGWListBucketMultiparts : public RGWOp { |
1951 | protected: | |
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 | |
1966 | public: | |
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 | ||
1990 | class RGWGetCrossDomainPolicy : public RGWOp { | |
1991 | public: | |
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 | ||
2015 | class RGWGetHealthCheck : public RGWOp { | |
2016 | public: | |
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 | ||
2038 | class 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 | 2062 | protected: |
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 |
2072 | public: |
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 | ||
2098 | class RGWInfo: public RGWOp { | |
2099 | public: | |
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 |
2109 | extern int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, |
2110 | req_state* s, optional_yield y); | |
2111 | extern int rgw_build_object_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, | |
2112 | req_state *s, bool prefetch_data, optional_yield y); | |
2113 | extern void rgw_build_iam_environment(rgw::sal::Driver* driver, | |
2114 | req_state* s); | |
20effc67 TL |
2115 | extern 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 |
2119 | inline 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 | ||
2147 | static 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 |
2177 | inline 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 | 2241 | inline 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 | 2253 | inline 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 | 2267 | inline 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 | 2283 | inline 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 |
2295 | using boost::container::flat_map; |
2296 | ||
2297 | class RGWGetAttrs : public RGWOp { | |
2298 | public: | |
2299 | using get_attrs_t = flat_map<std::string, std::optional<buffer::list>>; | |
2300 | protected: | |
2301 | get_attrs_t attrs; | |
2302 | ||
2303 | public: | |
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 |
2324 | class RGWSetAttrs : public RGWOp { |
2325 | protected: | |
20effc67 | 2326 | std::map<std::string, buffer::list> attrs; |
7c673cae FG |
2327 | |
2328 | public: | |
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 |
2347 | class RGWRMAttrs : public RGWOp { |
2348 | protected: | |
20effc67 | 2349 | rgw::sal::Attrs attrs; |
f67539c2 TL |
2350 | |
2351 | public: | |
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 | 2372 | class RGWGetObjLayout : public RGWOp { |
7c673cae FG |
2373 | public: |
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 | 2391 | class RGWPutBucketPolicy : public RGWOp { |
11fdf7f2 | 2392 | bufferlist data; |
31f18b77 FG |
2393 | public: |
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 |
2410 | class RGWGetBucketPolicy : public RGWOp { |
2411 | buffer::list policy; | |
2412 | public: | |
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 | ||
2426 | class RGWDeleteBucketPolicy : public RGWOp { | |
2427 | public: | |
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 |
2442 | class RGWPutBucketObjectLock : public RGWOp { |
2443 | protected: | |
2444 | bufferlist data; | |
2445 | bufferlist obj_lock_bl; | |
2446 | RGWObjectLock obj_lock; | |
2447 | public: | |
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 | ||
2460 | class RGWGetBucketObjectLock : public RGWOp { | |
2461 | public: | |
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 | ||
2471 | class RGWPutObjRetention : public RGWOp { | |
2472 | protected: | |
2473 | bufferlist data; | |
2474 | RGWObjectRetention obj_retention; | |
2475 | bool bypass_perm; | |
2476 | bool bypass_governance_mode; | |
2477 | public: | |
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 | ||
2489 | class RGWGetObjRetention : public RGWOp { | |
2490 | protected: | |
2491 | RGWObjectRetention obj_retention; | |
2492 | public: | |
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 | ||
2502 | class RGWPutObjLegalHold : public RGWOp { | |
2503 | protected: | |
2504 | bufferlist data; | |
2505 | RGWObjectLegalHold obj_legal_hold; | |
2506 | public: | |
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 | ||
2517 | class RGWGetObjLegalHold : public RGWOp { | |
2518 | protected: | |
2519 | RGWObjectLegalHold obj_legal_hold; | |
2520 | public: | |
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 | |
2531 | class RGWConfigBucketMetaSearch : public RGWOp { | |
2532 | protected: | |
2533 | std::map<std::string, uint32_t> mdsearch_config; | |
2534 | public: | |
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 | ||
2547 | class RGWGetBucketMetaSearch : public RGWOp { | |
2548 | public: | |
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 | ||
2560 | class RGWDelBucketMetaSearch : public RGWOp { | |
2561 | public: | |
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 |
2573 | class RGWGetClusterStat : public RGWOp { |
2574 | protected: | |
f67539c2 | 2575 | RGWClusterStat stats_op; |
28e407b8 AA |
2576 | public: |
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 |
2590 | class RGWGetBucketPolicyStatus : public RGWOp { |
2591 | protected: | |
2592 | bool isPublic {false}; | |
2593 | public: | |
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 | ||
2602 | class RGWPutBucketPublicAccessBlock : public RGWOp { | |
2603 | protected: | |
2604 | bufferlist data; | |
2605 | PublicAccessBlockConfiguration access_conf; | |
2606 | public: | |
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 | ||
2616 | class RGWGetBucketPublicAccessBlock : public RGWOp { | |
2617 | protected: | |
2618 | PublicAccessBlockConfiguration access_conf; | |
2619 | public: | |
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 | ||
2629 | class RGWDeleteBucketPublicAccessBlock : public RGWOp { | |
2630 | protected: | |
2631 | PublicAccessBlockConfiguration access_conf; | |
2632 | public: | |
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 | 2643 | inline 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 |
2674 | int rgw_policy_from_attrset(const DoutPrefixProvider *dpp, |
2675 | CephContext *cct, | |
2676 | std::map<std::string, bufferlist>& attrset, | |
2677 | RGWAccessControlPolicy *policy); |