ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/modules/m_gline.c
Revision: 987
Committed: Sun Aug 16 12:41:56 2009 UTC (14 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 22548 byte(s)
Log Message:
- mo_sgungline: calling sento_server with right amount of params sounds like
  a good idea

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, AWILD,
157 &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(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) ==
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 var_offset = 0;
301
302 DLINK_FOREACH(ptr, gdeny_items.head)
303 {
304 conf = ptr->data;
305 aconf = (struct AccessItem *)map_to_conf(conf);
306
307 if (match(conf->name, source_p->servptr->name) &&
308 match(aconf->user, source_p->username) &&
309 match(aconf->host, source_p->host))
310 {
311 var_offset = aconf->flags;
312 break;
313 }
314 }
315
316 if (prop && !(var_offset & GDENY_BLOCK))
317 {
318 sendto_server(client_p, NULL, CAP_GLN, NOCAPS,
319 ":%s GLINE %s %s :%s",
320 source_p->name, user, host, reason);
321 /* hyb-6 version to the rest */
322 sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
323 ":%s GLINE %s %s %s %s %s %s :%s",
324 source_p->servptr->name,
325 source_p->name, source_p->username, source_p->host,
326 source_p->servptr->name,
327 user, host, reason);
328 }
329 else if (ConfigFileEntry.gline_logging & GDENY_BLOCK && ServerInfo.hub)
330 {
331 sendto_realops_flags(UMODE_ALL, L_ALL, "Blocked G-Line %s requested on [%s@%s] [%s]",
332 get_oper_name(source_p), user, host, reason);
333 ilog(L_TRACE, "Blocked G-Line %s requested on [%s@%s] [%s]",
334 get_oper_name(source_p), user, host, reason);
335 logged = 1;
336 }
337
338
339 if (var_offset & GDENY_REJECT)
340 {
341 if (ConfigFileEntry.gline_logging & GDENY_REJECT && !logged)
342 {
343 sendto_realops_flags(UMODE_ALL, L_ALL, "Rejected G-Line %s requested on [%s@%s] [%s]",
344 get_oper_name(source_p), user, host, reason);
345 ilog(L_TRACE, "Rejected G-Line %s requested on [%s@%s] [%s]",
346 get_oper_name(source_p), user, host, reason);
347 }
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
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, GLINE_PENDING_ADD_TYPE) ==
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
416
417 conf = make_conf_item(GLINE_TYPE);
418 aconf = map_to_conf(conf);
419
420 ircsprintf(buffer, "%s (%s)", reason, smalldate(CurrentTime));
421 DupString(aconf->reason, buffer);
422 DupString(aconf->user, user);
423 DupString(aconf->host, host);
424
425 aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
426 add_temp_line(conf);
427
428 sendto_realops_flags(UMODE_ALL, L_ALL,
429 "%s added G-Line for [%s@%s] [%s]",
430 get_oper_name(source_p),
431 aconf->user, aconf->host, aconf->reason);
432 ilog(L_TRACE, "%s added G-Line for [%s@%s] [%s]",
433 get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
434 log_oper_action(LOG_GLINE_TYPE, source_p, "[%s@%s] [%s]\n",
435 aconf->user, aconf->host, aconf->reason);
436 /* Now, activate gline against current online clients */
437 rehashed_klines = 1;
438 }
439
440 #ifdef GLINE_VOTING
441 /* add_new_majority()
442 *
443 * inputs - operator requesting gline
444 * - username covered by the gline
445 * - hostname covered by the gline
446 * - reason for the gline
447 * output - NONE
448 * side effects -
449 * This function is called once a majority of opers
450 * have agreed on a gline, and it can be placed. The
451 * information about an operator being passed to us
452 * happens to be the operator who pushed us over the
453 * "majority" level needed. See check_majority()
454 * for more information.
455 */
456 static void
457 add_new_majority(const struct Client *source_p, const char *user,
458 const char *host, const char *reason)
459 {
460 struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
461
462 strlcpy(pending->vote_1.oper_nick, source_p->name, sizeof(pending->vote_1.oper_nick));
463 strlcpy(pending->vote_1.oper_user, source_p->username, sizeof(pending->vote_1.oper_user));
464 strlcpy(pending->vote_1.oper_host, source_p->host, sizeof(pending->vote_1.oper_host));
465 strlcpy(pending->vote_1.oper_server, source_p->servptr->name, sizeof(pending->vote_1.oper_server));
466
467 strlcpy(pending->user, user, sizeof(pending->user));
468 strlcpy(pending->host, host, sizeof(pending->host));
469 strlcpy(pending->vote_1.reason, reason, sizeof(pending->vote_1.reason));
470
471 pending->last_gline_time = CurrentTime;
472 pending->time_request1 = CurrentTime;
473
474 dlinkAdd(pending, &pending->node, &pending_glines[GLINE_PENDING_ADD_TYPE]);
475 }
476
477 /* check_majority()
478 *
479 * inputs - source, user, host, reason
480 *
481 * output - one of three results
482 *
483 * GLINE_ALREADY_VOTED - returned if oper/server has already voted
484 * GLINE_PLACED - returned if this triggers a gline
485 * GLINE_NOT_PLACED - returned if not triggered
486 *
487 * Side effects -
488 * See if there is a majority agreement on a GLINE on the given user
489 * There must be at least 3 different opers agreeing on this GLINE
490 *
491 */
492 static int
493 check_majority(const struct Client *source_p, const char *user,
494 const char *host, const char *reason, int type)
495 {
496 dlink_node *dn_ptr = NULL;
497
498 cleanup_glines(NULL);
499
500 /* if its already glined, why bother? :) -- fl_ */
501 if ((type == GLINE_PENDING_ADD_TYPE) && find_is_glined(host, user))
502 return GLINE_NOT_PLACED;
503
504 DLINK_FOREACH(dn_ptr, pending_glines[type].head)
505 {
506 struct gline_pending *gp_ptr = dn_ptr->data;
507
508 if (irccmp(gp_ptr->user, user) ||
509 irccmp(gp_ptr->host, host))
510 continue;
511
512 if (!irccmp(gp_ptr->vote_1.oper_user, source_p->username) ||
513 !irccmp(gp_ptr->vote_1.oper_host, source_p->host) ||
514 !irccmp(gp_ptr->vote_1.oper_server, source_p->servptr->name))
515 return GLINE_ALREADY_VOTED;
516
517 if (gp_ptr->vote_2.oper_user[0] != '\0')
518 {
519 /* if two other opers on two different servers have voted yes */
520 if (!irccmp(gp_ptr->vote_2.oper_user, source_p->username) ||
521 !irccmp(gp_ptr->vote_2.oper_host, source_p->host) ||
522 !irccmp(gp_ptr->vote_2.oper_server, source_p->servptr->name))
523 return GLINE_ALREADY_VOTED;
524
525 if (type == GLINE_PENDING_DEL_TYPE)
526 {
527 if (remove_gline_match(user, host))
528 {
529 sendto_realops_flags(UMODE_ALL, L_ALL,
530 "%s has removed the G-Line for: [%s@%s]",
531 get_oper_name(source_p), user, host);
532 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
533 get_oper_name(source_p), user, host);
534 }
535 }
536 else
537 /* trigger the gline using the original reason --fl */
538 set_local_gline(source_p, user, host, gp_ptr->vote_1.reason);
539
540 cleanup_glines(gp_ptr);
541 return GLINE_PLACED;
542 }
543
544 strlcpy(gp_ptr->vote2.oper_nick, source_p->name,
545 sizeof(gp_ptr->vote2.oper_nick));
546 strlcpy(gp_ptr->vote_2.oper_user, source_p->username,
547 sizeof(gp_ptr->vote_2.));
548 strlcpy(gp_ptr->vote_2.oper_host, source_p->host,
549 sizeof(gp_ptr->vote_2.oper_host));
550 strlcpy(gp_ptr->vote_2.reason, reason,
551 sizeof(gp_ptr->vote_2.reason));
552 strlcpy(gp_ptr->vote_2.oper_server, source_p->servptr->name,
553 sizeof(gp_ptr->vote_2.oper_server));
554 gp_ptr->last_gline_time = CurrentTime;
555 gp_ptr->vote_2.time_request = CurrentTime;
556 return GLINE_NOT_PLACED;
557 }
558
559 /*
560 * Didn't find this user@host gline in pending gline list
561 * so add it.
562 */
563 add_new_majority(source_p, user, host, reason);
564 return GLINE_NOT_PLACED;
565 }
566 #endif /* GLINE_VOTING */
567
568 static int
569 remove_gline_match(const char *user, const char *host)
570 {
571 struct AccessItem *aconf;
572 dlink_node *ptr = NULL;
573 struct irc_ssaddr addr, caddr;
574 int nm_t, cnm_t, bits, cbits;
575
576 nm_t = parse_netmask(host, &addr, &bits);
577
578 DLINK_FOREACH(ptr, temporary_glines.head)
579 {
580 aconf = map_to_conf(ptr->data);
581 cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
582
583 if (cnm_t != nm_t || irccmp(user, aconf->user))
584 continue;
585
586 if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
587 (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
588 #ifdef IPV6
589 || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
590 #endif
591 )
592 {
593 dlinkDelete(ptr, &temporary_glines);
594 delete_one_address_conf(aconf->host, aconf);
595 return 1;
596 }
597 }
598
599 return 0;
600 }
601
602 /*
603 * me_gungline()
604 * do_sungline()
605 *
606 * inputs - The usual for a m_ function
607 * output -
608 * side effects -
609 *
610 * Remove a G line if 3 opers agree on the identical user@host
611 *
612 * ENCAP'd UNGLINES are propagated by encap code.
613 */
614
615 static void
616 me_gungline(struct Client *client_p, struct Client *source_p,
617 int parc, char *parv[])
618 {
619 if (ConfigFileEntry.glines)
620 do_sungline(client_p, source_p, parc, parv, 0);
621 }
622
623 static void
624 do_sungline(struct Client *client_p, struct Client *source_p,
625 int parc, char *parv[], int prop)
626 {
627 const char *user = parv[1];
628 const char *host = parv[2]; /* user and host of GLINE "victim" */
629 const char *reason = parv[3];
630
631 assert(source_p->servptr != NULL);
632
633 #ifdef GLINE_VOTING
634 sendto_realops_flags(UMODE_ALL, L_ALL,
635 "%s requesting UNG-Line for [%s@%s] [%s]",
636 get_oper_name(source_p),
637 user, host, reason);
638 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s",
639 user, host, reason, get_oper_name(source_p));
640
641 /* If at least 3 opers agree this user should be un G lined then do it */
642 if (check_majority(source_p, user, host, reason, GLINE_PENDING_DEL_TYPE) ==
643 GLINE_ALREADY_VOTED)
644 sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
645 #else
646 if (remove_gline_match(user, host))
647 {
648 sendto_realops_flags(UMODE_ALL, L_ALL,
649 "%s has removed the G-Line for: [%s@%s]",
650 get_oper_name(source_p), user, host);
651 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
652 get_oper_name(source_p), user, host);
653 }
654 #endif
655 }
656
657 /* mo_gungline()
658 *
659 * inputs - The usual for a m_ function
660 * output -
661 * side effects -
662 *
663 * Remove a G line if 3 opers agree on the identical user@host
664 *
665 */
666 /* Allow this server to pass along UNGLINE if received and
667 * GLINES is not defined.
668 *
669 */
670 static void
671 mo_gungline(struct Client *client_p, struct Client *source_p,
672 int parc, char *parv[])
673 {
674 char *user = NULL;
675 char *host = NULL; /* user and host of GLINE "victim" */
676 char *reason = NULL; /* reason for "victims" demise */
677
678 if (!ConfigFileEntry.glines)
679 {
680 sendto_one(source_p, ":%s NOTICE %s :GUNGLINE disabled",
681 me.name, source_p->name);
682 return;
683 }
684
685 if (!IsOperGline(source_p))
686 {
687 sendto_one(source_p, form_str(ERR_NOPRIVS),
688 me.name, source_p->name, "gungline");
689 return;
690 }
691
692 if (parse_aline("GUNGLINE", source_p, parc, parv, 0, &user,
693 &host, NULL, NULL, &reason) < 0)
694 return;
695
696 #ifdef GLINE_VOTING
697 /*
698 * call these two functions first so the 'requesting' notice always comes
699 * before the 'has triggered' notice. -bill
700 */
701 sendto_realops_flags(UMODE_ALL, L_ALL,
702 "%s requesting UNG-Line for [%s@%s] [%s]",
703 get_oper_name(source_p),
704 user, host, reason);
705 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s!%s@%s",
706 user, host, reason, source_p->name, source_p->username,
707 source_p->host);
708
709 /* If at least 3 opers agree this user should be un G lined then do it */
710 if (check_majority(, source_p, user, host, reason, GLINE_PENDING_DEL_TYPE) ==
711 GLINE_ALREADY_VOTED)
712 sendto_one(source_p,
713 ":%s NOTICE %s :This server or oper has already voted",
714 me.name, source_p->name);
715 #else
716 if (remove_gline_match(user, host))
717 {
718 sendto_realops_flags(UMODE_ALL, L_ALL,
719 "%s has removed the G-Line for: [%s@%s]",
720 get_oper_name(source_p), user, host);
721 ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
722 get_oper_name(source_p), user, host);
723 }
724 else
725 sendto_one(source_p, ":%s NOTICE %s :No G-Line for %s@%s",
726 me.name, source_p->name, user, host);
727 #endif /* GLINE_VOTING */
728 sendto_server(client_p, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
729 ":%s ENCAP * GUNGLINE %s %s :%s",
730 ID(source_p), user, host, reason);
731 sendto_server(client_p, NULL, CAP_ENCAP, CAP_TS6,
732 ":%s ENCAP * GUNGLINE %s %s :%s",
733 source_p->name, user, host, reason);
734 }

Properties

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