8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:03:03 +01:00

Backported CORE-6450 & CORE-6441

This commit is contained in:
AlexPeshkoff 2020-11-19 13:38:18 +03:00
parent aae85103ce
commit 8f49cd73de
5 changed files with 77 additions and 47 deletions

View File

@ -51,7 +51,7 @@ void CachedSecurityDatabase::handler()
}
void PluginDatabases::getInstance(IPluginConfig* pluginConfig, RefPtr<CachedSecurityDatabase>& instance)
void PluginDatabases::getInstance(IPluginConfig* pluginConfig, CachedSecurityDatabase::Instance& instance)
{
// Determine sec.db name based on existing config
PathName secDbName;
@ -74,18 +74,28 @@ void PluginDatabases::getInstance(IPluginConfig* pluginConfig, RefPtr<CachedSecu
{ // guard scope
MutexLockGuard g(arrayMutex, FB_FUNCTION);
for (unsigned int i = 0; i < dbArray.getCount(); ++i)
for (unsigned int i = 0; i < dbArray.getCount(); )
{
if (secDbName == dbArray[i]->secureDbName)
{
instance = dbArray[i];
break;
CachedSecurityDatabase* fromCache = dbArray[i];
if (fromCache->secDb->test())
{
instance.set(fromCache);
break;
}
else
{
dbArray.remove(i);
continue;
}
}
++i;
}
if (!instance)
{
instance = FB_NEW CachedSecurityDatabase(this, secDbName);
instance.set(FB_NEW CachedSecurityDatabase(this, secDbName));
instance->addRef();
secDbName.copyTo(instance->secureDbName, sizeof(instance->secureDbName));
dbArray.add(instance);

View File

@ -49,6 +49,7 @@ public:
}
virtual bool lookup(void* inMsg, void* outMsg) = 0;
virtual bool test() = 0;
};
@ -85,6 +86,33 @@ public:
Firebird::Mutex mutex;
Firebird::AutoPtr<VSecDb> secDb;
PluginDatabases* list;
public:
// Related RAII holder
class Instance : public Firebird::RefPtr<CachedSecurityDatabase>
{
public:
Instance()
{ }
void set(CachedSecurityDatabase* db)
{
fb_assert(!hasData());
fb_assert(db);
assign(db);
(*this)->mutex.enter(FB_FUNCTION);
}
~Instance()
{
if (hasData())
{
(*this)->mutex.leave();
(*this)->close();
}
}
};
};
class PluginDatabases
@ -99,7 +127,7 @@ private:
Firebird::Mutex arrayMutex;
public:
void getInstance(Firebird::IPluginConfig* pluginConfig, Firebird::RefPtr<CachedSecurityDatabase>& instance);
void getInstance(Firebird::IPluginConfig* pluginConfig, CachedSecurityDatabase::Instance& instance);
int shutdown();
void handler(CachedSecurityDatabase* tgt);
};

View File

@ -120,6 +120,14 @@ public:
return false; // safe default
}
bool test() override
{
Jrd::FbLocalStatus status;
att->ping(&status);
return !(status->getState() & IStatus::STATE_ERRORS);
}
// This 2 are needed to satisfy temporarily different calling requirements
static int shutdown(const int, const int, void*)
{
@ -293,28 +301,19 @@ int SrpServer::authenticate(CheckStatusWrapper* status, IServerBlock* sb, IWrite
messages.param->loginNull = 0;
messages.data.clear();
{ // reference & mutex scope scope
{ // instance RAII scope
CachedSecurityDatabase::Instance instance;
// Get database block from cache
RefPtr<CachedSecurityDatabase> instance;
instances->getInstance(iParameter, instance);
secDbName = instance->secureDbName;
try
{
MutexLockGuard g(instance->mutex, FB_FUNCTION);
// Create SecurityDatabase if needed
if (!instance->secDb)
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName, cryptCallback);
secDbName = instance->secureDbName;
if (!instance->secDb)
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName, cryptCallback);
instance->secDb->lookup(messages.param.getData(), messages.data.getData());
}
catch(const Exception&)
{
instance->close();
throw;
}
instance->close();
// Lookup
instance->secDb->lookup(messages.param.getData(), messages.data.getData());
}
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: Executed statement\n"));

View File

@ -149,6 +149,11 @@ class SecurityDatabase : public VSecDb
public:
bool lookup(void* inMsg, void* outMsg);
bool test() override
{
return fb_ping(status, &lookup_db) == FB_SUCCESS;
}
// This 2 are needed to satisfy temporarily different calling requirements
static int shutdown(const int, const int, void*)
{
@ -326,32 +331,20 @@ int SecurityDatabaseServer::authenticate(CheckStatusWrapper* status, IServerBloc
bool found = false;
char pw1[MAX_LEGACY_PASSWORD_LENGTH + 1];
PathName secureDbName;
{ // reference & mutex scope scope
{ // instance scope
// Get database block from cache
RefPtr<CachedSecurityDatabase> instance;
CachedSecurityDatabase::Instance instance;
instances->getInstance(iParameter, instance);
try
{
MutexLockGuard g(instance->mutex, FB_FUNCTION);
secureDbName = instance->secureDbName;
if (!instance->secDb)
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName);
secureDbName = instance->secureDbName;
if (!instance->secDb)
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName);
user_name uname; // user name buffer
login.copyTo(uname, sizeof uname);
user_record user_block; // user record
found = instance->secDb->lookup(uname, &user_block);
fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1);
}
catch(const Exception&)
{
instance->close();
throw;
}
instance->close();
user_name uname; // user name buffer
login.copyTo(uname, sizeof uname);
user_record user_block; // user record
found = instance->secDb->lookup(uname, &user_block);
fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1);
}
if (!found)
{

View File

@ -193,7 +193,7 @@ namespace Firebird
return ptr;
}
private:
protected:
T* assign(T* const p)
{
if (ptr != p)