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

Fixed CORE-4969: SEC$USERS table is unavailable in case of any error in any configured user manager plugin

This commit is contained in:
alexpeshkoff 2015-11-06 17:10:27 +00:00
parent 9694ce5307
commit 3434d0aeee
5 changed files with 29 additions and 16 deletions

View File

@ -89,14 +89,14 @@ void UserData::clear(Firebird::CheckStatusWrapper*)
} }
// This function sets typical gsec return code based on requested operation if it was not set by plugin // This function sets typical gsec return code based on requested operation if it was not set by plugin
int setGsecCode(int code, IUser* user) int setGsecCode(int code, int operation)
{ {
if (code >= 0) if (code >= 0)
{ {
return code; return code;
} }
switch(user->operation()) switch(operation)
{ {
case ADD_OPER: case ADD_OPER:
return GsecMsg19; return GsecMsg19;

View File

@ -261,7 +261,7 @@ public:
Get(Config* firebirdConf, const char* plugName); Get(Config* firebirdConf, const char* plugName);
}; };
int setGsecCode(int code, Firebird::IUser* iUser); int setGsecCode(int code, int operation);
} // namespace Auth } // namespace Auth

View File

@ -303,13 +303,13 @@ USHORT UserManagement::put(Auth::DynamicUserData* userData)
} }
void UserManagement::checkSecurityResult(int errcode, IStatus* status, void UserManagement::checkSecurityResult(int errcode, IStatus* status,
const char* userName, IUser* user) const char* userName, int operation)
{ {
if (!errcode) if (!errcode)
{ {
return; return;
} }
errcode = Auth::setGsecCode(errcode, user); errcode = Auth::setGsecCode(errcode, operation);
Arg::StatusVector tmp; Arg::StatusVector tmp;
tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)); tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
@ -362,7 +362,7 @@ void UserManagement::execute(USHORT id)
OldAttributes oldAttributes; OldAttributes oldAttributes;
int ret = manager->execute(&statusWrapper, &cmd, &oldAttributes); int ret = manager->execute(&statusWrapper, &cmd, &oldAttributes);
checkSecurityResult(ret, &status, command->userName()->get(), command); checkSecurityResult(ret, &status, command->userName()->get(), command->operation());
if (command->op == Auth::ADDMOD_OPER) if (command->op == Auth::ADDMOD_OPER)
{ {
@ -453,7 +453,7 @@ void UserManagement::execute(USHORT id)
} }
int errcode = manager->execute(&statusWrapper, command, NULL); int errcode = manager->execute(&statusWrapper, command, NULL);
checkSecurityResult(errcode, &status, command->userName()->get(), command); checkSecurityResult(errcode, &status, command->userName()->get(), command->operation());
delete commands[id]; delete commands[id];
commands[id] = NULL; commands[id] = NULL;
@ -571,6 +571,13 @@ RecordBuffer* UserManagement::getList(thread_db* tdbb, jrd_rel* relation)
try try
{ {
openAllManagers(); openAllManagers();
bool flagSuccess = false;
LocalStatus st1, st2;
CheckStatusWrapper statusWrapper1(&st1);
CheckStatusWrapper statusWrapper2(&st2);
CheckStatusWrapper* currentWrapper(&statusWrapper1);
int errcode1, errcode2;
int* ec(&errcode1);
threadDbb = tdbb; threadDbb = tdbb;
MemoryPool* const pool = threadDbb->getTransaction()->tra_pool; MemoryPool* const pool = threadDbb->getTransaction()->tra_pool;
@ -579,15 +586,21 @@ RecordBuffer* UserManagement::getList(thread_db* tdbb, jrd_rel* relation)
for (FillSnapshot fillSnapshot(this); fillSnapshot.pos < managers.getCount(); ++fillSnapshot.pos) for (FillSnapshot fillSnapshot(this); fillSnapshot.pos < managers.getCount(); ++fillSnapshot.pos)
{ {
LocalStatus status;
CheckStatusWrapper statusWrapper(&status);
Auth::StackUserData u; Auth::StackUserData u;
u.op = Auth::DIS_OPER; u.op = Auth::DIS_OPER;
int errcode = managers[fillSnapshot.pos].second->execute(&statusWrapper, &u, &fillSnapshot); *ec = managers[fillSnapshot.pos].second->execute(currentWrapper, &u, &fillSnapshot);
checkSecurityResult(errcode, &status, "Unknown", &u); if (*ec)
{
currentWrapper = &statusWrapper2;
ec = &errcode2;
} }
else
flagSuccess = true;
}
if (!flagSuccess)
checkSecurityResult(errcode1, &st1, "Unknown", Auth::DIS_OPER);
} }
catch (const Exception&) catch (const Exception&)
{ {

View File

@ -80,7 +80,7 @@ private:
void openAllManagers(); void openAllManagers();
Firebird::IManagement* registerManager(Auth::Get& getPlugin, const char* plugName); Firebird::IManagement* registerManager(Auth::Get& getPlugin, const char* plugName);
static void checkSecurityResult(int errcode, Firebird::IStatus* status, static void checkSecurityResult(int errcode, Firebird::IStatus* status,
const char* userName, Firebird::IUser* user); const char* userName, int operation);
}; };
} // namespace } // namespace

View File

@ -554,7 +554,7 @@ int gsec(Firebird::UtilSvc* uSvc)
if (ret) if (ret)
{ {
ret = setGsecCode(ret, user_data); // user_data, not u ! ret = setGsecCode(ret, user_data->operation());
fb_utils::mergeStatus(status, FB_NELEM(status), &statusManager); fb_utils::mergeStatus(status, FB_NELEM(status), &statusManager);
GSEC_print(ret, user_data->userName()->get()); GSEC_print(ret, user_data->userName()->get());
if (status[1]) if (status[1])
@ -584,7 +584,7 @@ int gsec(Firebird::UtilSvc* uSvc)
if (ret) if (ret)
{ {
ret = setGsecCode(ret, user_data); ret = setGsecCode(ret, user_data->operation());
fb_utils::mergeStatus(status, FB_NELEM(status), &statusManager); fb_utils::mergeStatus(status, FB_NELEM(status), &statusManager);
GSEC_print(ret, user_data->userName()->get()); GSEC_print(ret, user_data->userName()->get());
if (status[1]) if (status[1])
@ -608,7 +608,7 @@ int gsec(Firebird::UtilSvc* uSvc)
if (status[1]) if (status[1])
{ {
GSEC_print_status(status); GSEC_print_status(status);
ret = setGsecCode(-1, user_data); ret = setGsecCode(-1, user_data->operation());
} }
} }
} }