From 82d2191dfda8d4ef031223929a6a76949ae050aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Czern=C3=BD?= Date: Wed, 4 Jan 2023 15:53:50 +0100 Subject: [PATCH] B #6022: Fix lock override and --all flag (#2427) * This commit syncs oned and API specification for the ALL flag. The internal defines were not consistent with the API specification. --- include/PoolObjectSQL.h | 13 ++++++++----- include/RequestManagerLock.h | 8 ++++++-- src/acl/AclManager.cc | 8 ++++---- src/image/Image.cc | 2 +- src/pool/PoolObjectSQL.cc | 11 ++++++++++- src/rm/RequestManagerLock.cc | 24 +++++++++++++++++++++++- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 753ed56063..254aa59a88 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -75,10 +75,10 @@ public: */ enum LockStates { - ST_NONE = 0x0LL, - ST_USE = 0x1LL, - ST_MANAGE = 0x2LL, - ST_ADMIN = 0x4LL + ST_NONE = 0, + ST_USE = 1, + ST_MANAGE = 2, + ST_ADMIN = 3 }; static const long int LockableObject; @@ -530,7 +530,10 @@ public: * * @return 0 if the lock was granted, -1 if the object is already locked */ - int lock_db(const int owner, const int req_id, const int level); + int lock_db(const int owner, + const int req_id, + const int level, + const bool is_admin); /** * Unlocks the DB lock for external applications. The object must be locked diff --git a/include/RequestManagerLock.h b/include/RequestManagerLock.h index d2b4fc5a88..8ea5f31143 100644 --- a/include/RequestManagerLock.h +++ b/include/RequestManagerLock.h @@ -40,9 +40,13 @@ protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; - int lock_db(PoolObjectSQL * object, const int owner, const int req_id, const int level) + int lock_db(PoolObjectSQL * object, + const int owner, + const int req_id, + const int level, + const bool is_admin) { - return object->lock_db(owner, req_id, level); + return object->lock_db(owner, req_id, level, is_admin); }; }; diff --git a/src/acl/AclManager.cc b/src/acl/AclManager.cc index 2669219a55..e4cd62e178 100644 --- a/src/acl/AclManager.cc +++ b/src/acl/AclManager.cc @@ -195,11 +195,11 @@ bool AclManager::authorize( long long user_req; long long resource_oid_req; - if (static_cast(op) & 0x10LL) //No lockable object + if (op & 0x10LL) //No lockable object { op = static_cast(op & 0x0FLL); } - else if (obj_perms.locked > 0 && obj_perms.locked <= static_cast(op)) + else if (obj_perms.locked > 0 && obj_perms.locked <= op) { return false; } @@ -385,11 +385,11 @@ bool AclManager::oneadmin_authorize( const PoolObjectAuth& obj_perms, AuthRequest::Operation op) const { - if (static_cast(op) & 0x10LL) //No lockable object + if (op & 0x10LL) //No lockable object { return true; } - else if (obj_perms.locked > 0 && obj_perms.locked <= static_cast(op)) + else if (obj_perms.locked > 0 && obj_perms.locked <= op) { return false; } diff --git a/src/image/Image.cc b/src/image/Image.cc index 55b9638011..0fdab80fd4 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -1016,7 +1016,7 @@ void Image::set_state(ImageState _state) } else if (state == LOCKED) { - lock_db(-1,-1, PoolObjectSQL::LockStates::ST_USE); + lock_db(-1,-1, PoolObjectSQL::LockStates::ST_USE, true); } if (_state != LOCKED ) diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index a7331be7d7..78c46da2a3 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -587,13 +587,22 @@ bool PoolObjectSQL::name_is_valid(const string& obj_name, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int PoolObjectSQL::lock_db(const int owner, const int req_id, const int level) +int PoolObjectSQL::lock_db(const int owner, + const int req_id, + const int level, + const bool is_admin) { if ( level < ST_NONE || level > ST_ADMIN ) { return -1; } + if (locked != ST_NONE && lock_owner != owner && !is_admin) + { + // Only admin can override lock + return -1; + } + locked = static_cast(level); lock_time = time(0); lock_owner = owner; diff --git a/src/rm/RequestManagerLock.cc b/src/rm/RequestManagerLock.cc index 083aa585b4..8f57774e0b 100644 --- a/src/rm/RequestManagerLock.cc +++ b/src/rm/RequestManagerLock.cc @@ -62,6 +62,27 @@ void RequestManagerLock::request_execute(xmlrpc_c::paramList const& paramList, return; } + switch(level) + { + case 1: //USE + MANAGE + ADMIN + level = PoolObjectSQL::ST_USE; + break; + case 2: //MANAGE + ADMIN + level = PoolObjectSQL::ST_MANAGE; + break; + case 3: //ADMIN + level = PoolObjectSQL::ST_ADMIN; + break; + case 4: //ALL equals USE + level = PoolObjectSQL::ST_USE; + break; + + default: + att.resp_msg = "Wrong lock level specified"; + failure_response(ACTION, att); + return; + } + if ((auth_object & PoolObjectSQL::LockableObject) != 0) { if ( test && object->test_lock_db(att.resp_msg) != 0 ) @@ -70,7 +91,7 @@ void RequestManagerLock::request_execute(xmlrpc_c::paramList const& paramList, } else { - rc = lock_db(object.get(), owner, att.req_id, level); + rc = lock_db(object.get(), owner, att.req_id, level, att.is_admin()); pool->update(object.get()); @@ -87,6 +108,7 @@ void RequestManagerLock::request_execute(xmlrpc_c::paramList const& paramList, } else { + att.resp_msg = "Object cannot be locked."; failure_response(AUTHORIZATION, att); }