Skip to content

Commit 8f49cd7

Browse files
committed
Backported CORE-6450 & CORE-6441
1 parent aae8510 commit 8f49cd7

5 files changed

Lines changed: 77 additions & 47 deletions

File tree

src/auth/SecDbCache.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void CachedSecurityDatabase::handler()
5151
}
5252

5353

54-
void PluginDatabases::getInstance(IPluginConfig* pluginConfig, RefPtr<CachedSecurityDatabase>& instance)
54+
void PluginDatabases::getInstance(IPluginConfig* pluginConfig, CachedSecurityDatabase::Instance& instance)
5555
{
5656
// Determine sec.db name based on existing config
5757
PathName secDbName;
@@ -74,18 +74,28 @@ void PluginDatabases::getInstance(IPluginConfig* pluginConfig, RefPtr<CachedSecu
7474

7575
{ // guard scope
7676
MutexLockGuard g(arrayMutex, FB_FUNCTION);
77-
for (unsigned int i = 0; i < dbArray.getCount(); ++i)
77+
for (unsigned int i = 0; i < dbArray.getCount(); )
7878
{
7979
if (secDbName == dbArray[i]->secureDbName)
8080
{
81-
instance = dbArray[i];
82-
break;
81+
CachedSecurityDatabase* fromCache = dbArray[i];
82+
if (fromCache->secDb->test())
83+
{
84+
instance.set(fromCache);
85+
break;
86+
}
87+
else
88+
{
89+
dbArray.remove(i);
90+
continue;
91+
}
8392
}
93+
++i;
8494
}
8595

8696
if (!instance)
8797
{
88-
instance = FB_NEW CachedSecurityDatabase(this, secDbName);
98+
instance.set(FB_NEW CachedSecurityDatabase(this, secDbName));
8999
instance->addRef();
90100
secDbName.copyTo(instance->secureDbName, sizeof(instance->secureDbName));
91101
dbArray.add(instance);

src/auth/SecDbCache.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class VSecDb
4949
}
5050

5151
virtual bool lookup(void* inMsg, void* outMsg) = 0;
52+
virtual bool test() = 0;
5253
};
5354

5455

@@ -85,6 +86,33 @@ class CachedSecurityDatabase FB_FINAL
8586
Firebird::Mutex mutex;
8687
Firebird::AutoPtr<VSecDb> secDb;
8788
PluginDatabases* list;
89+
90+
public:
91+
// Related RAII holder
92+
class Instance : public Firebird::RefPtr<CachedSecurityDatabase>
93+
{
94+
public:
95+
Instance()
96+
{ }
97+
98+
void set(CachedSecurityDatabase* db)
99+
{
100+
fb_assert(!hasData());
101+
fb_assert(db);
102+
103+
assign(db);
104+
(*this)->mutex.enter(FB_FUNCTION);
105+
}
106+
107+
~Instance()
108+
{
109+
if (hasData())
110+
{
111+
(*this)->mutex.leave();
112+
(*this)->close();
113+
}
114+
}
115+
};
88116
};
89117

90118
class PluginDatabases
@@ -99,7 +127,7 @@ class PluginDatabases
99127
Firebird::Mutex arrayMutex;
100128

101129
public:
102-
void getInstance(Firebird::IPluginConfig* pluginConfig, Firebird::RefPtr<CachedSecurityDatabase>& instance);
130+
void getInstance(Firebird::IPluginConfig* pluginConfig, CachedSecurityDatabase::Instance& instance);
103131
int shutdown();
104132
void handler(CachedSecurityDatabase* tgt);
105133
};

src/auth/SecureRemotePassword/server/SrpServer.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ class SecurityDatabase : public VSecDb
120120
return false; // safe default
121121
}
122122

123+
bool test() override
124+
{
125+
Jrd::FbLocalStatus status;
126+
127+
att->ping(&status);
128+
return !(status->getState() & IStatus::STATE_ERRORS);
129+
}
130+
123131
// This 2 are needed to satisfy temporarily different calling requirements
124132
static int shutdown(const int, const int, void*)
125133
{
@@ -293,28 +301,19 @@ int SrpServer::authenticate(CheckStatusWrapper* status, IServerBlock* sb, IWrite
293301
messages.param->loginNull = 0;
294302
messages.data.clear();
295303

296-
{ // reference & mutex scope scope
304+
{ // instance RAII scope
305+
CachedSecurityDatabase::Instance instance;
306+
297307
// Get database block from cache
298-
RefPtr<CachedSecurityDatabase> instance;
299308
instances->getInstance(iParameter, instance);
309+
secDbName = instance->secureDbName;
300310

301-
try
302-
{
303-
MutexLockGuard g(instance->mutex, FB_FUNCTION);
304-
305-
secDbName = instance->secureDbName;
306-
if (!instance->secDb)
307-
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName, cryptCallback);
308-
309-
instance->secDb->lookup(messages.param.getData(), messages.data.getData());
310-
}
311-
catch(const Exception&)
312-
{
313-
instance->close();
314-
throw;
315-
}
311+
// Create SecurityDatabase if needed
312+
if (!instance->secDb)
313+
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName, cryptCallback);
316314

317-
instance->close();
315+
// Lookup
316+
instance->secDb->lookup(messages.param.getData(), messages.data.getData());
318317
}
319318
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: SRP1: Executed statement\n"));
320319

src/auth/SecurityDatabase/LegacyServer.cpp

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ class SecurityDatabase : public VSecDb
149149
public:
150150
bool lookup(void* inMsg, void* outMsg);
151151

152+
bool test() override
153+
{
154+
return fb_ping(status, &lookup_db) == FB_SUCCESS;
155+
}
156+
152157
// This 2 are needed to satisfy temporarily different calling requirements
153158
static int shutdown(const int, const int, void*)
154159
{
@@ -326,32 +331,20 @@ int SecurityDatabaseServer::authenticate(CheckStatusWrapper* status, IServerBloc
326331
bool found = false;
327332
char pw1[MAX_LEGACY_PASSWORD_LENGTH + 1];
328333
PathName secureDbName;
329-
{ // reference & mutex scope scope
334+
{ // instance scope
330335
// Get database block from cache
331-
RefPtr<CachedSecurityDatabase> instance;
336+
CachedSecurityDatabase::Instance instance;
332337
instances->getInstance(iParameter, instance);
333338

334-
try
335-
{
336-
MutexLockGuard g(instance->mutex, FB_FUNCTION);
337-
338-
secureDbName = instance->secureDbName;
339-
if (!instance->secDb)
340-
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName);
341-
342-
user_name uname; // user name buffer
343-
login.copyTo(uname, sizeof uname);
344-
user_record user_block; // user record
345-
found = instance->secDb->lookup(uname, &user_block);
346-
fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1);
347-
}
348-
catch(const Exception&)
349-
{
350-
instance->close();
351-
throw;
352-
}
339+
secureDbName = instance->secureDbName;
340+
if (!instance->secDb)
341+
instance->secDb = FB_NEW SecurityDatabase(instance->secureDbName);
353342

354-
instance->close();
343+
user_name uname; // user name buffer
344+
login.copyTo(uname, sizeof uname);
345+
user_record user_block; // user record
346+
found = instance->secDb->lookup(uname, &user_block);
347+
fb_utils::copy_terminate(pw1, user_block.password, MAX_LEGACY_PASSWORD_LENGTH + 1);
355348
}
356349
if (!found)
357350
{

src/common/classes/RefCounted.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ namespace Firebird
193193
return ptr;
194194
}
195195

196-
private:
196+
protected:
197197
T* assign(T* const p)
198198
{
199199
if (ptr != p)

0 commit comments

Comments
 (0)