1 |
/* |
2 |
* ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). |
3 |
* m_kline.c: Bans a user. |
4 |
* |
5 |
* Copyright (C) 2002 by the past and present ircd coders, and others. |
6 |
* |
7 |
* This program is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License as published by |
9 |
* the Free Software Foundation; either version 2 of the License, or |
10 |
* (at your option) any later version. |
11 |
* |
12 |
* This program is distributed in the hope that it will be useful, |
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
* GNU General Public License for more details. |
16 |
* |
17 |
* You should have received a copy of the GNU General Public License |
18 |
* along with this program; if not, write to the Free Software |
19 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
20 |
* USA |
21 |
* |
22 |
* $Id$ |
23 |
*/ |
24 |
|
25 |
#include "stdinc.h" |
26 |
#include "tools.h" |
27 |
#include "channel.h" |
28 |
#include "client.h" |
29 |
#include "common.h" |
30 |
#include "irc_string.h" |
31 |
#include "sprintf_irc.h" |
32 |
#include "ircd.h" |
33 |
#include "hostmask.h" |
34 |
#include "numeric.h" |
35 |
#include "list.h" |
36 |
#include "fdlist.h" |
37 |
#include "s_bsd.h" |
38 |
#include "s_conf.h" |
39 |
#include "s_log.h" |
40 |
#include "s_misc.h" |
41 |
#include "send.h" |
42 |
#include "hash.h" |
43 |
#include "handlers.h" |
44 |
#include "s_serv.h" |
45 |
#include "msg.h" |
46 |
#include "s_gline.h" |
47 |
#include "parse.h" |
48 |
#include "modules.h" |
49 |
#include "tools.h" |
50 |
|
51 |
static void me_kline(struct Client *, struct Client *, int, char **); |
52 |
static void mo_kline(struct Client *, struct Client *, int, char **); |
53 |
static void ms_kline(struct Client *, struct Client *, int, char **); |
54 |
static void mo_dline(struct Client *, struct Client *, int, char **); |
55 |
static void me_unkline(struct Client *, struct Client *, int, char **); |
56 |
static void mo_unkline(struct Client *, struct Client *, int, char **); |
57 |
static void ms_unkline(struct Client *, struct Client *, int, char **); |
58 |
static void mo_undline(struct Client *, struct Client *, int, char **); |
59 |
|
60 |
#ifndef IPV6 |
61 |
static char *make_cidr(char *dlhost, struct Client *); |
62 |
#endif |
63 |
|
64 |
static int remove_tkline_match(const char *, const char *); |
65 |
static int remove_tdline_match(const char *); |
66 |
|
67 |
struct Message kline_msgtab = { |
68 |
"KLINE", 0, 0, 2, 0, MFLG_SLOW, 0, |
69 |
{m_unregistered, m_not_oper, ms_kline, me_kline, mo_kline, m_ignore} |
70 |
}; |
71 |
|
72 |
struct Message dline_msgtab = { |
73 |
"DLINE", 0, 0, 2, 0, MFLG_SLOW, 0, |
74 |
{m_unregistered, m_not_oper, m_error, m_ignore, mo_dline, m_ignore} |
75 |
}; |
76 |
|
77 |
struct Message unkline_msgtab = { |
78 |
"UNKLINE", 0, 0, 2, 0, MFLG_SLOW, 0, |
79 |
{m_unregistered, m_not_oper, ms_unkline, me_unkline, mo_unkline, m_ignore} |
80 |
}; |
81 |
|
82 |
struct Message undline_msgtab = { |
83 |
"UNDLINE", 0, 0, 2, 0, MFLG_SLOW, 0, |
84 |
{m_unregistered, m_not_oper, m_error, m_ignore, mo_undline, m_ignore} |
85 |
}; |
86 |
|
87 |
#ifndef STATIC_MODULES |
88 |
void |
89 |
_modinit(void) |
90 |
{ |
91 |
mod_add_cmd(&kline_msgtab); |
92 |
mod_add_cmd(&unkline_msgtab); |
93 |
mod_add_cmd(&dline_msgtab); |
94 |
mod_add_cmd(&undline_msgtab); |
95 |
add_capability("KLN", CAP_KLN, 1); |
96 |
add_capability("UNKLN", CAP_UNKLN, 1); |
97 |
} |
98 |
|
99 |
void |
100 |
_moddeinit(void) |
101 |
{ |
102 |
mod_del_cmd(&kline_msgtab); |
103 |
mod_del_cmd(&unkline_msgtab); |
104 |
mod_del_cmd(&dline_msgtab); |
105 |
mod_del_cmd(&undline_msgtab); |
106 |
delete_capability("UNKLN"); |
107 |
delete_capability("KLN"); |
108 |
} |
109 |
|
110 |
const char *_version = "$Revision$"; |
111 |
#endif |
112 |
|
113 |
/* Local function prototypes */ |
114 |
static int already_placed_kline(struct Client *, const char *, const char *, int); |
115 |
static void apply_kline(struct Client *, struct ConfItem *, const char *, time_t); |
116 |
static void apply_tkline(struct Client *, struct ConfItem *, int); |
117 |
|
118 |
static char buffer[IRCD_BUFSIZE]; |
119 |
|
120 |
/* mo_kline() |
121 |
* |
122 |
* inputs - pointer to server |
123 |
* - pointer to client |
124 |
* - parameter count |
125 |
* - parameter list |
126 |
* output - |
127 |
* side effects - k line is added |
128 |
*/ |
129 |
static void |
130 |
mo_kline(struct Client *client_p, struct Client *source_p, |
131 |
int parc, char **parv) |
132 |
{ |
133 |
char *reason = NULL; |
134 |
char *oper_reason; |
135 |
char *user = NULL; |
136 |
char *host = NULL; |
137 |
const char *current_date; |
138 |
char *target_server = NULL; |
139 |
struct ConfItem *conf; |
140 |
struct AccessItem *aconf; |
141 |
time_t tkline_time = 0; |
142 |
time_t cur_time; |
143 |
|
144 |
if (!IsOperK(source_p)) |
145 |
{ |
146 |
sendto_one(source_p, form_str(ERR_NOPRIVS), |
147 |
me.name, source_p->name, "kline"); |
148 |
return; |
149 |
} |
150 |
|
151 |
if (parse_aline("KLINE", source_p, parc, parv, |
152 |
AWILD, &user, &host, &tkline_time, &target_server, &reason) < 0) |
153 |
return; |
154 |
|
155 |
if (target_server != NULL) |
156 |
{ |
157 |
if (HasID(source_p)) |
158 |
{ |
159 |
sendto_server(NULL, source_p, NULL, CAP_KLN|CAP_TS6, NOCAPS, LL_ICLIENT, |
160 |
":%s KLINE %s %lu %s %s :%s", |
161 |
source_p->id, target_server, (unsigned long)tkline_time, |
162 |
user, host, reason); |
163 |
sendto_server(NULL, source_p, NULL, CAP_KLN, CAP_TS6, LL_ICLIENT, |
164 |
":%s KLINE %s %lu %s %s :%s", |
165 |
source_p->name, target_server, (unsigned long)tkline_time, |
166 |
user, host, reason); |
167 |
} |
168 |
else |
169 |
sendto_server(NULL, source_p, NULL, CAP_KLN, NOCAPS, LL_ICLIENT, |
170 |
":%s KLINE %s %lu %s %s :%s", |
171 |
source_p->name, target_server, (unsigned long)tkline_time, |
172 |
user, host, reason); |
173 |
|
174 |
/* Allow ON to apply local kline as well if it matches */ |
175 |
if (!match(target_server, me.name)) |
176 |
return; |
177 |
} |
178 |
else |
179 |
cluster_a_line(source_p, "KLINE", CAP_KLN, SHARED_KLINE, |
180 |
"%d %s %s :%s", tkline_time, user, host, reason); |
181 |
|
182 |
if (already_placed_kline(source_p, user, host, YES)) |
183 |
return; |
184 |
|
185 |
/* Look for an oper reason */ |
186 |
if ((oper_reason = strchr(reason, '|')) != NULL) |
187 |
*oper_reason++ = '\0'; |
188 |
|
189 |
cur_time = CurrentTime; |
190 |
current_date = smalldate(cur_time); |
191 |
conf = make_conf_item(KLINE_TYPE); |
192 |
aconf = map_to_conf(conf); |
193 |
|
194 |
DupString(aconf->host, host); |
195 |
DupString(aconf->user, user); |
196 |
|
197 |
if (tkline_time != 0) |
198 |
{ |
199 |
ircsprintf(buffer, "Temporary K-line %d min. - %s (%s)", |
200 |
(int)(tkline_time/60), reason, current_date); |
201 |
DupString(aconf->reason, buffer); |
202 |
|
203 |
if (oper_reason != NULL) |
204 |
DupString(aconf->oper_reason, oper_reason); |
205 |
apply_tkline(source_p, conf, tkline_time); |
206 |
} |
207 |
else |
208 |
{ |
209 |
ircsprintf(buffer, "%s (%s)", reason, current_date); |
210 |
DupString(aconf->reason, buffer); |
211 |
|
212 |
if (oper_reason != NULL) |
213 |
DupString(aconf->oper_reason, oper_reason); |
214 |
apply_kline(source_p, conf, current_date, cur_time); |
215 |
} |
216 |
} |
217 |
|
218 |
/* me_kline - handle remote kline. no propagation */ |
219 |
static void |
220 |
me_kline(struct Client *client_p, struct Client *source_p, |
221 |
int parc, char *parv[]) |
222 |
{ |
223 |
struct ConfItem *conf=NULL; |
224 |
struct AccessItem *aconf=NULL; |
225 |
int tkline_time; |
226 |
const char* current_date; |
227 |
time_t cur_time; |
228 |
char *kuser, *khost, *kreason, *oper_reason; |
229 |
|
230 |
if (parc != 6 || EmptyString(parv[5])) |
231 |
return; |
232 |
|
233 |
if (!match(parv[1], me.name)) |
234 |
return; |
235 |
|
236 |
tkline_time = valid_tkline(parv[2], TK_SECONDS); |
237 |
kuser = parv[3]; |
238 |
khost = parv[4]; |
239 |
kreason = parv[5]; |
240 |
|
241 |
if ((oper_reason = strchr(kreason, '|')) != NULL) |
242 |
*oper_reason++ = '\0'; |
243 |
|
244 |
cur_time = CurrentTime; |
245 |
current_date = smalldate(cur_time); |
246 |
|
247 |
if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, |
248 |
source_p->username, source_p->host, |
249 |
SHARED_KLINE)) |
250 |
{ |
251 |
if (!IsClient(source_p) || |
252 |
already_placed_kline(source_p, kuser, khost, YES)) |
253 |
return; |
254 |
|
255 |
conf = make_conf_item(KLINE_TYPE); |
256 |
aconf = map_to_conf(conf); |
257 |
DupString(aconf->host, khost); |
258 |
DupString(aconf->user, kuser); |
259 |
|
260 |
if (tkline_time != 0) |
261 |
{ |
262 |
ircsprintf(buffer, "Temporary K-line %d min. - %s (%s)", |
263 |
(int)(tkline_time/60), kreason, current_date); |
264 |
DupString(aconf->reason, buffer); |
265 |
|
266 |
if (oper_reason != NULL) |
267 |
DupString(aconf->oper_reason, oper_reason); |
268 |
apply_tkline(source_p, conf, tkline_time); |
269 |
} |
270 |
else |
271 |
{ |
272 |
ircsprintf(buffer, "%s (%s)", kreason, current_date); |
273 |
DupString(aconf->reason, buffer); |
274 |
|
275 |
if (oper_reason != NULL) |
276 |
DupString(aconf->oper_reason, oper_reason); |
277 |
apply_kline(source_p, conf, current_date, cur_time); |
278 |
} |
279 |
} |
280 |
} |
281 |
|
282 |
static void |
283 |
ms_kline(struct Client *client_p, struct Client *source_p, |
284 |
int parc, char *parv[]) |
285 |
{ |
286 |
if (parc != 6 || EmptyString(parv[5])) |
287 |
return; |
288 |
|
289 |
/* parv[0] parv[1] parv[2] parv[3] parv[4] parv[5] */ |
290 |
/* oper target_server tkline_time user host reason */ |
291 |
sendto_match_servs(source_p, parv[1], CAP_KLN, |
292 |
"KLINE %s %s %s %s :%s", |
293 |
parv[1], parv[2], parv[3], parv[4], parv[5]); |
294 |
|
295 |
me_kline(client_p, source_p, parc, parv); |
296 |
} |
297 |
|
298 |
/* apply_kline() |
299 |
* |
300 |
* inputs - |
301 |
* output - NONE |
302 |
* side effects - kline as given, is added to the hashtable |
303 |
* and conf file |
304 |
*/ |
305 |
static void |
306 |
apply_kline(struct Client *source_p, struct ConfItem *conf, |
307 |
const char *current_date, time_t cur_time) |
308 |
{ |
309 |
struct AccessItem *aconf = map_to_conf(conf); |
310 |
|
311 |
add_conf_by_address(CONF_KILL, aconf); |
312 |
write_conf_line(source_p, conf, current_date, cur_time); |
313 |
/* Now, activate kline against current online clients */ |
314 |
rehashed_klines = 1; |
315 |
} |
316 |
|
317 |
/* apply_tkline() |
318 |
* |
319 |
* inputs - |
320 |
* output - NONE |
321 |
* side effects - tkline as given is placed |
322 |
*/ |
323 |
static void |
324 |
apply_tkline(struct Client *source_p, struct ConfItem *conf, |
325 |
int tkline_time) |
326 |
{ |
327 |
struct AccessItem *aconf; |
328 |
|
329 |
aconf = (struct AccessItem *)map_to_conf(conf); |
330 |
aconf->hold = CurrentTime + tkline_time; |
331 |
add_temp_line(conf); |
332 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
333 |
"%s added temporary %d min. K-Line for [%s@%s] [%s]", |
334 |
get_oper_name(source_p), tkline_time/60, |
335 |
aconf->user, aconf->host, |
336 |
aconf->reason); |
337 |
sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. K-Line [%s@%s]", |
338 |
MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from), |
339 |
source_p->name, tkline_time/60, aconf->user, aconf->host); |
340 |
ilog(L_TRACE, "%s added temporary %d min. K-Line for [%s@%s] [%s]", |
341 |
source_p->name, tkline_time/60, |
342 |
aconf->user, aconf->host, aconf->reason); |
343 |
log_oper_action(LOG_TEMP_KLINE_TYPE, source_p, "[%s@%s] [%s]\n", |
344 |
aconf->user, aconf->host, aconf->reason); |
345 |
rehashed_klines = 1; |
346 |
} |
347 |
|
348 |
/* apply_tdline() |
349 |
* |
350 |
* inputs - |
351 |
* output - NONE |
352 |
* side effects - tkline as given is placed |
353 |
*/ |
354 |
static void |
355 |
apply_tdline(struct Client *source_p, struct ConfItem *conf, |
356 |
const char *current_date, int tkline_time) |
357 |
{ |
358 |
struct AccessItem *aconf; |
359 |
|
360 |
aconf = map_to_conf(conf); |
361 |
aconf->hold = CurrentTime + tkline_time; |
362 |
|
363 |
add_temp_line(conf); |
364 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
365 |
"%s added temporary %d min. D-Line for [%s] [%s]", |
366 |
get_oper_name(source_p), tkline_time/60, |
367 |
aconf->host, aconf->reason); |
368 |
|
369 |
sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]", |
370 |
MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from), |
371 |
source_p->name, tkline_time/60, aconf->host); |
372 |
ilog(L_TRACE, "%s added temporary %d min. D-Line for [%s] [%s]", |
373 |
source_p->name, tkline_time/60, aconf->host, aconf->reason); |
374 |
log_oper_action(LOG_TEMP_DLINE_TYPE, source_p, "[%s@%s] [%s]\n", |
375 |
aconf->user, aconf->host, aconf->reason); |
376 |
rehashed_klines = 1; |
377 |
} |
378 |
|
379 |
/* mo_dline() |
380 |
* |
381 |
* inputs - pointer to server |
382 |
* - pointer to client |
383 |
* - parameter count |
384 |
* - parameter list |
385 |
* output - |
386 |
* side effects - D line is added |
387 |
* |
388 |
*/ |
389 |
static void |
390 |
mo_dline(struct Client *client_p, struct Client *source_p, |
391 |
int parc, char *parv[]) |
392 |
{ |
393 |
char def_reason[] = "No reason"; |
394 |
char *dlhost, *oper_reason, *reason; |
395 |
const char *creason; |
396 |
#ifndef IPV6 |
397 |
struct Client *target_p; |
398 |
#endif |
399 |
struct irc_ssaddr daddr; |
400 |
struct ConfItem *conf=NULL; |
401 |
struct AccessItem *aconf=NULL; |
402 |
time_t tkline_time=0; |
403 |
int bits, t; |
404 |
const char* current_date; |
405 |
time_t cur_time; |
406 |
|
407 |
if (!IsOperK(source_p)) |
408 |
{ |
409 |
sendto_one(source_p, form_str(ERR_NOPRIVS), |
410 |
me.name, source_p->name, "kline"); |
411 |
return; |
412 |
} |
413 |
|
414 |
if (parse_aline("DLINE", source_p, parc, parv, |
415 |
AWILD, &dlhost, NULL, &tkline_time, NULL, &reason) < 0) |
416 |
return; |
417 |
|
418 |
if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) |
419 |
{ |
420 |
#ifdef IPV6 |
421 |
sendto_one(source_p, ":%s NOTICE %s :Sorry, please supply an address.", |
422 |
me.name, parv[0]); |
423 |
return; |
424 |
#else |
425 |
if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) |
426 |
return; |
427 |
|
428 |
t = HM_IPV4; |
429 |
if (IsServer(target_p)) |
430 |
{ |
431 |
sendto_one(source_p, |
432 |
":%s NOTICE %s :Can't DLINE a server silly", |
433 |
me.name, source_p->name); |
434 |
return; |
435 |
} |
436 |
|
437 |
if (!MyConnect(target_p)) |
438 |
{ |
439 |
sendto_one(source_p, |
440 |
":%s NOTICE %s :Can't DLINE nick on another server", |
441 |
me.name, source_p->name); |
442 |
return; |
443 |
} |
444 |
|
445 |
if (IsExemptKline(target_p)) |
446 |
{ |
447 |
sendto_one(source_p, |
448 |
":%s NOTICE %s :%s is E-lined",me.name, |
449 |
source_p->name, target_p->name); |
450 |
return; |
451 |
} |
452 |
|
453 |
if ((dlhost = make_cidr(dlhost, target_p)) == NULL) |
454 |
return; |
455 |
|
456 |
bits = 0xFFFFFF00UL; |
457 |
#endif |
458 |
} |
459 |
|
460 |
if (bits < 8) |
461 |
{ |
462 |
sendto_one(source_p, |
463 |
":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", |
464 |
me.name, source_p->name); |
465 |
return; |
466 |
} |
467 |
|
468 |
|
469 |
#ifdef IPV6 |
470 |
if (t == HM_IPV6) |
471 |
t = AF_INET6; |
472 |
else |
473 |
#endif |
474 |
t = AF_INET; |
475 |
|
476 |
parse_netmask(dlhost, &daddr, NULL); |
477 |
|
478 |
if ((aconf = find_dline_conf(&daddr, t)) != NULL) |
479 |
{ |
480 |
creason = aconf->reason ? aconf->reason : def_reason; |
481 |
if (IsConfExemptKline(aconf)) |
482 |
sendto_one(source_p, |
483 |
":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", |
484 |
me.name, source_p->name, dlhost, aconf->host, creason); |
485 |
else |
486 |
sendto_one(source_p, |
487 |
":%s NOTICE %s :[%s] already D-lined by [%s] - %s", |
488 |
me.name, source_p->name, dlhost, aconf->host, creason); |
489 |
return; |
490 |
} |
491 |
|
492 |
cur_time = CurrentTime; |
493 |
current_date = smalldate(cur_time); |
494 |
|
495 |
/* Look for an oper reason */ |
496 |
if ((oper_reason = strchr(reason, '|')) != NULL) |
497 |
*oper_reason++ = '\0'; |
498 |
|
499 |
if (!valid_comment(source_p, reason, YES)) |
500 |
return; |
501 |
|
502 |
conf = make_conf_item(DLINE_TYPE); |
503 |
aconf = map_to_conf(conf); |
504 |
DupString(aconf->host, dlhost); |
505 |
|
506 |
if (tkline_time != 0) |
507 |
{ |
508 |
ircsprintf(buffer, "Temporary D-line %d min. - %s (%s)", |
509 |
(int)(tkline_time/60), reason, current_date); |
510 |
DupString(aconf->reason, buffer); |
511 |
if (oper_reason != NULL) |
512 |
DupString(aconf->oper_reason, oper_reason); |
513 |
apply_tdline(source_p, conf, current_date, tkline_time); |
514 |
} |
515 |
else |
516 |
{ |
517 |
ircsprintf(buffer, "%s (%s)", reason, current_date); |
518 |
DupString(aconf->reason, buffer); |
519 |
if (oper_reason != NULL) |
520 |
DupString(aconf->oper_reason, oper_reason); |
521 |
add_conf_by_address(CONF_DLINE, aconf); |
522 |
write_conf_line(source_p, conf, current_date, cur_time); |
523 |
} |
524 |
|
525 |
rehashed_klines = 1; |
526 |
} /* mo_dline() */ |
527 |
|
528 |
|
529 |
/* already_placed_kline() |
530 |
* inputs - user to complain to, username & host to check for |
531 |
* outputs - returns 1 on existing K-line, 0 if doesn't exist |
532 |
* side effects - notifies source_p if the K-line already exists |
533 |
*/ |
534 |
/* |
535 |
* Note: This currently works if the new K-line is a special case of an |
536 |
* existing K-line, but not the other way round. To do that we would |
537 |
* have to walk the hash and check every existing K-line. -A1kmm. |
538 |
*/ |
539 |
static int |
540 |
already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int warn) |
541 |
{ |
542 |
const char *reason; |
543 |
struct irc_ssaddr iphost, *piphost; |
544 |
struct AccessItem *aconf; |
545 |
int t; |
546 |
|
547 |
if ((t = parse_netmask(lhost, &iphost, &t)) != HM_HOST) |
548 |
{ |
549 |
#ifdef IPV6 |
550 |
if (t == HM_IPV6) |
551 |
t = AF_INET6; |
552 |
else |
553 |
#endif |
554 |
t = AF_INET; |
555 |
piphost = &iphost; |
556 |
} |
557 |
else |
558 |
{ |
559 |
t = 0; |
560 |
piphost = NULL; |
561 |
} |
562 |
|
563 |
if ((aconf = find_conf_by_address(lhost, piphost, CONF_KILL, t, luser, NULL))) |
564 |
{ |
565 |
if (warn) |
566 |
{ |
567 |
reason = aconf->reason ? aconf->reason : "No reason"; |
568 |
sendto_one(source_p, |
569 |
":%s NOTICE %s :[%s@%s] already K-Lined by [%s@%s] - %s", |
570 |
me.name, source_p->name, luser, lhost, aconf->user, |
571 |
aconf->host, reason); |
572 |
} |
573 |
return(1); |
574 |
} |
575 |
|
576 |
return(0); |
577 |
} |
578 |
|
579 |
#ifndef IPV6 |
580 |
static char * |
581 |
make_cidr(char *dlhost, struct Client *target_p) |
582 |
{ |
583 |
static char cidr_form_host[HOSTLEN + 2]; |
584 |
char *p; |
585 |
|
586 |
strlcpy(cidr_form_host, inetntoa((const char *)&target_p->localClient->ip), |
587 |
sizeof(cidr_form_host)); |
588 |
|
589 |
if ((p = strchr(cidr_form_host,'.')) == NULL) |
590 |
return(NULL); |
591 |
|
592 |
/* 192. <- p */ |
593 |
p++; |
594 |
if ((p = strchr(p,'.')) == NULL) |
595 |
return(NULL); |
596 |
|
597 |
/* 192.168. <- p */ |
598 |
p++; |
599 |
if ((p = strchr(p,'.')) == NULL) |
600 |
return(NULL); |
601 |
|
602 |
/* 192.168.0. <- p */ |
603 |
p++; |
604 |
*p++ = '0'; |
605 |
*p++ = '/'; |
606 |
*p++ = '2'; |
607 |
*p++ = '4'; |
608 |
*p++ = '\0'; |
609 |
|
610 |
return(cidr_form_host); |
611 |
} |
612 |
#endif |
613 |
|
614 |
/* |
615 |
** mo_unkline |
616 |
** Added Aug 31, 1997 |
617 |
** common (Keith Fralick) fralick@gate.net |
618 |
** |
619 |
** parv[0] = sender |
620 |
** parv[1] = address to remove |
621 |
* |
622 |
* |
623 |
*/ |
624 |
static void |
625 |
mo_unkline(struct Client *client_p,struct Client *source_p, |
626 |
int parc, char *parv[]) |
627 |
{ |
628 |
char *target_server = NULL; |
629 |
char *user, *host; |
630 |
|
631 |
if (!IsOperUnkline(source_p)) |
632 |
{ |
633 |
sendto_one(source_p, form_str(ERR_NOPRIVS), |
634 |
me.name, source_p->name, "unkline"); |
635 |
return; |
636 |
} |
637 |
|
638 |
if (parc < 2 || EmptyString(parv[1])) |
639 |
{ |
640 |
sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), |
641 |
me.name, source_p->name, "UNKLINE"); |
642 |
return; |
643 |
} |
644 |
|
645 |
if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user, |
646 |
&host, NULL, &target_server, NULL) < 0) |
647 |
return; |
648 |
|
649 |
if (target_server != NULL) |
650 |
{ |
651 |
sendto_match_servs(source_p, target_server, CAP_UNKLN, |
652 |
"UNKLINE %s %s %s", |
653 |
target_server, user, host); |
654 |
|
655 |
/* Allow ON to apply local unkline as well if it matches */ |
656 |
if (!match(target_server, me.name)) |
657 |
return; |
658 |
} |
659 |
else |
660 |
cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE, |
661 |
"%s %s", user, host); |
662 |
|
663 |
if (remove_tkline_match(host, user)) |
664 |
{ |
665 |
sendto_one(source_p, |
666 |
":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines", |
667 |
me.name, source_p->name, user, host); |
668 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
669 |
"%s has removed the temporary K-Line for: [%s@%s]", |
670 |
get_oper_name(source_p), user, host); |
671 |
ilog(L_NOTICE, "%s removed temporary K-Line for [%s@%s]", |
672 |
source_p->name, user, host); |
673 |
return; |
674 |
} |
675 |
|
676 |
if (remove_conf_line(KLINE_TYPE, source_p, user, host) > 0) |
677 |
{ |
678 |
sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed", |
679 |
me.name, source_p->name, user,host); |
680 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
681 |
"%s has removed the K-Line for: [%s@%s]", |
682 |
get_oper_name(source_p), user, host); |
683 |
ilog(L_NOTICE, "%s removed K-Line for [%s@%s]", |
684 |
source_p->name, user, host); |
685 |
} |
686 |
else |
687 |
sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found", |
688 |
me.name, source_p->name, user, host); |
689 |
} |
690 |
|
691 |
/* me_unkline() |
692 |
* |
693 |
* inputs - server |
694 |
* - client |
695 |
* - parc |
696 |
* - parv |
697 |
* outputs - none |
698 |
* side effects - if server is authorized, kline is removed |
699 |
* does not propagate message |
700 |
*/ |
701 |
static void |
702 |
me_unkline(struct Client *client_p, struct Client *source_p, |
703 |
int parc, char *parv[]) |
704 |
{ |
705 |
const char *kuser, *khost; |
706 |
|
707 |
if (parc != 4) |
708 |
return; |
709 |
|
710 |
kuser = parv[2]; |
711 |
khost = parv[3]; |
712 |
|
713 |
if (!IsClient(source_p) || !match(parv[1], me.name)) |
714 |
return; |
715 |
|
716 |
if (find_matching_name_conf(ULINE_TYPE, |
717 |
source_p->servptr->name, |
718 |
source_p->username, source_p->host, |
719 |
SHARED_UNKLINE)) |
720 |
{ |
721 |
if (remove_tkline_match(khost, kuser)) |
722 |
{ |
723 |
sendto_one(source_p, |
724 |
":%s NOTICE %s :Un-klined [%s@%s] from temporary K-Lines", |
725 |
me.name, source_p->name, kuser, khost); |
726 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
727 |
"%s has removed the temporary K-Line for: [%s@%s]", |
728 |
get_oper_name(source_p), kuser, khost); |
729 |
ilog(L_NOTICE, "%s removed temporary K-Line for [%s@%s]", |
730 |
source_p->name, kuser, khost); |
731 |
return; |
732 |
} |
733 |
|
734 |
if (remove_conf_line(KLINE_TYPE, source_p, kuser, khost) > 0) |
735 |
{ |
736 |
sendto_one(source_p, ":%s NOTICE %s :K-Line for [%s@%s] is removed", |
737 |
me.name, source_p->name, kuser, khost); |
738 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
739 |
"%s has removed the K-Line for: [%s@%s]", |
740 |
get_oper_name(source_p), kuser, khost); |
741 |
|
742 |
ilog(L_NOTICE, "%s removed K-Line for [%s@%s]", |
743 |
source_p->name, kuser, khost); |
744 |
} |
745 |
else |
746 |
sendto_one(source_p, ":%s NOTICE %s :No K-Line for [%s@%s] found", |
747 |
me.name, source_p->name, kuser, khost); |
748 |
} |
749 |
} |
750 |
|
751 |
/* ms_unkline - propagates and handles a remote unkline message */ |
752 |
static void |
753 |
ms_unkline(struct Client *client_p, struct Client *source_p, |
754 |
int parc, char *parv[]) |
755 |
{ |
756 |
if (parc != 4) |
757 |
return; |
758 |
|
759 |
sendto_match_servs(source_p, parv[1], CAP_UNKLN, |
760 |
"UNKLINE %s %s %s", |
761 |
parv[1], parv[2], parv[3]); |
762 |
|
763 |
me_unkline(client_p, source_p, parc, parv); |
764 |
} |
765 |
|
766 |
/* static int remove_tkline_match(const char *host, const char *user) |
767 |
* Input: A hostname, a username to unkline. |
768 |
* Output: returns YES on success, NO if no tkline removed. |
769 |
* Side effects: Any matching tklines are removed. |
770 |
*/ |
771 |
static int |
772 |
remove_tkline_match(const char *host, const char *user) |
773 |
{ |
774 |
struct AccessItem *tk_c; |
775 |
dlink_node *tk_n; |
776 |
struct irc_ssaddr addr, caddr; |
777 |
int nm_t, cnm_t, bits, cbits; |
778 |
nm_t = parse_netmask(host, &addr, &bits); |
779 |
|
780 |
DLINK_FOREACH(tk_n, temporary_klines.head) |
781 |
{ |
782 |
tk_c = map_to_conf(tk_n->data); |
783 |
cnm_t = parse_netmask(tk_c->host, &caddr, &cbits); |
784 |
if (cnm_t != nm_t || irccmp(user, tk_c->user)) |
785 |
continue; |
786 |
if ((nm_t==HM_HOST && !irccmp(tk_c->host, host)) || |
787 |
(nm_t==HM_IPV4 && bits==cbits && match_ipv4(&addr, &caddr, bits)) |
788 |
#ifdef IPV6 |
789 |
|| (nm_t==HM_IPV6 && bits==cbits && match_ipv6(&addr, &caddr, bits)) |
790 |
#endif |
791 |
) |
792 |
{ |
793 |
dlinkDelete(tk_n, &temporary_klines); |
794 |
delete_one_address_conf(tk_c->host, tk_c); |
795 |
return(YES); |
796 |
} |
797 |
} |
798 |
|
799 |
return(NO); |
800 |
} |
801 |
|
802 |
/* static int remove_tdline_match(const char *host, const char *user) |
803 |
* Input: An ip to undline. |
804 |
* Output: returns YES on success, NO if no tdline removed. |
805 |
* Side effects: Any matching tdlines are removed. |
806 |
*/ |
807 |
static int |
808 |
remove_tdline_match(const char *cidr) |
809 |
{ |
810 |
struct AccessItem *td_conf; |
811 |
dlink_node *td_node; |
812 |
struct irc_ssaddr addr, caddr; |
813 |
int nm_t, cnm_t, bits, cbits; |
814 |
nm_t = parse_netmask(cidr, &addr, &bits); |
815 |
|
816 |
DLINK_FOREACH(td_node, temporary_dlines.head) |
817 |
{ |
818 |
td_conf = map_to_conf(td_node->data); |
819 |
cnm_t = parse_netmask(td_conf->host, &caddr, &cbits); |
820 |
|
821 |
if (cnm_t != nm_t) |
822 |
continue; |
823 |
|
824 |
if((nm_t==HM_HOST && !irccmp(td_conf->host, cidr)) || |
825 |
(nm_t==HM_IPV4 && bits==cbits && match_ipv4(&addr, &caddr, bits)) |
826 |
#ifdef IPV6 |
827 |
|| (nm_t==HM_IPV6 && bits==cbits && match_ipv6(&addr, &caddr, bits)) |
828 |
#endif |
829 |
) |
830 |
{ |
831 |
dlinkDelete(td_node, &temporary_dlines); |
832 |
delete_one_address_conf(td_conf->host, td_conf); |
833 |
return(YES); |
834 |
} |
835 |
} |
836 |
|
837 |
return(NO); |
838 |
} |
839 |
|
840 |
/* |
841 |
** m_undline |
842 |
** added May 28th 2000 by Toby Verrall <toot@melnet.co.uk> |
843 |
** based totally on m_unkline |
844 |
** added to hybrid-7 7/11/2000 --is |
845 |
** |
846 |
** parv[0] = sender nick |
847 |
** parv[1] = dline to remove |
848 |
*/ |
849 |
static void |
850 |
mo_undline(struct Client *client_p, struct Client *source_p, |
851 |
int parc, char *parv[]) |
852 |
{ |
853 |
const char *cidr; |
854 |
|
855 |
if (!IsOperUnkline(source_p)) |
856 |
{ |
857 |
sendto_one(source_p, form_str(ERR_NOPRIVS), |
858 |
me.name, source_p->name, "undline"); |
859 |
return; |
860 |
} |
861 |
|
862 |
cidr = parv[1]; |
863 |
|
864 |
if (remove_tdline_match(cidr)) |
865 |
{ |
866 |
sendto_one(source_p, |
867 |
":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines", |
868 |
me.name, source_p->name, cidr); |
869 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
870 |
"%s has removed the temporary D-Line for: [%s]", |
871 |
get_oper_name(source_p), cidr); |
872 |
ilog(L_NOTICE, "%s removed temporary D-Line for [%s]", source_p->name, cidr); |
873 |
return; |
874 |
} |
875 |
|
876 |
if (remove_conf_line(DLINE_TYPE, source_p, cidr, NULL) > 0) |
877 |
{ |
878 |
sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", |
879 |
me.name, source_p->name, cidr); |
880 |
sendto_realops_flags(UMODE_ALL, L_ALL, |
881 |
"%s has removed the D-Line for: [%s]", |
882 |
get_oper_name(source_p), cidr); |
883 |
ilog(L_NOTICE, "%s removed D-Line for [%s]", |
884 |
get_oper_name(source_p), cidr); |
885 |
} |
886 |
else |
887 |
sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found", |
888 |
me.name, source_p->name, cidr); |
889 |
} |