unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

name_ban.c (5078B)

      1 /* name_ban.* RPC calls
      2  * (C) Copyright 2022-.. Bram Matthys (Syzop) and the UnrealIRCd team
      3  * License: GPLv2 or later
      4  */
      5 
      6 #include "unrealircd.h"
      7 
      8 ModuleHeader MOD_HEADER
      9 = {
     10 	"rpc/name_ban",
     11 	"1.0.1",
     12 	"name_ban.* RPC calls",
     13 	"UnrealIRCd Team",
     14 	"unrealircd-6",
     15 };
     16 
     17 /* Forward declarations */
     18 RPC_CALL_FUNC(rpc_name_ban_list);
     19 RPC_CALL_FUNC(rpc_name_ban_get);
     20 RPC_CALL_FUNC(rpc_name_ban_del);
     21 RPC_CALL_FUNC(rpc_name_ban_add);
     22 
     23 MOD_INIT()
     24 {
     25 	RPCHandlerInfo r;
     26 
     27 	MARK_AS_OFFICIAL_MODULE(modinfo);
     28 
     29 	memset(&r, 0, sizeof(r));
     30 	r.method = "name_ban.list";
     31 	r.loglevel = ULOG_DEBUG;
     32 	r.call = rpc_name_ban_list;
     33 	if (!RPCHandlerAdd(modinfo->handle, &r))
     34 	{
     35 		config_error("[rpc/name_ban] Could not register RPC handler");
     36 		return MOD_FAILED;
     37 	}
     38 	r.method = "name_ban.get";
     39 	r.loglevel = ULOG_DEBUG;
     40 	r.call = rpc_name_ban_get;
     41 	if (!RPCHandlerAdd(modinfo->handle, &r))
     42 	{
     43 		config_error("[rpc/name_ban] Could not register RPC handler");
     44 		return MOD_FAILED;
     45 	}
     46 	r.method = "name_ban.del";
     47 	r.call = rpc_name_ban_del;
     48 	if (!RPCHandlerAdd(modinfo->handle, &r))
     49 	{
     50 		config_error("[rpc/name_ban] Could not register RPC handler");
     51 		return MOD_FAILED;
     52 	}
     53 	r.method = "name_ban.add";
     54 	r.call = rpc_name_ban_add;
     55 	if (!RPCHandlerAdd(modinfo->handle, &r))
     56 	{
     57 		config_error("[rpc/name_ban] Could not register RPC handler");
     58 		return MOD_FAILED;
     59 	}
     60 
     61 	return MOD_SUCCESS;
     62 }
     63 
     64 MOD_LOAD()
     65 {
     66 	return MOD_SUCCESS;
     67 }
     68 
     69 MOD_UNLOAD()
     70 {
     71 	return MOD_SUCCESS;
     72 }
     73 
     74 RPC_CALL_FUNC(rpc_name_ban_list)
     75 {
     76 	json_t *result, *list, *item;
     77 	int index;
     78 	TKL *tkl;
     79 
     80 	result = json_object();
     81 	list = json_array();
     82 	json_object_set_new(result, "list", list);
     83 
     84 	for (index = 0; index < TKLISTLEN; index++)
     85 	{
     86 		for (tkl = tklines[index]; tkl; tkl = tkl->next)
     87 		{
     88 			if (TKLIsNameBan(tkl))
     89 			{
     90 				item = json_object();
     91 				json_expand_tkl(item, NULL, tkl, 1);
     92 				json_array_append_new(list, item);
     93 			}
     94 		}
     95 	}
     96 
     97 	rpc_response(client, request, result);
     98 	json_decref(result);
     99 }
    100 
    101 TKL *my_find_tkl_nameban(const char *name)
    102 {
    103 	TKL *tkl;
    104 
    105 	for (tkl = tklines[tkl_hash('Q')]; tkl; tkl = tkl->next)
    106 	{
    107 		if (!TKLIsNameBan(tkl))
    108 			continue;
    109 		if (!strcasecmp(name, tkl->ptr.nameban->name))
    110 			return tkl;
    111 	}
    112 	return NULL;
    113 }
    114 
    115 RPC_CALL_FUNC(rpc_name_ban_get)
    116 {
    117 	json_t *result, *list, *item;
    118 	const char *name;
    119 	TKL *tkl;
    120 
    121 	REQUIRE_PARAM_STRING("name", name);
    122 
    123 	if (!(tkl = my_find_tkl_nameban(name)))
    124 	{
    125 		rpc_error(client, request, JSON_RPC_ERROR_NOT_FOUND, "Ban not found");
    126 		return;
    127 	}
    128 
    129 	result = json_object();
    130 	json_expand_tkl(result, "tkl", tkl, 1);
    131 	rpc_response(client, request, result);
    132 	json_decref(result);
    133 }
    134 
    135 RPC_CALL_FUNC(rpc_name_ban_del)
    136 {
    137 	json_t *result, *list, *item;
    138 	const char *name;
    139 	const char *set_by;
    140 	TKL *tkl;
    141 	const char *tkllayer[7];
    142 
    143 	REQUIRE_PARAM_STRING("name", name);
    144 
    145 	OPTIONAL_PARAM_STRING("set_by", set_by);
    146 	if (!set_by)
    147 		set_by = client->name;
    148 
    149 	if (!(tkl = my_find_tkl_nameban(name)))
    150 	{
    151 		rpc_error(client, request, JSON_RPC_ERROR_NOT_FOUND, "Ban not found");
    152 		return;
    153 	}
    154 
    155 	result = json_object();
    156 	json_expand_tkl(result, "tkl", tkl, 1);
    157 
    158 	tkllayer[0] = NULL;
    159 	tkllayer[1] = "-";
    160 	tkllayer[2] = "Q";
    161 	tkllayer[3] = "*";
    162 	tkllayer[4] = name;
    163 	tkllayer[5] = set_by;
    164 	tkllayer[6] = NULL;
    165 	cmd_tkl(&me, NULL, 6, tkllayer);
    166 
    167 	if (!my_find_tkl_nameban(name))
    168 	{
    169 		rpc_response(client, request, result);
    170 	} else {
    171 		/* Actually this may not be an internal error, it could be an
    172 		 * incorrect request, such as asking to remove a config-based ban.
    173 		 */
    174 		rpc_error(client, request, JSON_RPC_ERROR_INTERNAL_ERROR, "Unable to remove item");
    175 	}
    176 	json_decref(result);
    177 }
    178 
    179 RPC_CALL_FUNC(rpc_name_ban_add)
    180 {
    181 	json_t *result, *list, *item;
    182 	const char *name;
    183 	const char *str;
    184 	const char *reason;
    185 	const char *set_by;
    186 	time_t tkl_expire_at;
    187 	time_t tkl_set_at = TStime();
    188 	TKL *tkl;
    189 
    190 	REQUIRE_PARAM_STRING("name", name);
    191 	REQUIRE_PARAM_STRING("reason", reason);
    192 
    193 	/* Duration / expiry time */
    194 	if ((str = json_object_get_string(params, "duration_string")))
    195 	{
    196 		tkl_expire_at = config_checkval(str, CFG_TIME);
    197 		if (tkl_expire_at > 0)
    198 			tkl_expire_at = TStime() + tkl_expire_at;
    199 	} else
    200 	if ((str = json_object_get_string(params, "expire_at")))
    201 	{
    202 		tkl_expire_at = server_time_to_unix_time(str);
    203 	} else
    204 	{
    205 		/* Never expire */
    206 		tkl_expire_at = 0;
    207 	}
    208 
    209 	OPTIONAL_PARAM_STRING("set_by", set_by);
    210 	if (!set_by)
    211 		set_by = client->name;
    212 
    213 	if ((tkl_expire_at != 0) && (tkl_expire_at < TStime()))
    214 	{
    215 		rpc_error_fmt(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Error: the specified expiry time is before current time (before now)");
    216 		return;
    217 	}
    218 
    219 	if (my_find_tkl_nameban(name))
    220 	{
    221 		rpc_error(client, request, JSON_RPC_ERROR_NOT_FOUND, "Ban already exists");
    222 		return;
    223 	}
    224 
    225 	tkl = tkl_add_nameban(TKL_NAME|TKL_GLOBAL, name, 0, reason,
    226 	                      set_by, tkl_expire_at, tkl_set_at,
    227 	                      0);
    228 
    229 	if (!tkl)
    230 	{
    231 		rpc_error(client, request, JSON_RPC_ERROR_INTERNAL_ERROR, "Unable to add item");
    232 		return;
    233 	}
    234 
    235 	tkl_added(client, tkl);
    236 
    237 	result = json_object();
    238 	json_expand_tkl(result, "tkl", tkl, 1);
    239 	rpc_response(client, request, result);
    240 	json_decref(result);
    241 }