]> jfr.im git - irc/rqf/shadowircd.git/blame - modules/core/m_ban.c
Do not install ban .conf files (like kline.conf, rsv.conf, etc) as they aren't used...
[irc/rqf/shadowircd.git] / modules / core / m_ban.c
CommitLineData
65b8e002
JT
1/*
2 * charybdis: An advanced ircd.
3 * m_ban.c: Propagates network bans across servers.
4 *
5 * Copyright (C) 2010 Jilles Tjoelker
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1.Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2.Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "stdinc.h"
31#include "send.h"
9b9d818b 32#include "channel.h"
65b8e002
JT
33#include "client.h"
34#include "common.h"
35#include "config.h"
36#include "ircd.h"
37#include "match.h"
38#include "s_conf.h"
70fd7fc9 39#include "s_newconf.h"
65b8e002
JT
40#include "msg.h"
41#include "modules.h"
42#include "hash.h"
43#include "s_serv.h"
44#include "operhash.h"
45#include "reject.h"
46#include "hostmask.h"
47
d8316e07 48static int m_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
65b8e002
JT
49static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
50
51struct Message ban_msgtab = {
52 "BAN", 0, 0, 0, MFLG_SLOW,
d8316e07 53 {mg_unreg, {m_ban, 0}, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, {m_ban, 0}}
65b8e002
JT
54};
55
56mapi_clist_av1 ban_clist[] = { &ban_msgtab, NULL };
57DECLARE_MODULE_AV1(ban, NULL, NULL, ban_clist, NULL, NULL, "$Revision: 1349 $");
58
d8316e07
JT
59static int
60m_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
61{
62 sendto_one_notice(source_p, ":The BAN command is not user-accessible.");
63 sendto_one_notice(source_p, ":To ban a user from a channel, see /QUOTE HELP CMODE");
64 if (IsOper(source_p))
65 sendto_one_notice(source_p, ":To ban a user from a server or from the network, see /QUOTE HELP KLINE");
66 return 0;
67}
68
65b8e002
JT
69/* ms_ban()
70 *
e49d8185
JT
71 * parv[1] - type
72 * parv[2] - username mask or *
73 * parv[3] - hostname mask
74 * parv[4] - creation TS
75 * parv[5] - duration (relative to creation)
76 * parv[6] - lifetime (relative to creation)
77 * parv[7] - oper or *
78 * parv[8] - reason (possibly with |operreason)
65b8e002
JT
79 */
80static int
81ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
82{
83 rb_dlink_node *ptr;
84 struct ConfItem *aconf;
85 unsigned int ntype;
86 const char *oper, *stype;
87 time_t created, hold, lifetime;
88 char *p;
89 int act;
9b9d818b 90 int valid;
65b8e002 91
e49d8185 92 if (strlen(parv[1]) != 1)
65b8e002
JT
93 {
94 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
95 "Unknown BAN type %s from %s",
e49d8185 96 parv[1], source_p->name);
65b8e002
JT
97 return 0;
98 }
e49d8185 99 switch (parv[1][0])
65b8e002
JT
100 {
101 case 'K':
102 ntype = CONF_KILL;
103 stype = "K-Line";
104 break;
112e8a66
JT
105 case 'X':
106 ntype = CONF_XLINE;
107 stype = "X-Line";
108 break;
9b9d818b
JT
109 case 'R':
110 ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL :
111 CONF_RESV_NICK;
112 stype = "RESV";
113 break;
65b8e002
JT
114 default:
115 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
116 "Unknown BAN type %s from %s",
e49d8185 117 parv[1], source_p->name);
65b8e002
JT
118 return 0;
119 }
e49d8185
JT
120 created = atol(parv[4]);
121 hold = created + atoi(parv[5]);
122 lifetime = created + atoi(parv[6]);
123 if (!strcmp(parv[7], "*"))
65b8e002
JT
124 oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
125 else
e49d8185
JT
126 oper = parv[7];
127 ptr = find_prop_ban(ntype, parv[2], parv[3]);
65b8e002
JT
128 if (ptr != NULL)
129 {
9dc68130 130 /* We already know about this ban mask. */
65b8e002 131 aconf = ptr->data;
c177d078
JT
132 if (aconf->created > created ||
133 (aconf->created == created &&
134 aconf->lifetime >= lifetime))
65b8e002
JT
135 {
136 if (IsPerson(source_p))
137 sendto_one_notice(source_p,
138 ":Your %s [%s%s%s] has been superseded",
139 stype,
140 aconf->user ? aconf->user : "",
141 aconf->user ? "@" : "",
142 aconf->host);
143 return 0;
144 }
9dc68130
JT
145 /* act indicates if something happened (from the oper's
146 * point of view). This is the case if the ban was
147 * previously active (not deleted) or if the new ban
148 * is not a removal and not already expired.
149 */
e49d8185
JT
150 act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
151 hold > rb_current_time());
65b8e002
JT
152 if (lifetime > aconf->lifetime)
153 aconf->lifetime = lifetime;
154 /* already expired, hmm */
155 if (aconf->lifetime <= rb_current_time())
156 return 0;
9dc68130 157 /* Deactivate, it will be reactivated later if appropriate. */
65b8e002
JT
158 deactivate_conf(aconf, ptr);
159 rb_free(aconf->user);
160 aconf->user = NULL;
161 rb_free(aconf->host);
162 aconf->host = NULL;
163 operhash_delete(aconf->info.oper);
164 aconf->info.oper = NULL;
165 rb_free(aconf->passwd);
166 aconf->passwd = NULL;
167 rb_free(aconf->spasswd);
168 aconf->spasswd = NULL;
169 }
170 else
171 {
9dc68130 172 /* New ban mask. */
65b8e002
JT
173 aconf = make_conf();
174 aconf->status = CONF_ILLEGAL | ntype;
175 aconf->lifetime = lifetime;
176 rb_dlinkAddAlloc(aconf, &prop_bans);
e49d8185 177 act = hold != created && hold > rb_current_time();
65b8e002
JT
178 }
179 aconf->flags &= ~CONF_FLAGS_MYOPER;
180 aconf->flags |= CONF_FLAGS_TEMPORARY;
e49d8185
JT
181 aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
182 aconf->host = rb_strdup(parv[3]);
65b8e002
JT
183 aconf->info.oper = operhash_add(oper);
184 aconf->created = created;
185 aconf->hold = hold;
a75522e6 186 if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
65b8e002
JT
187 aconf->passwd = rb_strdup(parv[parc - 1]);
188 else
189 {
190 aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
191 aconf->spasswd = rb_strdup(p + 1);
192 }
9dc68130
JT
193 /* The ban is fully filled in and in the prop_bans list
194 * but still deactivated. Now determine if it should be activated
195 * and send the server notices.
196 */
197 /* We only reject *@* and the like here.
198 * Otherwise malformed bans are fairly harmless and can be removed.
199 */
9b9d818b
JT
200 switch (ntype)
201 {
202 case CONF_KILL:
203 valid = valid_wild_card(aconf->user, aconf->host);
204 break;
205 case CONF_RESV_CHANNEL:
206 valid = 1;
207 break;
208 default:
209 valid = valid_wild_card_simple(aconf->host);
210 break;
211 }
212 if (act && hold != created && !valid)
70fd7fc9
JT
213 {
214 sendto_realops_snomask(SNO_GENERAL, L_ALL,
215 "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
7c880acb 216 (int)((hold - rb_current_time()) / 60),
70fd7fc9
JT
217 stype,
218 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
219 strcmp(parv[7], "*") ? " on behalf of " : "",
220 strcmp(parv[7], "*") ? parv[7] : "",
221 aconf->user ? aconf->user : "",
222 aconf->user ? "@" : "",
223 aconf->host);
224 if(IsPerson(source_p))
225 sendto_one_notice(source_p,
226 ":Your %s [%s%s%s] has too few non-wildcard characters",
227 stype,
228 aconf->user ? aconf->user : "",
229 aconf->user ? "@" : "",
230 aconf->host);
231 /* Propagate it, but do not apply it locally. */
232 }
233 else if (act && hold != created)
65b8e002
JT
234 {
235 /* Keep the notices in sync with modules/m_kline.c etc. */
236 sendto_realops_snomask(SNO_GENERAL, L_ALL,
237 "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
238 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
7c880acb 239 (int)((hold - rb_current_time()) / 60),
65b8e002 240 stype,
e49d8185
JT
241 strcmp(parv[7], "*") ? " from " : "",
242 strcmp(parv[7], "*") ? parv[7] : "",
65b8e002
JT
243 aconf->user ? aconf->user : "",
244 aconf->user ? "@" : "",
245 aconf->host,
246 parv[parc - 1]);
112e8a66 247 ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1],
65b8e002 248 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
7c880acb 249 (int)((hold - rb_current_time()) / 60),
112e8a66
JT
250 aconf->user ? aconf->user : "",
251 aconf->user ? " " : "",
252 aconf->host,
65b8e002 253 parv[parc - 1]);
e49d8185 254 aconf->status &= ~CONF_ILLEGAL;
65b8e002
JT
255 }
256 else if (act)
257 {
258 sendto_realops_snomask(SNO_GENERAL, L_ALL,
259 "%s has removed the global %s for: [%s%s%s]%s%s",
260 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
261 stype,
262 aconf->user ? aconf->user : "",
263 aconf->user ? "@" : "",
264 aconf->host,
e49d8185
JT
265 strcmp(parv[7], "*") ? " on behalf of " : "",
266 strcmp(parv[7], "*") ? parv[7] : "");
112e8a66 267 ilog(L_KLINE, "U%s %s %s%s %s", parv[1],
65b8e002 268 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
112e8a66
JT
269 aconf->user ? aconf->user : "",
270 aconf->user ? " " : "",
271 aconf->host);
65b8e002 272 }
9dc68130
JT
273 /* If CONF_ILLEGAL is still set at this point, remove entries from the
274 * reject cache (for klines and xlines).
275 * If CONF_ILLEGAL is not set, add the ban to the type-specific data
276 * structure and take action on matched clients/channels.
277 */
65b8e002
JT
278 switch (ntype)
279 {
280 case CONF_KILL:
281 if (aconf->status & CONF_ILLEGAL)
282 remove_reject_mask(aconf->user, aconf->host);
283 else
284 {
285 add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
286 if(ConfigFileEntry.kline_delay ||
287 (IsServer(source_p) &&
288 !HasSentEob(source_p)))
289 {
290 if(kline_queued == 0)
291 {
292 rb_event_addonce("check_klines", check_klines_event, NULL,
293 ConfigFileEntry.kline_delay);
294 kline_queued = 1;
295 }
296 }
297 else
298 check_klines();
299 }
300 break;
112e8a66
JT
301 case CONF_XLINE:
302 if (aconf->status & CONF_ILLEGAL)
303 remove_reject_mask(aconf->host, NULL);
304 else
305 {
306 rb_dlinkAddAlloc(aconf, &xline_conf_list);
307 check_xlines();
308 }
309 break;
9b9d818b
JT
310 case CONF_RESV_CHANNEL:
311 if (!(aconf->status & CONF_ILLEGAL))
312 {
313 add_to_resv_hash(aconf->host, aconf);
314 resv_chan_forcepart(aconf->host, aconf->passwd, hold - rb_current_time());
315 }
316 break;
317 case CONF_RESV_NICK:
318 if (!(aconf->status & CONF_ILLEGAL))
319 rb_dlinkAddAlloc(aconf, &resv_conf_list);
320 break;
65b8e002 321 }
05114b16 322 sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS,
e49d8185 323 ":%s BAN %s %s %s %s %s %s %s :%s",
65b8e002
JT
324 source_p->id,
325 parv[1],
326 parv[2],
327 parv[3],
328 parv[4],
329 parv[5],
330 parv[6],
331 parv[7],
65b8e002
JT
332 parv[parc - 1]);
333 return 0;
334}