MXS-1354: Add missing locking to the Users class

The Users class now performs locking when a method is called. This will
prevent concurrent access to the internal map of users.

Added missing const versions of SpinLockGuard.
This commit is contained in:
Markus Mäkelä
2017-08-15 10:18:40 +03:00
parent a48758a9d8
commit 4a179d973b
2 changed files with 17 additions and 7 deletions

View File

@ -46,7 +46,7 @@ public:
/** /**
* Acquires the spinlock. * Acquires the spinlock.
*/ */
void acquire() void acquire() const
{ {
spinlock_acquire(&m_lock); spinlock_acquire(&m_lock);
} }
@ -54,7 +54,7 @@ public:
/** /**
* Releases the spinlock. * Releases the spinlock.
*/ */
void release() void release() const
{ {
spinlock_release(&m_lock); spinlock_release(&m_lock);
} }
@ -64,7 +64,7 @@ private:
SpinLock& operator = (const SpinLock&) /* = delete */; SpinLock& operator = (const SpinLock&) /* = delete */;
private: private:
SPINLOCK m_lock; mutable SPINLOCK m_lock;
}; };
/** /**
@ -85,7 +85,7 @@ public:
* *
* @param lock The spinlock to lock. * @param lock The spinlock to lock.
*/ */
SpinLockGuard(SPINLOCK& lock) SpinLockGuard(const SPINLOCK& lock)
: m_lock(lock) : m_lock(lock)
{ {
spinlock_acquire(&m_lock); spinlock_acquire(&m_lock);
@ -96,7 +96,7 @@ public:
* *
* @param lock The spinlock to lock. * @param lock The spinlock to lock.
*/ */
SpinLockGuard(SpinLock& lock) SpinLockGuard(const SpinLock& lock)
: m_lock(lock.m_lock) : m_lock(lock.m_lock)
{ {
spinlock_acquire(&m_lock); spinlock_acquire(&m_lock);
@ -115,7 +115,7 @@ private:
SpinLockGuard(const SpinLockGuard&) /* = delete */; SpinLockGuard(const SpinLockGuard&) /* = delete */;
SpinLockGuard& operator = (const SpinLockGuard&) /* = delete */; SpinLockGuard& operator = (const SpinLockGuard&) /* = delete */;
SPINLOCK& m_lock; const SPINLOCK& m_lock;
}; };
} }

View File

@ -19,6 +19,7 @@
#include <maxscale/users.h> #include <maxscale/users.h>
#include <maxscale/authenticator.h> #include <maxscale/authenticator.h>
#include <maxscale/spinlock.hh>
namespace namespace
{ {
@ -60,11 +61,13 @@ public:
bool add(std::string user, std::string password) bool add(std::string user, std::string password)
{ {
mxs::SpinLockGuard guard(m_lock);
return m_data.insert(std::make_pair(user, UserInfo(password))).second; return m_data.insert(std::make_pair(user, UserInfo(password))).second;
} }
bool remove(std::string user) bool remove(std::string user)
{ {
mxs::SpinLockGuard guard(m_lock);
bool rval = false; bool rval = false;
if (get(user)) if (get(user))
@ -78,6 +81,7 @@ public:
bool get(std::string user, UserInfo* output = NULL) const bool get(std::string user, UserInfo* output = NULL) const
{ {
mxs::SpinLockGuard guard(m_lock);
UserMap::const_iterator it = m_data.find(user); UserMap::const_iterator it = m_data.find(user);
bool rval = false; bool rval = false;
@ -96,6 +100,7 @@ public:
bool check_permissions(std::string user, permission_type perm) const bool check_permissions(std::string user, permission_type perm) const
{ {
mxs::SpinLockGuard guard(m_lock);
UserMap::const_iterator it = m_data.find(user); UserMap::const_iterator it = m_data.find(user);
bool rval = false; bool rval = false;
@ -109,6 +114,7 @@ public:
bool set_permissions(std::string user, permission_type perm) bool set_permissions(std::string user, permission_type perm)
{ {
mxs::SpinLockGuard guard(m_lock);
UserMap::iterator it = m_data.find(user); UserMap::iterator it = m_data.find(user);
bool rval = false; bool rval = false;
@ -123,6 +129,7 @@ public:
json_t* diagnostic_json() const json_t* diagnostic_json() const
{ {
mxs::SpinLockGuard guard(m_lock);
json_t* rval = json_array(); json_t* rval = json_array();
for (UserMap::const_iterator it = m_data.begin(); it != m_data.end(); it++) for (UserMap::const_iterator it = m_data.begin(); it != m_data.end(); it++)
@ -135,6 +142,7 @@ public:
void diagnostic(DCB* dcb) const void diagnostic(DCB* dcb) const
{ {
mxs::SpinLockGuard guard(m_lock);
if (m_data.size()) if (m_data.size())
{ {
const char *sep = ""; const char *sep = "";
@ -150,11 +158,13 @@ public:
bool empty() const bool empty() const
{ {
mxs::SpinLockGuard guard(m_lock);
return m_data.size() > 0; return m_data.size() > 0;
} }
private: private:
UserMap m_data; mxs::SpinLock m_lock;
UserMap m_data;
}; };
} }