2 * ===============================================================
3 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
4 * ===============================================================
6 * This file is not open source and may not be copied without explicit
7 * written permission of AlliedModders LLC. This file may not be redistributed
8 * in whole or significant part.
9 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
16 #include "AdminCache.h"
18 #include "ForwardSys.h"
22 AdminCache::AdminCache()
24 m_pCmdOverrides = NULL;
25 m_pCmdGrpOverrides = NULL;
26 m_pStrings = new BaseStringTable(1024);
27 m_pMemory = m_pStrings->GetMemTable();
28 m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID;
29 m_FreeUserList = m_FirstUser = m_LastUser = INVALID_ADMIN_ID;
30 m_pGroups = sm_trie_create();
35 AdminCache::~AdminCache()
37 if (m_pCmdGrpOverrides)
39 sm_trie_destroy(m_pCmdGrpOverrides);
44 sm_trie_destroy(m_pCmdOverrides);
47 InvalidateGroupCache();
51 sm_trie_destroy(m_pGroups);
57 void AdminCache::OnSourceModStartup(bool late)
59 RegisterAuthIdentType("steam");
60 RegisterAuthIdentType("name");
61 RegisterAuthIdentType("ip");
64 void AdminCache::OnSourceModAllInitialized()
66 m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell);
67 g_ShareSys.AddInterface(NULL, this);
70 void AdminCache::OnSourceModShutdown()
72 g_Forwards.ReleaseForward(m_pCacheFwd);
76 void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag)
78 if (type == Override_Command)
80 _AddCommandOverride(cmd, flag);
81 } else if (type == Override_CommandGroup) {
82 _AddCommandGroupOverride(cmd, flag);
86 bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag)
88 if (type == Override_Command)
90 return _GetCommandOverride(cmd, pFlag);
91 } else if (type == Override_CommandGroup) {
92 return _GetCommandGroupOverride(cmd, pFlag);
98 void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type)
100 if (type == Override_Command)
102 return _UnsetCommandOverride(cmd);
103 } else if (type == Override_CommandGroup) {
104 return _UnsetCommandGroupOverride(cmd);
108 void AdminCache::_AddCommandGroupOverride(const char *group, AdminFlag flag)
110 if (!m_pCmdGrpOverrides)
112 m_pCmdGrpOverrides = sm_trie_create();
115 /* :TODO: Notify command system */
117 sm_trie_insert(m_pCmdGrpOverrides, group, (void *)flag);
120 void AdminCache::_AddCommandOverride(const char *cmd, AdminFlag flag)
122 if (!m_pCmdOverrides)
124 m_pCmdOverrides = sm_trie_create();
127 /* :TODO: Notify command system */
129 sm_trie_insert(m_pCmdOverrides, cmd, (void *)flag);
132 bool AdminCache::_GetCommandGroupOverride(const char *cmd, AdminFlag *pFlag)
134 if (!m_pCmdGrpOverrides)
141 return sm_trie_retrieve(m_pCmdGrpOverrides, cmd, NULL);
145 if (ret=sm_trie_retrieve(m_pCmdGrpOverrides, cmd, &object))
147 *pFlag = (AdminFlag)(int)object;
153 bool AdminCache::_GetCommandOverride(const char *cmd, AdminFlag *pFlag)
155 if (!m_pCmdOverrides)
162 return sm_trie_retrieve(m_pCmdOverrides, cmd, NULL);
166 if (ret=sm_trie_retrieve(m_pCmdOverrides, cmd, &object))
168 *pFlag = (AdminFlag)(int)object;
174 void AdminCache::_UnsetCommandGroupOverride(const char *group)
176 if (!m_pCmdGrpOverrides)
181 /* :TODO: Notify command system */
183 sm_trie_delete(m_pCmdGrpOverrides, group);
186 void AdminCache::_UnsetCommandOverride(const char *cmd)
188 if (!m_pCmdOverrides)
193 /* :TODO: Notify command system */
195 sm_trie_delete(m_pCmdOverrides, cmd);
198 void AdminCache::DumpCommandOverrideCache(OverrideType type)
200 if (type == Override_Command && m_pCmdOverrides)
202 sm_trie_clear(m_pCmdOverrides);
203 } else if (type == Override_CommandGroup && m_pCmdGrpOverrides) {
204 sm_trie_clear(m_pCmdGrpOverrides);
208 AdminId AdminCache::CreateAdmin(const char *name)
213 if (m_FreeUserList != INVALID_ADMIN_ID)
215 pUser = (AdminUser *)m_pMemory->GetAddress(m_FreeUserList);
216 assert(pUser->magic == USR_MAGIC_UNSET);
218 m_FreeUserList = pUser->next_user;
220 id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
222 pUser->grp_table = -1;
223 pUser->auth_size = 0;
224 pUser->auth_table = -1;
227 memset(pUser->flags, 0, sizeof(pUser->flags));
228 memset(pUser->eflags, 0, sizeof(pUser->flags));
229 pUser->grp_count = 0;
230 pUser->auth_count = 0;
231 pUser->password = -1;
232 pUser->magic = USR_MAGIC_SET;
234 if (m_FirstUser == INVALID_ADMIN_ID)
239 AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
240 pPrev->next_user = id;
241 pUser->prev_user = m_LastUser;
245 if (name && name[0] != '\0')
247 pUser->nameidx = m_pStrings->AddString(name);
253 GroupId AdminCache::AddGroup(const char *group_name)
255 if (sm_trie_retrieve(m_pGroups, group_name, NULL))
257 return INVALID_GROUP_ID;
262 if (m_FreeGroupList != INVALID_GROUP_ID)
264 pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList);
265 assert(pGroup->magic == GRP_MAGIC_UNSET);
266 id = m_FreeGroupList;
267 m_FreeGroupList = pGroup->next_grp;
269 id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup);
272 pGroup->immune_default = false;
273 pGroup->immune_global = false;
274 pGroup->immune_table = -1;
275 pGroup->magic = GRP_MAGIC_SET;
276 pGroup->next_grp = INVALID_GROUP_ID;
277 pGroup->pCmdGrpTable = NULL;
278 pGroup->pCmdTable = NULL;
279 memset(pGroup->addflags, 0, sizeof(AdminFlag) * AdminFlags_TOTAL);
281 if (m_FirstGroup == INVALID_GROUP_ID)
285 pGroup->prev_grp = INVALID_GROUP_ID;
287 AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
288 assert(pPrev->magic == GRP_MAGIC_SET);
289 pPrev->next_grp = id;
290 pGroup->prev_grp = m_LastGroup;
294 pGroup->nameidx = m_pStrings->AddString(group_name);
296 sm_trie_insert(m_pGroups, group_name, (void *)id);
301 GroupId AdminCache::FindGroupByName(const char *group_name)
305 if (!sm_trie_retrieve(m_pGroups, group_name, &object))
307 return INVALID_GROUP_ID;
310 GroupId id = (GroupId)object;
311 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
313 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
315 return INVALID_GROUP_ID;
321 void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled)
323 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
324 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
329 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
334 pGroup->addflags[flag] = enabled;
337 bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag)
339 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
340 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
345 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
350 return pGroup->addflags[flag];
353 unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total)
355 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
356 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
364 i < AdminFlags_TOTAL && i < total;
367 flags[i] = pGroup->addflags[i];
373 void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled)
375 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
376 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
381 if (type == Immunity_Default)
383 pGroup->immune_default = enabled;
384 } else if (type == Immunity_Global) {
385 pGroup->immune_global = enabled;
389 bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type)
391 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
392 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
397 if (type == Immunity_Default)
399 return pGroup->immune_default;
400 } else if (type == Immunity_Global) {
401 return pGroup->immune_global;
407 void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id)
409 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
410 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
415 AdminGroup *pOther = (AdminGroup *)m_pMemory->GetAddress(id);
416 if (!pOther || pOther->magic != GRP_MAGIC_SET)
421 /* We always need to resize the immunity table */
423 if (pOther->immune_table == -1)
425 tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table);
428 int *old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
429 tblidx = m_pMemory->CreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table);
430 /* Get the old address again in caes of resize */
431 old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
432 table[0] = old_table[0];
433 for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++)
435 table[i] = old_table[i];
440 pOther->immune_table = tblidx;
442 /* Add to the array */
444 table[table[0]] = other_id;
447 unsigned int AdminCache::GetGroupImmunityCount(GroupId id)
449 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
450 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
455 if (pGroup->immune_table == -1)
460 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
465 GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number)
467 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
468 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
470 return INVALID_GROUP_ID;
473 if (pGroup->immune_table == -1)
475 return INVALID_GROUP_ID;
478 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
479 if (number >= (unsigned int)table[0])
481 return INVALID_GROUP_ID;
484 return table[1 + number];
487 void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule)
489 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
490 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
496 if (type == Override_Command)
498 if (pGroup->pCmdTable == NULL)
500 pGroup->pCmdTable = sm_trie_create();
502 pTrie = pGroup->pCmdTable;
503 } else if (type == Override_CommandGroup) {
504 if (pGroup->pCmdGrpTable == NULL)
506 pGroup->pCmdGrpTable = sm_trie_create();
508 pTrie = pGroup->pCmdGrpTable;
513 sm_trie_insert(pTrie, name, (void *)(int)rule);
516 bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule)
518 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
519 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
525 if (type == Override_Command)
527 if (pGroup->pCmdTable == NULL)
531 pTrie = pGroup->pCmdTable;
532 } else if (type == Override_CommandGroup) {
533 if (pGroup->pCmdGrpTable == NULL)
537 pTrie = pGroup->pCmdGrpTable;
543 if (!sm_trie_retrieve(pTrie, name, &object))
550 *pRule = (OverrideRule)(int)object;
556 Trie *AdminCache::GetMethodByIndex(unsigned int index)
558 List<AuthMethod>::iterator iter;
559 for (iter=m_AuthMethods.begin();
560 iter!=m_AuthMethods.end();
565 return (*iter).table;
572 bool AdminCache::InvalidateAdmin(AdminId id)
574 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
576 if (!pUser || pUser->magic != USR_MAGIC_SET)
581 /* Unlink from the dbl link list */
582 if (id == m_FirstUser && id == m_LastUser)
584 m_FirstUser = INVALID_ADMIN_ID;
585 m_LastUser = INVALID_ADMIN_ID;
586 } else if (id == m_FirstUser) {
587 m_FirstUser = pUser->next_user;
588 pOther = (AdminUser *)m_pMemory->GetAddress(m_FirstUser);
589 pOther->prev_user = INVALID_ADMIN_ID;
590 } else if (id == m_LastUser) {
591 m_LastUser = pUser->prev_user;
592 pOther = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
593 pOther->next_user = INVALID_ADMIN_ID;
595 pOther = (AdminUser *)m_pMemory->GetAddress(pUser->prev_user);
596 pOther->next_user = pUser->next_user;
597 pOther = (AdminUser *)m_pMemory->GetAddress(pUser->next_user);
598 pOther->prev_user = pUser->prev_user;
601 /* Unlink from auth tables */
602 if (pUser->auth_count > 0)
604 UserAuth *pAuth = (UserAuth *)m_pMemory->GetAddress(pUser->auth_table);
606 for (unsigned int i=0; i<pUser->auth_count; i++)
608 pTrie = GetMethodByIndex(pAuth[i].index);
613 sm_trie_delete(pTrie, m_pStrings->GetString(pAuth->identidx));
617 /* Clear table counts */
618 pUser->grp_count = 0;
619 pUser->auth_count = 0;
621 /* Link into free list */
622 pUser->magic = USR_MAGIC_UNSET;
623 pUser->next_user = m_FreeUserList;
630 void AdminCache::InvalidateGroup(GroupId id)
632 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
635 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
640 const char *str = m_pStrings->GetString(pGroup->nameidx);
641 sm_trie_delete(m_pGroups, str);
643 /* Unlink from the live dbllink list */
644 if (id == m_FirstGroup && id == m_LastGroup)
646 m_LastGroup = INVALID_GROUP_ID;
647 m_FirstGroup = INVALID_GROUP_ID;
648 } else if (id == m_FirstGroup) {
649 m_FirstGroup = pGroup->next_grp;
650 pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup);
651 pOther->prev_grp = INVALID_GROUP_ID;
652 } else if (id == m_LastGroup) {
653 m_LastGroup = pGroup->prev_grp;
654 pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
655 pOther->next_grp = INVALID_GROUP_ID;
657 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp);
658 pOther->next_grp = pGroup->next_grp;
659 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp);
660 pOther->prev_grp = pGroup->prev_grp;
663 /* Free any used memory to be safe */
664 if (pGroup->pCmdGrpTable)
666 sm_trie_destroy(pGroup->pCmdGrpTable);
667 pGroup->pCmdGrpTable = NULL;
669 if (pGroup->pCmdTable)
671 sm_trie_destroy(pGroup->pCmdTable);
672 pGroup->pCmdTable = NULL;
675 /* Link into the free list */
676 pGroup->magic = GRP_MAGIC_UNSET;
677 pGroup->next_grp = m_FreeGroupList;
678 m_FreeGroupList = id;
680 int idx = m_FirstUser;
683 while (idx != INVALID_ADMIN_ID)
685 pUser = (AdminUser *)m_pMemory->GetAddress(idx);
686 if (pUser->grp_count > 0)
688 table = (int *)m_pMemory->GetAddress(pUser->grp_table);
689 for (unsigned int i=0; i<pUser->grp_count; i++)
693 /* We have to remove this entry */
694 for (unsigned int j=i+1; j<pUser->grp_count; j++)
696 /* Move everything down by one */
697 table[j-1] = table[j];
701 /* Recalculate effective flags */
702 memset(pUser->eflags, 0, sizeof(pUser->eflags));
703 for (unsigned int j=0; j<pUser->grp_count; j++)
705 pOther = (AdminGroup *)m_pMemory->GetAddress(table[j]);
706 for (unsigned int k=0; k<AdminFlags_TOTAL; k++)
708 pUser->eflags[k] = (pUser->flags[k] || pOther->addflags[k]);
711 /* Break now, duplicates aren't allowed */
716 idx = pUser->next_user;
720 void AdminCache::InvalidateGroupCache()
722 /* Nuke the free list */
723 m_FreeGroupList = -1;
725 /* Nuke reverse lookups */
726 sm_trie_clear(m_pGroups);
728 /* Free memory on groups */
729 GroupId cur = m_FirstGroup;
731 while (cur != INVALID_GROUP_ID)
733 pGroup = (AdminGroup *)m_pMemory->GetAddress(cur);
734 assert(pGroup->magic == GRP_MAGIC_SET);
735 if (pGroup->pCmdGrpTable)
737 sm_trie_destroy(pGroup->pCmdGrpTable);
739 if (pGroup->pCmdTable)
741 sm_trie_destroy(pGroup->pCmdTable);
743 cur = pGroup->next_grp;
746 m_FirstGroup = INVALID_GROUP_ID;
747 m_LastGroup = INVALID_GROUP_ID;
749 InvalidateAdminCache(false);
751 /* Reset the memory table */
755 void AdminCache::AddAdminListener(IAdminListener *pListener)
757 m_hooks.push_back(pListener);
760 void AdminCache::RemoveAdminListener(IAdminListener *pListener)
762 m_hooks.remove(pListener);
765 void AdminCache::RegisterAuthIdentType(const char *name)
767 if (sm_trie_retrieve(m_pAuthTables, name, NULL))
772 Trie *pAuth = sm_trie_create();
775 method.name.assign(name);
776 method.table = pAuth;
778 m_AuthMethods.push_back(method);
780 sm_trie_insert(m_pAuthTables, name, pAuth);
783 void AdminCache::InvalidateAdminCache(bool unlink_admins)
785 /* Wipe the identity cache first */
786 List<AuthMethod>::iterator iter;
787 for (iter=m_AuthMethods.begin();
788 iter!=m_AuthMethods.end();
791 sm_trie_clear((*iter).table);
794 while (m_FirstUser != INVALID_ADMIN_ID)
796 InvalidateAdmin(m_FirstUser);
800 void AdminCache::DumpAdminCache(int cache_flags, bool rebuild)
802 if (cache_flags & ADMIN_CACHE_OVERRIDES)
804 DumpCommandOverrideCache(Override_Command);
805 DumpCommandOverrideCache(Override_CommandGroup);
808 /* This will auto-invalidate the admin cache */
809 if (cache_flags & ADMIN_CACHE_GROUPS)
811 InvalidateGroupCache();
814 /* If we only requested an admin rebuild, re-use the internal memory */
815 if ((cache_flags & ADMIN_CACHE_ADMINS) &&
816 !(cache_flags & ADMIN_CACHE_GROUPS))
818 InvalidateAdminCache(true);
823 List<IAdminListener *>::iterator iter;
824 IAdminListener *pListener;
826 for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
829 pListener->OnRebuildAdminCache(cache_flags);
831 m_pCacheFwd->PushCell(cache_flags);
832 m_pCacheFwd->Execute(&result);
836 const char *AdminCache::GetAdminName(AdminId id)
838 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
839 if (!pUser || pUser->magic != USR_MAGIC_SET)
844 return m_pStrings->GetString(pUser->nameidx);
847 bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
849 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
850 if (!pUser || pUser->magic != USR_MAGIC_SET)
856 if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
861 if (sm_trie_retrieve(pTable, ident, NULL))
866 return sm_trie_insert(pTable, ident, (void **)id);
869 AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
872 if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
874 return INVALID_ADMIN_ID;
878 if (!sm_trie_retrieve(pTable, identity, &object))
880 return INVALID_ADMIN_ID;
883 return (AdminId)object;
886 void AdminCache::SetAdminFlag(AdminId id, AdminFlag flag, bool enabled)
888 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
889 if (!pUser || pUser->magic != USR_MAGIC_SET)
894 if (flag < Admin_None
895 || flag >= AdminFlags_TOTAL)
900 pUser->flags[enabled] = false;
903 bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode)
905 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
906 if (!pUser || pUser->magic != USR_MAGIC_SET)
911 if (flag < Admin_None
912 || flag >= AdminFlags_TOTAL)
917 if (mode == Access_Real)
919 return pUser->flags[flag];
920 } else if (mode == Access_Effective) {
921 return (pUser->flags[flag] || pUser->eflags[flag]);
927 unsigned int AdminCache::GetAdminFlags(AdminId id, bool flags[], unsigned int total, AccessMode mode)
929 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
930 if (!pUser || pUser->magic != USR_MAGIC_SET)
936 if (mode == Access_Real)
938 for (i=0; i<AdminFlags_TOTAL && i<total; i++)
940 flags[i] = pUser->flags[i];
942 } else if (mode == Access_Effective) {
943 for (i=0; i<AdminFlags_TOTAL && i<total; i++)
945 flags[i] = (pUser->flags[i] || pUser->eflags[i]);
952 bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
954 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
955 if (!pUser || pUser->magic != USR_MAGIC_SET)
960 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
961 if (!pGroup || pGroup->magic != USR_MAGIC_SET)
967 if (pUser->grp_count + 1 > pUser->grp_size)
972 if (pUser->grp_size == 0)
976 new_size = pUser->grp_size * 2;
979 /* Create and refresh pointers */
980 tblidx = m_pMemory->CreateMem(new_size * sizeof(int), (void **)&table);
981 pUser = (AdminUser *)m_pMemory->GetAddress(id);
982 pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
984 /* Copy old data if necessary */
985 if (pUser->grp_table != -1)
987 int *old_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
988 memcpy(table, old_table, sizeof(int) * pUser->grp_count);
990 pUser->grp_table = tblidx;
991 pUser->grp_size = new_size;
993 table = (int *)m_pMemory->GetAddress(pUser->grp_table);
996 for (unsigned int i=0; i<pUser->grp_count; i++)
1004 table[pUser->grp_count] = gid;
1007 /* Compute new effective flags */
1008 for (unsigned int i=Admin_None;
1012 /* Only inherit flags additive flags we don't have */
1013 if (!pUser->eflags[i])
1015 pUser->eflags[i] = pGroup->addflags[i];
1022 unsigned int AdminCache::GetAdminGroupCount(AdminId id)
1024 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1025 if (!pUser || pUser->magic != USR_MAGIC_SET)
1030 return pUser->grp_count;
1033 GroupId AdminCache::GetAdminGroup(AdminId id, unsigned int index, const char **name)
1035 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1036 if (!pUser || pUser->magic != USR_MAGIC_SET || index >= pUser->grp_count)
1038 return INVALID_GROUP_ID;
1041 int *table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1043 return table[index];
1046 const char *AdminCache::GetAdminPassword(AdminId id)
1048 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1049 if (!pUser || pUser->magic != USR_MAGIC_SET)
1054 return m_pStrings->GetString(pUser->password);
1057 void AdminCache::SetAdminPassword(AdminId id, const char *password)
1059 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1060 if (!pUser || pUser->magic != USR_MAGIC_SET)
1065 pUser->password = m_pStrings->AddString(password);