added admin access checking
authorDavid Anderson <dvander@alliedmods.net>
Sat Feb 17 08:59:52 2007 +0000 (2007-02-17)
changeset 5144c02b38c26ed
parent 513 0c299b5ad420
child 515 643240c66787
added admin access checking
added syncing between overrides
(note: denial message is a todo)
core/AdminCache.cpp
core/CConCmdManager.cpp
core/CConCmdManager.h
core/smn_console.cpp
plugins/include/console.inc
     1.1 --- a/core/AdminCache.cpp	Sat Feb 17 07:54:20 2007 +0000
     1.2 +++ b/core/AdminCache.cpp	Sat Feb 17 08:59:52 2007 +0000
     1.3 @@ -17,6 +17,7 @@
     1.4  #include "ShareSys.h"
     1.5  #include "ForwardSys.h"
     1.6  #include "CPlayerManager.h"
     1.7 +#include "CConCmdManager.h"
     1.8  
     1.9  AdminCache g_Admins;
    1.10  
    1.11 @@ -93,6 +94,8 @@
    1.12  	}
    1.13  
    1.14  	sm_trie_insert(pTrie, cmd, (void *)(unsigned int)flags);
    1.15 +
    1.16 +	g_ConCmds.UpdateAdminCmdFlags(cmd, type, flags);
    1.17  }
    1.18  
    1.19  bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags)
    1.20 @@ -138,9 +141,9 @@
    1.21  		return;
    1.22  	}
    1.23  
    1.24 -	/* :TODO: Notify command system */
    1.25 +	sm_trie_delete(m_pCmdGrpOverrides, group);
    1.26  
    1.27 -	sm_trie_delete(m_pCmdGrpOverrides, group);
    1.28 +	g_ConCmds.UpdateAdminCmdFlags(group, Override_CommandGroup, 0);
    1.29  }
    1.30  
    1.31  void AdminCache::_UnsetCommandOverride(const char *cmd)
    1.32 @@ -150,9 +153,9 @@
    1.33  		return;
    1.34  	}
    1.35  
    1.36 -	/* :TODO: Notify command system */
    1.37 +	sm_trie_delete(m_pCmdOverrides, cmd);
    1.38  
    1.39 -	sm_trie_delete(m_pCmdOverrides, cmd);
    1.40 +	g_ConCmds.UpdateAdminCmdFlags(cmd, Override_Command, 0);
    1.41  }
    1.42  
    1.43  void AdminCache::DumpCommandOverrideCache(OverrideType type)
     2.1 --- a/core/CConCmdManager.cpp	Sat Feb 17 07:54:20 2007 +0000
     2.2 +++ b/core/CConCmdManager.cpp	Sat Feb 17 08:59:52 2007 +0000
     2.3 @@ -15,6 +15,8 @@
     2.4  #include "sm_srvcmds.h"
     2.5  #include "AdminCache.h"
     2.6  #include "sm_stringutil.h"
     2.7 +#include "CPlayerManager.h"
     2.8 +#include "CTranslator.h"
     2.9  
    2.10  CConCmdManager g_ConCmds;
    2.11  
    2.12 @@ -149,10 +151,13 @@
    2.13  			 iter++)
    2.14  		{
    2.15  			pHook = (*iter);
    2.16 -			if (pHook->pAdmin
    2.17 -				&& pHook->pAdmin->eflags)
    2.18 +			if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
    2.19  			{
    2.20 -				/* :TODO: admin calculations */
    2.21 +				if (result < Pl_Handled)
    2.22 +				{
    2.23 +					result = Pl_Handled;
    2.24 +				}
    2.25 +				continue;
    2.26  			}
    2.27  			pHook->pf->PushCell(client);
    2.28  			pHook->pf->PushCell(args);
    2.29 @@ -241,9 +246,13 @@
    2.30  			pHook = (*iter);
    2.31  			if (m_CmdClient 
    2.32  				&& pHook->pAdmin
    2.33 -				&& pHook->pAdmin->eflags)
    2.34 +				&& !CheckAccess(m_CmdClient, cmd, pHook->pAdmin))
    2.35  			{
    2.36 -				/* :TODO: check admin stuff */
    2.37 +				if (result < Pl_Handled)
    2.38 +				{
    2.39 +					result = Pl_Handled;
    2.40 +				}
    2.41 +				continue;
    2.42  			}
    2.43  			pHook->pf->PushCell(m_CmdClient);
    2.44  			pHook->pf->PushCell(args);
    2.45 @@ -271,9 +280,67 @@
    2.46  	}
    2.47  }
    2.48  
    2.49 -ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args)
    2.50 +bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
    2.51  {
    2.52 -	return Pl_Continue;
    2.53 +	FlagBits cmdflags = pAdmin->eflags;
    2.54 +	if (cmdflags == 0)
    2.55 +	{
    2.56 +		return true;
    2.57 +	}
    2.58 +
    2.59 +	CPlayer *player = g_Players.GetPlayerByIndex(client);
    2.60 +	if (!player)
    2.61 +	{
    2.62 +		return false;
    2.63 +	}
    2.64 +
    2.65 +	AdminId adm = player->GetAdminId();
    2.66 +	if (adm != INVALID_ADMIN_ID)
    2.67 +	{
    2.68 +		FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective);
    2.69 +
    2.70 +		/* root knows all, WHOA */
    2.71 +		if ((bits & ADMFLAG_ROOT) == ADMFLAG_ROOT)
    2.72 +		{
    2.73 +			return true;
    2.74 +		}
    2.75 +
    2.76 +		/* See if our other flags match */
    2.77 +		if ((bits & cmdflags) != cmdflags)
    2.78 +		{
    2.79 +			return true;
    2.80 +		}
    2.81 +
    2.82 +		/* Check for overrides */
    2.83 +		unsigned int groups = g_Admins.GetAdminGroupCount(adm);
    2.84 +		GroupId gid;
    2.85 +		OverrideRule rule;
    2.86 +		bool override = false;
    2.87 +		for (unsigned int i=0; i<groups; i++)
    2.88 +		{
    2.89 +			gid = g_Admins.GetAdminGroup(adm, i, NULL);
    2.90 +			/* First get group-level override */
    2.91 +			override = g_Admins.GetGroupCommandOverride(gid, cmd, Override_CommandGroup, &rule);
    2.92 +			/* Now get the specific command override */
    2.93 +			if (g_Admins.GetGroupCommandOverride(gid, cmd, Override_Command, &rule))
    2.94 +			{
    2.95 +				override = true;
    2.96 +			}
    2.97 +			if (override)
    2.98 +			{
    2.99 +				if (rule == Command_Allow)
   2.100 +				{
   2.101 +					return true;
   2.102 +				} else if (rule == Command_Deny) {
   2.103 +					break;
   2.104 +				}
   2.105 +			}
   2.106 +		}
   2.107 +	}
   2.108 +
   2.109 +	/* If we got here, the command failed... */
   2.110 +	/* :TODO: send a message to the client about this! */
   2.111 +	return false;
   2.112  }
   2.113  
   2.114  void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction, 
   2.115 @@ -467,6 +534,66 @@
   2.116  	}
   2.117  }
   2.118  
   2.119 +void CConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits)
   2.120 +{
   2.121 +	ConCmdInfo *pInfo;
   2.122 +
   2.123 +	if (type == Override_Command)
   2.124 +	{
   2.125 +		if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
   2.126 +		{
   2.127 +			return;
   2.128 +		}
   2.129 +
   2.130 +		List<CmdHook *>::iterator iter;
   2.131 +		CmdHook *pHook;
   2.132 +
   2.133 +		for (iter=pInfo->conhooks.begin(); iter!=pInfo->conhooks.end(); iter++)
   2.134 +		{
   2.135 +			pHook = (*iter);
   2.136 +			if (pHook->pAdmin)
   2.137 +			{
   2.138 +				if (bits)
   2.139 +				{
   2.140 +					pHook->pAdmin->eflags = bits;
   2.141 +				} else {
   2.142 +					pHook->pAdmin->eflags = pHook->pAdmin->flags;
   2.143 +				}
   2.144 +			}
   2.145 +		}
   2.146 +	} else if (type == Override_CommandGroup) {
   2.147 +		void *object;
   2.148 +		if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object))
   2.149 +		{
   2.150 +			return;
   2.151 +		}
   2.152 +		int grpid = (int)object;
   2.153 +
   2.154 +		/* This is bad :( loop through all commands */
   2.155 +		List<ConCmdInfo *>::iterator iter;
   2.156 +		CmdHook *pHook;
   2.157 +		for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++)
   2.158 +		{
   2.159 +			pInfo = (*iter);
   2.160 +			for (List<CmdHook *>::iterator citer=pInfo->conhooks.begin();
   2.161 +				 citer!=pInfo->conhooks.end();
   2.162 +				 citer++)
   2.163 +			{
   2.164 +				pHook = (*citer);
   2.165 +				if (pHook->pAdmin && pHook->pAdmin->cmdGrpId == grpid)
   2.166 +				{
   2.167 +					if (bits)
   2.168 +					{
   2.169 +						pHook->pAdmin->eflags = bits;
   2.170 +					} else {
   2.171 +						pHook->pAdmin->eflags = pHook->pAdmin->flags;
   2.172 +					}
   2.173 +				}
   2.174 +			}
   2.175 +		}
   2.176 +	}
   2.177 +}
   2.178 +
   2.179  void CConCmdManager::RemoveConCmd(ConCmdInfo *info)
   2.180  {
   2.181  	/* Remove console-specific information
     3.1 --- a/core/CConCmdManager.h	Sat Feb 17 07:54:20 2007 +0000
     3.2 +++ b/core/CConCmdManager.h	Sat Feb 17 08:59:52 2007 +0000
     3.3 @@ -98,6 +98,7 @@
     3.4  						 const char *description, 
     3.5  						 int flags);
     3.6  	ResultType DispatchClientCommand(int client, ResultType type);
     3.7 +	void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits);
     3.8  private:
     3.9  	void InternalDispatch();
    3.10  	ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
    3.11 @@ -106,10 +107,11 @@
    3.12  	void AddToCmdList(ConCmdInfo *info);
    3.13  	void RemoveConCmd(ConCmdInfo *info);
    3.14  	void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
    3.15 +	bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
    3.16  private:
    3.17  	Trie *m_pCmds;					/* command lookup */
    3.18  	Trie *m_pCmdGrps;				/* command group lookup */
    3.19 -	List<ConCmdInfo *> m_CmdList;	/* command list, currently unused */
    3.20 +	List<ConCmdInfo *> m_CmdList;	/* command list */
    3.21  	int m_CmdClient;				/* current client */
    3.22  	BaseStringTable m_Strings;		/* string table */
    3.23  };
     4.1 --- a/core/smn_console.cpp	Sat Feb 17 07:54:20 2007 +0000
     4.2 +++ b/core/smn_console.cpp	Sat Feb 17 08:59:52 2007 +0000
     4.3 @@ -16,6 +16,7 @@
     4.4  #include "HandleSys.h"
     4.5  #include "CConVarManager.h"
     4.6  #include "CConCmdManager.h"
     4.7 +#include "PluginSys.h"
     4.8  
     4.9  static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
    4.10  {
    4.11 @@ -361,6 +362,35 @@
    4.12  	return 1;
    4.13  }
    4.14  
    4.15 +static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
    4.16 +{
    4.17 +	char *name,*help;
    4.18 +	const char *group;
    4.19 +	IPluginFunction *pFunction;
    4.20 +	FlagBits flags = params[3];
    4.21 +	int cmdflags = params[6];
    4.22 +
    4.23 +	pContext->LocalToString(params[1], &name);
    4.24 +	pContext->LocalToString(params[4], &help);
    4.25 +	pContext->LocalToString(params[5], (char **)&group);
    4.26 +	pFunction = pContext->GetFunctionById(params[2]);
    4.27 +
    4.28 +	if (group[0] == '\0')
    4.29 +	{
    4.30 +		CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
    4.31 +		group = pPlugin->GetFilename();
    4.32 +	}
    4.33 +
    4.34 +	if (!pFunction)
    4.35 +	{
    4.36 +		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
    4.37 +	}
    4.38 +
    4.39 +	g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags);
    4.40 +
    4.41 +	return 1;
    4.42 +}
    4.43 +
    4.44  REGISTER_NATIVES(convarNatives)
    4.45  {
    4.46  	{"CreateConVar",		sm_CreateConVar},
     5.1 --- a/plugins/include/console.inc	Sat Feb 17 07:54:20 2007 +0000
     5.2 +++ b/plugins/include/console.inc	Sat Feb 17 08:59:52 2007 +0000
     5.3 @@ -112,7 +112,6 @@
     5.4   */
     5.5  native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
     5.6  
     5.7 -#if 0
     5.8  /**
     5.9   * Creates a console command as an administrative command.  If the command does not exist,
    5.10   * it is created. 
    5.11 @@ -126,13 +125,12 @@
    5.12   * @param flags			Optional console flags.
    5.13   * @noreturn
    5.14   */
    5.15 -native RegAdminCmd(const String:cmd[], 
    5.16 -						ConCmd:callback, 
    5.17 -						adminflags, 
    5.18 -						const String:group[]="", 
    5.19 -						const String:description[]="", 
    5.20 -						flags=0);
    5.21 -#endif
    5.22 +native RegAdminCmd(const String:cmd[],
    5.23 +					ConCmd:callback,
    5.24 +					adminflags,
    5.25 +					const String:description[]="",
    5.26 +					const String:group[]="",
    5.27 +					flags=0);
    5.28  
    5.29  /**
    5.30   * Creates a new console variable.