1.1 --- a/core/AdminCache.cpp Mon Feb 05 09:14:40 2007 +0000
1.2 +++ b/core/AdminCache.cpp Mon Feb 05 10:34:58 2007 +0000
1.3 @@ -35,15 +35,8 @@
1.4
1.5 AdminCache::~AdminCache()
1.6 {
1.7 - if (m_pCmdGrpOverrides)
1.8 - {
1.9 - sm_trie_destroy(m_pCmdGrpOverrides);
1.10 - }
1.11 -
1.12 - if (m_pCmdOverrides)
1.13 - {
1.14 - sm_trie_destroy(m_pCmdOverrides);
1.15 - }
1.16 + sm_trie_destroy(m_pCmdGrpOverrides);
1.17 + sm_trie_destroy(m_pCmdOverrides);
1.18
1.19 DumpAdminCache(0xFFFFFFFF, false);
1.20
1.21 @@ -193,6 +186,8 @@
1.22 pUser->magic = USR_MAGIC_SET;
1.23 pUser->auth.identidx = -1;
1.24 pUser->auth.index = 0;
1.25 + pUser->immune_default = false;
1.26 + pUser->immune_global = false;
1.27
1.28 if (m_FirstUser == INVALID_ADMIN_ID)
1.29 {
1.30 @@ -986,9 +981,18 @@
1.31 table[pUser->grp_count] = gid;
1.32 pUser->grp_count++;
1.33
1.34 - /* Compute new effective flags */
1.35 + /* Compute new effective permissions */
1.36 pUser->eflags |= pGroup->addflags;
1.37
1.38 + if (pGroup->immune_default)
1.39 + {
1.40 + pUser->immune_default = true;
1.41 + }
1.42 + if (pGroup->immune_global)
1.43 + {
1.44 + pUser->immune_global = true;
1.45 + }
1.46 +
1.47 return true;
1.48 }
1.49
1.50 @@ -1087,3 +1091,100 @@
1.51
1.52 return num;
1.53 }
1.54 +
1.55 +bool AdminCache::CheckAdminFlags(AdminId id, FlagBits bits)
1.56 +{
1.57 + AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.58 + if (!pUser || pUser->magic != USR_MAGIC_SET)
1.59 + {
1.60 + return false;
1.61 + }
1.62 +
1.63 + return ((pUser->eflags & bits) == bits);
1.64 +}
1.65 +
1.66 +bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
1.67 +{
1.68 + /**
1.69 + * Zeroth, if the targeting AdminId is INVALID_ADMIN_ID, targeting fails.
1.70 + * First, if the targetted AdminId is INVALID_ADMIN_ID, targeting succeeds.
1.71 + */
1.72 +
1.73 + if (id == INVALID_ADMIN_ID)
1.74 + {
1.75 + return false;
1.76 + }
1.77 +
1.78 + if (target == INVALID_ADMIN_ID)
1.79 + {
1.80 + return true;
1.81 + }
1.82 +
1.83 + AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.84 + if (!pUser || pUser->magic != USR_MAGIC_SET)
1.85 + {
1.86 + return false;
1.87 + }
1.88 +
1.89 + AdminUser *pTarget = (AdminUser *)m_pMemory->GetAddress(target);
1.90 + if (!pTarget || pTarget->magic != USR_MAGIC_SET)
1.91 + {
1.92 + return false;
1.93 + }
1.94 +
1.95 + /**
1.96 + * Second, if the targeting admin is root, targeting suceeds.
1.97 + */
1.98 + if (pUser->eflags & ADMFLAG_ROOT)
1.99 + {
1.100 + return true;
1.101 + }
1.102 +
1.103 + /** Fourth, if the targetted admin has global immunity, targeting fails. */
1.104 + if (pTarget->immune_global)
1.105 + {
1.106 + return false;
1.107 + }
1.108 +
1.109 + /**
1.110 + * Fifth, if the targetted admin has default immunity
1.111 + * and the admin belongs to no groups, targeting fails.
1.112 + */
1.113 + if (pTarget->immune_default && pUser->grp_count < 1)
1.114 + {
1.115 + return false;
1.116 + }
1.117 +
1.118 + /**
1.119 + * Sixth, if the targetted admin has specific immunity from the
1.120 + * targeting admin via group immunities, targeting fails.
1.121 + */
1.122 + //:TODO: speed this up... maybe with trie hacks.
1.123 + //idea is to insert %d.%d in the trie after computing this and use it as a cache lookup.
1.124 + //problem is the trie cannot delete prefixes, so we'd have a problem with invalidations.
1.125 + if (pTarget->grp_count > 0 && pUser->grp_count > 0)
1.126 + {
1.127 + int *grp_table = (int *)m_pMemory->GetAddress(pTarget->grp_table);
1.128 + int *src_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.129 + GroupId id, other;
1.130 + unsigned int num;
1.131 + for (unsigned int i=0; i<pTarget->grp_count; i++)
1.132 + {
1.133 + id = grp_table[i];
1.134 + num = GetGroupImmunityCount(id);
1.135 + for (unsigned int j=0; j<num; i++)
1.136 + {
1.137 + other = GetGroupImmunity(id, j);
1.138 + for (unsigned int k=0; k<pUser->grp_count; k++)
1.139 + {
1.140 + if (other == src_table[k])
1.141 + {
1.142 + return false;
1.143 + }
1.144 + }
1.145 + }
1.146 + }
1.147 + }
1.148 +
1.149 + return true;
1.150 +}