ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_gline.c
Revision: 957
Committed: Tue Jul 28 18:47:23 2009 UTC (16 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 22682 byte(s)
Log Message:
- implement proper GUNGLINE support

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 *, const char *);
63
64 #ifdef GLINE_VOTING
65 static int check_majority(const struct Client *, const char *,
66 const char *, const char *, int);
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 = 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, const char *user,
462 const char *host, const char *reason)
463 {
464 struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
465
466 strlcpy(pending->vote_1.oper_nick, source_p->name, sizeof(pending->vote_1.oper_nick));
467 strlcpy(pending->vote_1.oper_user, source_p->username, sizeof(pending->vote_1.oper_user));
468 strlcpy(pending->vote_1.oper_host, source_p->host, sizeof(pending->vote_1-oper_host));
469 strlcpy(pending->vote_1.oper_server, source_p->servptr->name, sizeof(pending->vote_1.oper_server));
470
471 strlcpy(pending->user, user, sizeof(pending->user));
472 strlcpy(pending->host, host, sizeof(pending->host));
473 strlcpy(pending->vote_1.reason, reason, sizeof(pending->vote_1.reason));
474
475 pending->last_gline_time = CurrentTime;
476 pending->time_request1 = CurrentTime;
477
478 dlinkAdd(pending, &pending->node, &pending_glines[GLINE_PENDING_ADD_TYPE]);
479 }
480
481 /* check_majority()
482 *
483 * inputs - source, user, host, reason
484 *
485 * output - one of three results
486 *
487 * GLINE_ALREADY_VOTED - returned if oper/server has already voted
488 * GLINE_PLACED - returned if this triggers a gline
489 * GLINE_NOT_PLACED - returned if not triggered
490 *
491 * Side effects -
492 * See if there is a majority agreement on a GLINE on the given user
493 * There must be at least 3 different opers agreeing on this GLINE
494 *
495 */
496 static int
497 check_majority(const struct Client *source_p, const char *user,
498 const char *host, const char *reason, int type)
499 {
500 dlink_node *dn_ptr = NULL;
501
502 cleanup_glines(NULL);
503
504 /* if its already glined, why bother? :) -- fl_ */
505 if ((type == GLINE_PENDING_ADD_TYPE) && find_is_glined(host, user))
506 return GLINE_NOT_PLACED;
507
508 DLINK_FOREACH(dn_ptr, pending_glines[type].head)
509 {
510 struct gline_pending *gp_ptr = dn_ptr->data;
511
512 if (irccmp(gp_ptr->user, user) ||
513 irccmp(gp_ptr->host, host))
514 continue;
515
516 if (!irccmp(gp_ptr->vote_1.oper_user, source_p->username) ||
517 !irccmp(gp_ptr->vote_1.oper_host, source_p->host) ||
518 !irccmp(gp_ptr->vote_1.oper_server, source_p->servptr->name))
519 return GLINE_ALREADY_VOTED;
520
521 if (gp_ptr->vote_2.oper_user[0] != '\0')
522 {
523 /* if two other opers on two different servers have voted yes */
524 if (!irccmp(gp_ptr->vote_2.oper_user, source_p->username) ||
525 !irccmp(gp_ptr->vote_2.oper_host, source_p->host) ||
526 !irccmp(gp_ptr->vote_2.oper_server, source_p->servptr->name))
527 return GLINE_ALREADY_VOTED;
528
529 if (type == GLINE_PENDING_DEL_TYPE)
530 {
531 if (remove_gline_match(user, host))
532 {
533 sendto_realops_flags(UMODE_ALL, L_ALL,
534 "%s has removed the G-Line for: [%s@%s]",
535 get_oper_name(source_p), user, host);
536 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
537 get_oper_name(source_p), user, host);
538 }
539 }
540 else
541 /* trigger the gline using the original reason --fl */
542 set_local_gline(source_p, user, host, gp_ptr->vote_1.reason);
543
544 cleanup_glines(gp_ptr);
545 return GLINE_PLACED;
546 }
547
548 strlcpy(gp_ptr->vote2.oper_nick, source_p->name,
549 sizeof(gp_ptr->vote2.oper_nick));
550 strlcpy(gp_ptr->vote_2.oper_user, source_p->username,
551 sizeof(gp_ptr->vote_2.));
552 strlcpy(gp_ptr->vote_2.oper_host, source_p->host,
553 sizeof(gp_ptr->vote_2.oper_host));
554 strlcpy(gp_ptr->vote_2.reason, reason,
555 sizeof(gp_ptr->vote_2.reason));
556 strlcpy(gp_ptr->vote_2.oper_server, source_p->servptr->name,
557 sizeof(gp_ptr->vote_2.oper_server));
558 gp_ptr->last_gline_time = CurrentTime;
559 gp_ptr->vote_2.time_request = CurrentTime;
560 return GLINE_NOT_PLACED;
561 }
562
563 /*
564 * Didn't find this user@host gline in pending gline list
565 * so add it.
566 */
567 add_new_majority(source_p, user, host, reason);
568 return GLINE_NOT_PLACED;
569 }
570 #endif /* GLINE_VOTING */
571
572 static int
573 remove_gline_match(const char *user, const char *host)
574 {
575 struct AccessItem *aconf;
576 dlink_node *ptr = NULL;
577 struct irc_ssaddr addr, caddr;
578 int nm_t, cnm_t, bits, cbits;
579
580 nm_t = parse_netmask(host, &addr, &bits);
581
582 DLINK_FOREACH(ptr, temporary_glines.head)
583 {
584 aconf = map_to_conf(ptr->data);
585 cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
586
587 if (cnm_t != nm_t || irccmp(user, aconf->user))
588 continue;
589
590 if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
591 (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
592 #ifdef IPV6
593 || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
594 #endif
595 )
596 {
597 dlinkDelete(ptr, &temporary_glines);
598 delete_one_address_conf(aconf->host, aconf);
599 return 1;
600 }
601 }
602
603 return 0;
604 }
605
606 /*
607 * me_gungline()
608 * do_sungline()
609 *
610 * inputs - The usual for a m_ function
611 * output -
612 * side effects -
613 *
614 * Remove a G line if 3 opers agree on the identical user@host
615 *
616 * ENCAP'd UNGLINES are propagated by encap code.
617 */
618
619 static void
620 me_gungline(struct Client *client_p, struct Client *source_p,
621 int parc, char *parv[])
622 {
623 if (!ConfigFileEntry.glines)
624 return;
625
626 do_sungline(client_p, source_p, parc, parv, 0);
627 }
628
629 static void
630 do_sungline(struct Client *client_p, struct Client *source_p,
631 int parc, char *parv[], int prop)
632 {
633 const char *reason = NULL; /* reason for "victims" demise */
634 char *user = NULL;
635 char *host = NULL; /* user and host of GLINE "victim" */
636 unsigned int var_offset = 0;
637
638 assert(source_p->servptr != NULL);
639
640 user = parv[++var_offset];
641 host = parv[++var_offset];
642 reason = parv[++var_offset];
643
644 #ifdef GLINE_VOTING
645 sendto_realops_flags(UMODE_ALL, L_ALL,
646 "%s requesting UNG-Line for [%s@%s] [%s]",
647 get_oper_name(source_p),
648 user, host, reason);
649 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s",
650 user, host, reason, get_oper_name(source_p));
651
652 /* If at least 3 opers agree this user should be un G lined then do it */
653 if (check_majority(1, source_p, user, host, reason) ==
654 GLINE_ALREADY_VOTED)
655 sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
656 #else
657 if (remove_gline_match(user, host))
658 {
659 sendto_realops_flags(UMODE_ALL, L_ALL,
660 "%s has removed the G-Line for: [%s@%s]",
661 get_oper_name(source_p), user, host);
662 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
663 get_oper_name(source_p), user, host);
664 }
665 #endif
666 }
667
668 /* mo_gungline()
669 *
670 * inputs - The usual for a m_ function
671 * output -
672 * side effects -
673 *
674 * Remove a G line if 3 opers agree on the identical user@host
675 *
676 */
677 /* Allow this server to pass along UNGLINE if received and
678 * GLINES is not defined.
679 *
680 */
681 static void
682 mo_gungline(struct Client *client_p, struct Client *source_p,
683 int parc, char *parv[])
684 {
685 char *user = NULL;
686 char *host = NULL; /* user and host of GLINE "victim" */
687 char *reason = NULL; /* reason for "victims" demise */
688
689 if (!ConfigFileEntry.glines)
690 {
691 sendto_one(source_p, ":%s NOTICE %s :GUNGLINE disabled",
692 me.name, source_p->name);
693 return;
694 }
695
696 if (!IsOperGline(source_p))
697 {
698 sendto_one(source_p, form_str(ERR_NOPRIVS),
699 me.name, source_p->name, "gungline");
700 return;
701 }
702
703 if (parse_aline("GUNGLINE", source_p, parc, parv, 0, &user,
704 &host, NULL, NULL, &reason) < 0)
705 return;
706
707 #ifdef GLINE_VOTING
708 /*
709 * call these two functions first so the 'requesting' notice always comes
710 * before the 'has triggered' notice. -bill
711 */
712 sendto_realops_flags(UMODE_ALL, L_ALL,
713 "%s requesting UNG-Line for [%s@%s] [%s]",
714 get_oper_name(source_p),
715 user, host, reason);
716 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s!%s@%s",
717 user, host, reason, source_p->name, source_p->username,
718 source_p->host);
719
720 /* If at least 3 opers agree this user should be un G lined then do it */
721 if (check_majority(1, source_p, user, host, reason) ==
722 GLINE_ALREADY_VOTED)
723 sendto_one(source_p,
724 ":%s NOTICE %s :This server or oper has already voted",
725 me.name, source_p->name);
726 #else
727 if (remove_gline_match(user, host))
728 {
729 sendto_realops_flags(UMODE_ALL, L_ALL,
730 "%s has removed the G-Line for: [%s@%s]",
731 get_oper_name(source_p), user, host);
732 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
733 get_oper_name(source_p), user, host);
734 }
735 else
736 sendto_one(source_p, ":%s NOTICE %s :No G-Line for %s@%s",
737 me.name, source_p->name, user, host);
738 #endif /* GLINE_VOTING */
739 sendto_server(client_p, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
740 ":%s ENCAP * GUNGLINE %s %s :%s",
741 ID(source_p), host, reason);
742 sendto_server(client_p, NULL, CAP_ENCAP, CAP_TS6,
743 ":%s ENCAP * GUNGLINE %s %s :%s",
744 source_p->name, user, host, reason);
745 }

Properties

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