1 |
|
/* |
2 |
|
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) |
3 |
|
* |
4 |
< |
* Copyright (c) 2001-2014 ircd-hybrid development team |
4 |
> |
* Copyright (c) 2001-2019 ircd-hybrid development team |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
15 |
|
* |
16 |
|
* You should have received a copy of the GNU General Public License |
17 |
|
* along with this program; if not, write to the Free Software |
18 |
< |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
18 |
> |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
19 |
|
* USA |
20 |
|
*/ |
21 |
|
|
42 |
|
ch = ch - 'A' + 10; \ |
43 |
|
else if (ch >= 'a' && ch <= 'f') \ |
44 |
|
ch = ch - 'a' + 10; \ |
45 |
< |
} while (0); |
45 |
> |
} while (false); |
46 |
> |
|
47 |
> |
/* Hashtable stuff...now external as it's used in m_stats.c */ |
48 |
> |
dlink_list atable[ATABLE_SIZE]; |
49 |
|
|
50 |
|
/* The mask parser/type determination code... */ |
51 |
|
|
56 |
|
* Side effects: None |
57 |
|
* Comments: Called from parse_netmask |
58 |
|
*/ |
56 |
– |
/* Fixed so ::/0 (any IPv6 address) is valid |
57 |
– |
Also a bug in DigitParse above. |
58 |
– |
-Gozem 2002-07-19 gozem@linux.nu |
59 |
– |
*/ |
60 |
– |
#ifdef IPV6 |
59 |
|
static int |
60 |
|
try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b) |
61 |
|
{ |
67 |
|
int bits = 128; |
68 |
|
int deficit = 0; |
69 |
|
short dc[8]; |
70 |
< |
struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; |
70 |
> |
struct sockaddr_in6 *const v6 = (struct sockaddr_in6 *)addr; |
71 |
|
|
72 |
|
for (const char *p = text; (c = *p); ++p) |
73 |
|
{ |
88 |
|
} |
89 |
|
else |
90 |
|
{ |
91 |
< |
/* If there were less than 4 hex digits, e.g. :ABC: shift right |
92 |
< |
* so we don't interpret it as ABC0 -A1kmm */ |
91 |
> |
/* |
92 |
> |
* If there were less than 4 hex digits, e.g. :ABC: shift right |
93 |
> |
* so we don't interpret it as ABC0 -A1kmm |
94 |
> |
*/ |
95 |
|
d[dp] = d[dp] >> 4 * nyble; |
96 |
|
nyble = 4; |
97 |
+ |
|
98 |
|
if (++dp >= 8) |
99 |
|
return HM_HOST; |
100 |
|
} |
154 |
|
|
155 |
|
/* And assign... -A1kmm */ |
156 |
|
if (addr) |
157 |
+ |
{ |
158 |
+ |
v6->sin6_family = AF_INET6; |
159 |
+ |
|
160 |
|
for (dp = 0; dp < 8; ++dp) |
161 |
|
/* The cast is a kludge to make netbsd work. */ |
162 |
|
((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]); |
163 |
+ |
} |
164 |
|
|
165 |
|
if (b) |
166 |
|
*b = bits; |
167 |
|
return HM_IPV6; |
168 |
|
} |
164 |
– |
#endif |
169 |
|
|
170 |
|
/* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *); |
171 |
|
* Input: A possible IPV4 address as a string. |
181 |
|
unsigned char addb[4]; |
182 |
|
int n = 0, bits = 0; |
183 |
|
char c; |
184 |
< |
struct sockaddr_in *v4 = (struct sockaddr_in *)addr; |
184 |
> |
struct sockaddr_in *const v4 = (struct sockaddr_in *)addr; |
185 |
|
|
186 |
|
digits[n++] = text; |
187 |
|
|
198 |
|
} |
199 |
|
else if (c == '*') |
200 |
|
{ |
201 |
< |
if (*(p + 1) || n == 0 || *(p - 1) != '.') |
201 |
> |
if (*(p + 1) || n == 1 || *(p - 1) != '.') |
202 |
|
return HM_HOST; |
203 |
|
|
204 |
|
bits = (n - 1) * 8; |
238 |
|
for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n) |
239 |
|
addb[n] = 0; |
240 |
|
if (addr) |
241 |
+ |
{ |
242 |
+ |
v4->sin_family = AF_INET; |
243 |
|
v4->sin_addr.s_addr = |
244 |
|
htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]); |
245 |
+ |
} |
246 |
+ |
|
247 |
|
if (b) |
248 |
|
*b = bits; |
249 |
|
return HM_IPV4; |
259 |
|
int |
260 |
|
parse_netmask(const char *text, struct irc_ssaddr *addr, int *b) |
261 |
|
{ |
262 |
+ |
if (addr) |
263 |
+ |
memset(addr, 0, sizeof(*addr)); |
264 |
+ |
|
265 |
|
if (strchr(text, '.')) |
266 |
|
return try_parse_v4_netmask(text, addr, b); |
256 |
– |
#ifdef IPV6 |
267 |
|
if (strchr(text, ':')) |
268 |
|
return try_parse_v6_netmask(text, addr, b); |
269 |
< |
#endif |
269 |
> |
|
270 |
|
return HM_HOST; |
271 |
|
} |
272 |
|
|
276 |
|
* Output: if match, -1 else 0 |
277 |
|
* Side effects: None |
278 |
|
*/ |
279 |
< |
#ifdef IPV6 |
270 |
< |
int |
279 |
> |
bool |
280 |
|
match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) |
281 |
|
{ |
282 |
|
int i, m, n = bits / 8; |
283 |
< |
const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr; |
284 |
< |
const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask; |
283 |
> |
const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr; |
284 |
> |
const struct sockaddr_in6 *const v6mask = (const struct sockaddr_in6 *)mask; |
285 |
|
|
286 |
|
for (i = 0; i < n; ++i) |
287 |
|
if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i]) |
288 |
< |
return 0; |
288 |
> |
return false; |
289 |
|
|
290 |
|
if ((m = bits % 8) == 0) |
291 |
< |
return -1; |
291 |
> |
return true; |
292 |
|
if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) == |
293 |
|
v6mask->sin6_addr.s6_addr[n]) |
294 |
< |
return -1; |
295 |
< |
return 0; |
294 |
> |
return true; |
295 |
> |
return false; |
296 |
|
} |
288 |
– |
#endif |
297 |
|
|
298 |
|
/* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int) |
299 |
|
* Input: An IP address, an IP mask, the number of bits in the mask. |
300 |
|
* Output: if match, -1 else 0 |
301 |
|
* Side Effects: None |
302 |
|
*/ |
303 |
< |
int |
303 |
> |
bool |
304 |
|
match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) |
305 |
|
{ |
306 |
< |
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr; |
307 |
< |
const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask; |
306 |
> |
const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr; |
307 |
> |
const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask; |
308 |
|
|
309 |
< |
if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) != |
309 |
> |
if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) == |
310 |
|
ntohl(v4mask->sin_addr.s_addr)) |
311 |
< |
return 0; |
312 |
< |
return -1; |
305 |
< |
} |
306 |
< |
|
307 |
< |
/* |
308 |
< |
* mask_addr |
309 |
< |
* |
310 |
< |
* inputs - pointer to the ip to mask |
311 |
< |
* - bitlen |
312 |
< |
* output - NONE |
313 |
< |
* side effects - |
314 |
< |
*/ |
315 |
< |
void |
316 |
< |
mask_addr(struct irc_ssaddr *ip, int bits) |
317 |
< |
{ |
318 |
< |
int mask; |
319 |
< |
#ifdef IPV6 |
320 |
< |
struct sockaddr_in6 *v6_base_ip; |
321 |
< |
int i, m, n; |
322 |
< |
#endif |
323 |
< |
struct sockaddr_in *v4_base_ip; |
324 |
< |
|
325 |
< |
#ifdef IPV6 |
326 |
< |
if (ip->ss.ss_family != AF_INET6) |
327 |
< |
#endif |
328 |
< |
{ |
329 |
< |
v4_base_ip = (struct sockaddr_in *)ip; |
330 |
< |
|
331 |
< |
mask = ~((1 << (32 - bits)) - 1); |
332 |
< |
v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask); |
333 |
< |
} |
334 |
< |
#ifdef IPV6 |
335 |
< |
else |
336 |
< |
{ |
337 |
< |
n = bits / 8; |
338 |
< |
m = bits % 8; |
339 |
< |
v6_base_ip = (struct sockaddr_in6 *)ip; |
340 |
< |
|
341 |
< |
mask = ~((1 << (8 - m)) -1 ); |
342 |
< |
v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask; |
343 |
< |
|
344 |
< |
for (i = n + 1; i < 16; i++) |
345 |
< |
v6_base_ip->sin6_addr.s6_addr[i] = 0; |
346 |
< |
} |
347 |
< |
#endif |
348 |
< |
} |
349 |
< |
|
350 |
< |
/* Hashtable stuff...now external as its used in m_stats.c */ |
351 |
< |
dlink_list atable[ATABLE_SIZE]; |
352 |
< |
|
353 |
< |
void |
354 |
< |
init_host_hash(void) |
355 |
< |
{ |
356 |
< |
memset(&atable, 0, sizeof(atable)); |
311 |
> |
return true; |
312 |
> |
return false; |
313 |
|
} |
314 |
|
|
315 |
|
/* unsigned long hash_ipv4(struct irc_ssaddr*) |
320 |
|
static uint32_t |
321 |
|
hash_ipv4(const struct irc_ssaddr *addr, int bits) |
322 |
|
{ |
323 |
< |
if (bits != 0) |
323 |
> |
if (bits) |
324 |
|
{ |
325 |
< |
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr; |
325 |
> |
const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr; |
326 |
|
uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1); |
327 |
|
|
328 |
|
return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1); |
336 |
|
* Output: A hash value of the IP address. |
337 |
|
* Side effects: None |
338 |
|
*/ |
383 |
– |
#ifdef IPV6 |
339 |
|
static uint32_t |
340 |
|
hash_ipv6(const struct irc_ssaddr *addr, int bits) |
341 |
|
{ |
342 |
|
uint32_t v = 0, n; |
343 |
< |
const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr; |
343 |
> |
const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)addr; |
344 |
|
|
345 |
|
for (n = 0; n < 16; ++n) |
346 |
|
{ |
357 |
|
else |
358 |
|
return v & (ATABLE_SIZE - 1); |
359 |
|
} |
360 |
+ |
|
361 |
|
return v & (ATABLE_SIZE - 1); |
362 |
|
} |
407 |
– |
#endif |
363 |
|
|
364 |
|
/* int hash_text(const char *start) |
365 |
|
* Input: The start of the text to hash. |
407 |
|
* should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0) |
408 |
|
*/ |
409 |
|
struct MaskItem * |
410 |
< |
find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type, |
411 |
< |
int fam, const char *username, const char *password, int do_match) |
410 |
> |
find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type, |
411 |
> |
const char *username, const char *password, int do_match) |
412 |
|
{ |
413 |
|
unsigned int hprecv = 0; |
414 |
< |
dlink_node *ptr = NULL; |
414 |
> |
dlink_node *node; |
415 |
|
struct MaskItem *hprec = NULL; |
416 |
|
struct AddressRec *arec = NULL; |
462 |
– |
int b; |
417 |
|
int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp; |
418 |
|
|
419 |
|
if (addr) |
420 |
|
{ |
421 |
|
/* Check for IPV6 matches... */ |
422 |
< |
#ifdef IPV6 |
469 |
< |
if (fam == AF_INET6) |
422 |
> |
if (addr->ss.ss_family == AF_INET6) |
423 |
|
{ |
424 |
< |
for (b = 128; b >= 0; b -= 16) |
424 |
> |
for (int b = 128; b >= 0; b -= 16) |
425 |
|
{ |
426 |
< |
DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head) |
426 |
> |
DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head) |
427 |
|
{ |
428 |
< |
arec = ptr->data; |
428 |
> |
arec = node->data; |
429 |
|
|
430 |
|
if ((arec->type == type) && |
431 |
|
arec->precedence > hprecv && |
442 |
|
} |
443 |
|
} |
444 |
|
} |
445 |
< |
else |
493 |
< |
#endif |
494 |
< |
if (fam == AF_INET) |
445 |
> |
else if (addr->ss.ss_family == AF_INET) |
446 |
|
{ |
447 |
< |
for (b = 32; b >= 0; b -= 8) |
447 |
> |
for (int b = 32; b >= 0; b -= 8) |
448 |
|
{ |
449 |
< |
DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head) |
449 |
> |
DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head) |
450 |
|
{ |
451 |
< |
arec = ptr->data; |
451 |
> |
arec = node->data; |
452 |
|
|
453 |
|
if ((arec->type == type) && |
454 |
|
arec->precedence > hprecv && |
471 |
|
{ |
472 |
|
const char *p = name; |
473 |
|
|
474 |
< |
while (1) |
474 |
> |
while (true) |
475 |
|
{ |
476 |
< |
DLINK_FOREACH(ptr, atable[hash_text(p)].head) |
476 |
> |
DLINK_FOREACH(node, atable[hash_text(p)].head) |
477 |
|
{ |
478 |
< |
arec = ptr->data; |
478 |
> |
arec = node->data; |
479 |
|
if ((arec->type == type) && |
480 |
|
arec->precedence > hprecv && |
481 |
|
(arec->masktype == HM_HOST) && |
494 |
|
++p; |
495 |
|
} |
496 |
|
|
497 |
< |
DLINK_FOREACH(ptr, atable[0].head) |
497 |
> |
DLINK_FOREACH(node, atable[0].head) |
498 |
|
{ |
499 |
< |
arec = ptr->data; |
499 |
> |
arec = node->data; |
500 |
|
|
501 |
|
if (arec->type == type && |
502 |
|
arec->precedence > hprecv && |
522 |
|
* Side-effects: None |
523 |
|
*/ |
524 |
|
struct MaskItem * |
525 |
< |
find_address_conf(const char *host, const char *user, |
575 |
< |
struct irc_ssaddr *ip, int aftype, char *password) |
525 |
> |
find_address_conf(const char *host, const char *user, const struct irc_ssaddr *addr, const char *password) |
526 |
|
{ |
527 |
|
struct MaskItem *authcnf = NULL, *killcnf = NULL; |
528 |
|
|
529 |
|
/* Find the best auth{} block... If none, return NULL -A1kmm */ |
530 |
< |
if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user, |
581 |
< |
password, 1)) == NULL) |
530 |
> |
if ((authcnf = find_conf_by_address(host, addr, CONF_CLIENT, user, password, 1)) == NULL) |
531 |
|
return NULL; |
532 |
|
|
533 |
|
/* If they are exempt from K-lines, return the best auth{} block. -A1kmm */ |
535 |
|
return authcnf; |
536 |
|
|
537 |
|
/* Find the best K-line... -A1kmm */ |
538 |
< |
killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1); |
538 |
> |
killcnf = find_conf_by_address(host, addr, CONF_KLINE, user, NULL, 1); |
539 |
|
|
540 |
|
/* |
541 |
|
* If they are K-lined, return the K-line. Otherwise, return the |
542 |
< |
* auth{} block. -A1kmm |
542 |
> |
* auth {} block. -A1kmm |
543 |
|
*/ |
544 |
|
if (killcnf) |
545 |
|
return killcnf; |
546 |
|
|
598 |
– |
if (IsConfExemptGline(authcnf)) |
599 |
– |
return authcnf; |
600 |
– |
|
601 |
– |
killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1); |
602 |
– |
if (killcnf) |
603 |
– |
return killcnf; |
604 |
– |
|
547 |
|
return authcnf; |
548 |
|
} |
549 |
|
|
554 |
|
* Side effects: None. |
555 |
|
*/ |
556 |
|
struct MaskItem * |
557 |
< |
find_dline_conf(struct irc_ssaddr *addr, int aftype) |
557 |
> |
find_dline_conf(const struct irc_ssaddr *addr) |
558 |
|
{ |
559 |
|
struct MaskItem *eline; |
560 |
|
|
561 |
< |
eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1); |
561 |
> |
eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, NULL, NULL, 1); |
562 |
|
if (eline) |
563 |
|
return eline; |
564 |
|
|
565 |
< |
return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1); |
565 |
> |
return find_conf_by_address(NULL, addr, CONF_DLINE, NULL, NULL, 1); |
566 |
|
} |
567 |
|
|
568 |
|
/* void add_conf_by_address(int, struct MaskItem *aconf) |
573 |
|
struct AddressRec * |
574 |
|
add_conf_by_address(const unsigned int type, struct MaskItem *conf) |
575 |
|
{ |
576 |
< |
const char *hostname = conf->host; |
577 |
< |
const char *username = conf->user; |
578 |
< |
static unsigned int prec_value = 0xFFFFFFFF; |
576 |
> |
const char *const hostname = conf->host; |
577 |
> |
const char *const username = conf->user; |
578 |
> |
static unsigned int prec_value = UINT_MAX; |
579 |
|
int bits = 0; |
638 |
– |
struct AddressRec *arec = NULL; |
580 |
|
|
581 |
|
assert(type && !EmptyString(hostname)); |
582 |
|
|
583 |
< |
arec = MyMalloc(sizeof(struct AddressRec)); |
583 |
> |
struct AddressRec *arec = xcalloc(sizeof(*arec)); |
584 |
|
arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits); |
585 |
|
arec->Mask.ipa.bits = bits; |
586 |
|
arec->username = username; |
595 |
|
bits -= bits % 8; |
596 |
|
dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]); |
597 |
|
break; |
657 |
– |
#ifdef IPV6 |
598 |
|
case HM_IPV6: |
599 |
|
/* We have to do this, since we do not re-hash for every bit -A1kmm. */ |
600 |
|
bits -= bits % 16; |
601 |
|
dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]); |
602 |
|
break; |
663 |
– |
#endif |
603 |
|
default: /* HM_HOST */ |
604 |
|
arec->Mask.hostname = hostname; |
605 |
|
dlinkAdd(arec, &arec->node, &atable[get_mask_hash(hostname)]); |
620 |
|
{ |
621 |
|
int bits = 0; |
622 |
|
uint32_t hv = 0; |
623 |
< |
dlink_node *ptr = NULL, *ptr_next = NULL; |
623 |
> |
dlink_node *node; |
624 |
|
struct irc_ssaddr addr; |
625 |
|
|
626 |
|
switch (parse_netmask(address, &addr, &bits)) |
630 |
|
bits -= bits % 8; |
631 |
|
hv = hash_ipv4(&addr, bits); |
632 |
|
break; |
694 |
– |
#ifdef IPV6 |
633 |
|
case HM_IPV6: |
634 |
|
/* We have to do this, since we do not re-hash for every bit -A1kmm. */ |
635 |
|
bits -= bits % 16; |
636 |
|
hv = hash_ipv6(&addr, bits); |
637 |
|
break; |
700 |
– |
#endif |
638 |
|
default: /* HM_HOST */ |
639 |
|
hv = get_mask_hash(address); |
640 |
|
break; |
641 |
|
} |
642 |
|
|
643 |
< |
DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head) |
643 |
> |
DLINK_FOREACH(node, atable[hv].head) |
644 |
|
{ |
645 |
< |
struct AddressRec *arec = ptr->data; |
645 |
> |
struct AddressRec *arec = node->data; |
646 |
|
|
647 |
|
if (arec->conf == conf) |
648 |
|
{ |
649 |
|
dlinkDelete(&arec->node, &atable[hv]); |
650 |
|
|
651 |
< |
if (!conf->ref_count) |
651 |
> |
if (conf->ref_count == 0) |
652 |
|
conf_free(conf); |
653 |
|
|
654 |
< |
MyFree(arec); |
654 |
> |
xfree(arec); |
655 |
|
return; |
656 |
|
} |
657 |
|
} |
667 |
|
void |
668 |
|
clear_out_address_conf(void) |
669 |
|
{ |
670 |
< |
dlink_node *ptr = NULL, *ptr_next = NULL; |
670 |
> |
dlink_node *node, *node_next; |
671 |
|
|
672 |
|
for (unsigned int i = 0; i < ATABLE_SIZE; ++i) |
673 |
|
{ |
674 |
< |
DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head) |
674 |
> |
DLINK_FOREACH_SAFE(node, node_next, atable[i].head) |
675 |
|
{ |
676 |
< |
struct AddressRec *arec = ptr->data; |
676 |
> |
struct AddressRec *arec = node->data; |
677 |
|
|
678 |
|
/* |
679 |
< |
* We keep the temporary K-lines and destroy the permanent ones, |
743 |
< |
* just to be confusing :) -A1kmm |
679 |
> |
* Destroy the ircd.conf items and keep those that are in the databases |
680 |
|
*/ |
681 |
< |
if (arec->conf->until || IsConfDatabase(arec->conf)) |
681 |
> |
if (IsConfDatabase(arec->conf)) |
682 |
|
continue; |
683 |
|
|
684 |
|
dlinkDelete(&arec->node, &atable[i]); |
685 |
+ |
arec->conf->active = false; |
686 |
|
|
687 |
< |
if (!arec->conf->ref_count) |
687 |
> |
if (arec->conf->ref_count == 0) |
688 |
|
conf_free(arec->conf); |
689 |
< |
MyFree(arec); |
689 |
> |
xfree(arec); |
690 |
|
} |
691 |
|
} |
692 |
|
} |
693 |
|
|
694 |
|
static void |
695 |
< |
hostmask_send_expiration(struct AddressRec *arec) |
695 |
> |
hostmask_send_expiration(const struct AddressRec *const arec) |
696 |
|
{ |
697 |
< |
char ban_type = '\0'; |
761 |
< |
|
762 |
< |
if (!ConfigFileEntry.tkline_expire_notices) |
763 |
< |
return; |
697 |
> |
char ban_type = '?'; |
698 |
|
|
699 |
|
switch (arec->type) |
700 |
|
{ |
704 |
|
case CONF_DLINE: |
705 |
|
ban_type = 'D'; |
706 |
|
break; |
773 |
– |
case CONF_GLINE: |
774 |
– |
ban_type = 'G'; |
775 |
– |
break; |
707 |
|
default: break; |
708 |
|
} |
709 |
|
|
710 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
710 |
> |
sendto_realops_flags(UMODE_EXPIRATION, L_ALL, SEND_NOTICE, |
711 |
|
"Temporary %c-line for [%s@%s] expired", ban_type, |
712 |
|
(arec->conf->user) ? arec->conf->user : "*", |
713 |
|
(arec->conf->host) ? arec->conf->host : "*"); |
716 |
|
void |
717 |
|
hostmask_expire_temporary(void) |
718 |
|
{ |
719 |
< |
dlink_node *ptr = NULL, *ptr_next = NULL; |
719 |
> |
dlink_node *node, *node_next; |
720 |
|
|
721 |
|
for (unsigned int i = 0; i < ATABLE_SIZE; ++i) |
722 |
|
{ |
723 |
< |
DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head) |
723 |
> |
DLINK_FOREACH_SAFE(node, node_next, atable[i].head) |
724 |
|
{ |
725 |
< |
struct AddressRec *arec = ptr->data; |
725 |
> |
struct AddressRec *arec = node->data; |
726 |
|
|
727 |
< |
if (!arec->conf->until || arec->conf->until > CurrentTime) |
727 |
> |
if (arec->conf->until == 0 || arec->conf->until > event_base->time.sec_real) |
728 |
|
continue; |
729 |
|
|
730 |
|
switch (arec->type) |
731 |
|
{ |
732 |
|
case CONF_KLINE: |
733 |
|
case CONF_DLINE: |
803 |
– |
case CONF_GLINE: |
734 |
|
hostmask_send_expiration(arec); |
735 |
|
|
736 |
|
dlinkDelete(&arec->node, &atable[i]); |
737 |
|
conf_free(arec->conf); |
738 |
< |
MyFree(arec); |
738 |
> |
xfree(arec); |
739 |
|
break; |
740 |
|
default: break; |
741 |
|
} |