instance = i;
}
- bool empty() {
+ bool empty() const {
return name.empty();
}
bool operator==(const rgw_obj_key& k) const {
extern bool verify_object_permission(struct req_state *s, int perm);
/** Convert an input URL into a sane object name
* by converting %-escaped strings into characters, etc*/
-extern bool url_decode(string& src_str, string& dest_str, bool in_query = false);
+extern bool url_decode(const string& src_str, string& dest_str, bool in_query = false);
extern void url_encode(const string& src, string& dst);
extern void calc_hmac_sha1(const char *key, int key_len,
return verify_object_permission(s, &bacl, &oacl, RGW_PERM_WRITE);
}
-bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path)
+bool RGWBulkDelete::Deleter::verify_permission(RGWBucketInfo& binfo,
+ map<string, bufferlist>& battrs)
{
int ret = 0;
+ RGWAccessControlPolicy bacl(store->ctx());
+ rgw_obj_key no_obj;
+ ret = read_policy(store, s, binfo, battrs, &bacl, binfo.bucket, no_obj);
+ if (ret < 0) {
+ return false;
+ }
+
+ return verify_bucket_permission(s, &bacl, RGW_PERM_WRITE);
+}
+
+bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path)
+{
+ int ret = 0;
auto& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
+
RGWBucketInfo binfo;
map<string, bufferlist> battrs;
ret = store->get_bucket_info(obj_ctx, path.bucket_name, binfo, NULL, &battrs);
goto binfo_fail;
}
- /* We do need a new scope due to goto. */
- {
+ if (!path.obj_key.empty()) {
rgw_obj obj(binfo.bucket, path.obj_key);
obj_ctx.set_atomic(obj);
if (ret < 0) {
goto delop_fail;
}
+ } else {
+ RGWObjVersionTracker ot;
+ ot.read_version = binfo.ep_objv;
+
+ if (!verify_permission(binfo, battrs)) {
+ ret = -EACCES;
+ goto auth_fail;
+ }
+
+ ret = store->delete_bucket(binfo.bucket, ot);
+ if (0 == ret) {
+ ret = rgw_unlink_bucket(store, binfo.owner, binfo.bucket.name, false);
+ if (ret < 0) {
+ ldout(s->cct, 0) << "WARNING: failed to unlink bucket: ret=" << ret << dendl;
+ }
+ }
+ if (ret < 0) {
+ goto delop_fail;
+ }
+
+ if (!store->region.is_master) {
+ bufferlist in_data;
+ JSONParser jp;
+ ret = forward_request_to_master(s, &ot.read_version, store, in_data, &jp);
+ if (ret < 0) {
+ if (ret == -ENOENT) { /* adjust error,
+ we want to return with NoSuchBucket and not NoSuchKey */
+ ret = -ERR_NO_SUCH_BUCKET;
+ }
+ goto delop_fail;
+ }
+ }
}
num_deleted++;
delop_fail:
if (-ENOENT == ret) {
- ldout(store->ctx(), 20) << "cannot find the object" << dendl;
+ ldout(store->ctx(), 20) << "cannot find entry " << path << dendl;
num_unfound++;
} else {
fail_desc_t failed_item = {
ldout(s->cct, 20) << "extracted Bulk Delete entry: " << path_str << dendl;
+ RGWBulkDelete::acct_path_t path;
+
const size_t sep_pos = path_str.find('/');
if (string::npos == sep_pos) {
- ldout(s->cct, 20) << "wrongly formatted item: " << path_str << dendl;
- continue;
- }
+ url_decode(path_str, path.bucket_name);
+ } else {
+ string bucket_name;
+ url_decode(path_str.substr(0, sep_pos), bucket_name);
- RGWBulkDelete::acct_path_t path;
- path.bucket_name = path_str.substr(0, sep_pos);
- path.obj_key = path_str.substr(sep_pos + 1);
+ string obj_name;
+ url_decode(path_str.substr(sep_pos + 1), obj_name);
+
+ path.bucket_name = bucket_name;
+ path.obj_key = obj_name;
+ }
items.push_back(path);
if (items.size() == MAX_CHUNK_ENTRIES) {
- is_truncated = true;
+ *is_truncated = true;
return 0;
}
}