]> jfr.im git - solanum.git/blame - ircd/hostmask.c
Replace most checks for +o with oper:general
[solanum.git] / ircd / hostmask.c
CommitLineData
212380e3
AC
1/*
2 * charybdis: an advanced internet relay chat daemon (ircd).
3 * hostmask.c: Code to efficiently find IP & hostmask based configs.
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
05ee179e 8 * Copyright (C) 2005-2008 charybdis development team
212380e3
AC
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
212380e3
AC
24 */
25
26#include "stdinc.h"
212380e3
AC
27#include "ircd_defs.h"
28#include "s_conf.h"
d4f7eb4c 29#include "s_newconf.h"
212380e3
AC
30#include "hostmask.h"
31#include "numeric.h"
32#include "send.h"
4562c604 33#include "match.h"
212380e3 34
212380e3 35static unsigned long hash_ipv6(struct sockaddr *, int);
212380e3
AC
36static unsigned long hash_ipv4(struct sockaddr *, int);
37
38
e7046ee5 39/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *);
212380e3
AC
40 * Input: A hostmask, or an IPV4/6 address.
41 * Output: An integer describing whether it is an IPV4, IPV6 address or a
42 * hostmask, an address(if it is an IP mask),
43 * a bitlength(if it is IP mask).
44 * Side effects: None
45 */
46int
29c92cf9 47parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb)
212380e3
AC
48{
49 char *ip = LOCAL_COPY(text);
50 char *ptr;
e7046ee5 51 struct rb_sockaddr_storage *addr, xaddr;
212380e3
AC
52 int *b, xb;
53 if(nb == NULL)
54 b = &xb;
55 else
56 b = nb;
55abcbb2 57
212380e3 58 if(naddr == NULL)
29c92cf9 59 addr = &xaddr;
212380e3 60 else
29c92cf9 61 addr = naddr;
17e4b48b
JT
62
63 if(strpbrk(ip, "*?") != NULL)
64 {
65 return HM_HOST;
66 }
212380e3 67 if(strchr(ip, ':'))
55abcbb2 68 {
212380e3
AC
69 if((ptr = strchr(ip, '/')))
70 {
71 *ptr = '\0';
72 ptr++;
73 *b = atoi(ptr);
74 if(*b > 128)
75 *b = 128;
4e4a5fcc
JT
76 else if(*b < 0)
77 return HM_HOST;
212380e3
AC
78 } else
79 *b = 128;
17809d2d 80 if(rb_inet_pton_sock(ip, addr) > 0)
212380e3
AC
81 return HM_IPV6;
82 else
83 return HM_HOST;
84 } else
212380e3
AC
85 if(strchr(text, '.'))
86 {
87 if((ptr = strchr(ip, '/')))
88 {
89 *ptr = '\0';
90 ptr++;
91 *b = atoi(ptr);
92 if(*b > 32)
93 *b = 32;
4e4a5fcc
JT
94 else if(*b < 0)
95 return HM_HOST;
212380e3
AC
96 } else
97 *b = 32;
17809d2d 98 if(rb_inet_pton_sock(ip, addr) > 0)
212380e3
AC
99 return HM_IPV4;
100 else
101 return HM_HOST;
102 }
103 return HM_HOST;
104}
105
106/* Hashtable stuff...now external as its used in m_stats.c */
107struct AddressRec *atable[ATABLE_SIZE];
108
109void
110init_host_hash(void)
111{
112 memset(&atable, 0, sizeof(atable));
113}
114
e7046ee5 115/* unsigned long hash_ipv4(struct rb_sockaddr_storage*)
212380e3
AC
116 * Input: An IP address.
117 * Output: A hash value of the IP address.
118 * Side effects: None
119 */
120static unsigned long
121hash_ipv4(struct sockaddr *saddr, int bits)
122{
29c92cf9 123 struct sockaddr_in *addr = (struct sockaddr_in *)(void *)saddr;
55abcbb2 124
212380e3
AC
125 if(bits != 0)
126 {
127 unsigned long av = ntohl(addr->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
128 return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
129 }
130
131 return 0;
132}
133
e7046ee5 134/* unsigned long hash_ipv6(struct rb_sockaddr_storage*)
212380e3
AC
135 * Input: An IP address.
136 * Output: A hash value of the IP address.
137 * Side effects: None
138 */
212380e3
AC
139static unsigned long
140hash_ipv6(struct sockaddr *saddr, int bits)
141{
29c92cf9 142 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)saddr;
212380e3
AC
143 unsigned long v = 0, n;
144 for (n = 0; n < 16; n++)
145 {
146 if(bits >= 8)
147 {
148 v ^= addr->sin6_addr.s6_addr[n];
149 bits -= 8;
150 }
151 else if(bits)
152 {
153 v ^= addr->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
154 return v & (ATABLE_SIZE - 1);
155 }
156 else
157 return v & (ATABLE_SIZE - 1);
158 }
159 return v & (ATABLE_SIZE - 1);
160}
212380e3
AC
161
162/* int hash_text(const char *start)
163 * Input: The start of the text to hash.
164 * Output: The hash of the string between 1 and (TH_MAX-1)
165 * Side-effects: None.
166 */
167static int
168hash_text(const char *start)
169{
170 const char *p = start;
171 unsigned long h = 0;
172
173 while(*p)
174 {
7e6b5384 175 h = (h << 4) - (h + (unsigned char) irctolower(*p++));
212380e3
AC
176 }
177
178 return (h & (ATABLE_SIZE - 1));
179}
180
181/* unsigned long get_hash_mask(const char *)
182 * Input: The text to hash.
183 * Output: The hash of the string right of the first '.' past the last
184 * wildcard in the string.
185 * Side-effects: None.
186 */
187static unsigned long
188get_mask_hash(const char *text)
189{
190 const char *hp = "", *p;
191
192 for (p = text + strlen(text) - 1; p >= text; p--)
193 if(*p == '*' || *p == '?')
194 return hash_text(hp);
195 else if(*p == '.')
196 hp = p + 1;
197 return hash_text(text);
198}
199
e7046ee5 200/* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*,
212380e3 201 * int type, int fam, const char *username)
b18dba6d
SA
202 *
203 * This process needs to be kept in sync with check_one_kline().
204 *
212380e3
AC
205 * Input: The hostname, the address, the type of mask to find, the address
206 * family, the username.
207 * Output: The matching value with the highest precedence.
208 * Side-effects: None
209 * Note: Setting bit 0 of the type means that the username is ignored.
210 */
211struct ConfItem *
212find_conf_by_address(const char *name, const char *sockhost,
213 const char *orighost,
55abcbb2 214 struct sockaddr *addr, int type, int fam,
40c1fd47 215 const char *username, const char *auth_user)
212380e3
AC
216{
217 unsigned long hprecv = 0;
218 struct ConfItem *hprec = NULL;
219 struct AddressRec *arec;
de0673d7
EK
220 struct sockaddr_in ip4;
221 struct sockaddr *pip4 = NULL;
212380e3
AC
222 int b;
223
224 if(username == NULL)
225 username = "";
226
227 if(addr)
228 {
de0673d7
EK
229 if (fam == AF_INET)
230 pip4 = addr;
231
232 if (fam == AF_INET6)
212380e3 233 {
de0673d7
EK
234 if (type == CONF_KILL && rb_ipv4_from_ipv6((struct sockaddr_in6 *)addr, &ip4))
235 pip4 = (struct sockaddr *)&ip4;
212380e3
AC
236
237 for (b = 128; b >= 0; b -= 16)
238 {
239 for (arec = atable[hash_ipv6(addr, b)]; arec; arec = arec->next)
240 if(arec->type == (type & ~0x1) &&
241 arec->masktype == HM_IPV6 &&
242 comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
55abcbb2
KB
243 arec->Mask.ipa.bits) &&
244 (type & 0x1 || match(arec-> username, username)) &&
245 (type != CONF_CLIENT || !arec->auth_user ||
246 (auth_user && match(arec->auth_user, auth_user))) &&
247 arec->precedence > hprecv)
212380e3
AC
248 {
249 hprecv = arec->precedence;
250 hprec = arec->aconf;
251 }
252 }
253 }
de0673d7
EK
254
255 if (pip4 != NULL)
212380e3
AC
256 {
257 for (b = 32; b >= 0; b -= 8)
258 {
de0673d7 259 for (arec = atable[hash_ipv4(pip4, b)]; arec; arec = arec->next)
212380e3
AC
260 if(arec->type == (type & ~0x1) &&
261 arec->masktype == HM_IPV4 &&
de0673d7 262 comp_with_mask_sock(pip4, (struct sockaddr *)&arec->Mask.ipa.addr,
55abcbb2
KB
263 arec->Mask.ipa.bits) &&
264 (type & 0x1 || match(arec->username, username)) &&
265 (type != CONF_CLIENT || !arec->auth_user ||
266 (auth_user && match(arec->auth_user, auth_user))) &&
267 arec->precedence > hprecv)
212380e3
AC
268 {
269 hprecv = arec->precedence;
270 hprec = arec->aconf;
271 }
272 }
273 }
274 }
275
276 if(orighost != NULL)
277 {
278 const char *p;
279
280 for (p = orighost; p != NULL;)
281 {
282 for (arec = atable[hash_text(p)]; arec; arec = arec->next)
55abcbb2 283
212380e3
AC
284 if((arec->type == (type & ~0x1)) &&
285 (arec->masktype == HM_HOST) &&
286 arec->precedence > hprecv &&
287 match(arec->Mask.hostname, orighost) &&
55abcbb2
KB
288 (type != CONF_CLIENT || !arec->auth_user ||
289 (auth_user && match(arec->auth_user, auth_user))) &&
212380e3
AC
290 (type & 0x1 || match(arec->username, username)))
291 {
292 hprecv = arec->precedence;
293 hprec = arec->aconf;
294 }
295 p = strchr(p, '.');
296 if(p != NULL)
297 p++;
298 else
299 break;
300 }
301 for (arec = atable[0]; arec; arec = arec->next)
302 {
303 if(arec->type == (type & ~0x1) &&
304 arec->masktype == HM_HOST &&
55abcbb2 305 arec->precedence > hprecv &&
212380e3
AC
306 (match(arec->Mask.hostname, orighost) ||
307 (sockhost && match(arec->Mask.hostname, sockhost))) &&
55abcbb2
KB
308 (type != CONF_CLIENT || !arec->auth_user ||
309 (auth_user && match(arec->auth_user, auth_user))) &&
212380e3
AC
310 (type & 0x1 || match(arec->username, username)))
311 {
312 hprecv = arec->precedence;
313 hprec = arec->aconf;
314 }
315 }
316 }
317
318 if(name != NULL)
319 {
320 const char *p;
321 /* And yes - we have to check p after strchr and p after increment for
322 * NULL -kre */
323 for (p = name; p != NULL;)
324 {
325 for (arec = atable[hash_text(p)]; arec; arec = arec->next)
326 if((arec->type == (type & ~0x1)) &&
327 (arec->masktype == HM_HOST) &&
328 arec->precedence > hprecv &&
329 match(arec->Mask.hostname, name) &&
55abcbb2
KB
330 (type != CONF_CLIENT || !arec->auth_user ||
331 (auth_user && match(arec->auth_user, auth_user))) &&
212380e3
AC
332 (type & 0x1 || match(arec->username, username)))
333 {
334 hprecv = arec->precedence;
335 hprec = arec->aconf;
336 }
337 p = strchr(p, '.');
338 if(p != NULL)
339 p++;
340 else
341 break;
342 }
343 for (arec = atable[0]; arec; arec = arec->next)
344 {
345 if(arec->type == (type & ~0x1) &&
346 arec->masktype == HM_HOST &&
55abcbb2 347 arec->precedence > hprecv &&
212380e3
AC
348 (match(arec->Mask.hostname, name) ||
349 (sockhost && match(arec->Mask.hostname, sockhost))) &&
55abcbb2
KB
350 (type != CONF_CLIENT || !arec->auth_user ||
351 (auth_user && match(arec->auth_user, auth_user))) &&
212380e3
AC
352 (type & 0x1 || match(arec->username, username)))
353 {
354 hprecv = arec->precedence;
355 hprec = arec->aconf;
356 }
357 }
358 }
359 return hprec;
360}
361
362/* struct ConfItem* find_address_conf(const char*, const char*,
e7046ee5 363 * struct rb_sockaddr_storage*, int);
212380e3
AC
364 * Input: The hostname, username, address, address family.
365 * Output: The applicable ConfItem.
366 * Side-effects: None
367 */
368struct ConfItem *
55abcbb2 369find_address_conf(const char *host, const char *sockhost, const char *user,
40c1fd47 370 const char *notildeuser, struct sockaddr *ip, int aftype, char *auth_user)
212380e3
AC
371{
372 struct ConfItem *iconf, *kconf;
373 const char *vuser;
374
375 /* Find the best I-line... If none, return NULL -A1kmm */
40c1fd47 376 if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user, auth_user)))
212380e3
AC
377 return NULL;
378 /* Find what their visible username will be.
379 * Note that the username without tilde may contain one char more.
380 * -- jilles */
381 vuser = IsNoTilde(iconf) ? notildeuser : user;
382
383 /* If they are exempt from K-lines, return the best I-line. -A1kmm */
384 if(IsConfExemptKline(iconf))
385 return iconf;
386
212380e3
AC
387 /* if theres a spoof, check it against klines.. */
388 if(IsConfDoSpoofIp(iconf))
389 {
27f616dd 390 char *p = strchr(iconf->info.name, '@');
212380e3
AC
391
392 /* note, we dont need to pass sockhost here, as its
67e05d5b 393 * guaranteed to not match by whats below.. --anfl
212380e3
AC
394 */
395 if(p)
396 {
397 *p = '\0';
67e05d5b 398 kconf = find_conf_by_address(p+1, NULL, NULL, NULL, CONF_KILL, aftype, iconf->info.name, NULL);
212380e3
AC
399 *p = '@';
400 }
401 else
67e05d5b 402 kconf = find_conf_by_address(iconf->info.name, NULL, NULL, NULL, CONF_KILL, aftype, vuser, NULL);
212380e3
AC
403
404 if(kconf)
405 return kconf;
67e05d5b
EK
406
407 /* everything else checks real hosts, if they're kline_spoof_ip we're done */
408 if(IsConfKlineSpoof(iconf))
409 return iconf;
212380e3
AC
410 }
411
67e05d5b
EK
412 /* Find the best K-line... -A1kmm */
413 kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL);
414
415 /* If they are K-lined, return the K-line */
416 if(kconf)
417 return kconf;
418
212380e3
AC
419 /* if no_tilde, check the username without tilde against klines too
420 * -- jilles */
421 if(user != vuser)
422 {
40c1fd47 423 kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser, NULL);
212380e3
AC
424 if(kconf)
425 return kconf;
426 }
427
212380e3
AC
428 return iconf;
429}
430
e7046ee5 431/* struct ConfItem* find_dline(struct rb_sockaddr_storage*, int)
54ac8b60
VY
432 * Input: An address, an address family.
433 * Output: The best matching D-line or exempt line.
434 * Side effects: None.
435 */
436struct ConfItem *
437find_dline(struct sockaddr *addr, int aftype)
438{
d006b551 439 struct ConfItem *aconf;
d006b551 440 struct sockaddr_in addr2;
d006b551
JT
441
442 aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL);
443 if(aconf)
444 return aconf;
445 aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL);
446 if(aconf)
447 return aconf;
d006b551 448 if(addr->sa_family == AF_INET6 &&
4eafa9e6 449 rb_ipv4_from_ipv6((const struct sockaddr_in6 *)(const void *)addr, &addr2))
d006b551
JT
450 {
451 aconf = find_conf_by_address(NULL, NULL, NULL, (struct sockaddr *)&addr2, CONF_DLINE | 1, AF_INET, NULL, NULL);
452 if(aconf)
453 return aconf;
454 }
d006b551 455 return NULL;
54ac8b60
VY
456}
457
6f3a09ff 458/* void find_exact_conf_by_address(const char*, int, const char *)
55abcbb2 459 * Input:
4e0f14a0
JT
460 * Output: ConfItem if found
461 * Side-effects: None
462 */
463struct ConfItem *
464find_exact_conf_by_address(const char *address, int type, const char *username)
465{
466 int masktype, bits;
467 unsigned long hv;
468 struct AddressRec *arec;
e7046ee5 469 struct rb_sockaddr_storage addr;
4e0f14a0
JT
470
471 if(address == NULL)
472 address = "/NOMATCH!/";
29c92cf9 473 masktype = parse_netmask(address, &addr, &bits);
4e0f14a0
JT
474 if(masktype == HM_IPV6)
475 {
476 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
477 hv = hash_ipv6((struct sockaddr *)&addr, bits - bits % 16);
478 }
de293496 479 else if(masktype == HM_IPV4)
4e0f14a0
JT
480 {
481 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
482 hv = hash_ipv4((struct sockaddr *)&addr, bits - bits % 8);
483 }
484 else
485 {
486 hv = get_mask_hash(address);
487 }
488 for (arec = atable[hv]; arec; arec = arec->next)
489 {
490 if (arec->type == type &&
491 arec->masktype == masktype &&
6f3a09ff 492 (arec->username == NULL || username == NULL ? arec->username == username : !irccmp(arec->username, username)))
4e0f14a0
JT
493 {
494 if (masktype == HM_HOST)
495 {
496 if (!irccmp(arec->Mask.hostname, address))
497 return arec->aconf;
498 }
499 else
500 {
501 if (arec->Mask.ipa.bits == bits &&
502 comp_with_mask_sock((struct sockaddr *)&arec->Mask.ipa.addr, (struct sockaddr *)&addr, bits))
503 return arec->aconf;
504 }
505 }
506 }
507 return NULL;
508}
509
212380e3
AC
510/* void add_conf_by_address(const char*, int, const char *,
511 * struct ConfItem *aconf)
55abcbb2 512 * Input:
212380e3
AC
513 * Output: None
514 * Side-effects: Adds this entry to the hash table.
515 */
516void
40c1fd47 517add_conf_by_address(const char *address, int type, const char *username, const char *auth_user, struct ConfItem *aconf)
212380e3
AC
518{
519 static unsigned long prec_value = 0xFFFFFFFF;
ab5fc9c0 520 int bits;
212380e3
AC
521 unsigned long hv;
522 struct AddressRec *arec;
523
524 if(address == NULL)
525 address = "/NOMATCH!/";
eddc2ab6 526 arec = rb_malloc(sizeof(struct AddressRec));
ab5fc9c0 527 arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
ab5fc9c0 528 if(arec->masktype == HM_IPV6)
212380e3 529 {
ab5fc9c0 530 arec->Mask.ipa.bits = bits;
212380e3
AC
531 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
532 bits -= bits % 16;
533 arec->next = atable[(hv = hash_ipv6((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
534 atable[hv] = arec;
535 }
de293496 536 else if(arec->masktype == HM_IPV4)
212380e3 537 {
ab5fc9c0 538 arec->Mask.ipa.bits = bits;
212380e3
AC
539 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
540 bits -= bits % 8;
541 arec->next = atable[(hv = hash_ipv4((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
542 atable[hv] = arec;
543 }
544 else
545 {
546 arec->Mask.hostname = address;
547 arec->next = atable[(hv = get_mask_hash(address))];
548 atable[hv] = arec;
549 }
550 arec->username = username;
40c1fd47 551 arec->auth_user = auth_user;
212380e3
AC
552 arec->aconf = aconf;
553 arec->precedence = prec_value--;
554 arec->type = type;
555}
556
557/* void delete_one_address(const char*, struct ConfItem*)
558 * Input: An address string, the associated ConfItem.
559 * Output: None
560 * Side effects: Deletes an address record. Frees the ConfItem if there
561 * is nothing referencing it, sets it as illegal otherwise.
562 */
563void
564delete_one_address_conf(const char *address, struct ConfItem *aconf)
565{
566 int masktype, bits;
567 unsigned long hv;
568 struct AddressRec *arec, *arecl = NULL;
e7046ee5 569 struct rb_sockaddr_storage addr;
29c92cf9 570 masktype = parse_netmask(address, &addr, &bits);
212380e3
AC
571 if(masktype == HM_IPV6)
572 {
573 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
574 bits -= bits % 16;
575 hv = hash_ipv6((struct sockaddr *)&addr, bits);
576 }
de293496 577 else if(masktype == HM_IPV4)
212380e3
AC
578 {
579 /* We have to do this, since we do not re-hash for every bit -A1kmm. */
580 bits -= bits % 8;
581 hv = hash_ipv4((struct sockaddr *)&addr, bits);
582 }
583 else
584 hv = get_mask_hash(address);
585 for (arec = atable[hv]; arec; arec = arec->next)
586 {
587 if(arec->aconf == aconf)
588 {
589 if(arecl)
590 arecl->next = arec->next;
591 else
592 atable[hv] = arec->next;
593 aconf->status |= CONF_ILLEGAL;
594 if(!aconf->clients)
595 free_conf(aconf);
637c4932 596 rb_free(arec);
212380e3
AC
597 return;
598 }
599 arecl = arec;
600 }
601}
602
603/* void clear_out_address_conf(void)
604 * Input: None
605 * Output: None
606 * Side effects: Clears out all address records in the hash table,
607 * frees them, and frees the ConfItems if nothing references
608 * them, otherwise sets them as illegal.
609 */
610void
611clear_out_address_conf(void)
612{
613 int i;
614 struct AddressRec **store_next;
615 struct AddressRec *arec, *arecn;
616
617 for (i = 0; i < ATABLE_SIZE; i++)
618 {
619 store_next = &atable[i];
620 for (arec = atable[i]; arec; arec = arecn)
621 {
622 arecn = arec->next;
623 /* We keep the temporary K-lines and destroy the
624 * permanent ones, just to be confusing :) -A1kmm */
625 if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
626 (arec->type != CONF_CLIENT && arec->type != CONF_EXEMPTDLINE))
627 {
628 *store_next = arec;
629 store_next = &arec->next;
630 }
631 else
632 {
633 arec->aconf->status |= CONF_ILLEGAL;
634 if(!arec->aconf->clients)
635 free_conf(arec->aconf);
637c4932 636 rb_free(arec);
212380e3
AC
637 }
638 }
639 *store_next = NULL;
640 }
641}
642
643void
644clear_out_address_conf_bans(void)
645{
646 int i;
647 struct AddressRec **store_next;
648 struct AddressRec *arec, *arecn;
649
650 for (i = 0; i < ATABLE_SIZE; i++)
651 {
652 store_next = &atable[i];
653 for (arec = atable[i]; arec; arec = arecn)
654 {
655 arecn = arec->next;
656 /* We keep the temporary K-lines and destroy the
657 * permanent ones, just to be confusing :) -A1kmm */
658 if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
659 (arec->type == CONF_CLIENT || arec->type == CONF_EXEMPTDLINE))
660 {
661 *store_next = arec;
662 store_next = &arec->next;
663 }
664 else
665 {
666 arec->aconf->status |= CONF_ILLEGAL;
667 if(!arec->aconf->clients)
668 free_conf(arec->aconf);
637c4932 669 rb_free(arec);
212380e3
AC
670 }
671 }
672 *store_next = NULL;
673 }
674}
675
676
677/*
678 * show_iline_prefix()
679 *
680 * inputs - pointer to struct Client requesting output
55abcbb2 681 * - pointer to struct ConfItem
212380e3
AC
682 * - name to which iline prefix will be prefixed to
683 * output - pointer to static string with prefixes listed in ascii form
684 * side effects - NONE
685 */
686char *
687show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name)
688{
689 static char prefix_of_host[USERLEN + 15];
690 char *prefix_ptr;
691
692 prefix_ptr = prefix_of_host;
693 if(IsNoTilde(aconf))
694 *prefix_ptr++ = '-';
212380e3
AC
695 if(IsNeedIdentd(aconf))
696 *prefix_ptr++ = '+';
212380e3
AC
697 if(IsConfDoSpoofIp(aconf))
698 *prefix_ptr++ = '=';
c4f13a64
JT
699 if(IsOper(sptr) && IsConfExemptFlood(aconf))
700 *prefix_ptr++ = '|';
c4f13a64
JT
701 if(IsOper(sptr) && IsConfExemptDNSBL(aconf) && !IsConfExemptKline(aconf))
702 *prefix_ptr++ = '$';
a63a1eab 703 if(IsOper(sptr) && IsConfExemptKline(aconf))
212380e3 704 *prefix_ptr++ = '^';
a63a1eab 705 if(IsOper(sptr) && IsConfExemptLimits(aconf))
212380e3 706 *prefix_ptr++ = '>';
212380e3
AC
707 *prefix_ptr = '\0';
708 strncpy(prefix_ptr, name, USERLEN);
709 return (prefix_of_host);
710}
711
712/* report_auth()
713 *
714 * Inputs: pointer to client to report to
715 * Output: None
716 * Side effects: Reports configured auth{} blocks to client_p
717 */
718void
719report_auth(struct Client *client_p)
720{
29c92cf9
JB
721 char *name, *host, *user, *classname;
722 const char *pass;
212380e3
AC
723 struct AddressRec *arec;
724 struct ConfItem *aconf;
725 int i, port;
726
727 for (i = 0; i < ATABLE_SIZE; i++)
728 for (arec = atable[i]; arec; arec = arec->next)
729 if(arec->type == CONF_CLIENT)
730 {
731 aconf = arec->aconf;
732
d4f7eb4c 733 if(!IsOperGeneral(client_p) && IsConfDoSpoofIp(aconf))
212380e3
AC
734 continue;
735
736 get_printable_conf(aconf, &name, &host, &pass, &user, &port,
737 &classname);
55abcbb2 738
40c1fd47
VY
739 if(!EmptyString(aconf->spasswd))
740 pass = aconf->spasswd;
212380e3 741
55abcbb2 742 sendto_one_numeric(client_p, RPL_STATSILINE,
212380e3 743 form_str(RPL_STATSILINE),
40c1fd47 744 name, pass, show_iline_prefix(client_p, aconf, user),
212380e3
AC
745 show_ip_conf(aconf, client_p) ? host : "255.255.255.255",
746 port, classname);
747 }
748}
749