ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_gline.c
Revision: 937
Committed: Mon Apr 13 04:31:12 2009 UTC (15 years ago) by db
Content type: text/x-csrc
File size: 23850 byte(s)
Log Message:
- Preliminary voting ungline code


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

Properties

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