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