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

Merge pull request #8274 from FirebirdSQL/work/win_sspi_reconnect

If client fails to connect using Win_SSPI plugin with Negotiate security package, try again using NTLM security package.
This commit is contained in:
Vlad Khorsun 2024-09-30 22:40:41 +03:00 committed by GitHub
commit f62f1336e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 112 additions and 66 deletions

View File

@ -67,6 +67,15 @@ namespace
namespace Auth { namespace Auth {
static thread_local bool legacySSP = false;
void setLegacySSP(bool value)
{
legacySSP = value;
}
HINSTANCE AuthSspi::library = 0; HINSTANCE AuthSspi::library = 0;
bool AuthSspi::initEntries() bool AuthSspi::initEntries()
@ -109,7 +118,8 @@ AuthSspi::AuthSspi()
groupNames(*getDefaultMemoryPool()), sessionKey(*getDefaultMemoryPool()) groupNames(*getDefaultMemoryPool()), sessionKey(*getDefaultMemoryPool())
{ {
TimeStamp timeOut; TimeStamp timeOut;
hasCredentials = initEntries() && (fAcquireCredentialsHandle(0, NEGOSSP_NAME_A, hasCredentials = initEntries() && (fAcquireCredentialsHandle(0,
legacySSP ? NTLMSP_NAME_A : NEGOSSP_NAME_A,
SECPKG_CRED_BOTH, 0, 0, 0, 0, SECPKG_CRED_BOTH, 0, 0, 0, 0,
&secHndl, &timeOut) == SEC_E_OK); &secHndl, &timeOut) == SEC_E_OK);
} }

View File

@ -145,6 +145,10 @@ private:
void registerTrustedClient(Firebird::IPluginManager* iPlugin); void registerTrustedClient(Firebird::IPluginManager* iPlugin);
void registerTrustedServer(Firebird::IPluginManager* iPlugin); void registerTrustedServer(Firebird::IPluginManager* iPlugin);
// Set per-thread flag that specify which security package should be used by
// newly created plugin instances: true - use NTLM, false - use Negotiate.
void setLegacySSP(bool value);
} // namespace Auth } // namespace Auth
#endif // TRUSTED_AUTH #endif // TRUSTED_AUTH

View File

@ -7405,10 +7405,21 @@ static rem_port* analyze(ClntAuthBlock& cBlock, PathName& attach_name, unsigned
cBlock.loadClnt(pb, &parSet); cBlock.loadClnt(pb, &parSet);
pb.deleteWithTag(parSet.auth_block); pb.deleteWithTag(parSet.auth_block);
authenticateStep0(cBlock);
bool needFile = !(flags & ANALYZE_EMP_NAME); bool needFile = !(flags & ANALYZE_EMP_NAME);
const PathName save_attach_name(attach_name);
#ifdef TRUSTED_AUTH
bool legacySSP = false;
Auth::setLegacySSP(legacySSP);
#endif
while (true)
{
authenticateStep0(cBlock);
try
{
#ifdef WIN_NT #ifdef WIN_NT
if (ISC_analyze_protocol(PROTOCOL_XNET, attach_name, node_name, NULL, needFile)) if (ISC_analyze_protocol(PROTOCOL_XNET, attach_name, node_name, NULL, needFile))
port = XNET_analyze(&cBlock, attach_name, flags & ANALYZE_USER_VFY, cBlock.getConfig(), ref_db_name); port = XNET_analyze(&cBlock, attach_name, flags & ANALYZE_USER_VFY, cBlock.getConfig(), ref_db_name);
@ -7493,6 +7504,27 @@ static rem_port* analyze(ClntAuthBlock& cBlock, PathName& attach_name, unsigned
} }
} }
break;
}
catch (const Exception&)
{
#ifdef TRUSTED_AUTH
const char* const pluginName = cBlock.plugins.name();
if (legacySSP || fb_utils::stricmp(pluginName, "WIN_SSPI") != 0)
throw;
// Retry connect with failed plugin only and using legacy security package
legacySSP = true;
Auth::setLegacySSP(legacySSP);
attach_name = save_attach_name;
cBlock.plugins.set(pluginName);
#else
throw;
#endif
}
}
if (!port) if (!port)
Arg::Gds(isc_unavailable).raise(); Arg::Gds(isc_unavailable).raise();