mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[9518] Implement account associated execute for RA commands
* Now at login by RA-connection RA-connection use account id/access level
for commands execute. So at login with moderator access by RA-connection you
can execute only moderator level commands. For administrator level accounts
allowed execute only console level commands if new config option RA.Stricted = 0.
For security reasons by default RA.Stricted = 1.
* RA-connection executed commands now logged for associalted account id
* Some own account related commands allowed execute in RA-connection
NOTE: config version updated because RA.Stricted = 1 not compatible with old
way work and this can break tools thta use RA-access if it not disabled.
Yuo will need update mangosd.conf.
This commit is contained in:
parent
39559fc73a
commit
7fdbe497e9
13 changed files with 114 additions and 58 deletions
|
|
@ -75,10 +75,10 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
|
{ "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
|
||||||
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
|
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
|
||||||
{ "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
|
{ "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
|
||||||
{ "lock", SEC_PLAYER, false, &ChatHandler::HandleAccountLockCommand, "", NULL },
|
{ "lock", SEC_PLAYER, true, &ChatHandler::HandleAccountLockCommand, "", NULL },
|
||||||
{ "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
|
{ "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
|
||||||
{ "password", SEC_PLAYER, false, &ChatHandler::HandleAccountPasswordCommand, "", NULL },
|
{ "password", SEC_PLAYER, true, &ChatHandler::HandleAccountPasswordCommand, "", NULL },
|
||||||
{ "", SEC_PLAYER, false, &ChatHandler::HandleAccountCommand, "", NULL },
|
{ "", SEC_PLAYER, true, &ChatHandler::HandleAccountCommand, "", NULL },
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -703,10 +703,20 @@ const char *ChatHandler::GetMangosString(int32 entry) const
|
||||||
return m_session->GetMangosString(entry);
|
return m_session->GetMangosString(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 ChatHandler::GetAccountId() const
|
||||||
|
{
|
||||||
|
return m_session->GetAccountId();
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountTypes ChatHandler::GetAccessLevel() const
|
||||||
|
{
|
||||||
|
return m_session->GetSecurity();
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::isAvailable(ChatCommand const& cmd) const
|
bool ChatHandler::isAvailable(ChatCommand const& cmd) const
|
||||||
{
|
{
|
||||||
// check security level only for simple command (without child commands)
|
// check security level only for simple command (without child commands)
|
||||||
return m_session->GetSecurity() >= (AccountTypes)cmd.SecurityLevel;
|
return GetAccessLevel() >= (AccountTypes)cmd.SecurityLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
|
bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
|
||||||
|
|
@ -733,12 +743,8 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
|
||||||
{
|
{
|
||||||
AccountTypes target_sec;
|
AccountTypes target_sec;
|
||||||
|
|
||||||
// allow everything from console and RA console
|
|
||||||
if (!m_session)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
|
// ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
|
||||||
if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_BOOL_GM_LOWER_SECURITY))
|
if (GetAccessLevel() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_BOOL_GM_LOWER_SECURITY))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
|
|
@ -748,7 +754,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
|
||||||
else
|
else
|
||||||
return true; // caller must report error for (target==NULL && target_account==0)
|
return true; // caller must report error for (target==NULL && target_account==0)
|
||||||
|
|
||||||
if (m_session->GetSecurity() < target_sec || (strong && m_session->GetSecurity() <= target_sec))
|
if (GetAccessLevel() < target_sec || (strong && GetAccessLevel() <= target_sec))
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
|
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
|
|
@ -890,14 +896,19 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, co
|
||||||
if(table[i].SecurityLevel > SEC_PLAYER)
|
if(table[i].SecurityLevel > SEC_PLAYER)
|
||||||
{
|
{
|
||||||
// chat case
|
// chat case
|
||||||
if(m_session)
|
if (m_session)
|
||||||
{
|
{
|
||||||
Player* p = m_session->GetPlayer();
|
Player* p = m_session->GetPlayer();
|
||||||
uint64 sel_guid = p->GetSelection();
|
uint64 sel_guid = p->GetSelection();
|
||||||
sLog.outCommand(m_session->GetAccountId(),"Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]",
|
sLog.outCommand(GetAccountId(),"Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]",
|
||||||
fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(),
|
fullcmd.c_str(),p->GetName(),GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(),
|
||||||
GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid));
|
GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid));
|
||||||
}
|
}
|
||||||
|
else // 0 account -> console
|
||||||
|
{
|
||||||
|
sLog.outCommand(GetAccountId(),"Command: %s [Account: %u from %s]",
|
||||||
|
fullcmd.c_str(),GetAccountId(),GetAccountId() ? "RA-connection" : "Console");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// some commands have custom error messages. Don't send the default one in these cases.
|
// some commands have custom error messages. Don't send the default one in these cases.
|
||||||
|
|
@ -2253,10 +2264,24 @@ const char *CliHandler::GetMangosString(int32 entry) const
|
||||||
return sObjectMgr.GetMangosStringForDBCLocale(entry);
|
return sObjectMgr.GetMangosStringForDBCLocale(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 CliHandler::GetAccountId() const
|
||||||
|
{
|
||||||
|
return m_accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountTypes CliHandler::GetAccessLevel() const
|
||||||
|
{
|
||||||
|
return m_loginAccessLevel;
|
||||||
|
}
|
||||||
|
|
||||||
bool CliHandler::isAvailable(ChatCommand const& cmd) const
|
bool CliHandler::isAvailable(ChatCommand const& cmd) const
|
||||||
{
|
{
|
||||||
// skip non-console commands in console case
|
// skip non-console commands in console case
|
||||||
return cmd.AllowConsole;
|
if (!cmd.AllowConsole)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// normal case
|
||||||
|
return GetAccessLevel() >= (AccountTypes)cmd.SecurityLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CliHandler::SendSysMessage(const char *str)
|
void CliHandler::SendSysMessage(const char *str)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ class ChatHandler
|
||||||
bool hasStringAbbr(const char* name, const char* part);
|
bool hasStringAbbr(const char* name, const char* part);
|
||||||
|
|
||||||
// function with different implementation for chat/console
|
// function with different implementation for chat/console
|
||||||
|
virtual uint32 GetAccountId() const;
|
||||||
|
virtual AccountTypes GetAccessLevel() const;
|
||||||
virtual bool isAvailable(ChatCommand const& cmd) const;
|
virtual bool isAvailable(ChatCommand const& cmd) const;
|
||||||
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
|
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
|
||||||
virtual bool needReportToTarget(Player* chr) const;
|
virtual bool needReportToTarget(Player* chr) const;
|
||||||
|
|
@ -554,10 +556,13 @@ class CliHandler : public ChatHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef void Print(void*, char const*);
|
typedef void Print(void*, char const*);
|
||||||
explicit CliHandler(void* callbackArg, Print* zprint) : m_callbackArg(callbackArg), m_print(zprint) {}
|
explicit CliHandler(uint32 accountId, AccountTypes accessLevel, void* callbackArg, Print* zprint)
|
||||||
|
: m_accountId(accountId), m_loginAccessLevel(accessLevel), m_callbackArg(callbackArg), m_print(zprint) {}
|
||||||
|
|
||||||
// overwrite functions
|
// overwrite functions
|
||||||
const char *GetMangosString(int32 entry) const;
|
const char *GetMangosString(int32 entry) const;
|
||||||
|
uint32 GetAccountId() const;
|
||||||
|
AccountTypes GetAccessLevel() const;
|
||||||
bool isAvailable(ChatCommand const& cmd) const;
|
bool isAvailable(ChatCommand const& cmd) const;
|
||||||
void SendSysMessage(const char *str);
|
void SendSysMessage(const char *str);
|
||||||
std::string GetNameLink() const;
|
std::string GetNameLink() const;
|
||||||
|
|
@ -566,6 +571,8 @@ class CliHandler : public ChatHandler
|
||||||
int GetSessionDbLocaleIndex() const;
|
int GetSessionDbLocaleIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint32 m_accountId;
|
||||||
|
AccountTypes m_loginAccessLevel;
|
||||||
void* m_callbackArg;
|
void* m_callbackArg;
|
||||||
Print* m_print;
|
Print* m_print;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ bool ChatHandler::HandleCommandsCommand(const char* /*args*/)
|
||||||
|
|
||||||
bool ChatHandler::HandleAccountCommand(const char* /*args*/)
|
bool ChatHandler::HandleAccountCommand(const char* /*args*/)
|
||||||
{
|
{
|
||||||
AccountTypes gmlevel = m_session->GetSecurity();
|
AccountTypes gmlevel = GetAccessLevel();
|
||||||
PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
|
PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/)
|
||||||
Player *player=m_session->GetPlayer();
|
Player *player=m_session->GetPlayer();
|
||||||
|
|
||||||
// save GM account without delay and output message (testing, etc)
|
// save GM account without delay and output message (testing, etc)
|
||||||
if(m_session->GetSecurity() > SEC_PLAYER)
|
if(GetAccessLevel() > SEC_PLAYER)
|
||||||
{
|
{
|
||||||
player->SaveToDB();
|
player->SaveToDB();
|
||||||
SendSysMessage(LANG_PLAYER_SAVED);
|
SendSysMessage(LANG_PLAYER_SAVED);
|
||||||
|
|
@ -179,6 +179,10 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
|
||||||
|
|
||||||
bool ChatHandler::HandleAccountPasswordCommand(const char* args)
|
bool ChatHandler::HandleAccountPasswordCommand(const char* args)
|
||||||
{
|
{
|
||||||
|
// allow use from RA, but not from console (not have associated account id)
|
||||||
|
if (!GetAccountId())
|
||||||
|
return false;
|
||||||
|
|
||||||
if(!*args)
|
if(!*args)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -200,14 +204,14 @@ bool ChatHandler::HandleAccountPasswordCommand(const char* args)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sAccountMgr.CheckPassword (m_session->GetAccountId(), password_old))
|
if (!sAccountMgr.CheckPassword (GetAccountId(), password_old))
|
||||||
{
|
{
|
||||||
SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD);
|
SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD);
|
||||||
SetSentErrorMessage (true);
|
SetSentErrorMessage (true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountOpResult result = sAccountMgr.ChangePassword(m_session->GetAccountId(), password_new);
|
AccountOpResult result = sAccountMgr.ChangePassword(GetAccountId(), password_new);
|
||||||
|
|
||||||
switch(result)
|
switch(result)
|
||||||
{
|
{
|
||||||
|
|
@ -230,6 +234,10 @@ bool ChatHandler::HandleAccountPasswordCommand(const char* args)
|
||||||
|
|
||||||
bool ChatHandler::HandleAccountLockCommand(const char* args)
|
bool ChatHandler::HandleAccountLockCommand(const char* args)
|
||||||
{
|
{
|
||||||
|
// allow use from RA, but not from console (not have associated account id)
|
||||||
|
if (!GetAccountId())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!*args)
|
if (!*args)
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_USE_BOL);
|
SendSysMessage(LANG_USE_BOL);
|
||||||
|
|
@ -239,14 +247,14 @@ bool ChatHandler::HandleAccountLockCommand(const char* args)
|
||||||
std::string argstr = (char*)args;
|
std::string argstr = (char*)args;
|
||||||
if (argstr == "on")
|
if (argstr == "on")
|
||||||
{
|
{
|
||||||
loginDatabase.PExecute( "UPDATE account SET locked = '1' WHERE id = '%d'",m_session->GetAccountId());
|
loginDatabase.PExecute( "UPDATE account SET locked = '1' WHERE id = '%d'",GetAccountId());
|
||||||
PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
|
PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argstr == "off")
|
if (argstr == "off")
|
||||||
{
|
{
|
||||||
loginDatabase.PExecute( "UPDATE account SET locked = '0' WHERE id = '%d'",m_session->GetAccountId());
|
loginDatabase.PExecute( "UPDATE account SET locked = '0' WHERE id = '%d'",GetAccountId());
|
||||||
PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
|
PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2169,7 +2169,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
|
||||||
username = fields[0].GetCppString();
|
username = fields[0].GetCppString();
|
||||||
security = (AccountTypes)fields[1].GetUInt32();
|
security = (AccountTypes)fields[1].GetUInt32();
|
||||||
|
|
||||||
if(!m_session || m_session->GetSecurity() >= security)
|
if(GetAccessLevel() >= security)
|
||||||
{
|
{
|
||||||
last_ip = fields[2].GetCppString();
|
last_ip = fields[2].GetCppString();
|
||||||
last_login = fields[3].GetCppString();
|
last_login = fields[3].GetCppString();
|
||||||
|
|
|
||||||
|
|
@ -961,7 +961,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/// account can't set security to same or grater level, need more power GM or console
|
/// account can't set security to same or grater level, need more power GM or console
|
||||||
AccountTypes plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
|
AccountTypes plSecurity = GetAccessLevel();
|
||||||
if (AccountTypes(gm) >= plSecurity )
|
if (AccountTypes(gm) >= plSecurity )
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
|
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
|
||||||
|
|
@ -5991,7 +5991,7 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
|
||||||
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
||||||
{
|
{
|
||||||
PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
||||||
itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
||||||
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -6014,7 +6014,7 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
|
||||||
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
||||||
{
|
{
|
||||||
PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
PSendSysMessage("map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
||||||
itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
||||||
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -6067,7 +6067,7 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char* args)
|
||||||
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
if (const MapEntry* entry = sMapStore.LookupEntry(itr->first))
|
||||||
{
|
{
|
||||||
PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
PSendSysMessage("unbinding map: %d (%s) inst: %d perm: %s diff: %d canReset: %s TTR: %s",
|
||||||
itr->first, entry->name[m_session->GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
itr->first, entry->name[GetSessionDbcLocale()], save->GetInstanceId(), itr->second.perm ? "yes" : "no",
|
||||||
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -6197,7 +6197,7 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
|
||||||
|
|
||||||
// Let set addon state only for lesser (strong) security level
|
// Let set addon state only for lesser (strong) security level
|
||||||
// or to self account
|
// or to self account
|
||||||
if (m_session && m_session->GetAccountId () != account_id &&
|
if (GetAccountId() && GetAccountId () != account_id &&
|
||||||
HasLowerSecurityAccount (NULL,account_id,true))
|
HasLowerSecurityAccount (NULL,account_id,true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1819,7 +1819,7 @@ void World::UpdateSessions( uint32 diff )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This handles the issued and queued CLI commands
|
// This handles the issued and queued CLI/RA commands
|
||||||
void World::ProcessCliCommands()
|
void World::ProcessCliCommands()
|
||||||
{
|
{
|
||||||
CliCommandHolder::Print* zprint = NULL;
|
CliCommandHolder::Print* zprint = NULL;
|
||||||
|
|
@ -1830,7 +1830,7 @@ void World::ProcessCliCommands()
|
||||||
sLog.outDebug("CLI command under processing...");
|
sLog.outDebug("CLI command under processing...");
|
||||||
zprint = command->m_print;
|
zprint = command->m_print;
|
||||||
callbackArg = command->m_callbackArg;
|
callbackArg = command->m_callbackArg;
|
||||||
CliHandler handler(callbackArg, zprint);
|
CliHandler handler(command->m_cliAccountId, command->m_cliAccessLevel, callbackArg, zprint);
|
||||||
handler.ParseCommands(command->m_command);
|
handler.ParseCommands(command->m_command);
|
||||||
|
|
||||||
if(command->m_commandFinished)
|
if(command->m_commandFinished)
|
||||||
|
|
|
||||||
|
|
@ -375,13 +375,15 @@ struct CliCommandHolder
|
||||||
typedef void Print(void*, const char*);
|
typedef void Print(void*, const char*);
|
||||||
typedef void CommandFinished(void*, bool success);
|
typedef void CommandFinished(void*, bool success);
|
||||||
|
|
||||||
|
uint32 m_cliAccountId; // 0 for console and real account id for RA/soap
|
||||||
|
AccountTypes m_cliAccessLevel;
|
||||||
void* m_callbackArg;
|
void* m_callbackArg;
|
||||||
char *m_command;
|
char *m_command;
|
||||||
Print* m_print;
|
Print* m_print;
|
||||||
CommandFinished* m_commandFinished;
|
CommandFinished* m_commandFinished;
|
||||||
|
|
||||||
CliCommandHolder(void* callbackArg, const char *command, Print* zprint, CommandFinished* commandFinished)
|
CliCommandHolder(uint32 accountId, AccountTypes cliAccessLevel, void* callbackArg, const char *command, Print* zprint, CommandFinished* commandFinished)
|
||||||
: m_callbackArg(callbackArg), m_print(zprint), m_commandFinished(commandFinished)
|
: m_cliAccountId(accountId), m_cliAccessLevel(cliAccessLevel), m_callbackArg(callbackArg), m_print(zprint), m_commandFinished(commandFinished)
|
||||||
{
|
{
|
||||||
size_t len = strlen(command)+1;
|
size_t len = strlen(command)+1;
|
||||||
m_command = new char[len];
|
m_command = new char[len];
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,7 @@ void CliRunnable::run()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sWorld.QueueCliCommand(new CliCommandHolder(NULL, command.c_str(), &utf8print, &commandFinished));
|
sWorld.QueueCliCommand(new CliCommandHolder(0, SEC_CONSOLE, NULL, command.c_str(), &utf8print, &commandFinished));
|
||||||
}
|
}
|
||||||
else if (feof(stdin))
|
else if (feof(stdin))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ int ns1__executeCommand(soap* soap, char* command, char** result)
|
||||||
// commands are executed in the world thread. We have to wait for them to be completed
|
// commands are executed in the world thread. We have to wait for them to be completed
|
||||||
{
|
{
|
||||||
// CliCommandHolder will be deleted from world, accessing after queueing is NOT save
|
// CliCommandHolder will be deleted from world, accessing after queueing is NOT save
|
||||||
CliCommandHolder* cmd = new CliCommandHolder(&connection, command, &SOAPCommand::print, &SOAPCommand::commandFinished);
|
CliCommandHolder* cmd = new CliCommandHolder(accountId, SEC_CONSOLE, &connection, command, &SOAPCommand::print, &SOAPCommand::commandFinished);
|
||||||
sWorld.QueueCliCommand(cmd);
|
sWorld.QueueCliCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ stage(NONE)
|
||||||
{
|
{
|
||||||
///- Get the config parameters
|
///- Get the config parameters
|
||||||
bSecure = sConfig.GetBoolDefault( "RA.Secure", true );
|
bSecure = sConfig.GetBoolDefault( "RA.Secure", true );
|
||||||
iMinLevel = sConfig.GetIntDefault( "RA.MinLevel", SEC_ADMINISTRATOR );
|
bStricted = sConfig.GetBoolDefault( "RA.Stricted", false );
|
||||||
|
iMinLevel = AccountTypes(sConfig.GetIntDefault( "RA.MinLevel", SEC_ADMINISTRATOR ));
|
||||||
reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
|
reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,30 +199,32 @@ int RASocket::handle_input(ACE_HANDLE)
|
||||||
}
|
}
|
||||||
sendf("\r\n");
|
sendf("\r\n");
|
||||||
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
|
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
AccountTypes sec = sAccountMgr.GetSecurity(accId);
|
|
||||||
|
|
||||||
///- if gmlevel is too low, deny access
|
accAccessLevel = sAccountMgr.GetSecurity(accId);
|
||||||
if (sec < iMinLevel)
|
|
||||||
|
///- if gmlevel is too low, deny access
|
||||||
|
if (accAccessLevel < iMinLevel)
|
||||||
|
{
|
||||||
|
sendf("-Not enough privileges.\r\n");
|
||||||
|
sLog.outRALog("User %s has no privilege.",szLogin.c_str());
|
||||||
|
if(bSecure)
|
||||||
{
|
{
|
||||||
sendf("-Not enough privileges.\r\n");
|
handle_output();
|
||||||
sLog.outRALog("User %s has no privilege.",szLogin.c_str());
|
return -1;
|
||||||
if(bSecure)
|
|
||||||
{
|
|
||||||
handle_output();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sendf("\r\n");
|
|
||||||
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stage=LG;
|
|
||||||
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_PASS));
|
|
||||||
}
|
}
|
||||||
|
sendf("\r\n");
|
||||||
|
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///- allow by remotely connected admin use console level commands dependent from config setting
|
||||||
|
if (accAccessLevel >= SEC_ADMINISTRATOR && !bStricted)
|
||||||
|
accAccessLevel = SEC_CONSOLE;
|
||||||
|
|
||||||
|
stage=LG;
|
||||||
|
sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_PASS));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
///<li> If the input is '<password>' (and the user already gave his username)
|
///<li> If the input is '<password>' (and the user already gave his username)
|
||||||
|
|
@ -261,7 +264,7 @@ int RASocket::handle_input(ACE_HANDLE)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CliCommandHolder* cmd = new CliCommandHolder(this, inputBuffer, &RASocket::zprint, &RASocket::commandFinished);
|
CliCommandHolder* cmd = new CliCommandHolder(accId, accAccessLevel, this, inputBuffer, &RASocket::zprint, &RASocket::commandFinished);
|
||||||
sWorld.QueueCliCommand(cmd);
|
sWorld.QueueCliCommand(cmd);
|
||||||
pendingCommands.acquire();
|
pendingCommands.acquire();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,11 @@ class RASocket: protected RAHandler
|
||||||
uint32 outputBufferLen;
|
uint32 outputBufferLen;
|
||||||
|
|
||||||
uint32 accId;
|
uint32 accId;
|
||||||
|
AccountTypes accAccessLevel;
|
||||||
bool bSecure; //kick on wrong pass, non exist. user OR user with no priv
|
bool bSecure; //kick on wrong pass, non exist. user OR user with no priv
|
||||||
//will protect from DOS, bruteforce attacks
|
//will protect from DOS, bruteforce attacks
|
||||||
//some 'smart' protection must be added for more security
|
bool bStricted; // not allow execute console only commands (SEC_CONSOLE) remotly
|
||||||
uint8 iMinLevel;
|
AccountTypes iMinLevel;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NONE, //initial value
|
NONE, //initial value
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#####################################
|
#####################################
|
||||||
# MaNGOS Configuration file #
|
# MaNGOS Configuration file #
|
||||||
#####################################
|
#####################################
|
||||||
ConfVersion=2008080101
|
ConfVersion=2010030401
|
||||||
|
|
||||||
###################################################################################################################
|
###################################################################################################################
|
||||||
# CONNECTIONS AND DIRECTORIES
|
# CONNECTIONS AND DIRECTORIES
|
||||||
|
|
@ -1373,12 +1373,21 @@ Network.TcpNodelay = 1
|
||||||
#
|
#
|
||||||
# Ra.Port
|
# Ra.Port
|
||||||
# Default remote console port
|
# Default remote console port
|
||||||
|
# Default: 3443
|
||||||
#
|
#
|
||||||
# Ra.MinLevel
|
# Ra.MinLevel
|
||||||
# Minimum level that's required to login,3 by default
|
# Minimum level that's required to login,3 by default
|
||||||
|
# Default: 3 (Administrator)
|
||||||
#
|
#
|
||||||
# Ra.Secure
|
# Ra.Secure
|
||||||
# Kick client on wrong pass
|
# Kick client on wrong pass
|
||||||
|
# 0 - off
|
||||||
|
# Default: 1 - on
|
||||||
|
#
|
||||||
|
# Ra.Stricted
|
||||||
|
# Not allow execute console level only commands remotly by RA
|
||||||
|
# 0 - off
|
||||||
|
# Default: 1 - on
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# SOAP.Enable
|
# SOAP.Enable
|
||||||
|
|
@ -1402,6 +1411,7 @@ Ra.IP = 0.0.0.0
|
||||||
Ra.Port = 3443
|
Ra.Port = 3443
|
||||||
Ra.MinLevel = 3
|
Ra.MinLevel = 3
|
||||||
Ra.Secure = 1
|
Ra.Secure = 1
|
||||||
|
Ra.Stricted = 1
|
||||||
|
|
||||||
SOAP.Enabled = 0
|
SOAP.Enabled = 0
|
||||||
SOAP.IP = 127.0.0.1
|
SOAP.IP = 127.0.0.1
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "9517"
|
#define REVISION_NR "9518"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue