mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 17:54:48 +01:00
Core/RBAC: Add .reload rbac command and prevent possible crash if rbac_permissions has wrong data
This commit is contained in:
3
sql/updates/world/2013_02_27_00_world_command.sql
Normal file
3
sql/updates/world/2013_02_27_00_world_command.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
DELETE FROM `command` WHERE `name` = 'reload rbac';
|
||||
INSERT INTO `command` (`name`,`security`,`help`) VALUES
|
||||
('reload rbac',3,'Syntax: .reload rbac\nReload rbac system.');
|
||||
@@ -31,14 +31,7 @@ AccountMgr::AccountMgr()
|
||||
|
||||
AccountMgr::~AccountMgr()
|
||||
{
|
||||
for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr)
|
||||
delete itr->second;
|
||||
ClearRBAC();
|
||||
}
|
||||
|
||||
AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
|
||||
@@ -337,11 +330,15 @@ bool AccountMgr::IsConsoleAccount(uint32 gmlevel)
|
||||
|
||||
void AccountMgr::LoadRBAC()
|
||||
{
|
||||
ClearRBAC();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC");
|
||||
uint32 oldMSTime = getMSTime();
|
||||
uint32 count1 = 0;
|
||||
uint32 count2 = 0;
|
||||
uint32 count3 = 0;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading permissions");
|
||||
QueryResult result = LoginDatabase.Query("SELECT id, name FROM rbac_permissions");
|
||||
if (!result)
|
||||
{
|
||||
@@ -358,6 +355,7 @@ void AccountMgr::LoadRBAC()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading roles");
|
||||
result = LoginDatabase.Query("SELECT id, name FROM rbac_roles");
|
||||
if (!result)
|
||||
{
|
||||
@@ -374,6 +372,7 @@ void AccountMgr::LoadRBAC()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading role permissions");
|
||||
result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions");
|
||||
if (!result)
|
||||
{
|
||||
@@ -390,6 +389,7 @@ void AccountMgr::LoadRBAC()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading groups");
|
||||
result = LoginDatabase.Query("SELECT id, name FROM rbac_groups");
|
||||
if (!result)
|
||||
{
|
||||
@@ -406,6 +406,7 @@ void AccountMgr::LoadRBAC()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading group roles");
|
||||
result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles");
|
||||
if (!result)
|
||||
{
|
||||
@@ -422,6 +423,7 @@ void AccountMgr::LoadRBAC()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading security level groups");
|
||||
result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC");
|
||||
if (!result)
|
||||
{
|
||||
@@ -445,6 +447,7 @@ void AccountMgr::LoadRBAC()
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default groups");
|
||||
// Load default groups to be added to any RBAC Object.
|
||||
std::string defaultGroups = ConfigMgr::GetStringDefault("RBAC.DefaultGroups", "");
|
||||
Tokenizer tokens(defaultGroups, ',');
|
||||
@@ -518,42 +521,68 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec
|
||||
}
|
||||
}
|
||||
|
||||
RBACGroup const* AccountMgr::GetRBACGroup(uint32 group) const
|
||||
RBACGroup const* AccountMgr::GetRBACGroup(uint32 groupId) const
|
||||
{
|
||||
RBACGroupsContainer::const_iterator it = _groups.find(group);
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACGroup: groupId: %u", groupId);
|
||||
RBACGroupsContainer::const_iterator it = _groups.find(groupId);
|
||||
if (it != _groups.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RBACRole const* AccountMgr::GetRBACRole(uint32 role) const
|
||||
RBACRole const* AccountMgr::GetRBACRole(uint32 roleId) const
|
||||
{
|
||||
RBACRolesContainer::const_iterator it = _roles.find(role);
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACRole: roleId: %u", roleId);
|
||||
RBACRolesContainer::const_iterator it = _roles.find(roleId);
|
||||
if (it != _roles.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RBACPermission const* AccountMgr::GetRBACPermission(uint32 permission) const
|
||||
RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const
|
||||
{
|
||||
RBACPermissionsContainer::const_iterator it = _permissions.find(permission);
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: roleId: %u", permissionId);
|
||||
RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId);
|
||||
if (it != _permissions.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool AccountMgr::HasPermission(uint32 accountId, uint32 permission, uint32 realmId)
|
||||
bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 realmId)
|
||||
{
|
||||
if (!accountId)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_RBAC, "AccountMgr::HasPermission: Wrong accountId 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
RBACData* rbac = new RBACData(accountId, "", realmId);
|
||||
rbac->LoadFromDB();
|
||||
bool hasPermission = rbac->HasPermission(permission);
|
||||
bool hasPermission = rbac->HasPermission(permissionId);
|
||||
delete rbac;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "AccountMgr::HasPermission [AccountId: %u, PermissionId: %u, realmId: %d]: %u",
|
||||
accountId, permissionId, realmId, hasPermission);
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
void AccountMgr::ClearRBAC()
|
||||
{
|
||||
for (RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
_permissions.clear();
|
||||
_roles.clear();
|
||||
_groups.clear();
|
||||
_defaultGroups.clear();
|
||||
_defaultSecGroups.clear();
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ class AccountMgr
|
||||
RBACGroupContainer const& GetRBACDefaultGroups() const { return _defaultGroups; }
|
||||
|
||||
private:
|
||||
void ClearRBAC();
|
||||
RBACPermissionsContainer _permissions;
|
||||
RBACRolesContainer _roles;
|
||||
RBACGroupsContainer _groups;
|
||||
|
||||
@@ -19,21 +19,67 @@
|
||||
#include "AccountMgr.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
void RBACRole::GrantPermission(uint32 permissionId)
|
||||
{
|
||||
if (permissionId < RBAC_PERM_MAX)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), permissionId);
|
||||
_perms.set(permissionId);
|
||||
}
|
||||
else
|
||||
sLog->outError(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Permission not lower than %u",
|
||||
GetId(), permissionId, RBAC_PERM_MAX);
|
||||
}
|
||||
|
||||
void RBACRole::RevokePermission(uint32 permissionId)
|
||||
{
|
||||
if (permissionId < RBAC_PERM_MAX)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Ok", GetId(), permissionId);
|
||||
_perms.reset(permissionId);
|
||||
}
|
||||
else
|
||||
sLog->outError(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Permission not lower than %u",
|
||||
GetId(), permissionId, RBAC_PERM_MAX);
|
||||
}
|
||||
|
||||
void RBACGroup::GrantRole(uint32 roleId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
|
||||
_roles.insert(roleId);
|
||||
}
|
||||
|
||||
void RBACGroup::RevokeRole(uint32 roleId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
|
||||
_roles.erase(roleId);
|
||||
}
|
||||
|
||||
RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */)
|
||||
{
|
||||
// Check if group Id exists
|
||||
RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId);
|
||||
if (!group)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group does not exists",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
return RBAC_ID_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// Already added?
|
||||
std::pair<std::set<uint32>::iterator, bool> ret = _groups.insert(groupId);
|
||||
if (!ret.second)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group Already added",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
return RBAC_CANT_ADD_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added and DB updated",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, groupId);
|
||||
@@ -42,6 +88,9 @@ RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */)
|
||||
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -50,11 +99,17 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */)
|
||||
{
|
||||
// could remove it?
|
||||
if (!_groups.erase(groupId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group not in list",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
return RBAC_CANT_REVOKE_NOT_IN_LIST;
|
||||
}
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed and DB updated",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, groupId);
|
||||
@@ -63,6 +118,9 @@ RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */)
|
||||
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed",
|
||||
GetId(), GetName().c_str(), groupId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -72,23 +130,40 @@ RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/)
|
||||
// Check if role Id exists
|
||||
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
|
||||
if (!role)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_ID_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// Check if already added in denied list
|
||||
if (_deniedRoles.find(roleId) != _deniedRoles.end())
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in deny list",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_IN_DENIED_LIST;
|
||||
}
|
||||
|
||||
// Already added?
|
||||
std::pair<std::set<uint32>::iterator, bool> ret = _grantedRoles.insert(roleId);
|
||||
if (!ret.second)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already granted",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_CANT_ADD_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
SaveRole(roleId, true, realmId);
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -98,23 +173,40 @@ RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/)
|
||||
// Check if role Id exists
|
||||
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
|
||||
if (!role)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_ID_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// Check if already added in granted list
|
||||
if (_grantedRoles.find(roleId) != _grantedRoles.end())
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in grant list",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_IN_GRANTED_LIST;
|
||||
}
|
||||
|
||||
// Already added?
|
||||
std::pair<std::set<uint32>::iterator, bool> ret = _deniedRoles.insert(roleId);
|
||||
if (!ret.second)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already denied",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_CANT_ADD_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
SaveRole(roleId, false, realmId);
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -135,11 +227,17 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/)
|
||||
|
||||
// could remove it?
|
||||
if (!revoked)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Not granted or revoked",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
return RBAC_CANT_REVOKE_NOT_IN_LIST;
|
||||
}
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, roleId);
|
||||
@@ -148,6 +246,9 @@ RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/)
|
||||
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), roleId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -157,24 +258,41 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /
|
||||
// Check if permission Id exists
|
||||
RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
|
||||
if (!perm)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_ID_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// Check if already added in denied list
|
||||
if (_deniedPerms.test(permissionId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_IN_DENIED_LIST;
|
||||
}
|
||||
|
||||
// Already added?
|
||||
if (_grantedPerms.test(permissionId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_CANT_ADD_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
_grantedPerms.set(permissionId);
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
SavePermission(permissionId, true, realmId);
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -184,24 +302,41 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /*
|
||||
// Check if permission Id exists
|
||||
RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
|
||||
if (!perm)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_ID_DOES_NOT_EXISTS;
|
||||
}
|
||||
|
||||
// Check if already added in granted list
|
||||
if (_grantedPerms.test(permissionId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_IN_GRANTED_LIST;
|
||||
}
|
||||
|
||||
// Already added?
|
||||
if (_deniedPerms.test(permissionId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_CANT_ADD_ALREADY_ADDED;
|
||||
}
|
||||
|
||||
_deniedPerms.set(permissionId);
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
SavePermission(permissionId, false, realmId);
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
@@ -216,32 +351,44 @@ void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
|
||||
LoginDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
RBACCommandResult RBACData::RevokePermission(uint32 permission, int32 realmId /* = 0*/)
|
||||
RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/)
|
||||
{
|
||||
// Check if it's present in any list
|
||||
if (!_grantedPerms.test(permission) && !_deniedPerms.test(permission))
|
||||
if (!_grantedPerms.test(permissionId) && !_deniedPerms.test(permissionId))
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
return RBAC_CANT_REVOKE_NOT_IN_LIST;
|
||||
}
|
||||
|
||||
_grantedPerms.reset(permission);
|
||||
_deniedPerms.reset(permission);
|
||||
_grantedPerms.reset(permissionId);
|
||||
_deniedPerms.reset(permissionId);
|
||||
|
||||
// Do not save to db when loading data from DB (realmId = 0)
|
||||
if (realmId)
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, permission);
|
||||
stmt->setUInt32(1, permissionId);
|
||||
stmt->setInt32(2, realmId);
|
||||
LoginDatabase.Execute(stmt);
|
||||
|
||||
CalculateNewPermissions();
|
||||
}
|
||||
else
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
|
||||
GetId(), GetName().c_str(), permissionId, realmId);
|
||||
|
||||
return RBAC_OK;
|
||||
}
|
||||
|
||||
void RBACData::LoadFromDB()
|
||||
{
|
||||
sLog->outInfo(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]", GetId(), GetName().c_str());
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading groups", GetId(), GetName().c_str());
|
||||
|
||||
// Load account group that affect current realm
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS);
|
||||
stmt->setUInt32(0, GetId());
|
||||
@@ -258,6 +405,7 @@ void RBACData::LoadFromDB()
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading roles", GetId(), GetName().c_str());
|
||||
// Load account roles (granted and denied) that affect current realm
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES);
|
||||
stmt->setUInt32(0, GetId());
|
||||
@@ -277,6 +425,7 @@ void RBACData::LoadFromDB()
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str());
|
||||
// Load account permissions (granted and denied) that affect current realm
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
|
||||
stmt->setUInt32(0, GetId());
|
||||
@@ -296,11 +445,13 @@ void RBACData::LoadFromDB()
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Adding default groups", GetId(), GetName().c_str());
|
||||
// Add default groups
|
||||
RBACGroupContainer const& groups = sAccountMgr->GetRBACDefaultGroups();
|
||||
for (RBACGroupContainer::const_iterator itr = groups.begin(); itr != groups.end(); ++itr)
|
||||
AddGroup(*itr);
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str());
|
||||
// Force calculation of permissions, it wasn't performed at load time
|
||||
// while adding groups, roles and permissions
|
||||
CalculateNewPermissions();
|
||||
@@ -308,6 +459,7 @@ void RBACData::LoadFromDB()
|
||||
|
||||
void RBACData::CalculateNewPermissions()
|
||||
{
|
||||
sLog->outTrace(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str());
|
||||
// Get the list of directly granted roles
|
||||
RBACRoleContainer tempGrantedRoles = GetGrantedRoles();
|
||||
|
||||
|
||||
@@ -146,9 +146,9 @@ class RBACRole: public RBACObject
|
||||
/// Gets the Permissions assigned to this role
|
||||
RBACPermissionContainer const& GetPermissions() const { return _perms; }
|
||||
/// Grants a Permission (Adds)
|
||||
void GrantPermission(uint32 id) { _perms.set(id); }
|
||||
void GrantPermission(uint32 id);
|
||||
/// Revokes a Permission (Removes)
|
||||
void RevokePermission(uint32 id) { _perms.reset(id); }
|
||||
void RevokePermission(uint32 id);
|
||||
|
||||
private:
|
||||
RBACPermissionContainer _perms; ///> Set of permissions
|
||||
@@ -164,9 +164,9 @@ class RBACGroup: public RBACObject
|
||||
/// Gets the Roles assigned to this group
|
||||
RBACRoleContainer const& GetRoles() const { return _roles; }
|
||||
/// Grants a Role (Adds)
|
||||
void GrantRole(uint32 role) { _roles.insert(role); }
|
||||
void GrantRole(uint32 role);
|
||||
/// Revokes a Role (Removes)
|
||||
void RevokeRole(uint32 role) { _roles.erase(role); }
|
||||
void RevokeRole(uint32 role);
|
||||
|
||||
private:
|
||||
RBACRoleContainer _roles; ///> Set of Roles
|
||||
|
||||
@@ -1175,11 +1175,13 @@ void WorldSession::LoadPermissions()
|
||||
{
|
||||
uint32 id = GetAccountId();
|
||||
std::string name;
|
||||
int32 realmId = ConfigMgr::GetIntDefault("RealmID", 0);
|
||||
AccountMgr::GetName(id, name);
|
||||
|
||||
_RBACData = new RBACData(id, name, realmId);
|
||||
_RBACData = new RBACData(id, name, realmID);
|
||||
_RBACData->LoadFromDB();
|
||||
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d]",
|
||||
id, name.c_str(), realmID);
|
||||
}
|
||||
|
||||
RBACData* WorldSession::GetRBACData()
|
||||
@@ -1192,5 +1194,17 @@ bool WorldSession::HasPermission(uint32 permission)
|
||||
if (!_RBACData)
|
||||
LoadPermissions();
|
||||
|
||||
return _RBACData->HasPermission(permission);
|
||||
bool hasPermission = _RBACData->HasPermission(permission);
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]",
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
|
||||
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
void WorldSession::InvalidateRBACData()
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_RBAC, "WorldSession::InvalidateRBACData [AccountId: %u, Name: %s, realmId: %d]",
|
||||
_RBACData->GetId(), _RBACData->GetName().c_str(), realmID);
|
||||
delete _RBACData;
|
||||
_RBACData = NULL;
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ class WorldSession
|
||||
RBACData* GetRBACData();
|
||||
bool HasPermission(uint32 permissionId);
|
||||
void LoadPermissions();
|
||||
void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check
|
||||
|
||||
AccountTypes GetSecurity() const { return _security; }
|
||||
uint32 GetAccountId() const { return _accountId; }
|
||||
|
||||
@@ -3122,3 +3122,11 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void World::ReloadRBAC()
|
||||
{
|
||||
sLog->outInfo(LOG_FILTER_RBAC, "World::ReloadRBAC()");
|
||||
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
|
||||
if (WorldSession* session = itr->second)
|
||||
session->InvalidateRBACData();
|
||||
}
|
||||
|
||||
@@ -739,6 +739,9 @@ class World
|
||||
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
|
||||
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
|
||||
void ResetEventSeasonalQuests(uint16 event_id);
|
||||
|
||||
void ReloadRBAC();
|
||||
|
||||
protected:
|
||||
void _UpdateGameTime();
|
||||
// callback for UpdateRealmCharacters
|
||||
|
||||
@@ -22,6 +22,7 @@ Comment: All reload related commands
|
||||
Category: commandscripts
|
||||
EndScriptData */
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AchievementMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Chat.h"
|
||||
@@ -128,6 +129,7 @@ public:
|
||||
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL },
|
||||
{ "quest_poi", SEC_ADMINISTRATOR, true, &HandleReloadQuestPOICommand, "", NULL },
|
||||
{ "quest_template", SEC_ADMINISTRATOR, true, &HandleReloadQuestTemplateCommand, "", NULL },
|
||||
{ "rbac", SEC_ADMINISTRATOR, true, &HandleReloadRBACCommand, "", NULL },
|
||||
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesReferenceCommand, "", NULL },
|
||||
{ "reserved_name", SEC_ADMINISTRATOR, true, &HandleReloadReservedNameCommand, "", NULL },
|
||||
{ "reputation_reward_rate", SEC_ADMINISTRATOR, true, &HandleReloadReputationRewardRateCommand, "", NULL },
|
||||
@@ -1242,6 +1244,15 @@ public:
|
||||
handler->SendGlobalGMSysMessage("Vehicle template accessories reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
sLog->outInfo(LOG_FILTER_GENERAL, "Reloading RBAC tables...");
|
||||
sAccountMgr->LoadRBAC();
|
||||
sWorld->ReloadRBAC();
|
||||
handler->SendGlobalGMSysMessage("RBAC data reloaded.");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_reload_commandscript()
|
||||
|
||||
@@ -216,6 +216,8 @@ char const* Appender::getLogFilterTypeString(LogFilterType type)
|
||||
return "OPCODE";
|
||||
case LOG_FILTER_SOAP:
|
||||
return "SOAP";
|
||||
case LOG_FILTER_RBAC:
|
||||
return "RBAC";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ enum LogFilterType
|
||||
LOG_FILTER_BATTLEFIELD = 39,
|
||||
LOG_FILTER_SERVER_LOADING = 40,
|
||||
LOG_FILTER_OPCODES = 41,
|
||||
LOG_FILTER_SOAP = 42
|
||||
LOG_FILTER_SOAP = 42,
|
||||
LOG_FILTER_RBAC = 43
|
||||
};
|
||||
|
||||
const uint8 MaxLogFilter = 43;
|
||||
|
||||
@@ -2789,6 +2789,7 @@ Appenders=Console Server GM DBErrors Char RA Warden Chat
|
||||
# 40 - Server Loading
|
||||
# 41 - Opcodes (just id and name sent / received)
|
||||
# 42 - SOAP
|
||||
# 43 - RBAC (Role Based Access Control)
|
||||
#
|
||||
# LogLevel
|
||||
# 0 - (Disabled)
|
||||
|
||||
Reference in New Issue
Block a user