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:
parent
aae85103ce
commit
8f49cd73de
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ namespace Firebird
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
T* assign(T* const p)
|
||||
{
|
||||
if (ptr != p)
|
||||
|
Loading…
Reference in New Issue
Block a user