Skip to content

Commit 1cecd8e

Browse files
committed
Backported CORE-6412: Firebird is freezing when trying to manage users via triggers
1 parent b1e04f3 commit 1cecd8e

10 files changed

Lines changed: 316 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 = NULL)
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
@@ -668,6 +668,10 @@ interface LogonInfo : Versioned
668668
const string networkProtocol();
669669
const string remoteAddress();
670670
const uchar* authBlock(uint* length);
671+
672+
version:
673+
Attachment attachment(Status status);
674+
Transaction transaction(Status status);
671675
}
672676

673677
interface Management : PluginBase

src/include/firebird/IdlFbInterfaces.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2704,6 +2704,8 @@ namespace Firebird
27042704
const char* (CLOOP_CARG *networkProtocol)(ILogonInfo* self) throw();
27052705
const char* (CLOOP_CARG *remoteAddress)(ILogonInfo* self) throw();
27062706
const unsigned char* (CLOOP_CARG *authBlock)(ILogonInfo* self, unsigned* length) throw();
2707+
IAttachment* (CLOOP_CARG *attachment)(ILogonInfo* self, IStatus* status) throw();
2708+
ITransaction* (CLOOP_CARG *transaction)(ILogonInfo* self, IStatus* status) throw();
27072709
};
27082710

27092711
protected:
@@ -2717,7 +2719,7 @@ namespace Firebird
27172719
}
27182720

27192721
public:
2720-
static const unsigned VERSION = 2;
2722+
static const unsigned VERSION = 3;
27212723

27222724
const char* name()
27232725
{
@@ -2748,6 +2750,34 @@ namespace Firebird
27482750
const unsigned char* ret = static_cast<VTable*>(this->cloopVTable)->authBlock(this, length);
27492751
return ret;
27502752
}
2753+
2754+
template <typename StatusType> IAttachment* attachment(StatusType* status)
2755+
{
2756+
if (cloopVTable->version < 3)
2757+
{
2758+
StatusType::setVersionError(status, "ILogonInfo", cloopVTable->version, 3);
2759+
StatusType::checkException(status);
2760+
return 0;
2761+
}
2762+
StatusType::clearException(status);
2763+
IAttachment* ret = static_cast<VTable*>(this->cloopVTable)->attachment(this, status);
2764+
StatusType::checkException(status);
2765+
return ret;
2766+
}
2767+
2768+
template <typename StatusType> ITransaction* transaction(StatusType* status)
2769+
{
2770+
if (cloopVTable->version < 3)
2771+
{
2772+
StatusType::setVersionError(status, "ILogonInfo", cloopVTable->version, 3);
2773+
StatusType::checkException(status);
2774+
return 0;
2775+
}
2776+
StatusType::clearException(status);
2777+
ITransaction* ret = static_cast<VTable*>(this->cloopVTable)->transaction(this, status);
2778+
StatusType::checkException(status);
2779+
return ret;
2780+
}
27512781
};
27522782

27532783
class IManagement : public IPluginBase
@@ -10815,6 +10845,8 @@ namespace Firebird
1081510845
this->networkProtocol = &Name::cloopnetworkProtocolDispatcher;
1081610846
this->remoteAddress = &Name::cloopremoteAddressDispatcher;
1081710847
this->authBlock = &Name::cloopauthBlockDispatcher;
10848+
this->attachment = &Name::cloopattachmentDispatcher;
10849+
this->transaction = &Name::clooptransactionDispatcher;
1081810850
}
1081910851
} vTable;
1082010852

@@ -10885,6 +10917,36 @@ namespace Firebird
1088510917
return static_cast<const unsigned char*>(0);
1088610918
}
1088710919
}
10920+
10921+
static IAttachment* CLOOP_CARG cloopattachmentDispatcher(ILogonInfo* self, IStatus* status) throw()
10922+
{
10923+
StatusType status2(status);
10924+
10925+
try
10926+
{
10927+
return static_cast<Name*>(self)->Name::attachment(&status2);
10928+
}
10929+
catch (...)
10930+
{
10931+
StatusType::catchException(&status2);
10932+
return static_cast<IAttachment*>(0);
10933+
}
10934+
}
10935+
10936+
static ITransaction* CLOOP_CARG clooptransactionDispatcher(ILogonInfo* self, IStatus* status) throw()
10937+
{
10938+
StatusType status2(status);
10939+
10940+
try
10941+
{
10942+
return static_cast<Name*>(self)->Name::transaction(&status2);
10943+
}
10944+
catch (...)
10945+
{
10946+
StatusType::catchException(&status2);
10947+
return static_cast<ITransaction*>(0);
10948+
}
10949+
}
1088810950
};
1088910951

1089010952
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<ILogonInfo> > >
@@ -10905,6 +10967,8 @@ namespace Firebird
1090510967
virtual const char* networkProtocol() = 0;
1090610968
virtual const char* remoteAddress() = 0;
1090710969
virtual const unsigned char* authBlock(unsigned* length) = 0;
10970+
virtual IAttachment* attachment(StatusType* status) = 0;
10971+
virtual ITransaction* transaction(StatusType* status) = 0;
1090810972
};
1090910973

1091010974
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
@@ -361,6 +361,8 @@ FbException = class(Exception)
361361
ILogonInfo_networkProtocolPtr = function(this: ILogonInfo): PAnsiChar; cdecl;
362362
ILogonInfo_remoteAddressPtr = function(this: ILogonInfo): PAnsiChar; cdecl;
363363
ILogonInfo_authBlockPtr = function(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl;
364+
ILogonInfo_attachmentPtr = function(this: ILogonInfo; status: IStatus): IAttachment; cdecl;
365+
ILogonInfo_transactionPtr = function(this: ILogonInfo; status: IStatus): ITransaction; cdecl;
364366
IManagement_startPtr = procedure(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl;
365367
IManagement_executePtr = function(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl;
366368
IManagement_commitPtr = procedure(this: IManagement; status: IStatus); cdecl;
@@ -1838,16 +1840,20 @@ LogonInfoVTable = class(VersionedVTable)
18381840
networkProtocol: ILogonInfo_networkProtocolPtr;
18391841
remoteAddress: ILogonInfo_remoteAddressPtr;
18401842
authBlock: ILogonInfo_authBlockPtr;
1843+
attachment: ILogonInfo_attachmentPtr;
1844+
transaction: ILogonInfo_transactionPtr;
18411845
end;
18421846

18431847
ILogonInfo = class(IVersioned)
1844-
const VERSION = 2;
1848+
const VERSION = 3;
18451849

18461850
function name(): PAnsiChar;
18471851
function role(): PAnsiChar;
18481852
function networkProtocol(): PAnsiChar;
18491853
function remoteAddress(): PAnsiChar;
18501854
function authBlock(length: CardinalPtr): BytePtr;
1855+
function attachment(status: IStatus): IAttachment;
1856+
function transaction(status: IStatus): ITransaction;
18511857
end;
18521858

18531859
ILogonInfoImpl = class(ILogonInfo)
@@ -1858,6 +1864,8 @@ ILogonInfoImpl = class(ILogonInfo)
18581864
function networkProtocol(): PAnsiChar; virtual; abstract;
18591865
function remoteAddress(): PAnsiChar; virtual; abstract;
18601866
function authBlock(length: CardinalPtr): BytePtr; virtual; abstract;
1867+
function attachment(status: IStatus): IAttachment; virtual; abstract;
1868+
function transaction(status: IStatus): ITransaction; virtual; abstract;
18611869
end;
18621870

18631871
ManagementVTable = class(PluginBaseVTable)
@@ -5993,6 +6001,18 @@ function ILogonInfo.authBlock(length: CardinalPtr): BytePtr;
59936001
Result := LogonInfoVTable(vTable).authBlock(Self, length);
59946002
end;
59956003

6004+
function ILogonInfo.attachment(status: IStatus): IAttachment;
6005+
begin
6006+
Result := LogonInfoVTable(vTable).attachment(Self, status);
6007+
FbException.checkException(status);
6008+
end;
6009+
6010+
function ILogonInfo.transaction(status: IStatus): ITransaction;
6011+
begin
6012+
Result := LogonInfoVTable(vTable).transaction(Self, status);
6013+
FbException.checkException(status);
6014+
end;
6015+
59966016
procedure IManagement.start(status: IStatus; logonInfo: ILogonInfo);
59976017
begin
59986018
ManagementVTable(vTable).start(Self, status, logonInfo);
@@ -9837,6 +9857,24 @@ function ILogonInfoImpl_authBlockDispatcher(this: ILogonInfo; length: CardinalPt
98379857
end
98389858
end;
98399859

9860+
function ILogonInfoImpl_attachmentDispatcher(this: ILogonInfo; status: IStatus): IAttachment; cdecl;
9861+
begin
9862+
try
9863+
Result := ILogonInfoImpl(this).attachment(status);
9864+
except
9865+
on e: Exception do FbException.catchException(status, e);
9866+
end
9867+
end;
9868+
9869+
function ILogonInfoImpl_transactionDispatcher(this: ILogonInfo; status: IStatus): ITransaction; cdecl;
9870+
begin
9871+
try
9872+
Result := ILogonInfoImpl(this).transaction(status);
9873+
except
9874+
on e: Exception do FbException.catchException(status, e);
9875+
end
9876+
end;
9877+
98409878
var
98419879
ILogonInfoImpl_vTable: LogonInfoVTable;
98429880

@@ -12963,12 +13001,14 @@ initialization
1296313001
IListUsersImpl_vTable.list := @IListUsersImpl_listDispatcher;
1296413002

1296513003
ILogonInfoImpl_vTable := LogonInfoVTable.create;
12966-
ILogonInfoImpl_vTable.version := 5;
13004+
ILogonInfoImpl_vTable.version := 7;
1296713005
ILogonInfoImpl_vTable.name := @ILogonInfoImpl_nameDispatcher;
1296813006
ILogonInfoImpl_vTable.role := @ILogonInfoImpl_roleDispatcher;
1296913007
ILogonInfoImpl_vTable.networkProtocol := @ILogonInfoImpl_networkProtocolDispatcher;
1297013008
ILogonInfoImpl_vTable.remoteAddress := @ILogonInfoImpl_remoteAddressDispatcher;
1297113009
ILogonInfoImpl_vTable.authBlock := @ILogonInfoImpl_authBlockDispatcher;
13010+
ILogonInfoImpl_vTable.attachment := @ILogonInfoImpl_attachmentDispatcher;
13011+
ILogonInfoImpl_vTable.transaction := @ILogonInfoImpl_transactionDispatcher;
1297213012

1297313013
IManagementImpl_vTable := ManagementVTable.create;
1297413014
IManagementImpl_vTable.version := 8;

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
@@ -72,8 +72,19 @@ namespace
7272
return aBlock.getCount() ? aBlock.begin() : NULL;
7373
}
7474

75+
JAttachment* attachment(CheckStatusWrapper*)
76+
{
77+
return att->getInterface();
78+
}
79+
80+
JTransaction* transaction(CheckStatusWrapper*)
81+
{
82+
return tra->getInterface(false);
83+
}
84+
7585
private:
76-
const Attachment* att;
86+
Attachment* att;
87+
jrd_tra* tra;
7788
};
7889

7990
class FillSnapshot : public AutoIface<IListUsersImpl<FillSnapshot, CheckStatusWrapper> >
@@ -144,13 +155,14 @@ bool UsersTableScan::retrieveRecord(thread_db* tdbb, jrd_rel* relation,
144155
}
145156

146157

147-
UserManagement::UserManagement(jrd_tra* tra)
148-
: SnapshotData(*tra->tra_pool),
158+
UserManagement::UserManagement(jrd_tra* pTra)
159+
: SnapshotData(*pTra->tra_pool),
149160
threadDbb(NULL),
150-
commands(*tra->tra_pool),
151-
managers(*tra->tra_pool),
152-
plugins(*tra->tra_pool),
153-
att(tra->tra_attachment)
161+
commands(*pTra->tra_pool),
162+
managers(*pTra->tra_pool),
163+
plugins(*pTra->tra_pool),
164+
att(pTra->tra_attachment),
165+
tra(pTra)
154166
{
155167
if (!att || !att->att_user)
156168
{
@@ -170,7 +182,7 @@ IManagement* UserManagement::registerManager(Auth::Get& getPlugin, const char* p
170182
LocalStatus status;
171183
CheckStatusWrapper statusWrapper(&status);
172184

173-
UserIdInfo idInfo(att);
185+
UserIdInfo idInfo(att, tra);
174186
manager->start(&statusWrapper, &idInfo);
175187
if (status.getState() & IStatus::STATE_ERRORS)
176188
{
@@ -298,6 +310,7 @@ USHORT UserManagement::put(Auth::DynamicUserData* userData)
298310
{
299311
status_exception::raise(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
@@ -75,6 +75,7 @@ class UserManagement : public SnapshotData
7575
Firebird::ObjectsArray<Manager> managers;
7676
Firebird::NoCaseString plugins;
7777
Attachment* att;
78+
jrd_tra* tra;
7879

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

src/jrd/inf.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,14 @@ void INF_database_info(thread_db* tdbb,
792792
length = INF_convert(tdbb->getAttachment()->att_remote_flags, buffer);
793793
break;
794794

795+
case fb_info_db_file_id:
796+
{
797+
const string& fileId = dbb->getUniqueFileId();
798+
if (!(info = INF_put_item(item, fileId.length(), fileId.c_str(), info, end)))
799+
return;
800+
}
801+
break;
802+
795803
default:
796804
buffer[0] = item;
797805
item = isc_info_error;

src/jrd/inf_pub.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ enum db_info_types
145145
fb_info_crypt_key = 133,
146146
fb_info_crypt_state = 134,
147147

148+
fb_info_db_file_id = 145,
149+
148150
isc_info_db_last_value /* Leave this LAST! */
149151
};
150152

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 NULL;
196+
}
197+
198+
Firebird::ITransaction* transaction(Firebird::CheckStatusWrapper* status)
199+
{
200+
return NULL;
201+
}
202+
193203
private:
194204
const char* dba;
195205
const char* sqlRole;

0 commit comments

Comments
 (0)