8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 04: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 // Determine sec.db name based on existing config
PathName secDbName; PathName secDbName;
@ -74,18 +74,28 @@ void PluginDatabases::getInstance(IPluginConfig* pluginConfig, RefPtr<CachedSecu
{ // guard scope { // guard scope
MutexLockGuard g(arrayMutex, FB_FUNCTION); 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) if (secDbName == dbArray[i]->secureDbName)
{ {
instance = dbArray[i]; CachedSecurityDatabase* fromCache = dbArray[i];
if (fromCache->secDb->test())
{
instance.set(fromCache);
break; break;
} }
else
{
dbArray.remove(i);
continue;
}
}
++i;
} }
if (!instance) if (!instance)
{ {
instance = FB_NEW CachedSecurityDatabase(this, secDbName); instance.set(FB_NEW CachedSecurityDatabase(this, secDbName));
instance->addRef(); instance->addRef();
secDbName.copyTo(instance->secureDbName, sizeof(instance->secureDbName)); secDbName.copyTo(instance->secureDbName, sizeof(instance->secureDbName));
dbArray.add(instance); dbArray.add(instance);

View File

@ -49,6 +49,7 @@ public:
} }
virtual bool lookup(void* inMsg, void* outMsg) = 0; virtual bool lookup(void* inMsg, void* outMsg) = 0;
virtual bool test() = 0;
}; };
@ -85,6 +86,33 @@ public:
Firebird::Mutex mutex; Firebird::Mutex mutex;
Firebird::AutoPtr<VSecDb> secDb; Firebird::AutoPtr<VSecDb> secDb;
PluginDatabases* list; 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 class PluginDatabases
@ -99,7 +127,7 @@ private:
Firebird::Mutex arrayMutex; Firebird::Mutex arrayMutex;
public: public:
void getInstance(Firebird::IPluginConfig* pluginConfig, Firebird::RefPtr<CachedSecurityDatabase>& instance); void getInstance(Firebird::IPluginConfig* pluginConfig, CachedSecurityDatabase::Instance& instance);
int shutdown(); int shutdown();
void handler(CachedSecurityDatabase* tgt); void handler(CachedSecurityDatabase* tgt);
}; };

View File

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

View File

@ -149,6 +149,11 @@ class SecurityDatabase : public VSecDb
public: public:
bool lookup(void* inMsg, void* outMsg); 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 // This 2 are needed to satisfy temporarily different calling requirements
static int shutdown(const int, const int, void*) static int shutdown(const int, const int, void*)
{ {
@ -326,15 +331,11 @@ int SecurityDatabaseServer::authenticate(CheckStatusWrapper* status, IServerBloc
bool found = false; bool found = false;
char pw1[MAX_LEGACY_PASSWORD_LENGTH + 1]; char pw1[MAX_LEGACY_PASSWORD_LENGTH + 1];
PathName secureDbName; PathName secureDbName;
{ // reference & mutex scope scope { // instance scope
// Get database block from cache // Get database block from cache
RefPtr<CachedSecurityDatabase> instance; CachedSecurityDatabase::Instance instance;
instances->getInstance(iParameter, instance); instances->getInstance(iParameter, instance);
try
{
MutexLockGuard g(instance->mutex, FB_FUNCTION);
secureDbName = instance->secureDbName; secureDbName = instance->secureDbName;
if (!instance->secDb) if (!instance->secDb)
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName); instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName);
@ -345,14 +346,6 @@ int SecurityDatabaseServer::authenticate(CheckStatusWrapper* status, IServerBloc
found = instance->secDb->lookup(uname, &user_block); found = instance->secDb->lookup(uname, &user_block);
fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1); fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1);
} }
catch(const Exception&)
{
instance->close();
throw;
}
instance->close();
}
if (!found) if (!found)
{ {
HANDSHAKE_DEBUG(fprintf(stderr, "LegacyServer (badlogin) %d\n", IAuth::AUTH_CONTINUE)); HANDSHAKE_DEBUG(fprintf(stderr, "LegacyServer (badlogin) %d\n", IAuth::AUTH_CONTINUE));

View File

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