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 }