diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 5358073dbea..b439743a799 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -51,7 +51,13 @@ return FALSE return ..() +/datum/config_entry/proc/VASProcCallGuard(str_val) + . = !(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + if(!.) + log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]") + /datum/config_entry/proc/ValidateAndSet(str_val) + VASProcCallGuard(str_val) CRASH("Invalid config entry type!") /datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter) @@ -92,6 +98,8 @@ return var_name != "auto_trim" && ..() /datum/config_entry/string/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE value = auto_trim ? trim(str_val) : str_val return TRUE @@ -103,6 +111,8 @@ var/min_val = -INFINITY /datum/config_entry/number/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE var/temp = text2num(trim(str_val)) if(!isnull(temp)) value = Clamp(integer ? round(temp) : temp, min_val, max_val) @@ -120,6 +130,8 @@ abstract_type = /datum/config_entry/flag /datum/config_entry/flag/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE value = text2num(trim(str_val)) != 0 return TRUE @@ -128,6 +140,8 @@ value = list() /datum/config_entry/number_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE str_val = trim(str_val) var/list/new_list = list() var/list/values = splittext(str_val," ") @@ -147,6 +161,8 @@ dupes_allowed = TRUE /datum/config_entry/keyed_flag_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ") /datum/config_entry/keyed_number_list @@ -159,6 +175,8 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_number_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter) /datum/config_entry/keyed_string_list @@ -171,6 +189,8 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_string_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter) #undef LIST_MODE_NUM diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 7624d2473d0..8df012e5deb 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -118,6 +118,9 @@ GLOBAL_PROTECT(config_dir) stat("[name]:", statclick) /datum/controller/configuration/proc/Get(entry_type) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return var/datum/config_entry/E = entry_type var/entry_is_abstract = initial(E.abstract_type) == entry_type if(entry_is_abstract) @@ -128,6 +131,9 @@ GLOBAL_PROTECT(config_dir) return E.value /datum/controller/configuration/proc/Set(entry_type, new_val) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") + return var/datum/config_entry/E = entry_type var/entry_is_abstract = initial(E.abstract_type) == entry_type if(entry_is_abstract) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index ba42dbb9bae..cff80e6117d 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -96,10 +96,16 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that to_chat(usr, .) SSblackbox.add_details("admin_verb","Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -GLOBAL_VAR_INIT(AdminProcCaller, null) +GLOBAL_VAR(AdminProcCaller) GLOBAL_PROTECT(AdminProcCaller) GLOBAL_VAR_INIT(AdminProcCallCount, 0) GLOBAL_PROTECT(AdminProcCallCount) +GLOBAL_VAR(LastAdminCalledTargetRef) +GLOBAL_PROTECT(LastAdminCalledTargetRef) +GLOBAL_VAR(LastAdminCalledTarget) +GLOBAL_PROTECT(LastAdminCalledTarget) +GLOBAL_VAR(LastAdminCalledProc) +GLOBAL_PROTECT(LastAdminCalledProc) /proc/WrapAdminProcCall(target, procname, list/arguments) var/current_caller = GLOB.AdminProcCaller @@ -108,6 +114,9 @@ GLOBAL_PROTECT(AdminProcCallCount) to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") UNTIL(!GLOB.AdminProcCaller) to_chat(usr, "Running your proc") + GLOB.LastAdminCalledProc = procname + if(target != GLOBAL_PROC) + GLOB.LastAdminCalledTargetRef = "\ref[target]" GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you ++GLOB.AdminProcCallCount . = world.WrapAdminProcCall(target, procname, arguments)