ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_dline.c
(Generate patch)

Comparing ircd-hybrid-8/modules/m_dline.c (file contents):
Revision 1219 by michael, Sun Sep 18 09:02:38 2011 UTC vs.
Revision 1474 by michael, Sun Jul 22 14:44:07 2012 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)