plugins/admin-flatfile/admin-users.sp
author Matt Woodrow <pred@alliedmods.net>
Tue Jul 01 23:42:19 2008 +0000 (2008-07-01)
changeset 2143 ad12a83e4acd
parent 2052 138936f11ab5
child 2289 44045ead61cd
permissions -rw-r--r--
Added a null check on the vtable symbol
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Admin File Reader Plugin
     5  * Reads the admins.cfg file.  Do not compile this directly.
     6  *
     7  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
     8  * =============================================================================
     9  *
    10  * This program is free software; you can redistribute it and/or modify it under
    11  * the terms of the GNU General Public License, version 3.0, as published by the
    12  * Free Software Foundation.
    13  * 
    14  * This program is distributed in the hope that it will be useful, but WITHOUT
    15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    17  * details.
    18  *
    19  * You should have received a copy of the GNU General Public License along with
    20  * this program.  If not, see <http://www.gnu.org/licenses/>.
    21  *
    22  * As a special exception, AlliedModders LLC gives you permission to link the
    23  * code of this program (as well as its derivative works) to "Half-Life 2," the
    24  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    25  * by the Valve Corporation.  You must obey the GNU General Public License in
    26  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    27  * this exception to all derivative works.  AlliedModders LLC defines further
    28  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    29  * or <http://www.sourcemod.net/license.php>.
    30  *
    31  * Version: $Id$
    32  */
    33 
    34 #define USER_STATE_NONE			0
    35 #define USER_STATE_ADMINS		1
    36 #define USER_STATE_INADMIN		2
    37 
    38 static Handle:g_hUserParser = INVALID_HANDLE;
    39 static g_UserState = USER_STATE_NONE;
    40 static String:g_CurAuth[64];
    41 static String:g_CurIdent[64];
    42 static String:g_CurName[64];
    43 static String:g_CurPass[64];
    44 static Handle:g_GroupArray;
    45 static g_CurFlags;
    46 static g_CurImmunity;
    47 
    48 public SMCResult:ReadUsers_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
    49 {
    50 	if (g_IgnoreLevel)
    51 	{
    52 		g_IgnoreLevel++;
    53 		return SMCParse_Continue;
    54 	}
    55 	
    56 	if (g_UserState == USER_STATE_NONE)
    57 	{
    58 		if (StrEqual(name, "Admins"))
    59 		{
    60 			g_UserState = USER_STATE_ADMINS;
    61 		}
    62 		else
    63 		{
    64 			g_IgnoreLevel++;
    65 		}
    66 	}
    67 	else if (g_UserState == USER_STATE_ADMINS)
    68 	{
    69 		g_UserState = USER_STATE_INADMIN;
    70 		strcopy(g_CurName, sizeof(g_CurName), name);
    71 		g_CurAuth[0] = '\0';
    72 		g_CurIdent[0] = '\0';
    73 		g_CurPass[0] = '\0';
    74 		ClearArray(g_GroupArray);
    75 		g_CurFlags = 0;
    76 		g_CurImmunity = 0;
    77 	}
    78 	else
    79 	{
    80 		g_IgnoreLevel++;
    81 	}
    82 	
    83 	return SMCParse_Continue;
    84 }
    85 
    86 public SMCResult:ReadUsers_KeyValue(Handle:smc, 
    87 									const String:key[], 
    88 									const String:value[], 
    89 									bool:key_quotes, 
    90 									bool:value_quotes)
    91 {
    92 	if (g_UserState != USER_STATE_INADMIN || g_IgnoreLevel)
    93 	{
    94 		return SMCParse_Continue;
    95 	}
    96 	
    97 	if (StrEqual(key, "auth"))
    98 	{
    99 		strcopy(g_CurAuth, sizeof(g_CurAuth), value);
   100 	}
   101 	else if (StrEqual(key, "identity"))
   102 	{
   103 		strcopy(g_CurIdent, sizeof(g_CurIdent), value);
   104 	}
   105 	else if (StrEqual(key, "password")) 
   106 	{
   107 		strcopy(g_CurPass, sizeof(g_CurPass), value);
   108 	} 
   109 	else if (StrEqual(key, "group")) 
   110 	{
   111 		new GroupId:id = FindAdmGroup(value);
   112 		if (id == INVALID_GROUP_ID)
   113 		{
   114 			ParseError("Unknown group \"%s\"", value);
   115 		}
   116 
   117 		PushArrayCell(g_GroupArray, id);
   118 	} 
   119 	else if (StrEqual(key, "flags")) 
   120 	{
   121 		new len = strlen(value);
   122 		new AdminFlag:flag;
   123 		
   124 		for (new i = 0; i < len; i++)
   125 		{
   126 			if (!FindFlagByChar(value[i], flag))
   127 			{
   128 				ParseError("Invalid flag detected: %c", value[i]);
   129 			}
   130 			else
   131 			{
   132 				g_CurFlags |= FlagToBit(flag);
   133 			}
   134 		}
   135 	} 
   136 	else if (StrEqual(key, "immunity")) 
   137 	{
   138 		g_CurImmunity = StringToInt(value);
   139 	}
   140 	
   141 	return SMCParse_Continue;
   142 }
   143 
   144 public SMCResult:ReadUsers_EndSection(Handle:smc)
   145 {
   146 	if (g_IgnoreLevel)
   147 	{
   148 		g_IgnoreLevel--;
   149 		return SMCParse_Continue;
   150 	}
   151 	
   152 	if (g_UserState == USER_STATE_INADMIN)
   153 	{
   154 		/* Dump this user to memory */
   155 		if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0')
   156 		{
   157 			decl AdminFlag:flags[26];
   158 			new AdminId:id, i, num_groups, num_flags;
   159 			
   160 			if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID)
   161 			{
   162 				id = CreateAdmin(g_CurName);
   163 				if (!BindAdminIdentity(id, g_CurAuth, g_CurIdent))
   164 				{
   165 					ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent);
   166 				}
   167 			}
   168 			
   169 			num_groups = GetArraySize(g_GroupArray);
   170 			for (i = 0; i < num_groups; i++)
   171 			{
   172 				AdminInheritGroup(id, GetArrayCell(g_GroupArray, i));
   173 			}
   174 			
   175 			SetAdminPassword(id, g_CurPass);
   176 			if (GetAdminImmunityLevel(id) < g_CurImmunity)
   177 			{
   178 				SetAdminImmunityLevel(id, g_CurImmunity);
   179 			}
   180 			
   181 			num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags));
   182 			for (i = 0; i < num_flags; i++)
   183 			{
   184 				SetAdminFlag(id, flags[i], true);
   185 			}
   186 		}
   187 		else
   188 		{
   189 			ParseError("Failed to create admin: did you forget either the auth or identity properties?");
   190 		}
   191 		
   192 		g_UserState = USER_STATE_ADMINS;
   193 	}
   194 	else if (g_UserState == USER_STATE_ADMINS)
   195 	{
   196 		g_UserState = USER_STATE_NONE;
   197 	}
   198 	
   199 	return SMCParse_Continue;
   200 }
   201 
   202 public SMCResult:ReadUsers_CurrentLine(Handle:smc, const String:line[], lineno)
   203 {
   204 	g_CurrentLine = lineno;
   205 	
   206 	return SMCParse_Continue;
   207 }
   208 
   209 static InitializeUserParser()
   210 {
   211 	if (g_hUserParser == INVALID_HANDLE)
   212 	{
   213 		g_hUserParser = SMC_CreateParser();
   214 		SMC_SetReaders(g_hUserParser,
   215 					   ReadUsers_NewSection,
   216 					   ReadUsers_KeyValue,
   217 					   ReadUsers_EndSection);
   218 		SMC_SetRawLine(g_hUserParser, ReadUsers_CurrentLine);
   219 		
   220 		g_GroupArray = CreateArray();
   221 	}
   222 }
   223 
   224 ReadUsers()
   225 {
   226 	InitializeUserParser();
   227 	
   228 	BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins.cfg");
   229 
   230 	/* Set states */
   231 	InitGlobalStates();
   232 	g_UserState = USER_STATE_NONE;
   233 		
   234 	new SMCError:err = SMC_ParseFile(g_hUserParser, g_Filename);
   235 	if (err != SMCError_Okay)
   236 	{
   237 		decl String:buffer[64];
   238 		if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
   239 		{
   240 			ParseError("%s", buffer);
   241 		}
   242 		else
   243 		{
   244 			ParseError("Fatal parse error");
   245 		}
   246 	}
   247 }