Skip to content

Commit 0cfdd3d

Browse files
committed
Fixed CORE-6412: Firebird is freezing when trying to manage users via triggers
1 parent 3089a2d commit 0cfdd3d

8 files changed

Lines changed: 306 additions & 91 deletions

File tree

src/auth/SecureRemotePassword/manage/SrpManagement.cpp

Lines changed: 151 additions & 78 deletions
Large diffs are not rendered by default.

src/common/classes/auto.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,16 @@ class AutoDispose : public AutoPtr<Where, SimpleDispose>
188188
};
189189

190190

191+
template <typename Where>
192+
class AutoRelease : public AutoPtr<Where, SimpleRelease>
193+
{
194+
public:
195+
AutoRelease(Where* v = nullptr)
196+
: AutoPtr<Where, SimpleRelease>(v)
197+
{ }
198+
};
199+
200+
191201
template <typename T>
192202
class AutoSetRestore
193203
{

src/include/firebird/FirebirdInterface.idl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,10 @@ interface LogonInfo : Versioned
797797
const string networkProtocol();
798798
const string remoteAddress();
799799
const uchar* authBlock(uint* length);
800+
801+
version:
802+
Attachment attachment(Status status);
803+
Transaction transaction(Status status);
800804
}
801805

802806
interface Management : PluginBase

src/include/firebird/IdlFbInterfaces.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3162,6 +3162,8 @@ namespace Firebird
31623162
const char* (CLOOP_CARG *networkProtocol)(ILogonInfo* self) throw();
31633163
const char* (CLOOP_CARG *remoteAddress)(ILogonInfo* self) throw();
31643164
const unsigned char* (CLOOP_CARG *authBlock)(ILogonInfo* self, unsigned* length) throw();
3165+
IAttachment* (CLOOP_CARG *attachment)(ILogonInfo* self, IStatus* status) throw();
3166+
ITransaction* (CLOOP_CARG *transaction)(ILogonInfo* self, IStatus* status) throw();
31653167
};
31663168

31673169
protected:
@@ -3175,7 +3177,7 @@ namespace Firebird
31753177
}
31763178

31773179
public:
3178-
static const unsigned VERSION = 2;
3180+
static const unsigned VERSION = 3;
31793181

31803182
const char* name()
31813183
{
@@ -3206,6 +3208,34 @@ namespace Firebird
32063208
const unsigned char* ret = static_cast<VTable*>(this->cloopVTable)->authBlock(this, length);
32073209
return ret;
32083210
}
3211+
3212+
template <typename StatusType> IAttachment* attachment(StatusType* status)
3213+
{
3214+
if (cloopVTable->version < 3)
3215+
{
3216+
StatusType::setVersionError(status, "ILogonInfo", cloopVTable->version, 3);
3217+
StatusType::checkException(status);
3218+
return 0;
3219+
}
3220+
StatusType::clearException(status);
3221+
IAttachment* ret = static_cast<VTable*>(this->cloopVTable)->attachment(this, status);
3222+
StatusType::checkException(status);
3223+
return ret;
3224+
}
3225+
3226+
template <typename StatusType> ITransaction* transaction(StatusType* status)
3227+
{
3228+
if (cloopVTable->version < 3)
3229+
{
3230+
StatusType::setVersionError(status, "ILogonInfo", cloopVTable->version, 3);
3231+
StatusType::checkException(status);
3232+
return 0;
3233+
}
3234+
StatusType::clearException(status);
3235+
ITransaction* ret = static_cast<VTable*>(this->cloopVTable)->transaction(this, status);
3236+
StatusType::checkException(status);
3237+
return ret;
3238+
}
32093239
};
32103240

32113241
class IManagement : public IPluginBase
@@ -12559,6 +12589,8 @@ namespace Firebird
1255912589
this->networkProtocol = &Name::cloopnetworkProtocolDispatcher;
1256012590
this->remoteAddress = &Name::cloopremoteAddressDispatcher;
1256112591
this->authBlock = &Name::cloopauthBlockDispatcher;
12592+
this->attachment = &Name::cloopattachmentDispatcher;
12593+
this->transaction = &Name::clooptransactionDispatcher;
1256212594
}
1256312595
} vTable;
1256412596

@@ -12629,6 +12661,36 @@ namespace Firebird
1262912661
return static_cast<const unsigned char*>(0);
1263012662
}
1263112663
}
12664+
12665+
static IAttachment* CLOOP_CARG cloopattachmentDispatcher(ILogonInfo* self, IStatus* status) throw()
12666+
{
12667+
StatusType status2(status);
12668+
12669+
try
12670+
{
12671+
return static_cast<Name*>(self)->Name::attachment(&status2);
12672+
}
12673+
catch (...)
12674+
{
12675+
StatusType::catchException(&status2);
12676+
return static_cast<IAttachment*>(0);
12677+
}
12678+
}
12679+
12680+
static ITransaction* CLOOP_CARG clooptransactionDispatcher(ILogonInfo* self, IStatus* status) throw()
12681+
{
12682+
StatusType status2(status);
12683+
12684+
try
12685+
{
12686+
return static_cast<Name*>(self)->Name::transaction(&status2);
12687+
}
12688+
catch (...)
12689+
{
12690+
StatusType::catchException(&status2);
12691+
return static_cast<ITransaction*>(0);
12692+
}
12693+
}
1263212694
};
1263312695

1263412696
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<ILogonInfo> > >
@@ -12649,6 +12711,8 @@ namespace Firebird
1264912711
virtual const char* networkProtocol() = 0;
1265012712
virtual const char* remoteAddress() = 0;
1265112713
virtual const unsigned char* authBlock(unsigned* length) = 0;
12714+
virtual IAttachment* attachment(StatusType* status) = 0;
12715+
virtual ITransaction* transaction(StatusType* status) = 0;
1265212716
};
1265312717

1265412718
template <typename Name, typename StatusType, typename Base>

src/include/gen/Firebird.pas

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ ISC_TIMESTAMP_TZ_EX = record
447447
ILogonInfo_networkProtocolPtr = function(this: ILogonInfo): PAnsiChar; cdecl;
448448
ILogonInfo_remoteAddressPtr = function(this: ILogonInfo): PAnsiChar; cdecl;
449449
ILogonInfo_authBlockPtr = function(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl;
450+
ILogonInfo_attachmentPtr = function(this: ILogonInfo; status: IStatus): IAttachment; cdecl;
451+
ILogonInfo_transactionPtr = function(this: ILogonInfo; status: IStatus): ITransaction; cdecl;
450452
IManagement_startPtr = procedure(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl;
451453
IManagement_executePtr = function(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl;
452454
IManagement_commitPtr = procedure(this: IManagement; status: IStatus); cdecl;
@@ -2127,16 +2129,20 @@ LogonInfoVTable = class(VersionedVTable)
21272129
networkProtocol: ILogonInfo_networkProtocolPtr;
21282130
remoteAddress: ILogonInfo_remoteAddressPtr;
21292131
authBlock: ILogonInfo_authBlockPtr;
2132+
attachment: ILogonInfo_attachmentPtr;
2133+
transaction: ILogonInfo_transactionPtr;
21302134
end;
21312135

21322136
ILogonInfo = class(IVersioned)
2133-
const VERSION = 2;
2137+
const VERSION = 3;
21342138

21352139
function name(): PAnsiChar;
21362140
function role(): PAnsiChar;
21372141
function networkProtocol(): PAnsiChar;
21382142
function remoteAddress(): PAnsiChar;
21392143
function authBlock(length: CardinalPtr): BytePtr;
2144+
function attachment(status: IStatus): IAttachment;
2145+
function transaction(status: IStatus): ITransaction;
21402146
end;
21412147

21422148
ILogonInfoImpl = class(ILogonInfo)
@@ -2147,6 +2153,8 @@ ILogonInfoImpl = class(ILogonInfo)
21472153
function networkProtocol(): PAnsiChar; virtual; abstract;
21482154
function remoteAddress(): PAnsiChar; virtual; abstract;
21492155
function authBlock(length: CardinalPtr): BytePtr; virtual; abstract;
2156+
function attachment(status: IStatus): IAttachment; virtual; abstract;
2157+
function transaction(status: IStatus): ITransaction; virtual; abstract;
21502158
end;
21512159

21522160
ManagementVTable = class(PluginBaseVTable)
@@ -6925,6 +6933,18 @@ function ILogonInfo.authBlock(length: CardinalPtr): BytePtr;
69256933
Result := LogonInfoVTable(vTable).authBlock(Self, length);
69266934
end;
69276935

6936+
function ILogonInfo.attachment(status: IStatus): IAttachment;
6937+
begin
6938+
Result := LogonInfoVTable(vTable).attachment(Self, status);
6939+
FbException.checkException(status);
6940+
end;
6941+
6942+
function ILogonInfo.transaction(status: IStatus): ITransaction;
6943+
begin
6944+
Result := LogonInfoVTable(vTable).transaction(Self, status);
6945+
FbException.checkException(status);
6946+
end;
6947+
69286948
procedure IManagement.start(status: IStatus; logonInfo: ILogonInfo);
69296949
begin
69306950
ManagementVTable(vTable).start(Self, status, logonInfo);
@@ -11392,6 +11412,24 @@ function ILogonInfoImpl_authBlockDispatcher(this: ILogonInfo; length: CardinalPt
1139211412
end
1139311413
end;
1139411414

11415+
function ILogonInfoImpl_attachmentDispatcher(this: ILogonInfo; status: IStatus): IAttachment; cdecl;
11416+
begin
11417+
try
11418+
Result := ILogonInfoImpl(this).attachment(status);
11419+
except
11420+
on e: Exception do FbException.catchException(status, e);
11421+
end
11422+
end;
11423+
11424+
function ILogonInfoImpl_transactionDispatcher(this: ILogonInfo; status: IStatus): ITransaction; cdecl;
11425+
begin
11426+
try
11427+
Result := ILogonInfoImpl(this).transaction(status);
11428+
except
11429+
on e: Exception do FbException.catchException(status, e);
11430+
end
11431+
end;
11432+
1139511433
var
1139611434
ILogonInfoImpl_vTable: LogonInfoVTable;
1139711435

@@ -15088,12 +15126,14 @@ initialization
1508815126
IListUsersImpl_vTable.list := @IListUsersImpl_listDispatcher;
1508915127

1509015128
ILogonInfoImpl_vTable := LogonInfoVTable.create;
15091-
ILogonInfoImpl_vTable.version := 2;
15129+
ILogonInfoImpl_vTable.version := 3;
1509215130
ILogonInfoImpl_vTable.name := @ILogonInfoImpl_nameDispatcher;
1509315131
ILogonInfoImpl_vTable.role := @ILogonInfoImpl_roleDispatcher;
1509415132
ILogonInfoImpl_vTable.networkProtocol := @ILogonInfoImpl_networkProtocolDispatcher;
1509515133
ILogonInfoImpl_vTable.remoteAddress := @ILogonInfoImpl_remoteAddressDispatcher;
1509615134
ILogonInfoImpl_vTable.authBlock := @ILogonInfoImpl_authBlockDispatcher;
15135+
ILogonInfoImpl_vTable.attachment := @ILogonInfoImpl_attachmentDispatcher;
15136+
ILogonInfoImpl_vTable.transaction := @ILogonInfoImpl_transactionDispatcher;
1509715137

1509815138
IManagementImpl_vTable := ManagementVTable.create;
1509915139
IManagementImpl_vTable.version := 4;

src/jrd/UserManagement.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ namespace
4040
class UserIdInfo : public AutoIface<ILogonInfoImpl<UserIdInfo, CheckStatusWrapper> >
4141
{
4242
public:
43-
explicit UserIdInfo(const Attachment* pAtt)
44-
: att(pAtt)
43+
explicit UserIdInfo(Attachment* pAtt, jrd_tra* pTra)
44+
: att(pAtt), tra(pTra)
4545
{ }
4646

4747
// ILogonInfo implementation
@@ -74,8 +74,19 @@ namespace
7474
return aBlock.getCount() ? aBlock.begin() : NULL;
7575
}
7676

77+
JAttachment* attachment(CheckStatusWrapper*)
78+
{
79+
return att->getInterface();
80+
}
81+
82+
JTransaction* transaction(CheckStatusWrapper*)
83+
{
84+
return tra->getInterface(false);
85+
}
86+
7787
private:
78-
const Attachment* att;
88+
Attachment* att;
89+
jrd_tra* tra;
7990
};
8091

8192
class FillSnapshot : public AutoIface<IListUsersImpl<FillSnapshot, CheckStatusWrapper> >
@@ -146,13 +157,14 @@ bool UsersTableScan::retrieveRecord(thread_db* tdbb, jrd_rel* relation,
146157
}
147158

148159

149-
UserManagement::UserManagement(jrd_tra* tra)
150-
: SnapshotData(*tra->tra_pool),
160+
UserManagement::UserManagement(jrd_tra* pTra)
161+
: SnapshotData(*pTra->tra_pool),
151162
threadDbb(NULL),
152-
commands(*tra->tra_pool),
153-
managers(*tra->tra_pool),
154-
plugins(*tra->tra_pool),
155-
att(tra->tra_attachment)
163+
commands(*pTra->tra_pool),
164+
managers(*pTra->tra_pool),
165+
plugins(*pTra->tra_pool),
166+
att(pTra->tra_attachment),
167+
tra(pTra)
156168
{
157169
if (!att || !att->att_user)
158170
{
@@ -172,7 +184,7 @@ IManagement* UserManagement::registerManager(Auth::Get& getPlugin, const char* p
172184
LocalStatus status;
173185
CheckStatusWrapper statusWrapper(&status);
174186

175-
UserIdInfo idInfo(att);
187+
UserIdInfo idInfo(att, tra);
176188
manager->start(&statusWrapper, &idInfo);
177189
if (status.getState() & IStatus::STATE_ERRORS)
178190
{
@@ -298,6 +310,7 @@ USHORT UserManagement::put(Auth::DynamicUserData* userData)
298310
{
299311
status_exception::raise(Arg::Gds(isc_imp_exc) << Arg::Gds(isc_random) << "Too many user management DDL per transaction");
300312
}
313+
301314
commands.push(userData);
302315
return ret;
303316
}

src/jrd/UserManagement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class UserManagement : public SnapshotData
7676
Firebird::ObjectsArray<Manager> managers;
7777
Firebird::NoCaseString plugins;
7878
Attachment* att;
79+
jrd_tra* tra;
7980

8081
Firebird::IManagement* getManager(const char* name);
8182
void openAllManagers();

src/utilities/gsec/gsec.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,16 @@ namespace {
190190
return authBytes;
191191
}
192192

193+
Firebird::IAttachment* attachment(Firebird::CheckStatusWrapper* status)
194+
{
195+
return nullptr;
196+
}
197+
198+
Firebird::ITransaction* transaction(Firebird::CheckStatusWrapper* status)
199+
{
200+
return nullptr;
201+
}
202+
193203
private:
194204
const char* dba;
195205
const char* sqlRole;

0 commit comments

Comments
 (0)