]> jfr.im git - irc/rqf/shadowircd.git/blame - modules/m_gline.c
start making this compile
[irc/rqf/shadowircd.git] / modules / m_gline.c
CommitLineData
212380e3 1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * m_gline.c: Votes towards globally banning a mask.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
61569b65 24 * $Id: m_gline.c 3225 2007-03-04 23:42:55Z jilles $
212380e3 25 */
26
27#include "stdinc.h"
28#include "tools.h"
29#include "s_gline.h"
30#include "channel.h"
31#include "client.h"
32#include "common.h"
33#include "config.h"
34#include "irc_string.h"
35#include "sprintf_irc.h"
36#include "ircd.h"
37#include "hostmask.h"
38#include "numeric.h"
39#include "commio.h"
40#include "s_conf.h"
41#include "s_newconf.h"
42#include "scache.h"
43#include "send.h"
44#include "msg.h"
45#include "s_serv.h"
46#include "hash.h"
47#include "parse.h"
48#include "modules.h"
49#include "s_log.h"
35f6f850 50#include "reject.h"
212380e3 51
52static int mo_gline(struct Client *, struct Client *, int, const char **);
53static int mc_gline(struct Client *, struct Client *, int, const char **);
54static int ms_gline(struct Client *, struct Client *, int, const char **);
55static int mo_ungline(struct Client *, struct Client *, int, const char **);
56
57struct Message gline_msgtab = {
58 "GLINE", 0, 0, 0, MFLG_SLOW,
59 {mg_unreg, mg_not_oper, {mc_gline, 3}, {ms_gline, 7}, mg_ignore, {mo_gline, 3}}
60};
61struct Message ungline_msgtab = {
62 "UNGLINE", 0, 0, 0, MFLG_SLOW,
63 {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_ungline, 2}}
64};
65
66mapi_clist_av1 gline_clist[] = { &gline_msgtab, &ungline_msgtab, NULL };
61569b65 67DECLARE_MODULE_AV1(gline, NULL, NULL, gline_clist, NULL, NULL, "$Revision: 3225 $");
212380e3 68
69static int majority_gline(struct Client *source_p, const char *user,
70 const char *host, const char *reason);
71static void set_local_gline(struct Client *source_p, const char *user,
72 const char *host, const char *reason);
73
74static int check_wild_gline(const char *, const char *);
75static int invalid_gline(struct Client *, const char *, const char *, char *);
76
77static int remove_temp_gline(const char *, const char *);
78
79
80/* mo_gline()
81 *
82 * inputs - The usual for a m_ function
83 * output -
84 * side effects - place a gline if 3 opers agree
85 */
86static int
87mo_gline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
88{
89 const char *user = NULL;
90 char *host = NULL; /* user and host of GLINE "victim" */
91 char *reason = NULL; /* reason for "victims" demise */
92 char splat[] = "*";
93 char *ptr;
94
95 if(!ConfigFileEntry.glines)
96 {
5366977b 97 sendto_one_notice(source_p, ":GLINE disabled, perhaps you want a clustered or remote KLINE?");
212380e3 98 return 0;
99 }
100
101 if(!IsOperGline(source_p))
102 {
103 sendto_one(source_p, form_str(ERR_NOPRIVS),
104 me.name, source_p->name, "gline");
105 return 0;
106 }
107
108 host = strchr(parv[1], '@');
109
110 /* specific user@host */
111 if(host != NULL)
112 {
113 user = parv[1];
114 *(host++) = '\0';
115
116 /* gline for "@host", use *@host */
117 if(*user == '\0')
118 user = splat;
119 }
120 /* just a host? */
121 else
122 {
123 /* ok, its not a host.. abort */
124 if(strchr(parv[1], '.') == NULL)
125 {
5366977b 126 sendto_one_notice(source_p, ":Invalid parameters");
212380e3 127 return 0;
128 }
129
130 user = splat;
131 host = LOCAL_COPY(parv[1]);
132 }
133
134 reason = LOCAL_COPY(parv[2]);
135
136 if(invalid_gline(source_p, user, host, reason))
137 return 0;
138
139 /* Not enough non-wild characters were found, assume they are trying to gline *@*. */
140 if(check_wild_gline(user, host))
141 {
142 if(MyClient(source_p))
5366977b 143 sendto_one_notice(source_p,
144 ":Please include at least %d non-wildcard characters with the user@host",
212380e3 145 ConfigFileEntry.min_nonwildcard);
146 return 0;
147 }
148
149 if((ptr = strchr(host, '/')) != NULL)
150 {
151 int bitlen;
152 bitlen = strtol(++ptr, NULL, 10);
153
154 /* ipv4? */
155 if(strchr(host, ':') == NULL)
156 {
157 if(bitlen < ConfigFileEntry.gline_min_cidr)
158 {
5366977b 159 sendto_one_notice(source_p, ":Cannot set G-Lines with cidr length < %d",
212380e3 160 ConfigFileEntry.gline_min_cidr);
161 return 0;
162 }
163 }
164 /* ipv6 */
165 else if(bitlen < ConfigFileEntry.gline_min_cidr6)
166 {
5366977b 167 sendto_one_notice(source_p, ":Cannot set G-Lines with cidr length < %d",
212380e3 168 ConfigFileEntry.gline_min_cidr6);
169 return 0;
170 }
171 }
172
173 /* inform users about the gline before we call majority_gline()
174 * so already voted comes below gline request --fl
175 */
176 sendto_realops_snomask(SNO_GENERAL, L_ALL,
177 "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
178 source_p->name, source_p->username,
179 source_p->host, me.name, user, host, reason);
180 ilog(L_GLINE, "R %s %s %s %s %s %s %s",
181 source_p->name, source_p->username, source_p->host,
c88cdb00 182 source_p->servptr->name, user, host, reason);
212380e3 183
184 /* If at least 3 opers agree this user should be G lined then do it */
185 majority_gline(source_p, user, host, reason);
186
187 /* 4 param version for hyb-7 servers */
188 sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
189 ":%s GLINE %s %s :%s",
190 use_id(source_p), user, host, reason);
191 sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
192 ":%s GLINE %s %s :%s",
193 source_p->name, user, host, reason);
194
195 /* 8 param for hyb-6 */
196 sendto_server(NULL, NULL, NOCAPS, CAP_GLN,
197 ":%s GLINE %s %s %s %s %s %s :%s",
198 me.name, source_p->name, source_p->username,
c88cdb00 199 source_p->host, source_p->servptr->name,
212380e3 200 user, host, reason);
201 return 0;
202}
203
204/* mc_gline()
205 */
206static int
207mc_gline(struct Client *client_p, struct Client *source_p,
208 int parc, const char *parv[])
209{
210 struct Client *acptr;
211 const char *user;
212 const char *host;
213 char *reason;
214 char *ptr;
215
216 /* hyb6 allows empty gline reasons */
217 if(parc < 4 || EmptyString(parv[3]))
218 return 0;
219
220 acptr = source_p;
221
222 user = parv[1];
223 host = parv[2];
224 reason = LOCAL_COPY(parv[3]);
225
226 if(invalid_gline(acptr, user, host, reason))
227 return 0;
228
229 sendto_server(client_p, NULL, CAP_GLN|CAP_TS6, NOCAPS,
230 ":%s GLINE %s %s :%s",
231 use_id(acptr), user, host, reason);
232 sendto_server(client_p, NULL, CAP_GLN, CAP_TS6,
233 ":%s GLINE %s %s :%s",
234 acptr->name, user, host, reason);
235 sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
236 ":%s GLINE %s %s %s %s %s %s :%s",
c88cdb00 237 acptr->servptr->name, acptr->name,
212380e3 238 acptr->username, acptr->host,
c88cdb00 239 acptr->servptr->name, user, host, reason);
212380e3 240
241 if(!ConfigFileEntry.glines)
242 return 0;
243
244 /* check theres enough non-wildcard chars */
245 if(check_wild_gline(user, host))
246 {
247 sendto_realops_snomask(SNO_GENERAL, L_ALL,
248 "%s!%s@%s on %s is requesting a gline without "
249 "%d non-wildcard characters for [%s@%s] [%s]",
250 acptr->name, acptr->username,
c88cdb00 251 acptr->host, acptr->servptr->name,
212380e3 252 ConfigFileEntry.min_nonwildcard,
253 user, host, reason);
254 return 0;
255 }
256
257 if((ptr = strchr(host, '/')) != NULL)
258 {
259 int bitlen;
260 bitlen = strtol(++ptr, NULL, 10);
261
262 /* ipv4? */
263 if(strchr(host, ':') == NULL)
264 {
265 if(bitlen < ConfigFileEntry.gline_min_cidr)
266 {
267 sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s!%s@%s on %s is requesting a "
268 "gline with a cidr mask < %d for [%s@%s] [%s]",
269 acptr->name, acptr->username, acptr->host,
c88cdb00 270 acptr->servptr->name,
212380e3 271 ConfigFileEntry.gline_min_cidr,
272 user, host, reason);
273 return 0;
274 }
275 }
276 /* ipv6 */
277 else if(bitlen < ConfigFileEntry.gline_min_cidr6)
278 {
279 sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s!%s@%s on %s is requesting a "
280 "gline with a cidr mask < %d for [%s@%s] [%s]",
281 acptr->name, acptr->username, acptr->host,
c88cdb00 282 acptr->servptr->name,
212380e3 283 ConfigFileEntry.gline_min_cidr6,
284 user, host, reason);
285 return 0;
286 }
287 }
288
289
290 sendto_realops_snomask(SNO_GENERAL, L_ALL,
291 "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
292 acptr->name, acptr->username, acptr->host,
c88cdb00 293 acptr->servptr->name, user, host, reason);
212380e3 294
295 ilog(L_GLINE, "R %s %s %s %s %s %s %s",
296 source_p->name, source_p->username, source_p->host,
c88cdb00 297 source_p->servptr->name, user, host, reason);
212380e3 298
299 /* If at least 3 opers agree this user should be G lined then do it */
300 majority_gline(acptr, user, host, reason);
301
302 return 0;
303}
304
305
306/* ms_gline()
307 *
308 * inputs - The usual for a m_ function
309 * output -
310 * side effects - attempts to place a gline, if 3 opers agree
311 */
312static int
313ms_gline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
314{
315 struct Client *acptr;
316 const char *user;
317 const char *host;
318 char *reason;
319
320 /* hyb6 allows empty gline reasons */
321 if(parc < 8 || EmptyString(parv[7]))
322 return 0;
323
324 /* client doesnt exist.. someones messing */
325 if((acptr = find_client(parv[1])) == NULL)
326 return 0;
327
328 /* client that sent the gline, isnt on the server that sent
329 * the gline out. somethings fucked.
330 */
331 if(acptr->servptr != source_p)
332 return 0;
333
334 user = parv[5];
335 host = parv[6];
336 reason = LOCAL_COPY(parv[7]);
337
338 if(invalid_gline(acptr, user, host, reason))
339 return 0;
340
341 sendto_server(client_p, NULL, CAP_GLN|CAP_TS6, NOCAPS,
342 ":%s GLINE %s %s :%s",
343 use_id(acptr), user, host, reason);
344 sendto_server(client_p, NULL, CAP_GLN, CAP_TS6,
345 ":%s GLINE %s %s :%s",
346 acptr->name, user, host, reason);
347 sendto_server(client_p, NULL, NOCAPS, CAP_GLN,
348 ":%s GLINE %s %s %s %s %s %s :%s",
c88cdb00 349 acptr->servptr->name, acptr->name,
212380e3 350 acptr->username, acptr->host,
c88cdb00 351 acptr->servptr->name, user, host, reason);
212380e3 352
353 if(!ConfigFileEntry.glines)
354 return 0;
355
356 /* check theres enough non-wildcard chars */
357 if(check_wild_gline(user, host))
358 {
359 sendto_realops_snomask(SNO_GENERAL, L_ALL,
360 "%s!%s@%s on %s is requesting a gline without "
361 "%d non-wildcard characters for [%s@%s] [%s]",
362 acptr->name, acptr->username,
c88cdb00 363 acptr->host, acptr->servptr->name,
212380e3 364 ConfigFileEntry.min_nonwildcard,
365 user, host, reason);
366 return 0;
367 }
368
369 sendto_realops_snomask(SNO_GENERAL, L_ALL,
370 "%s!%s@%s on %s is requesting gline for [%s@%s] [%s]",
371 acptr->name, acptr->username, acptr->host,
c88cdb00 372 acptr->servptr->name, user, host, reason);
212380e3 373
374 ilog(L_GLINE, "R %s %s %s %s %s %s %s",
375 acptr->name, acptr->username, acptr->host,
c88cdb00 376 acptr->servptr->name, user, host, reason);
212380e3 377
378 /* If at least 3 opers agree this user should be G lined then do it */
379 majority_gline(acptr, user, host, reason);
380
381 return 0;
382}
383
384/* mo_ungline()
385 *
386 * parv[0] = sender nick
387 * parv[1] = gline to remove
388 */
389static int
390mo_ungline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
391{
392 const char *user;
393 char *h = LOCAL_COPY(parv[1]);
394 char *host;
395 char splat[] = "*";
396
397 if(!ConfigFileEntry.glines)
398 {
5366977b 399 sendto_one_notice(source_p, ":UNGLINE disabled, perhaps you want UNKLINE?");
212380e3 400 return 0;
401 }
402
403 if(!IsOperUnkline(source_p) || !IsOperGline(source_p))
404 {
405 sendto_one(source_p, form_str(ERR_NOPRIVS),
406 me.name, source_p->name, "unkline");
407 return 0;
408 }
409
410 if((host = strchr(h, '@')) || *h == '*')
411 {
412 /* Explicit user@host mask given */
413
414 if(host)
415 {
416 *host++ = '\0';
417
418 /* check for @host */
419 if(*h)
420 user = h;
421 else
422 user = splat;
423
424 if(!*host)
425 host = splat;
426 }
427 else
428 {
429 user = splat;
430 host = h;
431 }
432 }
433 else
434 {
5366977b 435 sendto_one_notice(source_p, ":Invalid parameters");
212380e3 436 return 0;
437 }
438
439 if(remove_temp_gline(user, host))
440 {
5366977b 441 sendto_one_notice(source_p, ":Un-glined [%s@%s]", user, host);
212380e3 442 sendto_realops_snomask(SNO_GENERAL, L_ALL,
443 "%s has removed the G-Line for: [%s@%s]",
444 get_oper_name(source_p), user, host);
445 ilog(L_GLINE, "U %s %s %s %s %s %s",
446 source_p->name, source_p->username, source_p->host,
c88cdb00 447 source_p->servptr->name, user, host);
212380e3 448 }
449 else
450 {
5366977b 451 sendto_one_notice(source_p, ":No G-Line for %s@%s", user, host);
212380e3 452 }
453
454 return 0;
455}
456
457/*
458 * check_wild_gline
459 *
460 * inputs - user, host of gline
461 * output - 1 if not enough non-wildchar char's, 0 if ok
462 * side effects - NONE
463 */
464static int
465check_wild_gline(const char *user, const char *host)
466{
467 const char *p;
468 char tmpch;
469 int nonwild;
470
471 nonwild = 0;
472 p = user;
473
474 while ((tmpch = *p++))
475 {
476 if(!IsKWildChar(tmpch))
477 {
478 /* enough of them, break */
479 if(++nonwild >= ConfigFileEntry.min_nonwildcard)
480 break;
481 }
482 }
483
484 if(nonwild < ConfigFileEntry.min_nonwildcard)
485 {
486 /* user doesnt, try host */
487 p = host;
488 while ((tmpch = *p++))
489 {
490 if(!IsKWildChar(tmpch))
491 if(++nonwild >= ConfigFileEntry.min_nonwildcard)
492 break;
493 }
494 }
495
496 if(nonwild < ConfigFileEntry.min_nonwildcard)
497 return 1;
498 else
499 return 0;
500}
501
502/* invalid_gline
503 *
504 * inputs - pointer to source client, ident, host and reason
505 * outputs - 1 if invalid, 0 if valid
506 * side effects -
507 */
508static int
509invalid_gline(struct Client *source_p, const char *luser,
510 const char *lhost, char *lreason)
511{
512 if(strchr(luser, '!'))
513 {
5366977b 514 sendto_one_notice(source_p, ":Invalid character '!' in gline");
212380e3 515 return 1;
516 }
517
61569b65 518 if(strlen(lreason) > BANREASONLEN)
519 lreason[BANREASONLEN] = '\0';
212380e3 520
521 return 0;
522}
523
524/*
525 * set_local_gline
526 *
527 * inputs - pointer to oper nick/username/host/server,
528 * victim user/host and reason
529 * output - NONE
530 * side effects -
531 */
532static void
533set_local_gline(struct Client *source_p, const char *user,
534 const char *host, const char *reason)
535{
536 char buffer[IRCD_BUFSIZE];
537 struct ConfItem *aconf;
538 const char *current_date;
539 char *my_reason;
540 char *oper_reason;
541
542 current_date = smalldate();
543
544 my_reason = LOCAL_COPY(reason);
545
546 aconf = make_conf();
547 aconf->status = CONF_GLINE;
548 aconf->flags |= CONF_FLAGS_TEMPORARY;
549
61569b65 550 if(strlen(my_reason) > BANREASONLEN)
551 my_reason[BANREASONLEN-1] = '\0';
212380e3 552
553 if((oper_reason = strchr(my_reason, '|')) != NULL)
554 {
555 *oper_reason = '\0';
556 oper_reason++;
557
558 if(!EmptyString(oper_reason))
559 DupString(aconf->spasswd, oper_reason);
560 }
561
562 ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
563
564 DupString(aconf->passwd, buffer);
565 DupString(aconf->user, user);
566 DupString(aconf->host, host);
567 aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
568 add_gline(aconf);
569
570 sendto_realops_snomask(SNO_GENERAL, L_ALL,
571 "%s!%s@%s on %s has triggered gline for [%s@%s] [%s]",
572 source_p->name, source_p->username,
c88cdb00 573 source_p->host, source_p->servptr->name,
212380e3 574 user, host, reason);
575 ilog(L_GLINE, "T %s %s %s %s %s %s %s",
576 source_p->name, source_p->username, source_p->host,
c88cdb00 577 source_p->servptr->name, user, host, reason);
212380e3 578
579 check_glines();
580}
581
582/* majority_gline()
583 *
584 * input - client doing gline, user, host and reason of gline
585 * output - YES if there are 3 different opers/servers agree, else NO
586 * side effects -
587 */
588static int
589majority_gline(struct Client *source_p, const char *user,
590 const char *host, const char *reason)
591{
08d11e34 592 rb_dlink_node *pending_node;
212380e3 593 struct gline_pending *pending;
594
595 /* to avoid desync.. --fl */
596 cleanup_glines(NULL);
597
598 /* if its already glined, why bother? :) -- fl_ */
599 if(find_is_glined(host, user))
600 return NO;
601
08d11e34 602 RB_DLINK_FOREACH(pending_node, pending_glines.head)
212380e3 603 {
604 pending = pending_node->data;
605
606 if((irccmp(pending->user, user) == 0) &&
607 (irccmp(pending->host, host) == 0))
608 {
609 /* check oper or server hasnt already voted */
610 if(((irccmp(pending->oper_user1, source_p->username) == 0) ||
611 (irccmp(pending->oper_host1, source_p->host) == 0)))
612 {
613 sendto_realops_snomask(SNO_GENERAL, L_ALL, "oper has already voted");
614 return NO;
615 }
c88cdb00 616 else if(irccmp(pending->oper_server1, source_p->servptr->name) == 0)
212380e3 617 {
618 sendto_realops_snomask(SNO_GENERAL, L_ALL, "server has already voted");
619 return NO;
620 }
621
622 if(pending->oper_user2[0] != '\0')
623 {
624 /* if two other opers on two different servers have voted yes */
625 if(((irccmp(pending->oper_user2, source_p->username) == 0) ||
626 (irccmp(pending->oper_host2, source_p->host) == 0)))
627 {
628 sendto_realops_snomask(SNO_GENERAL, L_ALL,
629 "oper has already voted");
630 return NO;
631 }
c88cdb00 632 else if(irccmp(pending->oper_server2, source_p->servptr->name) == 0)
212380e3 633 {
634 sendto_realops_snomask(SNO_GENERAL, L_ALL,
635 "server has already voted");
636 return NO;
637 }
638
639 /* trigger the gline using the original reason --fl */
640 set_local_gline(source_p, user, host,
641 pending->reason1);
642
643 cleanup_glines(NULL);
644 return YES;
645 }
646 else
647 {
648 strlcpy(pending->oper_nick2, source_p->name,
649 sizeof(pending->oper_nick2));
650 strlcpy(pending->oper_user2, source_p->username,
651 sizeof(pending->oper_user2));
652 strlcpy(pending->oper_host2, source_p->host,
653 sizeof(pending->oper_host2));
654 DupString(pending->reason2, reason);
994544c2 655 pending->oper_server2 = scache_get_name(source_p->servptr->serv->nameinfo);
212380e3 656 pending->last_gline_time = CurrentTime;
657 pending->time_request2 = CurrentTime;
658 return NO;
659 }
660 }
661 }
662
663 /* no pending gline, create a new one */
664 pending = (struct gline_pending *)
665 MyMalloc(sizeof(struct gline_pending));
666
667 strlcpy(pending->oper_nick1, source_p->name,
668 sizeof(pending->oper_nick1));
669 strlcpy(pending->oper_user1, source_p->username,
670 sizeof(pending->oper_user1));
671 strlcpy(pending->oper_host1, source_p->host,
672 sizeof(pending->oper_host1));
673
994544c2 674 pending->oper_server1 = scache_get_name(source_p->servptr->serv->nameinfo);
212380e3 675
676 strlcpy(pending->user, user, sizeof(pending->user));
677 strlcpy(pending->host, host, sizeof(pending->host));
678 DupString(pending->reason1, reason);
679 pending->reason2 = NULL;
680
681 pending->last_gline_time = CurrentTime;
682 pending->time_request1 = CurrentTime;
683
684 dlinkAddAlloc(pending, &pending_glines);
685
686 return NO;
687}
688
689/* remove_temp_gline()
690 *
691 * inputs - username, hostname to ungline
692 * outputs -
693 * side effects - tries to ungline anything that matches
694 */
695static int
696remove_temp_gline(const char *user, const char *host)
697{
698 struct ConfItem *aconf;
08d11e34 699 rb_dlink_node *ptr;
212380e3 700 struct irc_sockaddr_storage addr, caddr;
701 int bits, cbits;
702 int mtype, gtype;
703
704 mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits);
705
08d11e34 706 RB_DLINK_FOREACH(ptr, glines.head)
212380e3 707 {
708 aconf = ptr->data;
709
710 gtype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
711
712 if(gtype != mtype || (user && irccmp(user, aconf->user)))
713 continue;
714
715 if(gtype == HM_HOST)
716 {
717 if(irccmp(aconf->host, host))
718 continue;
719 }
720 else if(bits != cbits ||
721 !comp_with_mask_sock((struct sockaddr *)&addr,
722 (struct sockaddr *)&caddr, bits))
723 continue;
724
725 dlinkDestroy(ptr, &glines);
35f6f850 726 remove_reject_mask(aconf->user, aconf->host);
212380e3 727 delete_one_address_conf(aconf->host, aconf);
728 return YES;
729 }
730
731 return NO;
732}