diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 5d63e777087..49ef7a72855 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -19,6 +19,8 @@ #define BANTYPE_JOB_TEMP 4 #define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban. #define BANTYPE_APPEARANCE 6 +#define BANTYPE_ADMIN_PERMA 7 +#define BANTYPE_ADMIN_TEMP 8 //Please don't edit these values without speaking to Errorage first ~Carn //Admin Permissions diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 8cd511a3c9a..72cee4a7b4c 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -1,3 +1,4 @@ +#define MAX_ADMIN_BANS_PER_ADMIN 1 datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null) @@ -10,14 +11,22 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = var/serverip = "[world.internet_address]:[world.port]" var/bantype_pass = 0 var/bantype_str + var/maxadminbancheck //Used to limit the number of active bans of a certein type that each admin can give. Used to protect against abuse or mutiny. + var/announceinirc //When set, it announces the ban in irc. Intended to be a way to raise an alarm, so to speak. + var/blockselfban //Used to prevent the banning of yourself. + var/kickbannedckey //Defines whether this proc should kick the banned person, if they are connected (if banned_mob is defined). + //some ban types kick players after this proc passes (tempban, permaban), but some are specific to db_ban, so + //they should kick within this proc. switch(bantype) if(BANTYPE_PERMA) bantype_str = "PERMABAN" duration = -1 bantype_pass = 1 + blockselfban = 1 if(BANTYPE_TEMP) bantype_str = "TEMPBAN" bantype_pass = 1 + blockselfban = 1 if(BANTYPE_JOB_PERMA) bantype_str = "JOB_PERMABAN" duration = -1 @@ -29,6 +38,21 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = bantype_str = "APPEARANCE_BAN" duration = -1 bantype_pass = 1 + if(BANTYPE_ADMIN_PERMA) + bantype_str = "ADMIN_PERMABAN" + duration = -1 + bantype_pass = 1 + maxadminbancheck = 1 + announceinirc = 1 + blockselfban = 1 + kickbannedckey = 1 + if(BANTYPE_ADMIN_TEMP) + bantype_str = "ADMIN_TEMPBAN" + bantype_pass = 1 + maxadminbancheck = 1 + announceinirc = 1 + blockselfban = 1 + kickbannedckey = 1 if( !bantype_pass ) return if( !istext(reason) ) return @@ -66,6 +90,11 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = a_ckey = src.owner:ckey a_computerid = src.owner:computer_id a_ip = src.owner:address + + if(blockselfban) + if(a_ckey == ckey) + usr << "You cannot apply this ban type on yourself." + return var/who for(var/client/C in clients) @@ -82,6 +111,15 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = adminwho += ", [C]" reason = sql_sanitize_text(reason) + + if(maxadminbancheck) + var/DBQuery/adm_query = dbcon.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") + adm_query.Execute() + if(adm_query.NextRow()) + var/adm_bans = text2num(adm_query.item[1]) + if(adm_bans >= MAX_ADMIN_BANS_PER_ADMIN) + usr << "You already logged [MAX_ADMIN_BANS_PER_ADMIN] admin ban(s) or more. Do not abuse this function!" + return var/sql = "INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)" var/DBQuery/query_insert = dbcon.NewQuery(sql) @@ -89,7 +127,12 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = usr << "\blue Ban saved to database." message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1) + if(announceinirc) + send2irc("BAN ALERT","[a_ckey] applied a [bantype_str] on [ckey]") + if(kickbannedckey) + if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey) + del(banned_mob.client) datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") @@ -114,6 +157,12 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "") if(BANTYPE_APPEARANCE) bantype_str = "APPEARANCE_BAN" bantype_pass = 1 + if(BANTYPE_ADMIN_PERMA) + bantype_str = "ADMIN_PERMABAN" + bantype_pass = 1 + if(BANTYPE_ADMIN_TEMP) + bantype_str = "ADMIN_TEMPBAN" + bantype_pass = 1 if(BANTYPE_ANY_FULLBAN) bantype_str = "ANY" bantype_pass = 1 @@ -300,6 +349,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" output += "" output += "" + output += "" + output += "" output += "" output += "Ckey: " output += "IP: " @@ -339,6 +390,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" output += "" output += "" + output += "" + output += "" output += "" output += "

" output += " Match(min. 3 characters to search by key or ip, and 7 to search by cid)
" @@ -406,6 +459,10 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) bantypesearch += "'JOB_TEMPBAN' " if(BANTYPE_APPEARANCE) bantypesearch += "'APPEARANCE_BAN' " + if(BANTYPE_ADMIN_PERMA) + bantypesearch = "'ADMIN_PERMABAN' " + if(BANTYPE_ADMIN_TEMP) + bantypesearch = "'ADMIN_TEMPBAN' " else bantypesearch += "'PERMABAN' " @@ -448,6 +505,10 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) typedesc = "TEMP JOBBAN
([job])
([duration] minutes
Expires [expiration]" if("APPEARANCE_BAN") typedesc = "APPEARANCE/NAME BAN" + if("ADMIN_PERMABAN") + typedesc = "ADMIN PERMABAN" + if("ADMIN_TEMPBAN") + typedesc = "ADMIN TEMPBAN
([duration] minutes [(unbanned) ? "" : "(Edit))"]
Expires [expiration]
" output += "" output += "[typedesc]" diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 158f7ed1916..44027257bee 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -2,7 +2,7 @@ world/IsBanned(key,address,computer_id) if (!key || !address || !computer_id) log_access("Failed Login (invalid data): [key] [address]-[computer_id]") - return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)") + return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.") var/admin = 0 var/ckey = ckey(key) if((ckey in admin_datums) || (ckey in deadmins)) @@ -10,23 +10,25 @@ world/IsBanned(key,address,computer_id) //Guest Checking if(!guests_allowed && IsGuestKey(key)) - log_access("Failed Login: [key] - Guests not allowed") + log_access("Failed Login: [key] [computer_id] [address] - Guests not allowed") // message_admins("\blue Failed Login: [key] - Guests not allowed") - return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") + return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.") - //check if the IP address is a known TOR node - if(config && config.ToRban && ToRban_isbanned(address)) - log_access("Failed Login: [src] - Banned: ToR") - message_admins("\blue Failed Login: [src] - Banned: ToR") + //check if the IP address is a known Tor node + if(config.ToRban && ToRban_isbanned(address)) + log_access("Failed Login: [key] [computer_id] [address] - Banned: Tor") + message_admins("Failed Login: [key] - Banned: Tor") //ban their computer_id and ckey for posterity - AddBan(ckey(key), computer_id, "Use of ToR", "Automated Ban", 0, 0) - return list("reason"="Using ToR", "desc"="\nReason: The network you are using to connect has been banned.\nIf you believe this is a mistake, please request help at [config.banappeals]") + AddBan(ckey(key), computer_id, "Use of Tor", "Automated Ban", 0, 0) + var/mistakemessage = "" + if(config.banappeals) + mistakemessage = "\nIf you believe this is a mistake, please request help at [config.banappeals]." + return list("reason"="using Tor", "desc"="\nReason: The network you are using to connect has been banned.[mistakemessage]") if(config.ban_legacy_system) - //Ban Checking - . = CheckBan( ckey(key), computer_id, address ) + . = CheckBan(ckey(key), computer_id, address) if(.) if (admin) log_admin("The admin [key] has been allowed to bypass a matching ban on [.["key"]]") @@ -35,9 +37,7 @@ world/IsBanned(key,address,computer_id) else log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . - else - var/ckeytext = ckey(key) if(!establish_db_connection()) @@ -86,7 +86,7 @@ world/IsBanned(key,address,computer_id) expires = "The ban is for [duration] minutes and expires on [expiration] (server time)." else var/appealmessage = "" - if(config && config.banappeals) + if(config.banappeals) appealmessage = " You may appeal it at [config.banappeals]." expires = " The is a permanent ban.[appealmessage]" @@ -94,7 +94,6 @@ world/IsBanned(key,address,computer_id) . = list("reason"="[bantype]", "desc"="[desc]") - log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") return . @@ -107,7 +106,7 @@ world/IsBanned(key,address,computer_id) if (admin) log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban") message_admins("The admin [key] has been allowed to bypass a matching host/sticky ban") - addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban") + addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban") return null else log_access("Failed Login: [key] [computer_id] [address] - Banned [.["message"]]") diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm index ce8a756b7af..072cad1acf7 100644 --- a/code/modules/admin/stickyban.dm +++ b/code/modules/admin/stickyban.dm @@ -5,6 +5,7 @@ switch (action) if ("show") stickyban_show() + return if ("add") var/list/ban = list() var/ckey @@ -30,7 +31,7 @@ return ban["message"] = "[reason]" - world.SetConfig("ban",ckey,list2stickyban(ban)) + world.SetConfig("ban", ckey, list2stickyban(ban)) log_admin("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") message_admins("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") @@ -49,7 +50,7 @@ if (!get_stickyban_from_ckey(ckey)) usr << "Error: The ban disappeared." return - world.SetConfig("ban",ckey, null) + world.SetConfig("ban", ckey, null) log_admin("[key_name(usr)] removed [ckey]'s stickyban") message_admins("[key_name_admin(usr)] removed [ckey]'s stickyban") @@ -125,6 +126,8 @@ log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") message_admins("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") + + stickyban_show() /datum/admins/proc/stickyban_gethtml(ckey, ban) . = "\[-\][ckey]
" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index cc34e5a3437..b922b4979c8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -126,6 +126,17 @@ return banduration = null banjob = null + if(BANTYPE_ADMIN_PERMA) + if(!banckey || !banreason) + usr << "Not enough parameters (Requires ckey and reason)" + return + banduration = null + banjob = null + if(BANTYPE_ADMIN_TEMP) + if(!banckey || !banreason || !banduration) + usr << "Not enough parameters (Requires ckey, reason and duration)" + return + banjob = null var/mob/playermob diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index f0532fbd254..134cc9ff3f5 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -323,8 +323,12 @@ var/list/forbidden_varedit_object_types = list( for(var/p in forbidden_varedit_object_types) if( istype(O,p) ) - usr << "\red It is forbidden to edit this object's variables." + usr << "It is forbidden to edit this object's variables." return + + if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key")) + usr << "You cannot edit ckeys on client objects." + return var/class var/variable