added some access helper functions
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40440
This commit is contained in:
parent
b018cd9d3a
commit
6858d12ad9
@ -35,15 +35,8 @@ AdminCache::AdminCache()
|
||||
|
||||
AdminCache::~AdminCache()
|
||||
{
|
||||
if (m_pCmdGrpOverrides)
|
||||
{
|
||||
sm_trie_destroy(m_pCmdGrpOverrides);
|
||||
}
|
||||
|
||||
if (m_pCmdOverrides)
|
||||
{
|
||||
sm_trie_destroy(m_pCmdOverrides);
|
||||
}
|
||||
sm_trie_destroy(m_pCmdGrpOverrides);
|
||||
sm_trie_destroy(m_pCmdOverrides);
|
||||
|
||||
DumpAdminCache(0xFFFFFFFF, false);
|
||||
|
||||
@ -193,6 +186,8 @@ AdminId AdminCache::CreateAdmin(const char *name)
|
||||
pUser->magic = USR_MAGIC_SET;
|
||||
pUser->auth.identidx = -1;
|
||||
pUser->auth.index = 0;
|
||||
pUser->immune_default = false;
|
||||
pUser->immune_global = false;
|
||||
|
||||
if (m_FirstUser == INVALID_ADMIN_ID)
|
||||
{
|
||||
@ -986,9 +981,18 @@ bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
|
||||
table[pUser->grp_count] = gid;
|
||||
pUser->grp_count++;
|
||||
|
||||
/* Compute new effective flags */
|
||||
/* Compute new effective permissions */
|
||||
pUser->eflags |= pGroup->addflags;
|
||||
|
||||
if (pGroup->immune_default)
|
||||
{
|
||||
pUser->immune_default = true;
|
||||
}
|
||||
if (pGroup->immune_global)
|
||||
{
|
||||
pUser->immune_global = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1087,3 +1091,100 @@ unsigned int AdminCache::FlagBitsToArray(FlagBits bits, AdminFlag array[], unsig
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
bool AdminCache::CheckAdminFlags(AdminId id, FlagBits bits)
|
||||
{
|
||||
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
|
||||
if (!pUser || pUser->magic != USR_MAGIC_SET)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((pUser->eflags & bits) == bits);
|
||||
}
|
||||
|
||||
bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
|
||||
{
|
||||
/**
|
||||
* Zeroth, if the targeting AdminId is INVALID_ADMIN_ID, targeting fails.
|
||||
* First, if the targetted AdminId is INVALID_ADMIN_ID, targeting succeeds.
|
||||
*/
|
||||
|
||||
if (id == INVALID_ADMIN_ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target == INVALID_ADMIN_ID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
|
||||
if (!pUser || pUser->magic != USR_MAGIC_SET)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminUser *pTarget = (AdminUser *)m_pMemory->GetAddress(target);
|
||||
if (!pTarget || pTarget->magic != USR_MAGIC_SET)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second, if the targeting admin is root, targeting suceeds.
|
||||
*/
|
||||
if (pUser->eflags & ADMFLAG_ROOT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Fourth, if the targetted admin has global immunity, targeting fails. */
|
||||
if (pTarget->immune_global)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fifth, if the targetted admin has default immunity
|
||||
* and the admin belongs to no groups, targeting fails.
|
||||
*/
|
||||
if (pTarget->immune_default && pUser->grp_count < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sixth, if the targetted admin has specific immunity from the
|
||||
* targeting admin via group immunities, targeting fails.
|
||||
*/
|
||||
//:TODO: speed this up... maybe with trie hacks.
|
||||
//idea is to insert %d.%d in the trie after computing this and use it as a cache lookup.
|
||||
//problem is the trie cannot delete prefixes, so we'd have a problem with invalidations.
|
||||
if (pTarget->grp_count > 0 && pUser->grp_count > 0)
|
||||
{
|
||||
int *grp_table = (int *)m_pMemory->GetAddress(pTarget->grp_table);
|
||||
int *src_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
|
||||
GroupId id, other;
|
||||
unsigned int num;
|
||||
for (unsigned int i=0; i<pTarget->grp_count; i++)
|
||||
{
|
||||
id = grp_table[i];
|
||||
num = GetGroupImmunityCount(id);
|
||||
for (unsigned int j=0; j<num; i++)
|
||||
{
|
||||
other = GetGroupImmunity(id, j);
|
||||
for (unsigned int k=0; k<pUser->grp_count; k++)
|
||||
{
|
||||
if (other == src_table[k])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ struct AdminUser
|
||||
int next_user; /* Next user in ze list */
|
||||
int prev_user; /* Prev user in the list */
|
||||
UserAuth auth; /* Auth method for this user */
|
||||
bool immune_global; /* Whether globally immune */
|
||||
bool immune_default; /* Whether defaultly immune */
|
||||
};
|
||||
|
||||
class AdminCache :
|
||||
@ -127,6 +129,8 @@ public: //IAdminSystem
|
||||
FlagBits FlagBitArrayToBits(const bool array[], unsigned int maxSize);
|
||||
FlagBits FlagArrayToBits(const AdminFlag array[], unsigned int numFlags);
|
||||
unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize);
|
||||
bool CheckAdminFlags(AdminId id, FlagBits bits);
|
||||
bool CanAdminTarget(AdminId id, AdminId target);
|
||||
private:
|
||||
void _UnsetCommandOverride(const char *cmd);
|
||||
void _UnsetCommandGroupOverride(const char *group);
|
||||
|
@ -416,7 +416,7 @@ namespace SourceMod
|
||||
virtual bool GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode) =0;
|
||||
|
||||
/**
|
||||
* @brief Returns a bitarray of flags enabled on an admin.
|
||||
* @brief Returns the bitstring of access flags on an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param mode Access mode to use.
|
||||
@ -524,6 +524,35 @@ namespace SourceMod
|
||||
* @return Number of flags written.
|
||||
*/
|
||||
virtual unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize) =0;
|
||||
|
||||
/**
|
||||
* @brief Checks whether a user has access to a given set of flag bits.
|
||||
* Note: This is a wrapper around GetAdminFlags().
|
||||
*
|
||||
* @param id AdminId index of admin.
|
||||
* @param flags Bitstring containing the permissions to check.
|
||||
* @return True if user has permission, false otherwise.
|
||||
*/
|
||||
virtual bool CheckAdminFlags(AdminId id, FlagBits bits) =0;
|
||||
|
||||
/**
|
||||
* @brief Checks whether an AdminId can target another AdminId.
|
||||
*
|
||||
* Zeroth, if the targeting AdminId is INVALID_ADMIN_ID, targeting fails.
|
||||
* First, if the targetted AdminId is INVALID_ADMIN_ID, targeting succeeds.
|
||||
* Second, if the targeting admin is root, targeting suceeds.
|
||||
* Third, if the targetted admin has global immunity, targeting fails.
|
||||
* Fourth, if the targetted admin has default immunity,
|
||||
* and the admin belongs to no groups, targeting fails.
|
||||
* Fifth, if the targetted admin has specific immunity from the
|
||||
* targeting admin via group immunities, targeting fails.
|
||||
* Sixth, targeting succeeds if it passes these tests.
|
||||
*
|
||||
* @param id AdminId index of admin doing the targeting. Can be INVALID_ADMIN_ID.
|
||||
* @param target AdminId index of the target admin. Can be INVALID_ADMIN_ID.
|
||||
* @return True if this admin has permission to target the other admin.
|
||||
*/
|
||||
virtual bool CanAdminTarget(AdminId id, AdminId target) =0;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user