op);
}
+int verify_object_lock(const DoutPrefixProvider* dpp, const map<string, buffer::list>& attrs, const bool bypass_perm, const bool bypass_governance_mode) {
+ auto aiter = attrs.find(RGW_ATTR_OBJECT_RETENTION);
+ if (aiter != attrs.end()) {
+ RGWObjectRetention obj_retention;
+ try {
+ decode(obj_retention, aiter->second);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode RGWObjectRetention" << dendl;
+ return -EIO;
+ }
+ if (ceph::real_clock::to_time_t(obj_retention.get_retain_until_date()) > ceph_clock_now()) {
+ if (obj_retention.get_mode().compare("GOVERNANCE") != 0 || !bypass_perm || !bypass_governance_mode) {
+ return -EACCES;
+ }
+ }
+ }
+ aiter = attrs.find(RGW_ATTR_OBJECT_LEGAL_HOLD);
+ if (aiter != attrs.end()) {
+ RGWObjectLegalHold obj_legal_hold;
+ try {
+ decode(obj_legal_hold, aiter->second);
+ } catch (buffer::error& err) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to decode RGWObjectLegalHold" << dendl;
+ return -EIO;
+ }
+ if (obj_legal_hold.is_enabled()) {
+ return -EACCES;
+ }
+ }
+
+ return 0;
+}
+
class HexTable
{
char table[256];
int perm);
extern bool verify_object_permission_no_policy(const DoutPrefixProvider* dpp, struct req_state *s,
int perm);
+
+int verify_object_lock(const DoutPrefixProvider* dpp, const map<string, buffer::list>& attrs, const bool bypass_perm, const bool bypass_governance_mode);
+
/** Convert an input URL into a sane object name
* by converting %-escaped strings into characters, etc*/
extern void rgw_uri_escape_char(char c, string& dst);
}
if (check_obj_lock) {
- auto aiter = attrs.find(RGW_ATTR_OBJECT_RETENTION);
- if (aiter != attrs.end()) {
- RGWObjectRetention obj_retention;
- try {
- decode(obj_retention, aiter->second);
- } catch (buffer::error& err) {
- ldpp_dout(this, 0) << "ERROR: failed to decode RGWObjectRetention" << dendl;
- op_ret = -EIO;
- return;
- }
- if (ceph::real_clock::to_time_t(obj_retention.get_retain_until_date()) > ceph_clock_now()) {
- if (obj_retention.get_mode().compare("GOVERNANCE") != 0 || !bypass_perm || !bypass_governance_mode) {
- op_ret = -EACCES;
- return;
- }
- }
- }
- aiter = attrs.find(RGW_ATTR_OBJECT_LEGAL_HOLD);
- if (aiter != attrs.end()) {
- RGWObjectLegalHold obj_legal_hold;
- try {
- decode(obj_legal_hold, aiter->second);
- } catch (buffer::error& err) {
- ldpp_dout(this, 0) << "ERROR: failed to decode RGWObjectLegalHold" << dendl;
- op_ret = -EIO;
- return;
- }
- if (obj_legal_hold.is_enabled()) {
- op_ret = -EACCES;
- return;
- }
- }
+ int object_lock_response = verify_object_lock(this, attrs, bypass_perm, bypass_governance_mode);
+ if (object_lock_response != 0) {
+ op_ret = object_lock_response;
+ return;
+ }
}
if (multipart_delete) {
iter != multi_delete->objects.end();
++iter) {
rgw_obj obj(bucket, *iter);
+ map<string, bufferlist> attrs;
if (s->iam_policy || ! s->iam_user_policies.empty()) {
auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env,
boost::none,
}
}
+ // verify_object_lock
+ bool check_obj_lock = obj.key.have_instance() && s->bucket_info.obj_lock_enabled();
+ if (check_obj_lock) {
+ int get_attrs_response = get_obj_attrs(store, s, obj, attrs);
+ if (get_attrs_response < 0) {
+ if (get_attrs_response == -ENOENT) {
+ // object maybe delete_marker, skip check_obj_lock
+ check_obj_lock = false;
+ } else {
+ // Something went wrong.
+ send_partial_response(*iter, false, "", get_attrs_response);
+ continue;
+ }
+ }
+ }
+
+ if (check_obj_lock) {
+ int object_lock_response = verify_object_lock(this, attrs, bypass_perm, bypass_governance_mode);
+ if (object_lock_response != 0) {
+ send_partial_response(*iter, false, "", object_lock_response);
+ continue;
+ }
+ }
+
obj_ctx->set_atomic(obj);
RGWRados::Object del_target(store, s->bucket_info, *obj_ctx, obj);