8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:03:04 +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
int setGsecCode(int code, IUser* user)
int setGsecCode(int code, int operation)
{
if (code >= 0)
{
return code;
}
switch(user->operation())
switch(operation)
{
case ADD_OPER:
return GsecMsg19;

View File

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

View File

@ -303,13 +303,13 @@ USHORT UserManagement::put(Auth::DynamicUserData* userData)
}
void UserManagement::checkSecurityResult(int errcode, IStatus* status,
const char* userName, IUser* user)
const char* userName, int operation)
{
if (!errcode)
{
return;
}
errcode = Auth::setGsecCode(errcode, user);
errcode = Auth::setGsecCode(errcode, operation);
Arg::StatusVector tmp;
tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
@ -362,7 +362,7 @@ void UserManagement::execute(USHORT id)
OldAttributes 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)
{
@ -453,7 +453,7 @@ void UserManagement::execute(USHORT id)
}
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];
commands[id] = NULL;
@ -571,6 +571,13 @@ RecordBuffer* UserManagement::getList(thread_db* tdbb, jrd_rel* relation)
try
{
openAllManagers();
bool flagSuccess = false;
LocalStatus st1, st2;
CheckStatusWrapper statusWrapper1(&st1);
CheckStatusWrapper statusWrapper2(&st2);
CheckStatusWrapper* currentWrapper(&statusWrapper1);
int errcode1, errcode2;
int* ec(&errcode1);
threadDbb = tdbb;
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)
{
LocalStatus status;
CheckStatusWrapper statusWrapper(&status);
Auth::StackUserData u;
u.op = Auth::DIS_OPER;
int errcode = managers[fillSnapshot.pos].second->execute(&statusWrapper, &u, &fillSnapshot);
checkSecurityResult(errcode, &status, "Unknown", &u);
*ec = managers[fillSnapshot.pos].second->execute(currentWrapper, &u, &fillSnapshot);
if (*ec)
{
currentWrapper = &statusWrapper2;
ec = &errcode2;
}
else
flagSuccess = true;
}
if (!flagSuccess)
checkSecurityResult(errcode1, &st1, "Unknown", Auth::DIS_OPER);
}
catch (const Exception&)
{

View File

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

View File

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