]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_s3.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / rgw_rest_s3.h
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae 3
9f95a23c 4#pragma once
7c673cae 5
7c673cae
FG
6#define TIME_BUF_SIZE 128
7
8#include <mutex>
f67539c2 9#include <string_view>
7c673cae 10
31f18b77 11#include <boost/container/static_vector.hpp>
f67539c2 12#include <boost/crc.hpp>
31f18b77 13
31f18b77 14#include "common/sstring.hh"
7c673cae
FG
15#include "rgw_op.h"
16#include "rgw_rest.h"
17#include "rgw_http_errors.h"
18#include "rgw_acl_s3.h"
19#include "rgw_policy_s3.h"
20#include "rgw_lc_s3.h"
21#include "rgw_keystone.h"
22#include "rgw_rest_conn.h"
23#include "rgw_ldap.h"
7c673cae
FG
24
25#include "rgw_token.h"
11fdf7f2 26#include "include/ceph_assert.h"
7c673cae
FG
27
28#include "rgw_auth.h"
29#include "rgw_auth_filters.h"
11fdf7f2 30#include "rgw_sts.h"
7c673cae 31
31f18b77
FG
32struct rgw_http_error {
33 int http_ret;
34 const char *s3_code;
35};
36
37void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
7c673cae
FG
38
39class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
40{
41protected:
42 // Serving a custom error page from an object is really a 200 response with
43 // just the status line altered.
44 int custom_http_ret = 0;
45 std::map<std::string, std::string> crypt_http_responses;
f67539c2 46 int override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y);
7c673cae
FG
47public:
48 RGWGetObj_ObjStore_S3() {}
49 ~RGWGetObj_ObjStore_S3() override {}
50
f67539c2
TL
51 int verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) override;
52 int get_params(optional_yield y) override;
53 int send_response_data_error(optional_yield y) override;
7c673cae
FG
54 int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
55 void set_custom_http_response(int http_ret) { custom_http_ret = http_ret; }
11fdf7f2
TL
56 int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
57 RGWGetObj_Filter* cb,
7c673cae
FG
58 bufferlist* manifest_bl) override;
59};
60
224ce89b
WB
61class RGWGetObjTags_ObjStore_S3 : public RGWGetObjTags_ObjStore
62{
224ce89b
WB
63public:
64 RGWGetObjTags_ObjStore_S3() {}
65 ~RGWGetObjTags_ObjStore_S3() {}
66
67 void send_response_data(bufferlist &bl) override;
68};
69
70class RGWPutObjTags_ObjStore_S3 : public RGWPutObjTags_ObjStore
71{
72public:
73 RGWPutObjTags_ObjStore_S3() {}
74 ~RGWPutObjTags_ObjStore_S3() {}
75
f67539c2 76 int get_params(optional_yield y) override;
224ce89b
WB
77 void send_response() override;
78};
79
80class RGWDeleteObjTags_ObjStore_S3 : public RGWDeleteObjTags
81{
82public:
83 ~RGWDeleteObjTags_ObjStore_S3() override {}
84 void send_response() override;
85};
86
9f95a23c
TL
87class RGWGetBucketTags_ObjStore_S3 : public RGWGetBucketTags_ObjStore
88{
89 bufferlist tags_bl;
90public:
91 void send_response_data(bufferlist &bl) override;
92};
93
94class RGWPutBucketTags_ObjStore_S3 : public RGWPutBucketTags_ObjStore
95{
96public:
b3b6e05e 97 int get_params(const DoutPrefixProvider *dpp, optional_yield y) override;
9f95a23c
TL
98 void send_response() override;
99};
100
101class RGWDeleteBucketTags_ObjStore_S3 : public RGWDeleteBucketTags
102{
103public:
104 void send_response() override;
105};
106
107class RGWGetBucketReplication_ObjStore_S3 : public RGWGetBucketReplication_ObjStore
108{
109public:
110 void send_response_data() override;
111};
112
113class RGWPutBucketReplication_ObjStore_S3 : public RGWPutBucketReplication_ObjStore
114{
115public:
f67539c2 116 int get_params(optional_yield y) override;
9f95a23c
TL
117 void send_response() override;
118};
119
120class RGWDeleteBucketReplication_ObjStore_S3 : public RGWDeleteBucketReplication_ObjStore
121{
122protected:
123 void update_sync_policy(rgw_sync_policy_info *policy) override;
124public:
125 void send_response() override;
126};
127
7c673cae
FG
128class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
129public:
130 RGWListBuckets_ObjStore_S3() {}
131 ~RGWListBuckets_ObjStore_S3() override {}
132
f67539c2 133 int get_params(optional_yield y) override {
7c673cae
FG
134 limit = -1; /* no limit */
135 return 0;
136 }
137 void send_response_begin(bool has_buckets) override;
20effc67 138 void send_response_data(rgw::sal::BucketList& buckets) override;
7c673cae
FG
139 void send_response_end() override;
140};
141
142class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
143public:
144 RGWGetUsage_ObjStore_S3() {}
145 ~RGWGetUsage_ObjStore_S3() override {}
146
f67539c2 147 int get_params(optional_yield y) override ;
7c673cae
FG
148 void send_response() override;
149};
150
151class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
92f5a8d4
TL
152protected:
153 bool objs_container;
154 bool encode_key {false};
eafe8130
TL
155 int get_common_params();
156 void send_common_response();
157 void send_common_versioned_response();
158 public:
7c673cae
FG
159 RGWListBucket_ObjStore_S3() : objs_container(false) {
160 default_max = 1000;
161 }
162 ~RGWListBucket_ObjStore_S3() override {}
163
f67539c2 164 int get_params(optional_yield y) override;
7c673cae
FG
165 void send_response() override;
166 void send_versioned_response();
167};
168
eafe8130
TL
169class RGWListBucket_ObjStore_S3v2 : public RGWListBucket_ObjStore_S3 {
170 bool fetchOwner;
171 bool start_after_exist;
172 bool continuation_token_exist;
20effc67
TL
173 std::string startAfter;
174 std::string continuation_token;
eafe8130
TL
175public:
176 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
177 }
178 ~RGWListBucket_ObjStore_S3v2() override {}
179
f67539c2 180 int get_params(optional_yield y) override;
eafe8130
TL
181 void send_response() override;
182 void send_versioned_response();
183};
184
7c673cae
FG
185class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
186public:
187 RGWGetBucketLogging_ObjStore_S3() {}
188 ~RGWGetBucketLogging_ObjStore_S3() override {}
189
190 void send_response() override;
191};
192
193class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
194public:
195 RGWGetBucketLocation_ObjStore_S3() {}
196 ~RGWGetBucketLocation_ObjStore_S3() override {}
197
198 void send_response() override;
199};
200
201class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
202public:
203 RGWGetBucketVersioning_ObjStore_S3() {}
204 ~RGWGetBucketVersioning_ObjStore_S3() override {}
205
206 void send_response() override;
207};
208
209class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
210public:
211 RGWSetBucketVersioning_ObjStore_S3() {}
212 ~RGWSetBucketVersioning_ObjStore_S3() override {}
213
f67539c2 214 int get_params(optional_yield y) override;
7c673cae
FG
215 void send_response() override;
216};
217
218class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
219public:
220 RGWGetBucketWebsite_ObjStore_S3() {}
221 ~RGWGetBucketWebsite_ObjStore_S3() override {}
222
223 void send_response() override;
224};
225
226class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
227public:
228 RGWSetBucketWebsite_ObjStore_S3() {}
229 ~RGWSetBucketWebsite_ObjStore_S3() override {}
230
f67539c2 231 int get_params(optional_yield y) override;
7c673cae
FG
232 void send_response() override;
233};
234
235class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
236public:
237 RGWDeleteBucketWebsite_ObjStore_S3() {}
238 ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
239
240 void send_response() override;
241};
242
243class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
244public:
245 RGWStatBucket_ObjStore_S3() {}
246 ~RGWStatBucket_ObjStore_S3() override {}
247
248 void send_response() override;
249};
250
251class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
252public:
253 RGWCreateBucket_ObjStore_S3() {}
254 ~RGWCreateBucket_ObjStore_S3() override {}
255
f67539c2 256 int get_params(optional_yield y) override;
7c673cae
FG
257 void send_response() override;
258};
259
260class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
261public:
262 RGWDeleteBucket_ObjStore_S3() {}
263 ~RGWDeleteBucket_ObjStore_S3() override {}
264
265 void send_response() override;
266};
267
268class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
269private:
270 std::map<std::string, std::string> crypt_http_responses;
271
272public:
273 RGWPutObj_ObjStore_S3() {}
274 ~RGWPutObj_ObjStore_S3() override {}
275
f67539c2 276 int get_params(optional_yield y) override;
7c673cae
FG
277 int get_data(bufferlist& bl) override;
278 void send_response() override;
279
20effc67
TL
280 int get_encrypt_filter(std::unique_ptr<rgw::sal::DataProcessor> *filter,
281 rgw::sal::DataProcessor *cb) override;
11fdf7f2
TL
282 int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
283 RGWGetObj_Filter* cb,
20effc67 284 std::map<std::string, bufferlist>& attrs,
7c673cae
FG
285 bufferlist* manifest_bl) override;
286};
287
288class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
289 parts_collection_t parts;
290 std::string filename;
291 std::string content_type;
292 RGWPolicyEnv env;
293 RGWPolicy post_policy;
20effc67 294 std::map<std::string, std::string> crypt_http_responses;
7c673cae
FG
295
296 const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
297
f67539c2 298 int get_policy(optional_yield y);
224ce89b 299 int get_tags();
20effc67 300 void rebuild_key(rgw::sal::Object* obj);
7c673cae
FG
301
302 std::string get_current_filename() const override;
303 std::string get_current_content_type() const override;
304
305public:
306 RGWPostObj_ObjStore_S3() {}
307 ~RGWPostObj_ObjStore_S3() override {}
308
f67539c2 309 int verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) override {
7c673cae 310 auth_registry_ptr = &auth_registry;
f67539c2 311 return RGWPostObj_ObjStore::verify_requester(auth_registry, y);
7c673cae
FG
312 }
313
f67539c2 314 int get_params(optional_yield y) override;
7c673cae
FG
315 int complete_get_params();
316
317 void send_response() override;
318 int get_data(ceph::bufferlist& bl, bool& again) override;
20effc67
TL
319 int get_encrypt_filter(std::unique_ptr<rgw::sal::DataProcessor> *filter,
320 rgw::sal::DataProcessor *cb) override;
7c673cae
FG
321};
322
323class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
324public:
325 RGWDeleteObj_ObjStore_S3() {}
326 ~RGWDeleteObj_ObjStore_S3() override {}
327
f67539c2 328 int get_params(optional_yield y) override;
7c673cae
FG
329 void send_response() override;
330};
331
332class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
333 bool sent_header;
334public:
335 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
336 ~RGWCopyObj_ObjStore_S3() override {}
337
338 int init_dest_policy() override;
f67539c2
TL
339 int get_params(optional_yield y) override;
340 int check_storage_class(const rgw_placement_rule& src_placement) override;
7c673cae
FG
341 void send_partial_response(off_t ofs) override;
342 void send_response() override;
343};
344
345class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
346public:
347 RGWGetACLs_ObjStore_S3() {}
348 ~RGWGetACLs_ObjStore_S3() override {}
349
350 void send_response() override;
351};
352
353class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
354public:
355 RGWPutACLs_ObjStore_S3() {}
356 ~RGWPutACLs_ObjStore_S3() override {}
357
20effc67 358 int get_policy_from_state(rgw::sal::Store* store, struct req_state *s, std::stringstream& ss) override;
7c673cae 359 void send_response() override;
f67539c2 360 int get_params(optional_yield y) override;
7c673cae
FG
361};
362
363class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
364protected:
11fdf7f2 365 RGWLifecycleConfiguration_S3 config;
7c673cae
FG
366public:
367 RGWGetLC_ObjStore_S3() {}
368 ~RGWGetLC_ObjStore_S3() override {}
f67539c2 369 void execute(optional_yield y) override;
7c673cae
FG
370
371 void send_response() override;
372};
373
374class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
375public:
376 RGWPutLC_ObjStore_S3() {}
377 ~RGWPutLC_ObjStore_S3() override {}
f67539c2 378
7c673cae
FG
379 void send_response() override;
380};
381
382class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
383public:
384 RGWDeleteLC_ObjStore_S3() {}
385 ~RGWDeleteLC_ObjStore_S3() override {}
f67539c2 386
7c673cae
FG
387 void send_response() override;
388};
389
390class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
391public:
392 RGWGetCORS_ObjStore_S3() {}
393 ~RGWGetCORS_ObjStore_S3() override {}
394
395 void send_response() override;
396};
397
398class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
399public:
400 RGWPutCORS_ObjStore_S3() {}
401 ~RGWPutCORS_ObjStore_S3() override {}
402
f67539c2 403 int get_params(optional_yield y) override;
7c673cae
FG
404 void send_response() override;
405};
406
407class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
408public:
409 RGWDeleteCORS_ObjStore_S3() {}
410 ~RGWDeleteCORS_ObjStore_S3() override {}
411
412 void send_response() override;
413};
414
415class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
416public:
417 RGWOptionsCORS_ObjStore_S3() {}
418 ~RGWOptionsCORS_ObjStore_S3() override {}
419
420 void send_response() override;
421};
422
20effc67
TL
423class RGWGetBucketEncryption_ObjStore_S3 : public RGWGetBucketEncryption_ObjStore {
424public:
425 RGWGetBucketEncryption_ObjStore_S3() {}
426 ~RGWGetBucketEncryption_ObjStore_S3() override {}
427
428 void send_response() override;
429};
430
431class RGWPutBucketEncryption_ObjStore_S3 : public RGWPutBucketEncryption_ObjStore {
432public:
433 RGWPutBucketEncryption_ObjStore_S3() {}
434 ~RGWPutBucketEncryption_ObjStore_S3() override {}
435
436 void send_response() override;
437};
438
439class RGWDeleteBucketEncryption_ObjStore_S3 : public RGWDeleteBucketEncryption_ObjStore {
440public:
441 RGWDeleteBucketEncryption_ObjStore_S3() {}
442 ~RGWDeleteBucketEncryption_ObjStore_S3() override {}
443
444 void send_response() override;
445};
446
7c673cae
FG
447class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
448public:
449 RGWGetRequestPayment_ObjStore_S3() {}
450 ~RGWGetRequestPayment_ObjStore_S3() override {}
451
452 void send_response() override;
453};
454
455class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
456public:
457 RGWSetRequestPayment_ObjStore_S3() {}
458 ~RGWSetRequestPayment_ObjStore_S3() override {}
459
f67539c2 460 int get_params(optional_yield y) override;
7c673cae
FG
461 void send_response() override;
462};
463
464class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
465private:
466 std::map<std::string, std::string> crypt_http_responses;
467public:
468 RGWInitMultipart_ObjStore_S3() {}
469 ~RGWInitMultipart_ObjStore_S3() override {}
470
f67539c2 471 int get_params(optional_yield y) override;
7c673cae 472 void send_response() override;
20effc67 473 int prepare_encryption(std::map<std::string, bufferlist>& attrs) override;
7c673cae
FG
474};
475
476class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
477public:
478 RGWCompleteMultipart_ObjStore_S3() {}
479 ~RGWCompleteMultipart_ObjStore_S3() override {}
480
f67539c2 481 int get_params(optional_yield y) override;
7c673cae
FG
482 void send_response() override;
483};
484
485class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
486public:
487 RGWAbortMultipart_ObjStore_S3() {}
488 ~RGWAbortMultipart_ObjStore_S3() override {}
489
490 void send_response() override;
491};
492
493class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
494public:
495 RGWListMultipart_ObjStore_S3() {}
496 ~RGWListMultipart_ObjStore_S3() override {}
497
498 void send_response() override;
499};
500
501class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
502public:
503 RGWListBucketMultiparts_ObjStore_S3() {
504 default_max = 1000;
505 }
506 ~RGWListBucketMultiparts_ObjStore_S3() override {}
507
508 void send_response() override;
509};
510
511class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
512public:
513 RGWDeleteMultiObj_ObjStore_S3() {}
514 ~RGWDeleteMultiObj_ObjStore_S3() override {}
515
f67539c2 516 int get_params(optional_yield y) override;
7c673cae
FG
517 void send_status() override;
518 void begin_response() override;
519 void send_partial_response(rgw_obj_key& key, bool delete_marker,
20effc67 520 const std::string& marker_version_id, int ret) override;
7c673cae
FG
521 void end_response() override;
522};
523
eafe8130
TL
524class RGWPutBucketObjectLock_ObjStore_S3 : public RGWPutBucketObjectLock_ObjStore {
525public:
526 RGWPutBucketObjectLock_ObjStore_S3() {}
527 ~RGWPutBucketObjectLock_ObjStore_S3() override {}
528 void send_response() override;
529};
530
531class RGWGetBucketObjectLock_ObjStore_S3 : public RGWGetBucketObjectLock_ObjStore {
532public:
533 RGWGetBucketObjectLock_ObjStore_S3() {}
534 ~RGWGetBucketObjectLock_ObjStore_S3() {}
535 void send_response() override;
536};
537
538class RGWPutObjRetention_ObjStore_S3 : public RGWPutObjRetention_ObjStore {
539public:
540 RGWPutObjRetention_ObjStore_S3() {}
541 ~RGWPutObjRetention_ObjStore_S3() {}
f67539c2 542 int get_params(optional_yield y) override;
eafe8130
TL
543 void send_response() override;
544};
545
546class RGWGetObjRetention_ObjStore_S3 : public RGWGetObjRetention_ObjStore {
547public:
548 RGWGetObjRetention_ObjStore_S3() {}
549 ~RGWGetObjRetention_ObjStore_S3() {}
550 void send_response() override;
551};
552
553class RGWPutObjLegalHold_ObjStore_S3 : public RGWPutObjLegalHold_ObjStore {
554public:
555 RGWPutObjLegalHold_ObjStore_S3() {}
556 ~RGWPutObjLegalHold_ObjStore_S3() {}
557 void send_response() override;
558};
559
560class RGWGetObjLegalHold_ObjStore_S3 : public RGWGetObjLegalHold_ObjStore {
561public:
562 RGWGetObjLegalHold_ObjStore_S3() {}
563 ~RGWGetObjLegalHold_ObjStore_S3() {}
564 void send_response() override;
565};
566
7c673cae
FG
567class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
568public:
569 RGWGetObjLayout_ObjStore_S3() {}
570 ~RGWGetObjLayout_ObjStore_S3() {}
571
11fdf7f2 572 void send_response() override;
7c673cae
FG
573};
574
31f18b77
FG
575class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
576public:
577 RGWConfigBucketMetaSearch_ObjStore_S3() {}
578 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
579
f67539c2 580 int get_params(optional_yield y) override;
31f18b77
FG
581 void send_response() override;
582};
583
584class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
585public:
586 RGWGetBucketMetaSearch_ObjStore_S3() {}
587 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
588
589 void send_response() override;
590};
591
592class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
593public:
594 RGWDelBucketMetaSearch_ObjStore_S3() {}
595 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
596
597 void send_response() override;
598};
7c673cae 599
9f95a23c
TL
600class RGWGetBucketPolicyStatus_ObjStore_S3 : public RGWGetBucketPolicyStatus {
601public:
602 void send_response() override;
603};
604
605class RGWPutBucketPublicAccessBlock_ObjStore_S3 : public RGWPutBucketPublicAccessBlock {
606public:
607 void send_response() override;
608};
609
610class RGWGetBucketPublicAccessBlock_ObjStore_S3 : public RGWGetBucketPublicAccessBlock {
611public:
612 void send_response() override;
613};
614
7c673cae 615class RGW_Auth_S3 {
7c673cae 616public:
11fdf7f2 617 static int authorize(const DoutPrefixProvider *dpp,
20effc67 618 rgw::sal::Store* store,
7c673cae 619 const rgw::auth::StrategyRegistry& auth_registry,
f67539c2 620 struct req_state *s, optional_yield y);
7c673cae
FG
621};
622
623class RGWHandler_Auth_S3 : public RGWHandler_REST {
624 friend class RGWRESTMgr_S3;
625
626 const rgw::auth::StrategyRegistry& auth_registry;
627
628public:
11fdf7f2 629 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
7c673cae
FG
630 : RGWHandler_REST(),
631 auth_registry(auth_registry) {
632 }
633 ~RGWHandler_Auth_S3() override = default;
634
20effc67
TL
635 static int validate_bucket_name(const std::string& bucket);
636 static int validate_object_name(const std::string& bucket);
7c673cae 637
20effc67 638 int init(rgw::sal::Store* store,
7c673cae
FG
639 struct req_state *s,
640 rgw::io::BasicClient *cio) override;
f67539c2
TL
641 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override {
642 return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
7c673cae 643 }
f67539c2 644 int postauth_init(optional_yield) override { return 0; }
7c673cae
FG
645};
646
647class RGWHandler_REST_S3 : public RGWHandler_REST {
648 friend class RGWRESTMgr_S3;
11fdf7f2 649protected:
7c673cae
FG
650 const rgw::auth::StrategyRegistry& auth_registry;
651public:
20effc67 652 static int init_from_header(rgw::sal::Store* store, struct req_state *s, int default_formatter, bool configurable_format);
7c673cae 653
11fdf7f2 654 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
7c673cae
FG
655 : RGWHandler_REST(),
656 auth_registry(auth_registry) {
11fdf7f2 657 }
7c673cae
FG
658 ~RGWHandler_REST_S3() override = default;
659
20effc67 660 int init(rgw::sal::Store* store,
7c673cae
FG
661 struct req_state *s,
662 rgw::io::BasicClient *cio) override;
f67539c2
TL
663 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
664 int postauth_init(optional_yield y) override;
7c673cae
FG
665};
666
667class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
668protected:
9f95a23c
TL
669 const bool isSTSEnabled;
670 const bool isIAMEnabled;
671 const bool isPSEnabled;
672 bool is_usage_op() const {
7c673cae
FG
673 return s->info.args.exists("usage");
674 }
675 RGWOp *op_get() override;
676 RGWOp *op_head() override;
677 RGWOp *op_post() override;
678public:
11fdf7f2 679 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry& auth_registry,
9f95a23c
TL
680 bool _isSTSEnabled, bool _isIAMEnabled, bool _isPSEnabled) :
681 RGWHandler_REST_S3(auth_registry), isSTSEnabled(_isSTSEnabled), isIAMEnabled(_isIAMEnabled), isPSEnabled(_isPSEnabled) {}
7c673cae
FG
682 ~RGWHandler_REST_Service_S3() override = default;
683};
684
685class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
eafe8130 686 const bool enable_pubsub;
7c673cae 687protected:
9f95a23c 688 bool is_acl_op() const {
7c673cae
FG
689 return s->info.args.exists("acl");
690 }
9f95a23c 691 bool is_cors_op() const {
7c673cae
FG
692 return s->info.args.exists("cors");
693 }
9f95a23c 694 bool is_lc_op() const {
7c673cae
FG
695 return s->info.args.exists("lifecycle");
696 }
9f95a23c 697 bool is_obj_update_op() const override {
7c673cae
FG
698 return is_acl_op() || is_cors_op();
699 }
9f95a23c
TL
700 bool is_tagging_op() const {
701 return s->info.args.exists("tagging");
702 }
703 bool is_request_payment_op() const {
7c673cae
FG
704 return s->info.args.exists("requestPayment");
705 }
9f95a23c 706 bool is_policy_op() const {
31f18b77
FG
707 return s->info.args.exists("policy");
708 }
9f95a23c 709 bool is_object_lock_op() const {
eafe8130
TL
710 return s->info.args.exists("object-lock");
711 }
712 bool is_notification_op() const {
713 if (enable_pubsub) {
714 return s->info.args.exists("notification");
715 }
716 return false;
717 }
9f95a23c
TL
718 bool is_replication_op() const {
719 return s->info.args.exists("replication");
720 }
721 bool is_policy_status_op() {
722 return s->info.args.exists("policyStatus");
723 }
724 bool is_block_public_access_op() {
725 return s->info.args.exists("publicAccessBlock");
726 }
20effc67
TL
727 bool is_bucket_encryption_op() {
728 return s->info.args.exists("encryption");
729 }
7c673cae 730
9f95a23c 731 RGWOp *get_obj_op(bool get_data) const;
7c673cae
FG
732 RGWOp *op_get() override;
733 RGWOp *op_head() override;
734 RGWOp *op_put() override;
735 RGWOp *op_delete() override;
736 RGWOp *op_post() override;
737 RGWOp *op_options() override;
738public:
eafe8130
TL
739 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry& auth_registry, bool _enable_pubsub) :
740 RGWHandler_REST_S3(auth_registry), enable_pubsub(_enable_pubsub) {}
7c673cae
FG
741 ~RGWHandler_REST_Bucket_S3() override = default;
742};
743
744class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
745protected:
9f95a23c 746 bool is_acl_op() const {
7c673cae
FG
747 return s->info.args.exists("acl");
748 }
9f95a23c 749 bool is_tagging_op() const {
224ce89b
WB
750 return s->info.args.exists("tagging");
751 }
9f95a23c 752 bool is_obj_retention_op() const {
eafe8130
TL
753 return s->info.args.exists("retention");
754 }
9f95a23c 755 bool is_obj_legal_hold_op() const {
eafe8130
TL
756 return s->info.args.exists("legal-hold");
757 }
758
f67539c2
TL
759 bool is_select_op() const {
760 return s->info.args.exists("select-type");
761 }
762
9f95a23c 763 bool is_obj_update_op() const override {
f67539c2 764 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op() || is_select_op();
7c673cae
FG
765 }
766 RGWOp *get_obj_op(bool get_data);
767
768 RGWOp *op_get() override;
769 RGWOp *op_head() override;
770 RGWOp *op_put() override;
771 RGWOp *op_delete() override;
772 RGWOp *op_post() override;
773 RGWOp *op_options() override;
774public:
775 using RGWHandler_REST_S3::RGWHandler_REST_S3;
776 ~RGWHandler_REST_Obj_S3() override = default;
777};
778
779class RGWRESTMgr_S3 : public RGWRESTMgr {
780private:
9f95a23c
TL
781 const bool enable_s3website;
782 const bool enable_sts;
783 const bool enable_iam;
eafe8130 784 const bool enable_pubsub;
7c673cae 785public:
9f95a23c
TL
786 explicit RGWRESTMgr_S3(bool _enable_s3website=false, bool _enable_sts=false, bool _enable_iam=false, bool _enable_pubsub=false)
787 : enable_s3website(_enable_s3website),
788 enable_sts(_enable_sts),
789 enable_iam(_enable_iam),
eafe8130 790 enable_pubsub(_enable_pubsub) {
7c673cae
FG
791 }
792
793 ~RGWRESTMgr_S3() override = default;
794
20effc67 795 RGWHandler_REST *get_handler(rgw::sal::Store* store,
f67539c2 796 struct req_state* s,
7c673cae
FG
797 const rgw::auth::StrategyRegistry& auth_registry,
798 const std::string& frontend_prefix) override;
799};
800
801class RGWHandler_REST_Obj_S3Website;
802
803static inline bool looks_like_ip_address(const char *bucket)
804{
9f95a23c
TL
805 struct in6_addr a;
806 if (inet_pton(AF_INET6, bucket, static_cast<void*>(&a)) == 1) {
807 return true;
808 }
7c673cae
FG
809 int num_periods = 0;
810 bool expect_period = false;
811 for (const char *b = bucket; *b; ++b) {
812 if (*b == '.') {
813 if (!expect_period)
814 return false;
815 ++num_periods;
816 if (num_periods > 3)
817 return false;
818 expect_period = false;
819 }
820 else if (isdigit(*b)) {
821 expect_period = true;
822 }
823 else {
824 return false;
825 }
826 }
827 return (num_periods == 3);
828}
829
20effc67 830inline int valid_s3_object_name(const std::string& name) {
7c673cae
FG
831 if (name.size() > 1024) {
832 return -ERR_INVALID_OBJECT_NAME;
833 }
834 if (check_utf8(name.c_str(), name.size())) {
835 return -ERR_INVALID_OBJECT_NAME;
836 }
837 return 0;
838}
839
20effc67 840inline int valid_s3_bucket_name(const std::string& name, bool relaxed=false)
7c673cae
FG
841{
842 // This function enforces Amazon's spec for bucket names.
843 // (The requirements, not the recommendations.)
844 int len = name.size();
9f95a23c
TL
845 int max = (relaxed ? 255 : 63);
846
7c673cae
FG
847 if (len < 3) {
848 // Name too short
849 return -ERR_INVALID_BUCKET_NAME;
9f95a23c 850 } else if (len > max) {
7c673cae
FG
851 // Name too long
852 return -ERR_INVALID_BUCKET_NAME;
853 }
854
9f95a23c 855 // bucket names must start with a number or letter
7c673cae
FG
856 if (!(isalpha(name[0]) || isdigit(name[0]))) {
857 if (!relaxed)
858 return -ERR_INVALID_BUCKET_NAME;
859 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
860 return -ERR_INVALID_BUCKET_NAME;
861 }
862
9f95a23c
TL
863 // bucket names must end with a number or letter
864 if (!(isalpha(name[len-1]) || isdigit(name[len-1])))
865 if (!relaxed)
866 return -ERR_INVALID_BUCKET_NAME;
867
7c673cae
FG
868 for (const char *s = name.c_str(); *s; ++s) {
869 char c = *s;
9f95a23c 870 if (isdigit(c))
7c673cae 871 continue;
9f95a23c
TL
872
873 if (isalpha(c)) {
874 // name cannot contain uppercase letters
875 if (relaxed || islower(c))
876 continue;
877 }
878
879 if (c == '_')
880 // name cannot contain underscore
881 if (relaxed)
882 continue;
883
884 if (c == '-')
7c673cae 885 continue;
9f95a23c
TL
886
887 if (c == '.') {
888 if (!relaxed && s && *s) {
889 // name cannot have consecutive periods or dashes
890 // adjacent to periods
891 // ensure s is neither the first nor the last character
892 char p = *(s-1);
893 char n = *(s+1);
894 if ((p != '-') && (n != '.') && (n != '-'))
895 continue;
896 } else {
897 continue;
898 }
899 }
900
7c673cae
FG
901 // Invalid character
902 return -ERR_INVALID_BUCKET_NAME;
903 }
904
905 if (looks_like_ip_address(name.c_str()))
906 return -ERR_INVALID_BUCKET_NAME;
907
908 return 0;
909}
910
9f95a23c 911namespace rgw::auth::s3 {
7c673cae 912
31f18b77 913class AWSEngine : public rgw::auth::Engine {
7c673cae 914public:
31f18b77
FG
915 class VersionAbstractor {
916 static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
917 static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
918
919 /* Knowing the signature max size allows us to employ the sstring, and thus
920 * avoid dynamic allocations. The multiplier comes from representing digest
921 * in the base64-encoded form. */
922 static constexpr size_t SIGNATURE_MAX_SIZE = \
11fdf7f2 923 std::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
31f18b77 924
7c673cae 925 public:
31f18b77 926 virtual ~VersionAbstractor() {};
7c673cae 927
f67539c2
TL
928 using access_key_id_t = std::string_view;
929 using client_signature_t = std::string_view;
930 using session_token_t = std::string_view;
31f18b77 931 using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
7c673cae
FG
932 using string_to_sign_t = std::string;
933
31f18b77
FG
934 /* Transformation for crafting the AWS signature at server side which is
935 * used later to compare with the user-provided one. The methodology for
936 * doing that depends on AWS auth version. */
937 using signature_factory_t = \
938 std::function<server_signature_t(CephContext* cct,
939 const std::string& secret_key,
940 const string_to_sign_t& string_to_sign)>;
941
942 /* Return an instance of Completer for verifying the payload's fingerprint
943 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
944 * key */
945 using completer_factory_t = \
946 std::function<rgw::auth::Completer::cmplptr_t(
947 const boost::optional<std::string>& secret_key)>;
948
224ce89b
WB
949 struct auth_data_t {
950 access_key_id_t access_key_id;
951 client_signature_t client_signature;
11fdf7f2 952 session_token_t session_token;
224ce89b
WB
953 string_to_sign_t string_to_sign;
954 signature_factory_t signature_factory;
955 completer_factory_t completer_factory;
956 };
957
958 virtual auth_data_t get_auth_data(const req_state* s) const = 0;
7c673cae
FG
959 };
960
961protected:
962 CephContext* cct;
31f18b77 963 const VersionAbstractor& ver_abstractor;
7c673cae 964
31f18b77 965 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
7c673cae 966 : cct(cct),
31f18b77 967 ver_abstractor(ver_abstractor) {
7c673cae
FG
968 }
969
970 using result_t = rgw::auth::Engine::result_t;
31f18b77
FG
971 using string_to_sign_t = VersionAbstractor::string_to_sign_t;
972 using signature_factory_t = VersionAbstractor::signature_factory_t;
973 using completer_factory_t = VersionAbstractor::completer_factory_t;
974
975 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
976 * the signature get_auth_data() of VersionAbstractor is too complicated.
977 * Replace these thing with a simple, dedicated structure. */
11fdf7f2 978 virtual result_t authenticate(const DoutPrefixProvider* dpp,
f67539c2
TL
979 const std::string_view& access_key_id,
980 const std::string_view& signature,
981 const std::string_view& session_token,
31f18b77
FG
982 const string_to_sign_t& string_to_sign,
983 const signature_factory_t& signature_factory,
984 const completer_factory_t& completer_factory,
f67539c2
TL
985 const req_state* s,
986 optional_yield y) const = 0;
7c673cae
FG
987
988public:
f67539c2
TL
989 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
990 optional_yield y) const final;
7c673cae
FG
991};
992
31f18b77
FG
993
994class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
995 CephContext* const cct;
996
31f18b77
FG
997 virtual boost::optional<std::string>
998 get_v4_canonical_headers(const req_info& info,
f67539c2 999 const std::string_view& signedheaders,
31f18b77
FG
1000 const bool using_qs) const;
1001
224ce89b 1002 auth_data_t get_auth_data_v2(const req_state* s) const;
11fdf7f2 1003 auth_data_t get_auth_data_v4(const req_state* s, const bool using_qs) const;
31f18b77 1004
7c673cae 1005public:
11fdf7f2 1006 explicit AWSGeneralAbstractor(CephContext* const cct)
7c673cae
FG
1007 : cct(cct) {
1008 }
1009
224ce89b 1010 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
1011};
1012
31f18b77
FG
1013class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
1014 boost::optional<std::string>
1015 get_v4_canonical_headers(const req_info& info,
f67539c2 1016 const std::string_view& signedheaders,
31f18b77
FG
1017 const bool using_qs) const override;
1018
1019public:
1020 using AWSGeneralAbstractor::AWSGeneralAbstractor;
1021};
7c673cae 1022
31f18b77 1023class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
1024 static std::string to_string(ceph::bufferlist bl) {
1025 return std::string(bl.c_str(),
1026 static_cast<std::string::size_type>(bl.length()));
1027 }
1028
31f18b77
FG
1029 auth_data_t get_auth_data_v2(const req_state* s) const;
1030 auth_data_t get_auth_data_v4(const req_state* s) const;
1031
7c673cae 1032public:
11fdf7f2 1033 explicit AWSBrowserUploadAbstractor(CephContext*) {
7c673cae
FG
1034 }
1035
224ce89b 1036 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
1037};
1038
20effc67
TL
1039class AWSSignerV4 {
1040 const DoutPrefixProvider *dpp;
1041 CephContext *cct;
1042
1043public:
1044 AWSSignerV4(const DoutPrefixProvider *_dpp) : dpp(_dpp),
1045 cct(_dpp->get_cct()) {}
1046
1047 using access_key_id_t = std::string_view;
1048 using string_to_sign_t = AWSEngine::VersionAbstractor::string_to_sign_t;
1049 using signature_headers_t = std::map<std::string, std::string>;
1050
1051 struct prepare_result_t;
1052
1053 using signature_factory_t = \
1054 std::function<signature_headers_t(const DoutPrefixProvider* dpp,
1055 const std::string& secret_key,
1056 const prepare_result_t&)>;
1057
1058 struct prepare_result_t {
1059 access_key_id_t access_key_id;
1060 std::string date;
1061 std::string scope;
1062 std::string signed_headers;
1063 string_to_sign_t string_to_sign;
1064 std::map<std::string, std::string> extra_headers;
1065 signature_factory_t signature_factory;
1066 };
1067
1068 static prepare_result_t prepare(const DoutPrefixProvider *dpp,
1069 const std::string& access_key_id,
1070 const string& region,
1071 const string& service,
1072 const req_info& info,
1073 const bufferlist *opt_content,
1074 bool s3_op);
1075};
1076
1077
1078extern AWSSignerV4::signature_headers_t
1079gen_v4_signature(const DoutPrefixProvider *dpp,
1080 const std::string_view& secret_key,
1081 const AWSSignerV4::prepare_result_t& sig_info);
7c673cae 1082
31f18b77 1083class LDAPEngine : public AWSEngine {
7c673cae
FG
1084 static rgw::LDAPHelper* ldh;
1085 static std::mutex mtx;
1086
1087 static void init(CephContext* const cct);
1088
1089 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1090 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1091 using result_t = rgw::auth::Engine::result_t;
1092
1093protected:
20effc67 1094 rgw::sal::Store* store;
7c673cae
FG
1095 const rgw::auth::RemoteApplier::Factory* const apl_factory;
1096
1097 acl_strategy_t get_acl_strategy() const;
1098 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
1099
11fdf7f2 1100 result_t authenticate(const DoutPrefixProvider* dpp,
f67539c2
TL
1101 const std::string_view& access_key_id,
1102 const std::string_view& signature,
1103 const std::string_view& session_token,
31f18b77
FG
1104 const string_to_sign_t& string_to_sign,
1105 const signature_factory_t&,
1106 const completer_factory_t& completer_factory,
f67539c2
TL
1107 const req_state* s,
1108 optional_yield y) const override;
7c673cae
FG
1109public:
1110 LDAPEngine(CephContext* const cct,
20effc67 1111 rgw::sal::Store* store,
31f18b77 1112 const VersionAbstractor& ver_abstractor,
7c673cae 1113 const rgw::auth::RemoteApplier::Factory* const apl_factory)
31f18b77 1114 : AWSEngine(cct, ver_abstractor),
20effc67 1115 store(store),
7c673cae
FG
1116 apl_factory(apl_factory) {
1117 init(cct);
1118 }
1119
31f18b77 1120 using AWSEngine::authenticate;
7c673cae
FG
1121
1122 const char* get_name() const noexcept override {
1123 return "rgw::auth::s3::LDAPEngine";
1124 }
a8e16298
TL
1125
1126 static bool valid();
11fdf7f2 1127 static void shutdown();
7c673cae
FG
1128};
1129
31f18b77 1130class LocalEngine : public AWSEngine {
20effc67 1131 rgw::sal::Store* store;
7c673cae
FG
1132 const rgw::auth::LocalApplier::Factory* const apl_factory;
1133
11fdf7f2 1134 result_t authenticate(const DoutPrefixProvider* dpp,
f67539c2
TL
1135 const std::string_view& access_key_id,
1136 const std::string_view& signature,
1137 const std::string_view& session_token,
31f18b77
FG
1138 const string_to_sign_t& string_to_sign,
1139 const signature_factory_t& signature_factory,
1140 const completer_factory_t& completer_factory,
f67539c2
TL
1141 const req_state* s,
1142 optional_yield y) const override;
7c673cae 1143public:
31f18b77 1144 LocalEngine(CephContext* const cct,
20effc67 1145 rgw::sal::Store* store,
31f18b77
FG
1146 const VersionAbstractor& ver_abstractor,
1147 const rgw::auth::LocalApplier::Factory* const apl_factory)
1148 : AWSEngine(cct, ver_abstractor),
20effc67 1149 store(store),
7c673cae
FG
1150 apl_factory(apl_factory) {
1151 }
1152
31f18b77 1153 using AWSEngine::authenticate;
7c673cae
FG
1154
1155 const char* get_name() const noexcept override {
31f18b77 1156 return "rgw::auth::s3::LocalEngine";
7c673cae
FG
1157 }
1158};
1159
11fdf7f2 1160class STSEngine : public AWSEngine {
20effc67 1161 rgw::sal::Store* store;
11fdf7f2
TL
1162 const rgw::auth::LocalApplier::Factory* const local_apl_factory;
1163 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory;
1164 const rgw::auth::RoleApplier::Factory* const role_apl_factory;
1165
1166 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1167 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1168
1169 acl_strategy_t get_acl_strategy() const { return nullptr; };
1170 auth_info_t get_creds_info(const STS::SessionToken& token) const noexcept;
1171
f67539c2 1172 int get_session_token(const DoutPrefixProvider* dpp, const std::string_view& session_token,
11fdf7f2
TL
1173 STS::SessionToken& token) const;
1174
1175 result_t authenticate(const DoutPrefixProvider* dpp,
f67539c2
TL
1176 const std::string_view& access_key_id,
1177 const std::string_view& signature,
1178 const std::string_view& session_token,
11fdf7f2
TL
1179 const string_to_sign_t& string_to_sign,
1180 const signature_factory_t& signature_factory,
1181 const completer_factory_t& completer_factory,
f67539c2
TL
1182 const req_state* s,
1183 optional_yield y) const override;
11fdf7f2
TL
1184public:
1185 STSEngine(CephContext* const cct,
20effc67 1186 rgw::sal::Store* store,
11fdf7f2
TL
1187 const VersionAbstractor& ver_abstractor,
1188 const rgw::auth::LocalApplier::Factory* const local_apl_factory,
1189 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory,
1190 const rgw::auth::RoleApplier::Factory* const role_apl_factory)
1191 : AWSEngine(cct, ver_abstractor),
20effc67 1192 store(store),
11fdf7f2
TL
1193 local_apl_factory(local_apl_factory),
1194 remote_apl_factory(remote_apl_factory),
1195 role_apl_factory(role_apl_factory) {
1196 }
1197
1198 using AWSEngine::authenticate;
1199
1200 const char* get_name() const noexcept override {
1201 return "rgw::auth::s3::STSEngine";
1202 }
1203};
7c673cae 1204
d2e6a577
FG
1205class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
1206 bool is_applicable(const req_state* s) const noexcept override;
1207
1208public:
1209 /* Let's reuse the parent class' constructor. */
1210 using rgw::auth::AnonymousEngine::AnonymousEngine;
1211
1212 const char* get_name() const noexcept override {
1213 return "rgw::auth::s3::S3AnonymousEngine";
1214 }
1215};
1216
1217
9f95a23c 1218} // namespace rgw::auth::s3