ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_gline.c
Revision: 940
Committed: Sat May 2 02:01:54 2009 UTC (14 years, 11 months ago) by db
Content type: text/x-csrc
File size: 23735 byte(s)
Log Message:
- gunline code added to gline module
  awaiting Wohalis' version.


File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_gline.c: Votes towards globally banning a mask.
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 "handlers.h"
28 #include "s_gline.h"
29 #include "channel.h"
30 #include "client.h"
31 #include "common.h"
32 #include "irc_string.h"
33 #include "sprintf_irc.h"
34 #include "ircd.h"
35 #include "hostmask.h"
36 #include "numeric.h"
37 #include "fdlist.h"
38 #include "s_bsd.h"
39 #include "s_conf.h"
40 #include "s_misc.h"
41 #include "send.h"
42 #include "msg.h"
43 #include "fileio.h"
44 #include "s_serv.h"
45 #include "hash.h"
46 #include "parse.h"
47 #include "modules.h"
48 #include "list.h"
49 #include "s_log.h"
50
51 #define GLINE_NOT_PLACED 0
52 #ifdef GLINE_VOTING
53 #define GLINE_ALREADY_VOTED -1
54 #endif /* GLINE_VOTING */
55 #define GLINE_PLACED 1
56
57 extern dlink_list gdeny_items;
58
59 /* internal functions */
60 static void set_local_gline(const struct Client *,
61 const char *, const char *, const char *);
62 static int remove_gline_match(const char *user, const char *host);
63
64 #ifdef GLINE_VOTING
65 static int check_majority(int isungline, const struct Client *,
66 const char *, const char *, const char *);
67
68 static void add_new_majority(const struct Client *,
69 const char *, const char *, const char *);
70 #endif /* GLINE_VOTING */
71
72 static void do_sgline(struct Client *, struct Client *, int, char **, int);
73
74 static void me_gline(struct Client *, struct Client *, int, char **);
75 static void ms_gline(struct Client *, struct Client *, int, char **);
76 static void mo_gline(struct Client *, struct Client *, int, char **);
77
78 static void do_sungline(struct Client *, struct Client *, int, char **, int);
79
80 static void me_gungline(struct Client *, struct Client *, int, char **);
81 static void mo_gungline(struct Client *, struct Client *, int, char **);
82
83 /*
84 * gline enforces 3 parameters to force operator to give a reason
85 * a gline is not valid with "No reason"
86 * -db
87 */
88 struct Message gline_msgtab = {
89 "GLINE", 0, 0, 3, 0, MFLG_SLOW, 0,
90 {m_unregistered, m_not_oper, ms_gline, me_gline, mo_gline, m_ignore}
91 };
92
93 struct Message ungline_msgtab = {
94 "GUNGLINE", 0, 0, 3, 0, MFLG_SLOW, 0,
95 {m_unregistered, m_not_oper, m_ignore, me_gungline, mo_gungline, m_ignore}
96 };
97
98
99 #ifndef STATIC_MODULES
100 void
101 _modinit(void)
102 {
103 mod_add_cmd(&gline_msgtab);
104 mod_add_cmd(&ungline_msgtab);
105 add_capability("GLN", CAP_GLN, 1);
106 }
107
108 void
109 _moddeinit(void)
110 {
111 mod_del_cmd(&gline_msgtab);
112 mod_del_cmd(&ungline_msgtab);
113 delete_capability("GLN");
114 }
115
116 const char *_version = "$Revision$";
117 #endif
118
119 /* mo_gline()
120 *
121 * inputs - The usual for a m_ function
122 * output -
123 * side effects -
124 *
125 * Place a G line if 3 opers agree on the identical user@host
126 *
127 */
128 /* Allow this server to pass along GLINE if received and
129 * GLINES is not defined.
130 *
131 */
132
133 static void
134 mo_gline(struct Client *client_p, struct Client *source_p,
135 int parc, char *parv[])
136 {
137 char *user = NULL;
138 char *host = NULL; /* user and host of GLINE "victim" */
139 char *reason = NULL; /* reason for "victims" demise */
140 char *p;
141
142 if (!ConfigFileEntry.glines)
143 {
144 sendto_one(source_p, ":%s NOTICE %s :GLINE disabled",
145 me.name, source_p->name);
146 return;
147 }
148
149 if (!IsOperGline(source_p))
150 {
151 sendto_one(source_p, form_str(ERR_NOPRIVS),
152 me.name, source_p->name, "gline");
153 return;
154 }
155
156 if (parse_aline("GLINE", source_p, parc, parv,
157 AWILD, &user, &host, NULL, NULL, &reason) < 0)
158 return;
159
160 if ((p = strchr(host, '/')) != NULL)
161 {
162 int bitlen = strtol(++p, NULL, 10);
163 int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
164 ConfigFileEntry.gline_min_cidr;
165 if (bitlen < min_bitlen)
166 {
167 sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with CIDR length < %d",
168 me.name, source_p->name, min_bitlen);
169 return;
170 }
171 }
172
173 #ifdef GLINE_VOTING
174 /* If at least 3 opers agree this user should be G lined then do it */
175 if (check_majority(0, source_p, user, host, reason) ==
176 GLINE_ALREADY_VOTED)
177 {
178 sendto_one(source_p,
179 ":%s NOTICE %s :This server or oper has already voted",
180 me.name, source_p->name);
181 return;
182 }
183
184 /*
185 * call these two functions first so the 'requesting' notice always comes
186 * before the 'has triggered' notice. -bill
187 */
188 sendto_realops_flags(UMODE_ALL, L_ALL,
189 "%s requesting G-Line for [%s@%s] [%s]",
190 get_oper_name(source_p),
191 user, host, reason);
192 ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s!%s@%s",
193 user, host, reason, source_p->name, source_p->username,
194 source_p->host);
195 #else
196 set_local_gline(source_p, user, host, reason);
197 #endif /* GLINE_VOTING */
198
199 /* 4 param version for hyb-7 servers */
200 sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
201 ":%s GLINE %s %s :%s",
202 ID(source_p), user, host, reason);
203 sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
204 ":%s GLINE %s %s :%s",
205 source_p->name, user, host, reason);
206
207 /* 8 param for hyb-6 */
208 sendto_server(NULL, NULL, CAP_TS6, CAP_GLN,
209 ":%s GLINE %s %s %s %s %s %s :%s",
210 ID(&me),
211 ID(source_p), source_p->username,
212 source_p->host, source_p->servptr->name, user, host,
213 reason);
214 sendto_server(NULL, NULL, NOCAPS, CAP_GLN|CAP_TS6,
215 ":%s GLINE %s %s %s %s %s %s :%s",
216 me.name, source_p->name, source_p->username,
217 source_p->host, source_p->servptr->name, user, host,
218 reason);
219 }
220
221 /* ms_gline()
222 * me_gline()
223 * do_sgline()
224 *
225 * inputs - The usual for a m_ function
226 * output -
227 * side effects -
228 *
229 * Place a G line if 3 opers agree on the identical user@host
230 *
231 * Allow this server to pass along GLINE if received and
232 * GLINES is not defined.
233 *
234 * ENCAP'd GLINES are propagated by encap code.
235 */
236
237 static void
238 ms_gline(struct Client *client_p, struct Client *source_p,
239 int parc, char *parv[])
240 {
241 do_sgline(client_p, source_p, parc, parv, 1);
242 }
243
244 static void
245 me_gline(struct Client *client_p, struct Client *source_p,
246 int parc, char *parv[])
247 {
248 do_sgline(client_p, source_p, parc, parv, 0);
249 }
250
251 static void
252 do_sgline(struct Client *client_p, struct Client *source_p,
253 int parc, char *parv[], int prop)
254 {
255 const char *reason = NULL; /* reason for "victims" demise */
256 char *user = NULL;
257 char *host = NULL; /* user and host of GLINE "victim" */
258 int var_offset, logged = 0;
259 dlink_node *ptr;
260 struct ConfItem *conf;
261 struct AccessItem *aconf;
262
263 /* hyb-7 style gline (post beta3) */
264 if (parc == 4 && IsClient(source_p))
265 var_offset = 0;
266 /* or it's a hyb-6 style */
267 else if (parc == 8 && IsServer(source_p))
268 {
269 var_offset = 4;
270
271 /*
272 * if we are dealing with an old style formatted gline,
273 * the gline message is originating from the oper's server,
274 * so we update source_p to point to the oper now, so that
275 * logging works down the line. -bill
276 */
277 if ((source_p = find_person(client_p, parv[1])) == NULL)
278 return;
279
280 if (irccmp(parv[2], source_p->username) != 0 ||
281 irccmp(parv[3], source_p->host) != 0 ||
282 irccmp(parv[4], source_p->servptr->name) != 0)
283 {
284 /*
285 * at this point we know one of the parameters provided by
286 * the h6 server was faulty. bail out.
287 */
288 return;
289 }
290 }
291 /* none of the above */
292 else
293 return;
294
295 assert(source_p->servptr != NULL);
296
297 user = parv[++var_offset];
298 host = parv[++var_offset];
299 reason = parv[++var_offset];
300
301 var_offset = 0;
302
303 DLINK_FOREACH(ptr, gdeny_items.head)
304 {
305 conf = ptr->data;
306 aconf = (struct AccessItem *)map_to_conf(conf);
307
308 if (match(conf->name, source_p->servptr->name) &&
309 match(aconf->user, source_p->username) &&
310 match(aconf->host, source_p->host))
311 {
312 var_offset = aconf->flags;
313 break;
314 }
315 }
316
317 if (prop && !(var_offset & GDENY_BLOCK))
318 {
319 sendto_server(client_p, NULL, CAP_GLN, NOCAPS,
320 ":%s GLINE %s %s :%s",
321 source_p->name, user, host, reason);
322 /* hyb-6 version to the rest */
323 sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
324 ":%s GLINE %s %s %s %s %s %s :%s",
325 source_p->servptr->name,
326 source_p->name, source_p->username, source_p->host,
327 source_p->servptr->name,
328 user, host, reason);
329 }
330 else if (ConfigFileEntry.gline_logging & GDENY_BLOCK && ServerInfo.hub)
331 {
332 sendto_realops_flags(UMODE_ALL, L_ALL, "Blocked G-Line %s requested on [%s@%s] [%s]",
333 get_oper_name(source_p), user, host, reason);
334 ilog(L_TRACE, "Blocked G-Line %s requested on [%s@%s] [%s]",
335 get_oper_name(source_p), user, host, reason);
336 logged = 1;
337 }
338
339
340 if (var_offset & GDENY_REJECT)
341 {
342 if (ConfigFileEntry.gline_logging & GDENY_REJECT && !logged)
343 {
344 sendto_realops_flags(UMODE_ALL, L_ALL, "Rejected G-Line %s requested on [%s@%s] [%s]",
345 get_oper_name(source_p), user, host, reason);
346 ilog(L_TRACE, "Rejected G-Line %s requested on [%s@%s] [%s]",
347 get_oper_name(source_p), user, host, reason);
348 }
349 return;
350 }
351
352 if (ConfigFileEntry.glines)
353 {
354 if (!valid_wild_card(source_p, YES, 2, user, host))
355 return;
356
357 if (IsClient(source_p))
358 {
359 const char *p = NULL;
360 if ((p = strchr(host, '/')))
361 {
362 int bitlen = strtol(++p, NULL, 10);
363 int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
364 ConfigFileEntry.gline_min_cidr;
365
366 if (bitlen < min_bitlen)
367 {
368 sendto_realops_flags(UMODE_ALL, L_ALL, "%s!%s@%s on %s is requesting "
369 "a GLINE with a CIDR mask < %d for [%s@%s] [%s]",
370 source_p->name, source_p->username, source_p->host,
371 source_p->servptr->name, min_bitlen, user, host, reason);
372 return;
373 }
374 }
375 }
376
377 #ifdef GLINE_VOTING
378 /* If at least 3 opers agree this user should be G lined then do it */
379 if (check_majority(0, source_p, user, host, reason) ==
380 GLINE_ALREADY_VOTED)
381 {
382 sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
383 return;
384 }
385
386 sendto_realops_flags(UMODE_ALL, L_ALL,
387 "%s requesting G-Line for [%s@%s] [%s]",
388 get_oper_name(source_p),
389 user, host, reason);
390 ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s",
391 user, host, reason, get_oper_name(source_p));
392 #else
393 set_local_gline(source_p, user, host, reason);
394 #endif /* GLINE_VOTING */
395 }
396 }
397
398 /* set_local_gline()
399 *
400 * inputs - pointer to client struct of oper
401 * - pointer to victim user
402 * - pointer to victim host
403 * - pointer reason
404 * output - NONE
405 * side effects -
406 */
407 static void
408 set_local_gline(const struct Client *source_p, const char *user,
409 const char *host, const char *reason)
410 {
411 char buffer[IRCD_BUFSIZE];
412 struct ConfItem *conf;
413 struct AccessItem *aconf;
414 const char *current_date;
415 time_t cur_time;
416
417 set_time();
418 cur_time = CurrentTime;
419
420 current_date = smalldate(cur_time);
421 conf = make_conf_item(GLINE_TYPE);
422 aconf = (struct AccessItem *)map_to_conf(conf);
423
424 ircsprintf(buffer, "%s (%s)", reason, current_date);
425 DupString(aconf->reason, buffer);
426 DupString(aconf->user, user);
427 DupString(aconf->host, host);
428
429 aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
430 add_temp_line(conf);
431
432 sendto_realops_flags(UMODE_ALL, L_ALL,
433 "%s added G-Line for [%s@%s] [%s]",
434 get_oper_name(source_p),
435 aconf->user, aconf->host, aconf->reason);
436 ilog(L_TRACE, "%s added G-Line for [%s@%s] [%s]",
437 get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
438 log_oper_action(LOG_GLINE_TYPE, source_p, "[%s@%s] [%s]\n",
439 aconf->user, aconf->host, aconf->reason);
440 /* Now, activate gline against current online clients */
441 rehashed_klines = 1;
442 }
443
444 #ifdef GLINE_VOTING
445 /* add_new_majority()
446 *
447 * inputs - operator requesting gline
448 * - username covered by the gline
449 * - hostname covered by the gline
450 * - reason for the gline
451 * output - NONE
452 * side effects -
453 * This function is called once a majority of opers
454 * have agreed on a gline, and it can be placed. The
455 * information about an operator being passed to us
456 * happens to be the operator who pushed us over the
457 * "majority" level needed. See check_majority()
458 * for more information.
459 */
460 static void
461 add_new_majority(const struct Client *source_p,
462 const char *user, const char *host, const char *reason)
463 {
464 struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
465
466 strlcpy(pending->oper_nick1, source_p->name, sizeof(pending->oper_nick1));
467 strlcpy(pending->oper_user1, source_p->username, sizeof(pending->oper_user1));
468 strlcpy(pending->oper_host1, source_p->host, sizeof(pending->oper_host1));
469
470 strlcpy(pending->oper_server1, source_p->servptr->name, sizeof(pending->oper_server1));
471
472 strlcpy(pending->user, user, sizeof(pending->user));
473 strlcpy(pending->host, host, sizeof(pending->host));
474 strlcpy(pending->reason1, reason, sizeof(pending->reason1));
475
476 pending->last_gline_time = CurrentTime;
477 pending->time_request1 = CurrentTime;
478
479 dlinkAdd(pending, &pending->node, &pending_glines);
480 }
481
482 /* check_majority()
483 *
484 * inputs - source, user, host, reason
485 *
486 * output - one of three results
487 *
488 * GLINE_ALREADY_VOTED - returned if oper/server has already voted
489 * GLINE_PLACED - returned if this triggers a gline
490 * GLINE_NOT_PLACED - returned if not triggered
491 *
492 * Side effects -
493 * See if there is a majority agreement on a GLINE on the given user
494 * There must be at least 3 different opers agreeing on this GLINE
495 *
496 */
497 static int
498 check_majority(int isungline, const struct Client *source_p,
499 const char *user, const char *host, const char *reason)
500 {
501 dlink_node *pending_node;
502 struct gline_pending *gline_pending_ptr;
503 char ckuser[USERLEN * 2 + 2];
504
505 /* if its already glined, why bother? :) -- fl_ */
506 if (!isungline && find_is_glined(host, user))
507 return(GLINE_NOT_PLACED);
508
509 if (isungline)
510 ircsprintf(ckuser, "-%s", user);
511 else
512 ircsprintf(ckuser, "%s", user);
513
514 /* special case condition where there are no pending glines */
515 if (dlink_list_length(&pending_glines) == 0) /* first gline request placed */
516 {
517 add_new_majority(source_p, ckuser, host, reason);
518 return(GLINE_NOT_PLACED);
519 }
520
521 DLINK_FOREACH(pending_node, pending_glines.head)
522 {
523 gline_pending_ptr = pending_node->data;
524
525 if ((irccmp(gline_pending_ptr->user, ckuser) == 0) &&
526 (irccmp(gline_pending_ptr->host, host) == 0))
527 {
528 if (((irccmp(gline_pending_ptr->oper_user1, source_p->username) == 0) ||
529 (irccmp(gline_pending_ptr->oper_host1, source_p->host) == 0)) ||
530 (irccmp(gline_pending_ptr->oper_server1, source_p->servptr->name) == 0))
531 {
532 return(GLINE_ALREADY_VOTED);
533 }
534
535 if (gline_pending_ptr->oper_user2[0] != '\0')
536 {
537 /* if two other opers on two different servers have voted yes */
538
539 if(((irccmp(gline_pending_ptr->oper_user2, source_p->username)==0) ||
540 (irccmp(gline_pending_ptr->oper_host2, source_p->host)==0)) ||
541 (irccmp(gline_pending_ptr->oper_server2, source_p->servptr->name)==0))
542 {
543 return(GLINE_ALREADY_VOTED);
544 }
545
546 if(gline_pending_ptr->user[0] == '-')
547 {
548 if (remove_gline_match(user, host))
549 {
550 sendto_one(source_p, ":%s NOTICE %s :G-Line for [%s@%s] is removed",
551 me.name, source_p->name, user, host);
552 sendto_realops_flags(UMODE_ALL, L_ALL,
553 "%s has removed the G-Line for: [%s@%s]",
554 get_oper_name(source_p), user, host);
555 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
556 get_oper_name(source_p), user, host);
557 }
558 else
559 {
560 sendto_one(source_p, ":%s NOTICE %s :No G-Line for %s@%s",
561 me.name, source_p->name, user, host);
562 }
563 }
564 else
565 {
566 /* trigger the gline using the original reason --fl */
567 set_local_gline(source_p, user, host, gline_pending_ptr->reason1);
568 cleanup_glines(NULL);
569 return(GLINE_PLACED);
570 }
571 }
572 }
573 else
574 {
575 strlcpy(gline_pending_ptr->oper_nick2, source_p->name,
576 sizeof(gline_pending_ptr->oper_nick2));
577 strlcpy(gline_pending_ptr->oper_user2, source_p->username,
578 sizeof(gline_pending_ptr->oper_user2));
579 strlcpy(gline_pending_ptr->oper_host2, source_p->host,
580 sizeof(gline_pending_ptr->oper_host2));
581 strlcpy(gline_pending_ptr->reason2, reason,
582 sizeof(gline_pending_ptr->reason2));
583 strlcpy(gline_pending_ptr->oper_server2, source_p->servptr->name,
584 sizeof(gline_pending_ptr->oper_server2));
585 gline_pending_ptr->last_gline_time = CurrentTime;
586 gline_pending_ptr->time_request2 = CurrentTime;
587 return(GLINE_NOT_PLACED);
588 }
589 }
590
591 /* Didn't find this user@host gline in pending gline list
592 * so add it.
593 */
594 add_new_majority(source_p, ckuser, host, reason);
595 return(GLINE_NOT_PLACED);
596 }
597 #endif /* GLINE_VOTING */
598
599 static int
600 remove_gline_match(const char *user, const char *host)
601 {
602 struct AccessItem *aconf;
603 dlink_node *ptr = NULL;
604 struct irc_ssaddr addr, caddr;
605 int nm_t, cnm_t, bits, cbits;
606
607 nm_t = parse_netmask(host, &addr, &bits);
608
609 DLINK_FOREACH(ptr, temporary_glines.head)
610 {
611 aconf = map_to_conf(ptr->data);
612 cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
613
614 if (cnm_t != nm_t || irccmp(user, aconf->user))
615 continue;
616
617 if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
618 (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
619 #ifdef IPV6
620 || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
621 #endif
622 )
623 {
624 dlinkDelete(ptr, &temporary_glines);
625 delete_one_address_conf(aconf->host, aconf);
626 return(1);
627 }
628 }
629
630 return(0);
631 }
632
633 /*
634 * me_gungline()
635 * do_sungline()
636 *
637 * inputs - The usual for a m_ function
638 * output -
639 * side effects -
640 *
641 * Remove a G line if 3 opers agree on the identical user@host
642 *
643 * ENCAP'd UNGLINES are propagated by encap code.
644 */
645
646 static void
647 me_gungline(struct Client *client_p, struct Client *source_p,
648 int parc, char *parv[])
649 {
650 do_sungline(client_p, source_p, parc, parv, 0);
651 }
652
653 static void
654 do_sungline(struct Client *client_p, struct Client *source_p,
655 int parc, char *parv[], int prop)
656 {
657 const char *reason = NULL; /* reason for "victims" demise */
658 char *user = NULL;
659 char *host = NULL; /* user and host of GLINE "victim" */
660 int var_offset = 0;
661 int logged = 0;
662 dlink_node *ptr;
663 struct ConfItem *conf;
664 struct AccessItem *aconf;
665
666 assert(source_p->servptr != NULL);
667
668 user = parv[++var_offset];
669 host = parv[++var_offset];
670 reason = parv[++var_offset];
671
672 if (ConfigFileEntry.glines)
673 {
674 if (!valid_wild_card(source_p, YES, 2, user, host))
675 return;
676
677 #ifdef GLINE_VOTING
678 /* If at least 3 opers agree this user should be un G lined then do it */
679 if (check_majority(1, source_p, user, host, reason) ==
680 GLINE_ALREADY_VOTED)
681 {
682 sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
683 return;
684 }
685
686 sendto_realops_flags(UMODE_ALL, L_ALL,
687 "%s requesting UNG-Line for [%s@%s] [%s]",
688 get_oper_name(source_p),
689 user, host, reason);
690 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s",
691 user, host, reason, get_oper_name(source_p));
692 #else
693 if (remove_gline_match(user, host))
694 {
695 sendto_one(source_p, ":%s NOTICE %s :G-Line for [%s@%s] is removed",
696 me.name, source_p->name, user, host);
697 sendto_realops_flags(UMODE_ALL, L_ALL,
698 "%s has removed the G-Line for: [%s@%s]",
699 get_oper_name(source_p), user, host);
700 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
701 get_oper_name(source_p), user, host);
702 }
703 else
704 {
705 sendto_one(source_p, ":%s NOTICE %s :No G-Line for %s@%s",
706 me.name, source_p->name, user, host);
707 }
708 #endif /* GLINE_VOTING */
709 }
710 }
711
712 /* mo_gungline()
713 *
714 * inputs - The usual for a m_ function
715 * output -
716 * side effects -
717 *
718 * Remove a G line if 3 opers agree on the identical user@host
719 *
720 */
721 /* Allow this server to pass along UNGLINE if received and
722 * GLINES is not defined.
723 *
724 */
725
726 static void
727 mo_gungline(struct Client *client_p, struct Client *source_p,
728 int parc, char *parv[])
729 {
730 char *user = NULL;
731 char *host = NULL; /* user and host of GLINE "victim" */
732 char *reason = NULL; /* reason for "victims" demise */
733 char encap_ungline[IRCD_BUFSIZE];
734
735 if (!ConfigFileEntry.glines)
736 {
737 sendto_one(source_p, ":%s NOTICE %s :UNGLINE disabled",
738 me.name, source_p->name);
739 return;
740 }
741
742 if (!IsOperGline(source_p))
743 {
744 sendto_one(source_p, form_str(ERR_NOPRIVS),
745 me.name, source_p->name, "ungline");
746 return;
747 }
748
749 if (parse_aline("UNGLINE", source_p, parc, parv,
750 0, &user, &host, NULL, NULL, &reason) < 0)
751 return;
752
753 #ifdef GLINE_VOTING
754 /* If at least 3 opers agree this user should be un G lined then do it */
755 if (check_majority(1, source_p, user, host, reason) ==
756 GLINE_ALREADY_VOTED)
757 {
758 sendto_one(source_p,
759 ":%s NOTICE %s :This server or oper has already voted",
760 me.name, source_p->name);
761 return;
762 }
763
764 /*
765 * call these two functions first so the 'requesting' notice always comes
766 * before the 'has triggered' notice. -bill
767 */
768 sendto_realops_flags(UMODE_ALL, L_ALL,
769 "%s requesting UNG-Line for [%s@%s] [%s]",
770 get_oper_name(source_p),
771 user, host, reason);
772 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s!%s@%s",
773 user, host, reason, source_p->name, source_p->username,
774 source_p->host);
775 #else
776 if (remove_gline_match(user, host))
777 {
778 sendto_one(source_p, ":%s NOTICE %s :G-Line for [%s@%s] is removed",
779 me.name, source_p->name, user, host);
780 sendto_realops_flags(UMODE_ALL, L_ALL,
781 "%s has removed the G-Line for: [%s@%s]",
782 get_oper_name(source_p), user, host);
783 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
784 get_oper_name(source_p), user, host);
785 }
786 #endif /* GLINE_VOTING */
787
788 ircsprintf(encap_ungline, "GUNGLINE %s %s :%s",
789 user, host, reason);
790 /* 4 param version for hyb-7 servers */
791 /*
792 sendto_match_servs(struct Client *source_p, const char *mask, int cap,
793 const char *pattern, ...)
794 */
795 sendto_match_servs(NULL, NULL, CAP_ENCAP,
796 "ENCAP %s", encap_ungline);
797
798 }

Properties

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