From 6e19a5559039740932948d05b40502cf31ab3ab0 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Thu, 25 Feb 2021 17:39:08 -0500 Subject: [PATCH] rgw: objectlock: improve client error messages A bucket object lock configuration can only be set on buckets created with the object-lock option enabled. Likewise, on object lock or object retention hold can only be set on objects in buckets with object lock enabled. Object lock and related policy and policy violations are also potentially confusing to client users. Raise the debug level to 4, but add a human-readable client error message, when object lock constraints are violated. Fixes: https://tracker.ceph.com/issues/49541 Signed-off-by: Matt Benjamin (cherry picked from commit 7583374e5294b1c1c16068999123fef98827e9dc) --- src/rgw/rgw_op.cc | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index d6bc277e6dbd..7deb0d6218c8 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -2532,6 +2532,8 @@ void RGWSetBucketVersioning::execute(optional_yield y) } if (s->bucket->get_info().obj_lock_enabled() && versioning_status != VersioningEnabled) { + s->err.message = "bucket versioning cannot be disabled on buckets with object lock enabled"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_BUCKET_STATE; return; } @@ -4735,6 +4737,9 @@ void RGWDeleteObj::execute(optional_yield y) int object_lock_response = verify_object_lock(this, attrs, bypass_perm, bypass_governance_mode); if (object_lock_response != 0) { op_ret = object_lock_response; + if (op_ret == -EACCES) { + s->err.message = "forbidden by object lock"; + } return; } } @@ -7686,7 +7691,8 @@ int RGWPutBucketObjectLock::verify_permission(optional_yield y) void RGWPutBucketObjectLock::execute(optional_yield y) { if (!s->bucket->get_info().obj_lock_enabled()) { - ldpp_dout(this, 0) << "ERROR: object Lock configuration cannot be enabled on existing buckets" << dendl; + s->err.message = "object lock configuration can't be set if bucket object lock not enabled"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_BUCKET_STATE; return; } @@ -7714,7 +7720,8 @@ void RGWPutBucketObjectLock::execute(optional_yield y) return; } if (obj_lock.has_rule() && !obj_lock.retention_period_valid()) { - ldpp_dout(this, 0) << "ERROR: retention period must be a positive integer value" << dendl; + s->err.message = "retention period must be a positive integer value"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_RETENTION_PERIOD; return; } @@ -7774,7 +7781,8 @@ void RGWPutObjRetention::pre_exec() void RGWPutObjRetention::execute(optional_yield y) { if (!s->bucket->get_info().obj_lock_enabled()) { - ldpp_dout(this, 0) << "ERROR: object retention can't be set if bucket object lock not configured" << dendl; + s->err.message = "object retention can't be set if bucket object lock not configured"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_REQUEST; return; } @@ -7800,7 +7808,8 @@ void RGWPutObjRetention::execute(optional_yield y) } if (ceph::real_clock::to_time_t(obj_retention.get_retain_until_date()) < ceph_clock_now()) { - ldpp_dout(this, 0) << "ERROR: the retain until date must be in the future" << dendl; + s->err.message = "the retain-until date must be in the future"; + ldpp_dout(this, 0) << "ERROR: " << s->err.message << dendl; op_ret = -EINVAL; return; } @@ -7826,6 +7835,7 @@ void RGWPutObjRetention::execute(optional_yield y) } if (ceph::real_clock::to_time_t(obj_retention.get_retain_until_date()) < ceph::real_clock::to_time_t(old_obj_retention.get_retain_until_date())) { if (old_obj_retention.get_mode().compare("GOVERNANCE") != 0 || !bypass_perm || !bypass_governance_mode) { + s->err.message = "proposed retain-until date shortens an existing retention period and governance bypass check failed"; op_ret = -EACCES; return; } @@ -7853,7 +7863,8 @@ void RGWGetObjRetention::pre_exec() void RGWGetObjRetention::execute(optional_yield y) { if (!s->bucket->get_info().obj_lock_enabled()) { - ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl; + s->err.message = "bucket object lock not configured"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_REQUEST; return; } @@ -7896,7 +7907,8 @@ void RGWPutObjLegalHold::pre_exec() void RGWPutObjLegalHold::execute(optional_yield y) { if (!s->bucket->get_info().obj_lock_enabled()) { - ldpp_dout(this, 0) << "ERROR: object legal hold can't be set if bucket object lock not configured" << dendl; + s->err.message = "object legal hold can't be set if bucket object lock not enabled"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_REQUEST; return; } @@ -7947,7 +7959,8 @@ void RGWGetObjLegalHold::pre_exec() void RGWGetObjLegalHold::execute(optional_yield y) { if (!s->bucket->get_info().obj_lock_enabled()) { - ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl; + s->err.message = "bucket object lock not configured"; + ldpp_dout(this, 4) << "ERROR: " << s->err.message << dendl; op_ret = -ERR_INVALID_REQUEST; return; } @@ -7980,7 +7993,6 @@ void RGWGetClusterStat::execute(optional_yield y) op_ret = store->cluster_stat(stats_op); } - int RGWGetBucketPolicyStatus::verify_permission(optional_yield y) { if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicyStatus)) { -- 2.47.3