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

Fixed bug CORE-5995 : Creator user name is empty in user trace sessions

This commit is contained in:
hvlad 2019-01-29 12:26:00 +02:00
parent 17642e73fc
commit 85fd7bdd44
6 changed files with 78 additions and 29 deletions

View File

@ -3200,3 +3200,8 @@ const char* Service::getServiceName() const
{ {
return svc_service_run ? svc_service_run->serv_name : NULL; return svc_service_run ? svc_service_run->serv_name : NULL;
} }
bool Service::getUserAdminFlag() const
{
return (svc_user_flag & SVC_user_dba);
}

View File

@ -191,6 +191,10 @@ public: // external interface with service
return svc_username; return svc_username;
} }
// return true if user have admin privileges in security database used
// for service user authentication
bool getUserAdminFlag() const;
const Firebird::string& getNetworkProtocol() const { return svc_network_protocol; } const Firebird::string& getNetworkProtocol() const { return svc_network_protocol; }
const Firebird::string& getRemoteAddress() const { return svc_remote_address; } const Firebird::string& getRemoteAddress() const { return svc_remote_address; }
const Firebird::string& getRemoteProcess() const { return svc_remote_process; } const Firebird::string& getRemoteProcess() const { return svc_remote_process; }

View File

@ -278,7 +278,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
const Switches authSwitches(trace_auth_in_sw_table, FB_NELEM(trace_auth_in_sw_table), const Switches authSwitches(trace_auth_in_sw_table, FB_NELEM(trace_auth_in_sw_table),
false, true); false, true);
string svc_name, user, pwd; string svc_name, user, pwd;
bool adminRole = false; bool trusted = false;
for (int itr = 1; itr < argc; ++itr) for (int itr = 1; itr < argc; ++itr)
{ {
if (!argv[itr]) if (!argv[itr])
@ -354,7 +354,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
if (uSvc->isService()) if (uSvc->isService())
usage(uSvc, isc_trace_switch_user_only, sw->in_sw_name); usage(uSvc, isc_trace_switch_user_only, sw->in_sw_name);
adminRole = true; trusted = true;
break; break;
case IN_SW_TRACE_SERVICE_NAME: case IN_SW_TRACE_SERVICE_NAME:
@ -400,19 +400,7 @@ void fbtrace(UtilSvc* uSvc, TraceSvcIntf* traceSvc)
} }
} }
AuthReader::AuthBlock authBlock; traceSvc->setAttachInfo(svc_name, user, pwd, trusted);
const unsigned char* bytes;
unsigned int authBlockSize = uSvc->getAuthBlock(&bytes);
if (authBlockSize)
{
authBlock.add(bytes, authBlockSize);
pwd = "";
user = "";
adminRole = false;
}
traceSvc->setAttachInfo(svc_name, user, pwd, authBlock, adminRole);
switch (action_sw->in_sw) switch (action_sw->in_sw)
{ {

View File

@ -38,6 +38,7 @@
#include "../../jrd/trace/TraceLog.h" #include "../../jrd/trace/TraceLog.h"
#include "../../jrd/trace/TraceManager.h" #include "../../jrd/trace/TraceManager.h"
#include "../../jrd/trace/TraceService.h" #include "../../jrd/trace/TraceService.h"
#include "../../jrd/Mapping.h"
using namespace Firebird; using namespace Firebird;
using namespace Jrd; using namespace Jrd;
@ -55,7 +56,7 @@ public:
virtual ~TraceSvcJrd() {}; virtual ~TraceSvcJrd() {};
virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd, virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd,
const AuthReader::AuthBlock& authBlock, bool isAdmin); bool trusted);
virtual void startSession(TraceSession& session, bool interactive); virtual void startSession(TraceSession& session, bool interactive);
virtual void stopSession(ULONG id); virtual void stopSession(ULONG id);
@ -67,6 +68,9 @@ private:
bool changeFlags(ULONG id, int setFlags, int clearFlags); bool changeFlags(ULONG id, int setFlags, int clearFlags);
bool checkAliveAndFlags(ULONG sesId, int& flags); bool checkAliveAndFlags(ULONG sesId, int& flags);
// Check if current service is allowed to list\stop given other session
bool checkPrivileges(TraceSession& session);
Service& m_svc; Service& m_svc;
string m_user; string m_user;
AuthReader::AuthBlock m_authBlock; AuthReader::AuthBlock m_authBlock;
@ -74,12 +78,21 @@ private:
ULONG m_chg_number; ULONG m_chg_number;
}; };
void TraceSvcJrd::setAttachInfo(const string& /*svc_name*/, const string& user, const string& pwd, void TraceSvcJrd::setAttachInfo(const string& /*svc_name*/, const string& user, const string& /*pwd*/,
const AuthReader::AuthBlock& authBlock, bool isAdmin) bool /*trusted*/)
{ {
m_authBlock = authBlock; const unsigned char* bytes;
m_user = user; unsigned int authBlockSize = m_svc.getAuthBlock(&bytes);
m_admin = isAdmin || (m_user == SYSDBA_USER_NAME); if (authBlockSize)
{
m_authBlock.add(bytes, authBlockSize);
m_user = "";
}
else
{
m_user = user;
m_admin = (m_user == SYSDBA_USER_NAME);
}
} }
void TraceSvcJrd::startSession(TraceSession& session, bool interactive) void TraceSvcJrd::startSession(TraceSession& session, bool interactive)
@ -96,7 +109,7 @@ void TraceSvcJrd::startSession(TraceSession& session, bool interactive)
StorageGuard guard(storage); StorageGuard guard(storage);
session.ses_auth = m_authBlock; session.ses_auth = m_authBlock;
session.ses_user = m_user; session.ses_user = m_user.hasData() ? m_user : m_svc.getUserName();
session.ses_flags = trs_active; session.ses_flags = trs_active;
if (m_admin) { if (m_admin) {
@ -146,7 +159,7 @@ void TraceSvcJrd::stopSession(ULONG id)
if (id != session.ses_id) if (id != session.ses_id)
continue; continue;
if (m_admin || m_user == session.ses_user) if (checkPrivileges(session))
{ {
storage->removeSession(id); storage->removeSession(id);
m_svc.printf(false, "Trace session ID %ld stopped\n", id); m_svc.printf(false, "Trace session ID %ld stopped\n", id);
@ -189,7 +202,7 @@ bool TraceSvcJrd::changeFlags(ULONG id, int setFlags, int clearFlags)
if (id != session.ses_id) if (id != session.ses_id)
continue; continue;
if (m_admin || m_user == session.ses_user) if (checkPrivileges(session))
{ {
const int saveFlags = session.ses_flags; const int saveFlags = session.ses_flags;
@ -223,7 +236,7 @@ void TraceSvcJrd::listSessions()
TraceSession session(*getDefaultMemoryPool()); TraceSession session(*getDefaultMemoryPool());
while (storage->getNextSession(session)) while (storage->getNextSession(session))
{ {
if (m_admin || m_user == session.ses_user) if (checkPrivileges(session))
{ {
m_svc.printf(false, "\nSession ID: %d\n", session.ses_id); m_svc.printf(false, "\nSession ID: %d\n", session.ses_id);
if (!session.ses_name.empty()) { if (!session.ses_name.empty()) {
@ -331,6 +344,45 @@ bool TraceSvcJrd::checkAliveAndFlags(ULONG sesId, int& flags)
return alive; return alive;
} }
bool TraceSvcJrd::checkPrivileges(TraceSession& session)
{
// Our service run in embedded mode and have no auth info - trust user name as is
if (m_admin || m_user.hasData() && (m_user == session.ses_user))
return true;
// Other session is fully authorized - try to map our auth info using other's
// security database
if (session.ses_auth.hasData())
{
AuthReader::Info info;
for (AuthReader rdr(session.ses_auth); rdr.getInfo(info); rdr.moveNext())
{
const char* secDb = info.secDb.hasData() ? info.secDb.c_str() :
Config::getDefaultConfig()->getSecurityDatabase();
string s_user, t_role;
try
{
mapUser(s_user, t_role, NULL, NULL, m_authBlock,
NULL, NULL, secDb, m_svc.getCryptCallback(), NULL);
}
catch (const Firebird::Exception&)
{
// Error in mapUser() means missing context, therefore...
continue;
}
t_role.upper();
if (s_user == SYSDBA_USER_NAME || t_role == ADMIN_ROLE)
return true;
}
}
// Other session's service run in embedded mode - check our user name as is
else if (m_svc.getUserName() == session.ses_user || m_svc.getUserAdminFlag())
return true;
return false;
}
// service entrypoint // service entrypoint
int TRACE_main(UtilSvc* arg) int TRACE_main(UtilSvc* arg)

View File

@ -49,7 +49,7 @@ class TraceSvcIntf
{ {
public: public:
virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd, virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd,
const AuthReader::AuthBlock& authBlock, bool isAdmin) = 0; bool trusted) = 0;
virtual void startSession(TraceSession& session, bool interactive) = 0; virtual void startSession(TraceSession& session, bool interactive) = 0;
virtual void stopSession(ULONG id) = 0; virtual void stopSession(ULONG id) = 0;

View File

@ -54,7 +54,7 @@ public:
virtual ~TraceSvcUtil(); virtual ~TraceSvcUtil();
virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd, virtual void setAttachInfo(const string& service_name, const string& user, const string& pwd,
const AuthReader::AuthBlock& authBlock, bool isAdmin); bool trusted);
virtual void startSession(TraceSession& session, bool interactive); virtual void startSession(TraceSession& session, bool interactive);
virtual void stopSession(ULONG id); virtual void stopSession(ULONG id);
@ -85,7 +85,7 @@ TraceSvcUtil::~TraceSvcUtil()
} }
void TraceSvcUtil::setAttachInfo(const string& service_name, const string& user, const string& pwd, void TraceSvcUtil::setAttachInfo(const string& service_name, const string& user, const string& pwd,
const AuthReader::AuthBlock& /*authBlock*/, bool isAdmin) bool trusted)
{ {
ISC_STATUS_ARRAY status = {0}; ISC_STATUS_ARRAY status = {0};
@ -97,7 +97,7 @@ void TraceSvcUtil::setAttachInfo(const string& service_name, const string& user,
if (pwd.hasData()) { if (pwd.hasData()) {
spb.insertString(isc_spb_password, pwd); spb.insertString(isc_spb_password, pwd);
} }
if (isAdmin) { if (trusted) {
spb.insertTag(isc_spb_trusted_auth); spb.insertTag(isc_spb_trusted_auth);
} }