]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_oidc_provider.cc
b9aceac83d04d2173b98aeafe1c56d9930c1b80e
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
8 #include "common/errno.h"
9 #include "common/Formatter.h"
10 #include "common/ceph_json.h"
11 #include "common/ceph_time.h"
12 #include "rgw_rados.h"
15 #include "include/types.h"
16 #include "rgw_string.h"
18 #include "rgw_common.h"
19 #include "rgw_tools.h"
20 #include "rgw_oidc_provider.h"
22 #include "services/svc_zone.h"
23 #include "services/svc_sys_obj.h"
25 #define dout_subsys ceph_subsys_rgw
27 const string
RGWOIDCProvider::oidc_url_oid_prefix
= "oidc_url.";
28 const string
RGWOIDCProvider::oidc_arn_prefix
= "arn:aws:iam::";
30 int RGWOIDCProvider::store_url(const string
& url
, bool exclusive
,
34 string oid
= tenant
+ get_url_oid_prefix() + url
;
40 auto obj_ctx
= svc
->sysobj
->init_obj_ctx();
41 return rgw_put_system_obj(obj_ctx
, svc
->zone
->get_zone_params().oidc_pool
, oid
,
42 bl
, exclusive
, NULL
, real_time(), y
);
45 int RGWOIDCProvider::get_tenant_url_from_arn(string
& tenant
, string
& url
)
47 auto provider_arn
= rgw::ARN::parse(arn
);
51 url
= provider_arn
->resource
;
52 tenant
= provider_arn
->account
;
53 auto pos
= url
.find("oidc-provider/");
54 if (pos
!= std::string::npos
) {
60 int RGWOIDCProvider::create(bool exclusive
, optional_yield y
)
64 if (! validate_input()) {
68 string idp_url
= url_remove_prefix(provider_url
);
70 /* check to see the name is not used */
71 ret
= read_url(idp_url
, tenant
);
72 if (exclusive
&& ret
== 0) {
73 ldout(cct
, 0) << "ERROR: url " << provider_url
<< " already in use"
76 } else if ( ret
< 0 && ret
!= -ENOENT
) {
77 ldout(cct
, 0) << "failed reading provider url " << provider_url
<< ": "
78 << cpp_strerror(-ret
) << dendl
;
83 arn
= oidc_arn_prefix
+ tenant
+ ":oidc-provider/" + idp_url
;
86 real_clock::time_point t
= real_clock::now();
89 real_clock::to_timeval(t
, tv
);
93 gmtime_r(&tv
.tv_sec
, &result
);
94 strftime(buf
,30,"%Y-%m-%dT%H:%M:%S", &result
);
95 sprintf(buf
+ strlen(buf
),".%dZ",(int)tv
.tv_usec
/1000);
96 creation_date
.assign(buf
, strlen(buf
));
100 auto& pool
= svc
->zone
->get_zone_params().oidc_pool
;
101 ret
= store_url(idp_url
, exclusive
, y
);
103 ldout(cct
, 0) << "ERROR: storing role info in pool: " << pool
.name
<< ": "
104 << provider_url
<< ": " << cpp_strerror(-ret
) << dendl
;
111 int RGWOIDCProvider::delete_obj(optional_yield y
)
114 auto& pool
= svc
->zone
->get_zone_params().oidc_pool
;
117 auto ret
= get_tenant_url_from_arn(tenant
, url
);
119 ldout(cct
, 0) << "ERROR: failed to parse arn" << dendl
;
123 if (this->tenant
!= tenant
) {
124 ldout(cct
, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant
<< ", "
125 << tenant
<< ": " << dendl
;
130 string oid
= tenant
+ get_url_oid_prefix() + url
;
131 ret
= rgw_delete_system_obj(svc
->sysobj
, pool
, oid
, NULL
, y
);
133 ldout(cct
, 0) << "ERROR: deleting oidc url from pool: " << pool
.name
<< ": "
134 << provider_url
<< ": " << cpp_strerror(-ret
) << dendl
;
140 int RGWOIDCProvider::get()
143 auto ret
= get_tenant_url_from_arn(tenant
, url
);
145 ldout(cct
, 0) << "ERROR: failed to parse arn" << dendl
;
149 if (this->tenant
!= tenant
) {
150 ldout(cct
, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant
<< ", "
151 << tenant
<< ": " << dendl
;
155 ret
= read_url(url
, tenant
);
163 void RGWOIDCProvider::dump(Formatter
*f
) const
165 encode_json("OpenIDConnectProviderArn", arn
, f
);
168 void RGWOIDCProvider::dump_all(Formatter
*f
) const
170 f
->open_object_section("ClientIDList");
171 for (auto it
: client_ids
) {
172 encode_json("member", it
, f
);
175 encode_json("CreateDate", creation_date
, f
);
176 f
->open_object_section("ThumbprintList");
177 for (auto it
: thumbprints
) {
178 encode_json("member", it
, f
);
181 encode_json("Url", provider_url
, f
);
184 void RGWOIDCProvider::decode_json(JSONObj
*obj
)
186 JSONDecoder::decode_json("OpenIDConnectProviderArn", arn
, obj
);
189 int RGWOIDCProvider::read_url(const string
& url
, const string
& tenant
)
192 auto& pool
= svc
->zone
->get_zone_params().oidc_pool
;
193 string oid
= tenant
+ get_url_oid_prefix() + url
;
195 auto obj_ctx
= svc
->sysobj
->init_obj_ctx();
197 int ret
= rgw_get_system_obj(obj_ctx
, pool
, oid
, bl
, NULL
, NULL
, null_yield
);
204 auto iter
= bl
.cbegin();
206 } catch (buffer::error
& err
) {
207 ldout(cct
, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool
.name
<<
208 ": " << url
<< dendl
;
215 bool RGWOIDCProvider::validate_input()
217 if (provider_url
.length() > MAX_OIDC_URL_LEN
) {
218 ldout(cct
, 0) << "ERROR: Invalid length of url " << dendl
;
221 if (client_ids
.size() > MAX_OIDC_NUM_CLIENT_IDS
) {
222 ldout(cct
, 0) << "ERROR: Invalid number of client ids " << dendl
;
226 for (auto& it
: client_ids
) {
227 if (it
.length() > MAX_OIDC_CLIENT_ID_LEN
) {
232 if (thumbprints
.size() > MAX_OIDC_NUM_THUMBPRINTS
) {
233 ldout(cct
, 0) << "ERROR: Invalid number of thumbprints " << thumbprints
.size() << dendl
;
237 for (auto& it
: thumbprints
) {
238 if (it
.length() > MAX_OIDC_THUMBPRINT_LEN
) {
246 int RGWOIDCProvider::get_providers(RGWRados
*store
,
247 const string
& tenant
,
248 vector
<RGWOIDCProvider
>& providers
)
250 auto ctl
= store
->pctl
;
252 auto pool
= store
->svc
.zone
->get_zone_params().oidc_pool
;
253 string prefix
= tenant
+ oidc_url_oid_prefix
;
255 //Get the filtered objects
258 RGWListRawObjsCtx ctx
;
261 int r
= store
->list_raw_objects(pool
, prefix
, 1000, ctx
, oids
, &is_truncated
);
263 ldout(ctl
->cct
, 0) << "ERROR: listing filtered objects failed: " << pool
.name
<< ": "
264 << prefix
<< ": " << cpp_strerror(-r
) << dendl
;
267 for (const auto& iter
: oids
) {
268 RGWOIDCProvider
provider(ctl
->cct
, store
->pctl
);
270 auto obj_ctx
= svc
->sysobj
->init_obj_ctx();
272 int ret
= rgw_get_system_obj(obj_ctx
, pool
, iter
, bl
, NULL
, NULL
, null_yield
);
279 auto iter
= bl
.cbegin();
280 decode(provider
, iter
);
281 } catch (buffer::error
& err
) {
282 ldout(ctl
->cct
, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool
.name
<<
283 ": " << iter
<< dendl
;
287 providers
.push_back(std::move(provider
));
289 } while (is_truncated
);
294 const string
& RGWOIDCProvider::get_url_oid_prefix()
296 return oidc_url_oid_prefix
;