00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "memory.h"
00027 #include "ircd_defs.h"
00028 #include "tools.h"
00029 #include "s_conf.h"
00030 #include "hostmask.h"
00031 #include "numeric.h"
00032 #include "send.h"
00033 #include "irc_string.h"
00034
00035 #ifdef IPV6
00036 static int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
00037 static unsigned long hash_ipv6(struct irc_ssaddr *, int);
00038 #endif
00039 static int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
00040 static unsigned long hash_ipv4(struct irc_ssaddr *, int);
00041
00042 #define DigitParse(ch) do { \
00043 if (ch >= '0' && ch <= '9') \
00044 ch = ch - '0'; \
00045 else if (ch >= 'A' && ch <= 'F') \
00046 ch = ch - 'A' + 10; \
00047 else if (ch >= 'a' && ch <= 'f') \
00048 ch = ch - 'a' + 10; \
00049 } while(0);
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifdef IPV6
00065 static int
00066 try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
00067 {
00068 const char *p;
00069 char c;
00070 int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00071 int dp = 0;
00072 int nyble = 4;
00073 int finsert = -1;
00074 int bits = 128;
00075 int deficit = 0;
00076 short dc[8];
00077 struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr;
00078
00079 for (p = text; (c = *p); p++)
00080 if (IsXDigit(c))
00081 {
00082 if (nyble == 0)
00083 return HM_HOST;
00084 DigitParse(c);
00085 d[dp] |= c << (4 * --nyble);
00086 }
00087 else if (c == ':')
00088 {
00089 if (p > text && *(p - 1) == ':')
00090 {
00091 if (finsert >= 0)
00092 return HM_HOST;
00093 finsert = dp;
00094 }
00095 else
00096 {
00097
00098
00099 d[dp] = d[dp] >> 4 * nyble;
00100 nyble = 4;
00101 if (++dp >= 8)
00102 return HM_HOST;
00103 }
00104 }
00105 else if (c == '*')
00106 {
00107
00108 if (finsert >= 0 || *(p + 1) || dp == 0 || *(p - 1) != ':')
00109 return HM_HOST;
00110 bits = dp * 16;
00111 }
00112 else if (c == '/')
00113 {
00114 char *after;
00115
00116 d[dp] = d[dp] >> 4 * nyble;
00117 dp++;
00118 bits = strtoul(p + 1, &after, 10);
00119 if (bits < 0 || *after)
00120 return HM_HOST;
00121 if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
00122 return HM_HOST;
00123 break;
00124 }
00125 else
00126 return HM_HOST;
00127
00128 d[dp] = d[dp] >> 4 * nyble;
00129 if (c == 0)
00130 dp++;
00131 if (finsert < 0 && bits == 0)
00132 bits = dp * 16;
00133
00134 deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
00135
00136 for (dp = 0, nyble = 0; dp < 8; dp++)
00137 {
00138 if (nyble == finsert && deficit)
00139 {
00140 dc[dp] = 0;
00141 deficit--;
00142 }
00143 else
00144 dc[dp] = d[nyble++];
00145 }
00146
00147 if (bits < 128 && (bits % 16 != 0))
00148 dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
00149 for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
00150 dc[dp] = 0;
00151
00152 if (addr)
00153 for (dp = 0; dp < 8; dp++)
00154
00155 ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
00156 if (b != NULL)
00157 *b = bits;
00158 return HM_IPV6;
00159 }
00160 #endif
00161
00162
00163
00164
00165
00166
00167
00168
00169 static int
00170 try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
00171 {
00172 const char *p;
00173 const char *digits[4];
00174 unsigned char addb[4];
00175 int n = 0, bits = 0;
00176 char c;
00177 struct sockaddr_in *v4 = (struct sockaddr_in*) addr;
00178
00179 digits[n++] = text;
00180
00181 for (p = text; (c = *p); p++)
00182 if (c >= '0' && c <= '9')
00183 ;
00184 else if (c == '.')
00185 {
00186 if (n >= 4)
00187 return HM_HOST;
00188 digits[n++] = p + 1;
00189 }
00190 else if (c == '*')
00191 {
00192 if (*(p + 1) || n == 0 || *(p - 1) != '.')
00193 return HM_HOST;
00194 bits = (n - 1) * 8;
00195 break;
00196 }
00197 else if (c == '/')
00198 {
00199 char *after;
00200 bits = strtoul(p + 1, &after, 10);
00201 if (!bits || *after)
00202 return HM_HOST;
00203 if (bits > n * 8)
00204 return HM_HOST;
00205 break;
00206 }
00207 else
00208 return HM_HOST;
00209
00210 if (n < 4 && bits == 0)
00211 bits = n * 8;
00212 if (bits)
00213 while (n < 4)
00214 digits[n++] = "0";
00215 for (n = 0; n < 4; n++)
00216 addb[n] = strtoul(digits[n], NULL, 10);
00217 if (bits == 0)
00218 bits = 32;
00219
00220 if (bits < 32 && bits % 8)
00221 addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
00222 for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
00223 addb[n] = 0;
00224 if (addr)
00225 v4->sin_addr.s_addr =
00226 htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
00227 if (b != NULL)
00228 *b = bits;
00229 return HM_IPV4;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 int
00240 parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
00241 {
00242 #ifdef IPV6
00243 if (strchr(text, ':'))
00244 return try_parse_v6_netmask(text, addr, b);
00245 #endif
00246 if (strchr(text, '.'))
00247 return try_parse_v4_netmask(text, addr, b);
00248 return HM_HOST;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 #ifdef IPV6
00258 int
00259 match_ipv6(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
00260 {
00261 int i, m, n = bits / 8;
00262 struct sockaddr_in6 *v6 = (struct sockaddr_in6*)addr;
00263 struct sockaddr_in6 *v6mask = (struct sockaddr_in6*)mask;
00264
00265 for (i = 0; i < n; i++)
00266 if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
00267 return 0;
00268 if ((m = bits % 8) == 0)
00269 return -1;
00270 if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
00271 v6mask->sin6_addr.s6_addr[n])
00272 return -1;
00273 return 0;
00274 }
00275 #endif
00276
00277
00278
00279
00280
00281 int
00282 match_ipv4(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits)
00283 {
00284 struct sockaddr_in *v4 = (struct sockaddr_in*) addr;
00285 struct sockaddr_in *v4mask = (struct sockaddr_in*) mask;
00286 if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
00287 ntohl(v4mask->sin_addr.s_addr))
00288 return 0;
00289 return -1;
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void
00301 mask_addr(struct irc_ssaddr *ip, int bits)
00302 {
00303 int mask;
00304 #ifdef IPV6
00305 struct sockaddr_in6 *v6_base_ip;
00306 int i, m, n;
00307 #endif
00308 struct sockaddr_in *v4_base_ip;
00309
00310 #ifdef IPV6
00311 if (ip->ss.ss_family != AF_INET6)
00312 #endif
00313 {
00314 v4_base_ip = (struct sockaddr_in*)ip;
00315 mask = ~((1 << (32 - bits)) - 1);
00316 v4_base_ip->sin_addr.s_addr =
00317 htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
00318 }
00319 #ifdef IPV6
00320 else
00321 {
00322 n = bits / 8;
00323 m = bits % 8;
00324 v6_base_ip = (struct sockaddr_in6*)ip;
00325
00326 mask = ~((1 << (8 - m)) -1 );
00327 v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
00328 for (i = n + 1; i < 16; i++)
00329 v6_base_ip->sin6_addr.s6_addr[i] = 0;
00330 }
00331 #endif
00332 }
00333
00334
00335 struct AddressRec *atable[ATABLE_SIZE];
00336
00337 void
00338 init_host_hash(void)
00339 {
00340 memset(&atable, 0, sizeof(atable));
00341 }
00342
00343
00344
00345
00346
00347
00348 static unsigned long
00349 hash_ipv4(struct irc_ssaddr *addr, int bits)
00350 {
00351 if (bits != 0)
00352 {
00353 struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
00354 unsigned long av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
00355 return((av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1));
00356 }
00357
00358 return(0);
00359 }
00360
00361
00362
00363
00364
00365
00366 #ifdef IPV6
00367 static unsigned long
00368 hash_ipv6(struct irc_ssaddr *addr, int bits)
00369 {
00370 unsigned long v = 0, n;
00371 struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr;
00372
00373 for (n = 0; n < 16; n++)
00374 {
00375 if (bits >= 8)
00376 {
00377 v ^= v6->sin6_addr.s6_addr[n];
00378 bits -= 8;
00379 }
00380 else if (bits)
00381 {
00382 v ^= v6->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
00383 return v & (ATABLE_SIZE - 1);
00384 }
00385 else
00386 return v & (ATABLE_SIZE - 1);
00387 }
00388 return v & (ATABLE_SIZE - 1);
00389 }
00390 #endif
00391
00392
00393
00394
00395
00396
00397 static int
00398 hash_text(const char *start)
00399 {
00400 const char *p = start;
00401 unsigned long h = 0;
00402
00403 while (*p)
00404 {
00405 h = (h << 4) - (h + (unsigned char)ToLower(*p++));
00406 }
00407 return (h & (ATABLE_SIZE - 1));
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 static unsigned long
00417 get_mask_hash(const char *text)
00418 {
00419 const char *hp = "", *p;
00420
00421 for (p = text + strlen(text) - 1; p >= text; p--)
00422 if (IsMWildChar(*p))
00423 return hash_text(hp);
00424 else if (*p == '.')
00425 hp = p + 1;
00426 return hash_text(text);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 struct AccessItem *
00440 find_conf_by_address(const char *name, struct irc_ssaddr *addr, int type,
00441 int fam, const char *username, const char *password)
00442 {
00443 unsigned long hprecv = 0;
00444 struct AccessItem *hprec = NULL;
00445 struct AddressRec *arec;
00446 int b;
00447
00448 if (username == NULL)
00449 username = "";
00450 if (password == NULL)
00451 password = "";
00452
00453 if (addr)
00454 {
00455
00456 #ifdef IPV6
00457 if (fam == AF_INET6)
00458 {
00459 for (b = 128; b >= 0; b -= 16)
00460 {
00461 for (arec = atable[hash_ipv6(addr, b)]; arec; arec = arec->next)
00462 if (arec->type == (type & ~0x1) &&
00463 arec->precedence > hprecv &&
00464 arec->masktype == HM_IPV6 &&
00465 match_ipv6(addr, &arec->Mask.ipa.addr,
00466 arec->Mask.ipa.bits) &&
00467 (type & 0x1 || match(arec->username, username)) &&
00468 (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
00469 match_conf_password(password, arec->aconf)))
00470 {
00471 hprecv = arec->precedence;
00472 hprec = arec->aconf;
00473 }
00474 }
00475 }
00476 else
00477 #endif
00478 if (fam == AF_INET)
00479 {
00480 for (b = 32; b >= 0; b -= 8)
00481 {
00482 for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next)
00483 if (arec->type == (type & ~0x1) &&
00484 arec->precedence > hprecv &&
00485 arec->masktype == HM_IPV4 &&
00486 match_ipv4(addr, &arec->Mask.ipa.addr,
00487 arec->Mask.ipa.bits) &&
00488 (type & 0x1 || match(arec->username, username)) &&
00489 (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
00490 match_conf_password(password, arec->aconf)))
00491 {
00492 hprecv = arec->precedence;
00493 hprec = arec->aconf;
00494 }
00495 }
00496 }
00497 }
00498
00499 if (name != NULL)
00500 {
00501 const char *p = name;
00502
00503 while (1)
00504 {
00505 for (arec = atable[hash_text(p)]; arec != NULL; arec = arec->next)
00506 if ((arec->type == (type & ~0x1)) &&
00507 arec->precedence > hprecv &&
00508 (arec->masktype == HM_HOST) &&
00509 match(arec->Mask.hostname, name) &&
00510 (type & 0x1 || match(arec->username, username)) &&
00511 (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
00512 match_conf_password(password, arec->aconf)))
00513 {
00514 hprecv = arec->precedence;
00515 hprec = arec->aconf;
00516 }
00517 p = strchr(p, '.');
00518 if (p == NULL)
00519 break;
00520 p++;
00521 }
00522 for (arec = atable[0]; arec; arec = arec->next)
00523 if (arec->type == (type & ~0x1) &&
00524 arec->precedence > hprecv &&
00525 arec->masktype == HM_HOST &&
00526 match(arec->Mask.hostname, name) &&
00527 (type & 0x1 || match(arec->username, username)) &&
00528 (IsNeedPassword(arec->aconf) || arec->aconf->passwd == NULL ||
00529 match_conf_password(password, arec->aconf)))
00530 {
00531 hprecv = arec->precedence;
00532 hprec = arec->aconf;
00533 }
00534 }
00535
00536 return hprec;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545 struct AccessItem *
00546 find_address_conf(const char *host, const char *user,
00547 struct irc_ssaddr *ip, int aftype, char *password)
00548 {
00549 struct AccessItem *iconf, *kconf;
00550
00551
00552 if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
00553 password)) == NULL)
00554 return(NULL);
00555
00556
00557 if (IsConfExemptKline(iconf))
00558 return(iconf);
00559
00560
00561 kconf = find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL);
00562
00563
00564
00565 if (kconf != NULL)
00566 return(kconf);
00567
00568 kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL);
00569 if (kconf != NULL && !IsConfExemptGline(iconf))
00570 return(kconf);
00571
00572 return(iconf);
00573 }
00574
00575 struct AccessItem *
00576 find_gline_conf(const char *host, const char *user,
00577 struct irc_ssaddr *ip, int aftype)
00578 {
00579 struct AccessItem *eline;
00580
00581 eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
00582 user, NULL);
00583 if (eline != NULL)
00584 return(eline);
00585
00586 return(find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL));
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 struct AccessItem *
00598 find_kline_conf(const char *host, const char *user,
00599 struct irc_ssaddr *ip, int aftype)
00600 {
00601 struct AccessItem *eline;
00602
00603 eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype,
00604 user, NULL);
00605 if (eline != NULL)
00606 return(eline);
00607
00608 return(find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL));
00609 }
00610
00611
00612
00613
00614
00615
00616
00617 struct AccessItem *
00618 find_dline_conf(struct irc_ssaddr *addr, int aftype)
00619 {
00620 struct AccessItem *eline;
00621
00622 eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype,
00623 NULL, NULL);
00624 if (eline != NULL)
00625 return(eline);
00626 return(find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL));
00627 }
00628
00629
00630
00631
00632
00633
00634 void
00635 add_conf_by_address(int type, struct AccessItem *aconf)
00636 {
00637 const char *address;
00638 const char *username;
00639 static unsigned long prec_value = 0xFFFFFFFF;
00640 int masktype, bits;
00641 unsigned long hv;
00642 struct AddressRec *arec;
00643
00644 address = aconf->host;
00645 username = aconf->user;
00646
00647 assert(type != 0);
00648 assert(aconf != NULL);
00649
00650 if (EmptyString(address))
00651 address = "/NOMATCH!/";
00652
00653 arec = MyMalloc(sizeof(struct AddressRec));
00654 masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
00655 arec->Mask.ipa.bits = bits;
00656 arec->masktype = masktype;
00657 #ifdef IPV6
00658 if (masktype == HM_IPV6)
00659 {
00660
00661 bits -= bits % 16;
00662 arec->next = atable[(hv = hash_ipv6(&arec->Mask.ipa.addr, bits))];
00663 atable[hv] = arec;
00664 }
00665 else
00666 #endif
00667 if (masktype == HM_IPV4)
00668 {
00669
00670 bits -= bits % 8;
00671 arec->next = atable[(hv = hash_ipv4(&arec->Mask.ipa.addr, bits))];
00672 atable[hv] = arec;
00673 }
00674 else
00675 {
00676 arec->Mask.hostname = address;
00677 arec->next = atable[(hv = get_mask_hash(address))];
00678 atable[hv] = arec;
00679 }
00680 arec->username = username;
00681 arec->aconf = aconf;
00682 arec->precedence = prec_value--;
00683 arec->type = type;
00684 }
00685
00686
00687
00688
00689
00690
00691
00692 void
00693 delete_one_address_conf(const char *address, struct AccessItem *aconf)
00694 {
00695 int masktype, bits;
00696 unsigned long hv;
00697 struct AddressRec *arec, *arecl = NULL;
00698 struct irc_ssaddr addr;
00699 masktype = parse_netmask(address, &addr, &bits);
00700
00701 #ifdef IPV6
00702 if (masktype == HM_IPV6)
00703 {
00704
00705 bits -= bits % 16;
00706 hv = hash_ipv6(&addr, bits);
00707 }
00708 else
00709 #endif
00710 if (masktype == HM_IPV4)
00711 {
00712
00713 bits -= bits % 8;
00714 hv = hash_ipv4(&addr, bits);
00715 }
00716 else
00717 hv = get_mask_hash(address);
00718 for (arec = atable[hv]; arec; arec = arec->next)
00719 {
00720 if (arec->aconf == aconf)
00721 {
00722 if (arecl)
00723 arecl->next = arec->next;
00724 else
00725 atable[hv] = arec->next;
00726 aconf->status |= CONF_ILLEGAL;
00727 if (aconf->clients == 0)
00728 free_access_item(aconf);
00729 MyFree(arec);
00730 return;
00731 }
00732 arecl = arec;
00733 }
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743 void
00744 clear_out_address_conf(void)
00745 {
00746 int i;
00747 struct AddressRec *arec;
00748 struct AddressRec *last_arec;
00749 struct AddressRec *next_arec;
00750
00751 for (i = 0; i < ATABLE_SIZE; i++)
00752 {
00753 last_arec = NULL;
00754 for (arec = atable[i]; arec; arec = next_arec)
00755 {
00756
00757
00758
00759 next_arec = arec->next;
00760
00761 if (arec->aconf->flags & CONF_FLAGS_TEMPORARY)
00762 {
00763 last_arec = arec;
00764 }
00765 else
00766 {
00767
00768
00769 if (last_arec == NULL)
00770 {
00771 atable[i] = next_arec;
00772 }
00773 else
00774 {
00775 last_arec->next = next_arec;
00776 }
00777
00778 arec->aconf->status |= CONF_ILLEGAL;
00779 if (arec->aconf->clients == 0)
00780 free_access_item(arec->aconf);
00781 MyFree(arec);
00782 }
00783 }
00784 }
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 char *
00797 show_iline_prefix(struct Client *sptr, struct AccessItem *aconf, const char *name)
00798 {
00799 static char prefix_of_host[USERLEN + 14];
00800 char *prefix_ptr;
00801
00802 prefix_ptr = prefix_of_host;
00803 if (IsNoTilde(aconf))
00804 *prefix_ptr++ = '-';
00805 if (IsLimitIp(aconf))
00806 *prefix_ptr++ = '!';
00807 if (IsNeedIdentd(aconf))
00808 *prefix_ptr++ = '+';
00809 if (!IsNeedPassword(aconf))
00810 *prefix_ptr++ = '&';
00811 if (IsConfExemptResv(aconf))
00812 *prefix_ptr++ = '$';
00813 if (IsNoMatchIp(aconf))
00814 *prefix_ptr++ = '%';
00815 if (IsConfDoSpoofIp(aconf))
00816 *prefix_ptr++ = '=';
00817 if (MyOper(sptr) && IsConfExemptKline(aconf))
00818 *prefix_ptr++ = '^';
00819 if (MyOper(sptr) && IsConfExemptGline(aconf))
00820 *prefix_ptr++ = '_';
00821 if (MyOper(sptr) && IsConfExemptLimits(aconf))
00822 *prefix_ptr++ = '>';
00823 if (MyOper(sptr) && IsConfIdlelined(aconf))
00824 *prefix_ptr++ = '<';
00825 if (IsConfCanFlood(aconf))
00826 *prefix_ptr++ = '|';
00827 strlcpy(prefix_ptr, name, USERLEN);
00828
00829 return(prefix_of_host);
00830 }
00831
00832
00833
00834
00835
00836
00837
00838 void
00839 report_auth(struct Client *client_p)
00840 {
00841 struct AddressRec *arec;
00842 struct ConfItem *conf;
00843 struct AccessItem *aconf;
00844 int i;
00845
00846 for (i = 0; i < ATABLE_SIZE; i++)
00847 {
00848 for (arec = atable[i]; arec; arec = arec->next)
00849 {
00850 if (arec->type == CONF_CLIENT)
00851 {
00852 aconf = arec->aconf;
00853
00854 if (!MyOper(client_p) && IsConfDoSpoofIp(aconf))
00855 continue;
00856
00857 conf = unmap_conf_item(aconf);
00858
00859
00860
00861
00862 if (ConfigFileEntry.hide_spoof_ips)
00863 sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
00864 client_p->name, 'I',
00865 conf->name == NULL ? "*" : conf->name,
00866 show_iline_prefix(client_p, aconf, aconf->user),
00867 IsConfDoSpoofIp(aconf) ? "255.255.255.255" :
00868 aconf->host, aconf->port,
00869 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00870
00871 else
00872 sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
00873 client_p->name, 'I',
00874 conf->name == NULL ? "*" : conf->name,
00875 show_iline_prefix(client_p, aconf, aconf->user),
00876 aconf->host, aconf->port,
00877 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00878 }
00879 }
00880 }
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890 void
00891 report_Klines(struct Client *client_p, int tkline)
00892 {
00893 struct AddressRec *arec = NULL;
00894 struct AccessItem *aconf = NULL;
00895 int i;
00896 const char *p = NULL;
00897
00898 if (tkline)
00899 p = "k";
00900 else
00901 p = "K";
00902
00903 for (i = 0; i < ATABLE_SIZE; i++)
00904 {
00905 for (arec = atable[i]; arec; arec = arec->next)
00906 {
00907 if (arec->type == CONF_KILL)
00908 {
00909 if ((tkline && !((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)) ||
00910 (!tkline && ((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)))
00911 continue;
00912
00913 if (IsOper(client_p))
00914 sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
00915 client_p->name, p, aconf->host, aconf->user,
00916 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
00917 else
00918 sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
00919 client_p->name, p, aconf->host, aconf->user,
00920 aconf->reason, "");
00921 }
00922 }
00923 }
00924 }