ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_dline.c
Revision: 1301
Committed: Sat Mar 10 21:47:17 2012 UTC (14 years, 5 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_dline.c
File size: 16994 byte(s)
Log Message:
- add 'dline' and 'undline' operator flags
- implement remote dlines mainly for services purposes, but can be used
  by operators as well
- update example configuration files; remove invalid shared::flags entries

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_dline.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 "list.h"
27 #include "channel.h"
28 #include "client.h"
29 #include "irc_string.h"
30 #include "sprintf_irc.h"
31 #include "ircd.h"
32 #include "hostmask.h"
33 #include "numeric.h"
34 #include "fdlist.h"
35 #include "s_bsd.h"
36 #include "s_conf.h"
37 #include "s_log.h"
38 #include "s_misc.h"
39 #include "send.h"
40 #include "hash.h"
41 #include "s_serv.h"
42 #include "s_gline.h"
43 #include "parse.h"
44 #include "modules.h"
45
46
47 /* apply_tdline()
48 *
49 * inputs -
50 * output - NONE
51 * side effects - tkline as given is placed
52 */
53 static void
54 apply_tdline(struct Client *source_p, struct ConfItem *conf,
55 const char *current_date, int tkline_time)
56 {
57 struct AccessItem *aconf;
58
59 aconf = map_to_conf(conf);
60 aconf->hold = CurrentTime + tkline_time;
61
62 add_temp_line(conf);
63 sendto_realops_flags(UMODE_ALL, L_ALL,
64 "%s added temporary %d min. D-Line for [%s] [%s]",
65 get_oper_name(source_p), tkline_time/60,
66 aconf->host, aconf->reason);
67
68 sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]",
69 MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
70 source_p->name, tkline_time/60, aconf->host);
71 ilog(LOG_TYPE_DLINE, "%s added temporary %d min. D-Line for [%s] [%s]",
72 source_p->name, tkline_time/60, aconf->host, aconf->reason);
73
74 rehashed_klines = 1;
75 }
76
77 /* static int remove_tdline_match(const char *host, const char *user)
78 * Input: An ip to undline.
79 * Output: returns YES on success, NO if no tdline removed.
80 * Side effects: Any matching tdlines are removed.
81 */
82 static int
83 remove_tdline_match(const char *host)
84 {
85 struct AccessItem *td_conf;
86 dlink_node *td_node;
87 struct irc_ssaddr addr, caddr;
88 int nm_t, cnm_t, bits, cbits;
89
90 nm_t = parse_netmask(host, &addr, &bits);
91
92 DLINK_FOREACH(td_node, temporary_dlines.head)
93 {
94 td_conf = map_to_conf(td_node->data);
95 cnm_t = parse_netmask(td_conf->host, &caddr, &cbits);
96
97 if (cnm_t != nm_t)
98 continue;
99
100 if ((nm_t == HM_HOST && !irccmp(td_conf->host, host)) ||
101 (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
102 #ifdef IPV6
103 || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
104 #endif
105 )
106 {
107 dlinkDelete(td_node, &temporary_dlines);
108 delete_one_address_conf(td_conf->host, td_conf);
109 return 1;
110 }
111 }
112
113 return 0;
114 }
115
116 /* mo_dline()
117 *
118 * inputs - pointer to server
119 * - pointer to client
120 * - parameter count
121 * - parameter list
122 * output -
123 * side effects - D line is added
124 *
125 */
126 static void
127 mo_dline(struct Client *client_p, struct Client *source_p,
128 int parc, char *parv[])
129 {
130 char def_reason[] = "<No reason specified>";
131 char *dlhost = NULL, *oper_reason = NULL, *reason = NULL;
132 char *target_server = NULL;
133 const char *creason;
134 const struct Client *target_p = NULL;
135 struct irc_ssaddr daddr;
136 struct ConfItem *conf=NULL;
137 struct AccessItem *aconf=NULL;
138 time_t tkline_time=0;
139 int bits, t;
140 const char *current_date = NULL;
141 time_t cur_time;
142 char hostip[HOSTIPLEN];
143 char buffer[IRCD_BUFSIZE];
144
145 if (!HasOFlag(source_p, OPER_FLAG_DLINE))
146 {
147 sendto_one(source_p, form_str(ERR_NOPRIVS),
148 me.name, source_p->name, "kline");
149 return;
150 }
151
152 if (parse_aline("DLINE", source_p, parc, parv, AWILD, &dlhost,
153 NULL, &tkline_time, &target_server, &reason) < 0)
154 return;
155
156 if (target_server != NULL)
157 {
158 if (HasID(source_p))
159 {
160 sendto_server(NULL, NULL, CAP_DLN|CAP_TS6, NOCAPS,
161 ":%s DLINE %s %lu %s :%s",
162 source_p->id, target_server, (unsigned long)tkline_time,
163 dlhost, reason);
164 sendto_server(NULL, NULL, CAP_DLN, CAP_TS6,
165 ":%s DLINE %s %lu %s :%s",
166 source_p->name, target_server, (unsigned long)tkline_time,
167 dlhost, reason);
168 }
169 else
170 sendto_server(NULL, NULL, CAP_DLN, NOCAPS,
171 ":%s DLINE %s %lu %s :%s",
172 source_p->name, target_server, (unsigned long)tkline_time,
173 dlhost, reason);
174
175 /* Allow ON to apply local kline as well if it matches */
176 if (!match(target_server, me.name))
177 return;
178 }
179 else
180 cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE,
181 "%d %s :%s", tkline_time, dlhost, reason);
182
183 if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
184 {
185 if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
186 return;
187
188 if (!MyConnect(target_p))
189 {
190 sendto_one(source_p,
191 ":%s NOTICE %s :Can't DLINE nick on another server",
192 me.name, source_p->name);
193 return;
194 }
195
196 if (IsExemptKline(target_p))
197 {
198 sendto_one(source_p,
199 ":%s NOTICE %s :%s is E-lined", me.name,
200 source_p->name, target_p->name);
201 return;
202 }
203
204 getnameinfo((struct sockaddr *)&target_p->localClient->ip,
205 target_p->localClient->ip.ss_len, hostip,
206 sizeof(hostip), NULL, 0, NI_NUMERICHOST);
207 dlhost = hostip;
208 t = parse_netmask(dlhost, NULL, &bits);
209 assert(t == HM_IPV4 || t == HM_IPV6);
210 }
211
212 if (bits < 8)
213 {
214 sendto_one(source_p,
215 ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
216 me.name, source_p->name);
217 return;
218 }
219
220 #ifdef IPV6
221 if (t == HM_IPV6)
222 t = AF_INET6;
223 else
224 #endif
225 t = AF_INET;
226
227 parse_netmask(dlhost, &daddr, NULL);
228
229 if ((aconf = find_dline_conf(&daddr, t)) != NULL)
230 {
231 creason = aconf->reason ? aconf->reason : def_reason;
232 if (IsConfExemptKline(aconf))
233 sendto_one(source_p,
234 ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
235 me.name, source_p->name, dlhost, aconf->host, creason);
236 else
237 sendto_one(source_p,
238 ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
239 me.name, source_p->name, dlhost, aconf->host, creason);
240 return;
241 }
242
243 cur_time = CurrentTime;
244 current_date = smalldate(cur_time);
245
246 /* Look for an oper reason */
247 if ((oper_reason = strchr(reason, '|')) != NULL)
248 *oper_reason++ = '\0';
249
250 if (!valid_comment(source_p, reason, 1))
251 return;
252
253 conf = make_conf_item(DLINE_TYPE);
254 aconf = map_to_conf(conf);
255 DupString(aconf->host, dlhost);
256
257 if (tkline_time != 0)
258 {
259 snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)",
260 (int)(tkline_time/60), reason, current_date);
261 DupString(aconf->reason, buffer);
262 if (oper_reason != NULL)
263 DupString(aconf->oper_reason, oper_reason);
264 apply_tdline(source_p, conf, current_date, tkline_time);
265 }
266 else
267 {
268 snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
269 DupString(aconf->reason, buffer);
270 if (oper_reason != NULL)
271 DupString(aconf->oper_reason, oper_reason);
272 add_conf_by_address(CONF_DLINE, aconf);
273 write_conf_line(source_p, conf, current_date, cur_time);
274 }
275
276 rehashed_klines = 1;
277 }
278
279 static void
280 ms_dline(struct Client *client_p, struct Client *source_p,
281 int parc, char *parv[])
282 {
283 char def_reason[] = "<No reason specified>";
284 char *dlhost, *oper_reason, *reason;
285 const char *creason;
286 const struct Client *target_p = NULL;
287 struct irc_ssaddr daddr;
288 struct ConfItem *conf=NULL;
289 struct AccessItem *aconf=NULL;
290 time_t tkline_time=0;
291 int bits, t;
292 const char *current_date = NULL;
293 time_t cur_time;
294 char hostip[HOSTIPLEN];
295 char buffer[IRCD_BUFSIZE];
296
297 if (parc != 5 || EmptyString(parv[4]))
298 return;
299
300 /* parv[0] parv[1] parv[2] parv[3] parv[4] */
301 /* oper target_server tkline_time host reason */
302 sendto_match_servs(source_p, parv[1], CAP_DLN,
303 "DLINE %s %s %s :%s",
304 parv[1], parv[2], parv[3], parv[4]);
305
306 if (!match(parv[1], me.name))
307 return;
308
309 tkline_time = valid_tkline(parv[2], TK_SECONDS);
310 dlhost = parv[3];
311 reason = parv[4];
312
313 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
314 source_p->username, source_p->host,
315 SHARED_DLINE))
316 {
317 if (!IsClient(source_p))
318 return;
319 if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
320 {
321 if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
322 return;
323
324 if (!MyConnect(target_p))
325 {
326 sendto_one(source_p,
327 ":%s NOTICE %s :Can't DLINE nick on another server",
328 me.name, source_p->name);
329 return;
330 }
331
332 if (IsExemptKline(target_p))
333 {
334 sendto_one(source_p,
335 ":%s NOTICE %s :%s is E-lined", me.name,
336 source_p->name, target_p->name);
337 return;
338 }
339
340 getnameinfo((struct sockaddr *)&target_p->localClient->ip,
341 target_p->localClient->ip.ss_len, hostip,
342 sizeof(hostip), NULL, 0, NI_NUMERICHOST);
343 dlhost = hostip;
344 t = parse_netmask(dlhost, NULL, &bits);
345 assert(t == HM_IPV4 || t == HM_IPV6);
346 }
347
348 if (bits < 8)
349 {
350 sendto_one(source_p,
351 ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
352 me.name, source_p->name);
353 return;
354 }
355
356 #ifdef IPV6
357 if (t == HM_IPV6)
358 t = AF_INET6;
359 else
360 #endif
361 t = AF_INET;
362
363 parse_netmask(dlhost, &daddr, NULL);
364
365 if ((aconf = find_dline_conf(&daddr, t)) != NULL)
366 {
367 creason = aconf->reason ? aconf->reason : def_reason;
368 if (IsConfExemptKline(aconf))
369 sendto_one(source_p,
370 ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
371 me.name, source_p->name, dlhost, aconf->host, creason);
372 else
373 sendto_one(source_p,
374 ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
375 me.name, source_p->name, dlhost, aconf->host, creason);
376 return;
377 }
378
379 cur_time = CurrentTime;
380 current_date = smalldate(cur_time);
381
382 /* Look for an oper reason */
383 if ((oper_reason = strchr(reason, '|')) != NULL)
384 *oper_reason++ = '\0';
385
386 if (!valid_comment(source_p, reason, 1))
387 return;
388
389 conf = make_conf_item(DLINE_TYPE);
390 aconf = map_to_conf(conf);
391 DupString(aconf->host, dlhost);
392
393 if (tkline_time != 0)
394 {
395 snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)",
396 (int)(tkline_time/60), reason, current_date);
397 DupString(aconf->reason, buffer);
398 if (oper_reason != NULL)
399 DupString(aconf->oper_reason, oper_reason);
400 apply_tdline(source_p, conf, current_date, tkline_time);
401 }
402 else
403 {
404 snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
405 DupString(aconf->reason, buffer);
406 if (oper_reason != NULL)
407 DupString(aconf->oper_reason, oper_reason);
408 add_conf_by_address(CONF_DLINE, aconf);
409 write_conf_line(source_p, conf, current_date, cur_time);
410 }
411
412 rehashed_klines = 1;
413 }
414 }
415
416 /*
417 ** m_undline
418 ** added May 28th 2000 by Toby Verrall <toot@melnet.co.uk>
419 ** based totally on m_unkline
420 ** added to hybrid-7 7/11/2000 --is
421 **
422 ** parv[0] = sender nick
423 ** parv[1] = dline to remove
424 */
425 static void
426 mo_undline(struct Client *client_p, struct Client *source_p,
427 int parc, char *parv[])
428 {
429 char *addr = NULL, *user = NULL;
430 char *target_server = NULL;
431
432 if (!HasOFlag(source_p, OPER_FLAG_UNDLINE))
433 {
434 sendto_one(source_p, form_str(ERR_NOPRIVS),
435 me.name, source_p->name, "undline");
436 return;
437 }
438
439 if (parc < 2 || EmptyString(parv[1]))
440 {
441 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
442 me.name, source_p->name, "UNDLINE");
443 return;
444 }
445
446 if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user,
447 &addr, NULL, &target_server, NULL) < 0)
448 return;
449
450 if (target_server != NULL)
451 {
452 sendto_match_servs(source_p, target_server, CAP_UNDLN,
453 "UNDLINE %s %s", target_server, addr);
454
455 /* Allow ON to apply local unkline as well if it matches */
456 if (!match(target_server, me.name))
457 return;
458 }
459 else
460 cluster_a_line(source_p, "UNDLINE", CAP_UNDLN, SHARED_UNDLINE,
461 "%s", addr);
462
463 if (remove_tdline_match(addr))
464 {
465 sendto_one(source_p,
466 ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines",
467 me.name, source_p->name, addr);
468 sendto_realops_flags(UMODE_ALL, L_ALL,
469 "%s has removed the temporary D-Line for: [%s]",
470 get_oper_name(source_p), addr);
471 ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]",
472 source_p->name, addr);
473 return;
474 }
475
476 if (remove_conf_line(DLINE_TYPE, source_p, addr, NULL) > 0)
477 {
478 sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed",
479 me.name, source_p->name, addr);
480 sendto_realops_flags(UMODE_ALL, L_ALL,
481 "%s has removed the D-Line for: [%s]",
482 get_oper_name(source_p), addr);
483 ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]",
484 get_oper_name(source_p), addr);
485 }
486 else
487 sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
488 me.name, source_p->name, addr);
489 }
490
491 static void
492 me_undline(struct Client *client_p, struct Client *source_p,
493 int parc, char *parv[])
494 {
495 const char *addr = NULL;
496
497 if (parc != 3 || EmptyString(parv[2]))
498 return;
499
500 addr = parv[2];
501
502 if (!IsClient(source_p) || !match(parv[1], me.name))
503 return;
504
505 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE,
506 source_p->servptr->name,
507 source_p->username, source_p->host,
508 SHARED_UNDLINE))
509 {
510 if (remove_tdline_match(addr))
511 {
512 sendto_one(source_p,
513 ":%s NOTICE %s :Un-Dlined [%s] from temporary D-Lines",
514 me.name, source_p->name, addr);
515 sendto_realops_flags(UMODE_ALL, L_ALL,
516 "%s has removed the temporary D-Line for: [%s]",
517 get_oper_name(source_p), addr);
518 ilog(LOG_TYPE_DLINE, "%s removed temporary D-Line for [%s]",
519 source_p->name, addr);
520 return;
521 }
522
523 if (remove_conf_line(DLINE_TYPE, source_p, addr, NULL) > 0)
524 {
525 sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed",
526 me.name, source_p->name, addr);
527 sendto_realops_flags(UMODE_ALL, L_ALL,
528 "%s has removed the D-Line for: [%s]",
529 get_oper_name(source_p), addr);
530 ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]",
531 get_oper_name(source_p), addr);
532 }
533 else
534 sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
535 me.name, source_p->name, addr);
536 }
537 }
538
539 static void
540 ms_undline(struct Client *client_p, struct Client *source_p,
541 int parc, char *parv[])
542 {
543 if (parc != 3 || EmptyString(parv[2]))
544 return;
545
546 sendto_match_servs(source_p, parv[1], CAP_UNDLN,
547 "UNDLINE %s %s %s",
548 parv[1], parv[2]);
549
550 me_undline(client_p, source_p, parc, parv);
551 }
552
553 static struct Message dline_msgtab = {
554 "DLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
555 {m_unregistered, m_not_oper, ms_dline, m_ignore, mo_dline, m_ignore}
556 };
557
558 static struct Message undline_msgtab = {
559 "UNDLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
560 {m_unregistered, m_not_oper, ms_undline, m_ignore, mo_undline, m_ignore}
561 };
562
563 static void
564 module_init(void)
565 {
566 mod_add_cmd(&dline_msgtab);
567 mod_add_cmd(&undline_msgtab);
568 add_capability("DLN", CAP_DLN, 1);
569 add_capability("UNDLN", CAP_UNDLN, 1);
570 }
571
572 static void
573 module_exit(void)
574 {
575 mod_del_cmd(&dline_msgtab);
576 mod_del_cmd(&undline_msgtab);
577 delete_capability("UNDLN");
578 delete_capability("DLN");
579 }
580
581 struct module module_entry = {
582 .node = { NULL, NULL, NULL },
583 .name = NULL,
584 .version = "$Revision$",
585 .handle = NULL,
586 .modinit = module_init,
587 .modexit = module_exit,
588 .flags = 0
589 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision