mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:03:03 +01:00
Add system privilege PROFILE_ANY_ATTACHMENT and permission check.
Add some static_asserts.
This commit is contained in:
parent
82a569fb7e
commit
e090ec0f60
@ -557,6 +557,7 @@ GRANT_REVOKE_ANY_DDL_RIGHT GRANT and REVOKE any DDL rights
|
||||
CREATE_PRIVILEGED_ROLES Use SET SYSTEM PRIVILEGES in roles
|
||||
MODIFY_EXT_CONN_POOL Manage properties of pool of external connections
|
||||
REPLICATE_INTO_DATABASE Use replication API to load changesets into database
|
||||
PROFILE_ANY_ATTACHMENT Profile other users' attachments
|
||||
|
||||
|
||||
22) New grantee type in GRANT and REVOKE operators - SYSTEM PRIVILEGE.
|
||||
|
@ -14,6 +14,8 @@ Remote profiling just forwards commands to the remote attachment. So it's possib
|
||||
|
||||
Remote issued commands needs that the target attachment be in an idle state, i.e., not executing others requests. When they are not idle the call blocks waiting for that state.
|
||||
|
||||
If remote attachment is from a different user, the calling user must have system privilege PROFILE_ANY_ATTACHMENT.
|
||||
|
||||
After a session is started, PSQL and SQL statements statistics starts to be collected in memory. Note that a profile session collects data only of statements executed in the same attachment associated with the session.
|
||||
|
||||
Data is aggregated and stored per requests (i.e. a statement execution). When querying snapshot tables, user may do extra aggregation per statements or use the auxiliary views that do that automatically.
|
||||
|
@ -88,6 +88,7 @@ namespace
|
||||
event_t clientEvent;
|
||||
USHORT bufferSize;
|
||||
Tag tag;
|
||||
char userName[USERNAME_LENGTH + 1]; // \0 if has PROFILE_ANY_ATTACHMENT
|
||||
alignas(FB_ALIGNMENT) UCHAR buffer[4096];
|
||||
};
|
||||
|
||||
@ -107,12 +108,14 @@ namespace
|
||||
template <typename Input, typename Output>
|
||||
void sendAndReceive(thread_db* tdbb, Tag tag, const Input* in, Output* out)
|
||||
{
|
||||
static_assert(sizeof(*in) <= sizeof(std::declval<Header>().buffer), "Buffer size too small");
|
||||
internalSendAndReceive(tdbb, tag, in, sizeof(*in), out, sizeof(*out));
|
||||
}
|
||||
|
||||
template <typename Input>
|
||||
void send(thread_db* tdbb, Tag tag, const Input* in)
|
||||
{
|
||||
static_assert(sizeof(*in) <= sizeof(std::declval<Header>().buffer), "Buffer size too small");
|
||||
internalSendAndReceive(tdbb, tag, in, sizeof(*in), nullptr, 0);
|
||||
}
|
||||
|
||||
@ -757,6 +760,8 @@ void ProfilerIpc::mutexBug(int osErrorCode, const char* text)
|
||||
void ProfilerIpc::internalSendAndReceive(thread_db* tdbb, Tag tag,
|
||||
const void* in, unsigned inSize, void* out, unsigned outSize)
|
||||
{
|
||||
const auto attachment = tdbb->getAttachment();
|
||||
|
||||
{ // scope
|
||||
ThreadStatusGuard tempStatus(tdbb);
|
||||
|
||||
@ -782,9 +787,15 @@ void ProfilerIpc::internalSendAndReceive(thread_db* tdbb, Tag tag,
|
||||
|
||||
const auto header = sharedMemory->getHeader();
|
||||
|
||||
header->bufferSize = inSize;
|
||||
header->tag = tag;
|
||||
|
||||
if (attachment->locksmith(tdbb, PROFILE_ANY_ATTACHMENT))
|
||||
header->userName[0] = '\0';
|
||||
else
|
||||
strcpy(header->userName, attachment->getUserName().c_str());
|
||||
|
||||
header->bufferSize = inSize;
|
||||
|
||||
fb_assert(inSize <= sizeof(header->buffer));
|
||||
memcpy(header->buffer, in, inSize);
|
||||
|
||||
@ -928,6 +939,9 @@ void ProfilerListener::processCommand(thread_db* tdbb)
|
||||
const auto header = ipc->sharedMemory->getHeader();
|
||||
const auto profilerManager = attachment->getProfilerManager(tdbb);
|
||||
|
||||
if (header->userName[0] && attachment->getUserName() != header->userName)
|
||||
status_exception::raise(Arg::Gds(isc_miss_prvlg) << "PROFILE_ANY_ATTACHMENT");
|
||||
|
||||
using Tag = ProfilerIpc::Tag;
|
||||
|
||||
switch (header->tag)
|
||||
@ -983,6 +997,7 @@ void ProfilerListener::processCommand(thread_db* tdbb)
|
||||
in->pluginOptionsNull ? 0 : in->pluginOptions.length);
|
||||
|
||||
const auto out = reinterpret_cast<ProfilerPackage::StartSessionOutput::Type*>(header->buffer);
|
||||
static_assert(sizeof(*out) <= sizeof(header->buffer), "Buffer size too small");
|
||||
header->bufferSize = sizeof(*out);
|
||||
|
||||
out->sessionIdNull = FB_FALSE;
|
||||
|
@ -65,6 +65,7 @@ SYSTEM_PRIVILEGE(CREATE_PRIVILEGED_ROLES)
|
||||
SYSTEM_PRIVILEGE(GET_DBCRYPT_INFO)
|
||||
SYSTEM_PRIVILEGE(MODIFY_EXT_CONN_POOL)
|
||||
SYSTEM_PRIVILEGE(REPLICATE_INTO_DATABASE)
|
||||
SYSTEM_PRIVILEGE(PROFILE_ANY_ATTACHMENT)
|
||||
|
||||
#ifdef FB_JRD_SYSTEM_PRIVILEGES_TMP
|
||||
maxSystemPrivilege
|
||||
|
Loading…
Reference in New Issue
Block a user