const rgw_user& id,
const std::string& name,
const std::string& read_list,
- const std::string& write_list)
+ const std::string& write_list,
+ uint32_t& rw_mask)
{
acl.create_default(id, name);
owner.set_id(id);
owner.set_name(name);
+ rw_mask = 0;
if (read_list.size()) {
std::vector<std::string> uids;
<< r << dendl;
return r;
}
+ rw_mask |= SWIFT_PERM_READ;
}
if (write_list.size()) {
std::vector<std::string> uids;
<< r << dendl;
return r;
}
+ rw_mask |= SWIFT_PERM_WRITE;
}
return 0;
}
+void RGWAccessControlPolicy_SWIFT::filter_merge(uint32_t rw_mask,
+ RGWAccessControlPolicy_SWIFT *old)
+{
+ /* rw_mask&SWIFT_PERM_READ => setting read acl,
+ * rw_mask&SWIFT_PERM_WRITE => setting write acl
+ * when bit is cleared, copy matching elements from old.
+ */
+ if (rw_mask == (SWIFT_PERM_READ|SWIFT_PERM_WRITE)) {
+ return;
+ }
+ rw_mask ^= (SWIFT_PERM_READ|SWIFT_PERM_WRITE);
+ for (auto &iter: old->acl.get_grant_map()) {
+ ACLGrant& grant = iter.second;
+ uint32_t perm = grant.get_permission().get_permissions();
+ rgw_user id;
+ string url_spec;
+ if (!grant.get_id(id)) {
+ if (grant.get_group() != ACL_GROUP_ALL_USERS) {
+ url_spec = grant.get_referer();
+ if (url_spec.empty()) {
+ continue;
+ }
+ if (perm == 0) {
+ /* We need to carry also negative, HTTP referrer-based ACLs. */
+ perm = SWIFT_PERM_READ;
+ }
+ }
+ }
+ if (perm & rw_mask) {
+ acl.add_grant(&grant);
+ }
+ }
+}
+
void RGWAccessControlPolicy_SWIFT::to_str(string& read, string& write)
{
multimap<string, ACLGrant>& m = acl.get_grant_map();
const rgw_user& id,
const std::string& name,
const std::string& read_list,
- const std::string& write_list);
+ const std::string& write_list,
+ uint32_t& rw_mask);
+ void filter_merge(uint32_t mask, RGWAccessControlPolicy_SWIFT *policy);
void to_str(std::string& read, std::string& write);
};
#include "compressor/Compressor.h"
+#include "rgw_acl_swift.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rgw
* the hood. This method will add the new items only if the map doesn't
* contain such keys yet. */
if (has_policy) {
+ if (s->dialect.compare("swift") == 0) {
+ auto old_policy = static_cast<RGWAccessControlPolicy_SWIFT*>(s->bucket_acl);
+ auto new_policy = static_cast<RGWAccessControlPolicy_SWIFT*>(&policy);
+ new_policy->filter_merge(policy_rw_mask, old_policy);
+ policy = *new_policy;
+ }
buffer::list bl;
policy.encode(bl);
emplace_attr(RGW_ATTR_ACL, std::move(bl));
map<string, buffer::list> attrs;
set<string> rmattr_names;
bool has_policy, has_cors;
+ uint32_t policy_rw_mask;
RGWAccessControlPolicy policy;
RGWCORSConfiguration cors_config;
string placement_rule;
public:
RGWPutMetadataBucket()
- : has_policy(false), has_cors(false)
+ : has_policy(false), has_cors(false), policy_rw_mask(0)
{}
void emplace_attr(std::string&& key, buffer::list&& bl) {
RGWRados * const store,
RGWAccessControlPolicy * const policy,
bool * const has_policy,
+ uint32_t * rw_mask,
RGWCORSConfiguration * const cors_config,
bool * const has_cors)
{
s->user->user_id,
s->user->display_name,
read_list,
- write_list);
+ write_list,
+ *rw_mask);
if (r < 0) {
return r;
}
int RGWCreateBucket_ObjStore_SWIFT::get_params()
{
bool has_policy;
+ uint32_t policy_rw_mask = 0;
- int r = get_swift_container_settings(s, store, &policy, &has_policy, &cors_config, &has_cors);
+ int r = get_swift_container_settings(s, store, &policy, &has_policy,
+ &policy_rw_mask, &cors_config, &has_cors);
if (r < 0) {
return r;
}
}
int r = get_swift_container_settings(s, store, &policy, &has_policy,
- &cors_config, &has_cors);
+ &policy_rw_mask, &cors_config, &has_cors);
if (r < 0) {
return r;
}