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
00026
00027 #include "stdinc.h"
00028 #include "ircd_defs.h"
00029 #include "tools.h"
00030 #include "s_conf.h"
00031 #include "s_serv.h"
00032 #include "resv.h"
00033 #include "s_stats.h"
00034 #include "channel.h"
00035 #include "client.h"
00036 #include "common.h"
00037 #include "event.h"
00038 #include "hash.h"
00039 #include "hook.h"
00040 #include "irc_string.h"
00041 #include "sprintf_irc.h"
00042 #include "s_bsd.h"
00043 #include "irc_getnameinfo.h"
00044 #include "irc_getaddrinfo.h"
00045 #include "ircd.h"
00046 #include "list.h"
00047 #include "listener.h"
00048 #include "hostmask.h"
00049 #include "modules.h"
00050 #include "numeric.h"
00051 #include "fdlist.h"
00052 #include "s_log.h"
00053 #include "send.h"
00054 #include "s_gline.h"
00055 #include "fileio.h"
00056 #include "memory.h"
00057 #include "irc_res.h"
00058 #include "userhost.h"
00059 #include "s_user.h"
00060 #include "channel_mode.h"
00061
00062 struct Callback *client_check_cb = NULL;
00063 struct config_server_hide ConfigServerHide;
00064
00065
00066 dlink_list server_items = { NULL, NULL, 0 };
00067 dlink_list cluster_items = { NULL, NULL, 0 };
00068 dlink_list hub_items = { NULL, NULL, 0 };
00069 dlink_list leaf_items = { NULL, NULL, 0 };
00070 dlink_list oconf_items = { NULL, NULL, 0 };
00071 dlink_list uconf_items = { NULL, NULL, 0 };
00072 dlink_list xconf_items = { NULL, NULL, 0 };
00073 dlink_list rxconf_items = { NULL, NULL, 0 };
00074 dlink_list rkconf_items = { NULL, NULL, 0 };
00075 dlink_list nresv_items = { NULL, NULL, 0 };
00076 dlink_list class_items = { NULL, NULL, 0 };
00077 dlink_list gdeny_items = { NULL, NULL, 0 };
00078
00079 dlink_list temporary_klines = { NULL, NULL, 0 };
00080 dlink_list temporary_dlines = { NULL, NULL, 0 };
00081 dlink_list temporary_xlines = { NULL, NULL, 0 };
00082 dlink_list temporary_rklines = { NULL, NULL, 0 };
00083 dlink_list temporary_glines = { NULL, NULL, 0 };
00084 dlink_list temporary_rxlines = { NULL, NULL, 0 };
00085 dlink_list temporary_resv = { NULL, NULL, 0 };
00086
00087 extern unsigned int lineno;
00088 extern char linebuf[];
00089 extern char conffilebuf[IRCD_BUFSIZE];
00090 extern char yytext[];
00091 extern int yyparse();
00092 int ypass = 1;
00093
00094
00095 static void lookup_confhost(struct ConfItem *);
00096 static void set_default_conf(void);
00097 static void validate_conf(void);
00098 static void read_conf(FBFILE *);
00099 static void clear_out_old_conf(void);
00100 static void flush_deleted_I_P(void);
00101 static void expire_tklines(dlink_list *);
00102 static void garbage_collect_ip_entries(void);
00103 static int hash_ip(struct irc_ssaddr *);
00104 static int verify_access(struct Client *, const char *);
00105 static int attach_iline(struct Client *, struct ConfItem *);
00106 static struct ip_entry *find_or_add_ip(struct irc_ssaddr *);
00107 static void parse_conf_file(int, int);
00108 static dlink_list *map_to_list(ConfType);
00109 static struct AccessItem *find_regexp_kline(const char *[]);
00110 static int find_user_host(struct Client *, char *, char *, char *, unsigned int);
00111
00112
00113
00114
00115 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
00116 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
00117 static void destroy_cidr_class(struct ClassItem *);
00118
00119 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
00120
00121 FBFILE *conf_fbfile_in = NULL;
00122
00123
00124 static struct ConfItem *class_default;
00125
00126
00127
00128
00129
00130 #define IP_HASH_SIZE 0x1000
00131
00132 struct ip_entry
00133 {
00134 struct irc_ssaddr ip;
00135 int count;
00136 time_t last_attempt;
00137 struct ip_entry *next;
00138 };
00139
00140 static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
00141 static BlockHeap *ip_entry_heap = NULL;
00142 static int ip_entries_count = 0;
00143
00144
00145 inline void *
00146 map_to_conf(struct ConfItem *aconf)
00147 {
00148 void *conf;
00149 conf = (void *)((unsigned long)aconf +
00150 (unsigned long)sizeof(struct ConfItem));
00151 return(conf);
00152 }
00153
00154 inline struct ConfItem *
00155 unmap_conf_item(void *aconf)
00156 {
00157 struct ConfItem *conf;
00158
00159 conf = (struct ConfItem *)((unsigned long)aconf -
00160 (unsigned long)sizeof(struct ConfItem));
00161 return(conf);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 static void
00175 conf_dns_callback(void *vptr, struct DNSReply *reply)
00176 {
00177 struct AccessItem *aconf = (struct AccessItem *)vptr;
00178 struct ConfItem *conf;
00179
00180 MyFree(aconf->dns_query);
00181 aconf->dns_query = NULL;
00182
00183 if (reply != NULL)
00184 memcpy(&aconf->ipnum, &reply->addr, sizeof(reply->addr));
00185 else {
00186 ilog(L_NOTICE, "Host not found: %s, ignoring connect{} block",
00187 aconf->host);
00188 conf = unmap_conf_item(aconf);
00189 sendto_realops_flags(UMODE_ALL, L_ALL,
00190 "Ignoring connect{} block for %s - host not found",
00191 conf->name);
00192 delete_conf_item(conf);
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 static void
00203 conf_dns_lookup(struct AccessItem *aconf)
00204 {
00205 if (aconf->dns_query == NULL)
00206 {
00207 aconf->dns_query = MyMalloc(sizeof(struct DNSQuery));
00208 aconf->dns_query->ptr = aconf;
00209 aconf->dns_query->callback = conf_dns_callback;
00210 gethost_byname(aconf->host, aconf->dns_query);
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 struct ConfItem *
00221 make_conf_item(ConfType type)
00222 {
00223 struct ConfItem *conf = NULL;
00224 struct AccessItem *aconf = NULL;
00225 struct ClassItem *aclass = NULL;
00226 int status = 0;
00227
00228 switch (type)
00229 {
00230 case DLINE_TYPE:
00231 case EXEMPTDLINE_TYPE:
00232 case GLINE_TYPE:
00233 case KLINE_TYPE:
00234 case CLIENT_TYPE:
00235 case OPER_TYPE:
00236 case SERVER_TYPE:
00237 conf = MyMalloc(sizeof(struct ConfItem) +
00238 sizeof(struct AccessItem));
00239 aconf = map_to_conf(conf);
00240 aconf->aftype = AF_INET;
00241
00242
00243 switch (type)
00244 {
00245 case EXEMPTDLINE_TYPE:
00246 status = CONF_EXEMPTDLINE;
00247 break;
00248
00249 case DLINE_TYPE:
00250 status = CONF_DLINE;
00251 break;
00252
00253 case KLINE_TYPE:
00254 status = CONF_KLINE;
00255 break;
00256
00257 case GLINE_TYPE:
00258 status = CONF_GLINE;
00259 break;
00260
00261 case CLIENT_TYPE:
00262 status = CONF_CLIENT;
00263 break;
00264
00265 case OPER_TYPE:
00266 status = CONF_OPERATOR;
00267 dlinkAdd(conf, &conf->node, &oconf_items);
00268 break;
00269
00270 case SERVER_TYPE:
00271 status = CONF_SERVER;
00272 dlinkAdd(conf, &conf->node, &server_items);
00273 break;
00274
00275 default:
00276 break;
00277 }
00278 aconf->status = status;
00279 break;
00280
00281 case LEAF_TYPE:
00282 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00283 sizeof(struct MatchItem));
00284 dlinkAdd(conf, &conf->node, &leaf_items);
00285 break;
00286
00287 case HUB_TYPE:
00288 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00289 sizeof(struct MatchItem));
00290 dlinkAdd(conf, &conf->node, &hub_items);
00291 break;
00292
00293 case ULINE_TYPE:
00294 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00295 sizeof(struct MatchItem));
00296 dlinkAdd(conf, &conf->node, &uconf_items);
00297 break;
00298
00299 case GDENY_TYPE:
00300 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00301 sizeof(struct AccessItem));
00302 dlinkAdd(conf, &conf->node, &gdeny_items);
00303 break;
00304
00305 case XLINE_TYPE:
00306 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00307 sizeof(struct MatchItem));
00308 dlinkAdd(conf, &conf->node, &xconf_items);
00309 break;
00310
00311 case RXLINE_TYPE:
00312 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00313 sizeof(struct MatchItem));
00314 dlinkAdd(conf, &conf->node, &rxconf_items);
00315 break;
00316
00317 case RKLINE_TYPE:
00318 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00319 sizeof(struct AccessItem));
00320 aconf = map_to_conf(conf);
00321 aconf->status = CONF_KLINE;
00322 dlinkAdd(conf, &conf->node, &rkconf_items);
00323 break;
00324
00325 case CLUSTER_TYPE:
00326 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
00327 dlinkAdd(conf, &conf->node, &cluster_items);
00328 break;
00329
00330 case CRESV_TYPE:
00331 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00332 sizeof(struct ResvChannel));
00333 break;
00334
00335 case NRESV_TYPE:
00336 conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
00337 sizeof(struct MatchItem));
00338 dlinkAdd(conf, &conf->node, &nresv_items);
00339 break;
00340
00341 case CLASS_TYPE:
00342 conf = MyMalloc(sizeof(struct ConfItem) +
00343 sizeof(struct ClassItem));
00344 dlinkAdd(conf, &conf->node, &class_items);
00345
00346 aclass = map_to_conf(conf);
00347 aclass->active = 1;
00348 ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
00349 PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
00350 MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
00351 MaxSendq(aclass) = DEFAULT_SENDQ;
00352
00353 break;
00354
00355 default:
00356 conf = NULL;
00357 break;
00358 }
00359
00360
00361 conf->type = type;
00362
00363 return conf;
00364 }
00365
00366 void
00367 delete_conf_item(struct ConfItem *conf)
00368 {
00369 dlink_node *m = NULL;
00370 struct MatchItem *match_item;
00371 struct AccessItem *aconf;
00372 ConfType type = conf->type;
00373
00374 MyFree(conf->name);
00375 conf->name = NULL;
00376
00377 switch(type)
00378 {
00379 case DLINE_TYPE:
00380 case EXEMPTDLINE_TYPE:
00381 case GLINE_TYPE:
00382 case KLINE_TYPE:
00383 case CLIENT_TYPE:
00384 case OPER_TYPE:
00385 case SERVER_TYPE:
00386 aconf = map_to_conf(conf);
00387
00388 if (aconf->dns_query != NULL)
00389 {
00390 delete_resolver_queries(aconf->dns_query);
00391 MyFree(aconf->dns_query);
00392 }
00393 if (aconf->passwd != NULL)
00394 memset(aconf->passwd, 0, strlen(aconf->passwd));
00395 if (aconf->spasswd != NULL)
00396 memset(aconf->spasswd, 0, strlen(aconf->spasswd));
00397 aconf->class_ptr = NULL;
00398
00399 MyFree(aconf->passwd);
00400 MyFree(aconf->spasswd);
00401 MyFree(aconf->reason);
00402 MyFree(aconf->oper_reason);
00403 MyFree(aconf->user);
00404 MyFree(aconf->host);
00405 MyFree(aconf->fakename);
00406 #ifdef HAVE_LIBCRYPTO
00407 if (aconf->rsa_public_key)
00408 RSA_free(aconf->rsa_public_key);
00409 MyFree(aconf->rsa_public_key_file);
00410 #endif
00411
00412
00413 switch(type)
00414 {
00415 case EXEMPTDLINE_TYPE:
00416 case DLINE_TYPE:
00417 case GLINE_TYPE:
00418 case KLINE_TYPE:
00419 case CLIENT_TYPE:
00420 MyFree(conf);
00421 break;
00422
00423 case OPER_TYPE:
00424 aconf = map_to_conf(conf);
00425 if (!IsConfIllegal(aconf))
00426 dlinkDelete(&conf->node, &oconf_items);
00427 MyFree(conf);
00428 break;
00429
00430 case SERVER_TYPE:
00431 aconf = map_to_conf(conf);
00432 if (!IsConfIllegal(aconf))
00433 dlinkDelete(&conf->node, &server_items);
00434 MyFree(conf);
00435 break;
00436
00437 default:
00438 break;
00439 }
00440 break;
00441
00442 case HUB_TYPE:
00443 match_item = map_to_conf(conf);
00444 MyFree(match_item->user);
00445 MyFree(match_item->host);
00446 MyFree(match_item->reason);
00447 MyFree(match_item->oper_reason);
00448
00449 if (!match_item->illegal)
00450 dlinkDelete(&conf->node, &hub_items);
00451 MyFree(conf);
00452 break;
00453
00454 case LEAF_TYPE:
00455 match_item = map_to_conf(conf);
00456 MyFree(match_item->user);
00457 MyFree(match_item->host);
00458 MyFree(match_item->reason);
00459 MyFree(match_item->oper_reason);
00460
00461 if (!match_item->illegal)
00462 dlinkDelete(&conf->node, &leaf_items);
00463 MyFree(conf);
00464 break;
00465
00466 case ULINE_TYPE:
00467 match_item = map_to_conf(conf);
00468 MyFree(match_item->user);
00469 MyFree(match_item->host);
00470 MyFree(match_item->reason);
00471 MyFree(match_item->oper_reason);
00472 dlinkDelete(&conf->node, &uconf_items);
00473 MyFree(conf);
00474 break;
00475
00476 case XLINE_TYPE:
00477 match_item = map_to_conf(conf);
00478 MyFree(match_item->user);
00479 MyFree(match_item->host);
00480 MyFree(match_item->reason);
00481 MyFree(match_item->oper_reason);
00482 dlinkDelete(&conf->node, &xconf_items);
00483 MyFree(conf);
00484 break;
00485
00486 case RKLINE_TYPE:
00487 aconf = map_to_conf(conf);
00488 MyFree(aconf->regexuser);
00489 MyFree(aconf->regexhost);
00490 MyFree(aconf->user);
00491 MyFree(aconf->host);
00492 MyFree(aconf->reason);
00493 MyFree(aconf->oper_reason);
00494 dlinkDelete(&conf->node, &rkconf_items);
00495 MyFree(conf);
00496 break;
00497
00498 case RXLINE_TYPE:
00499 MyFree(conf->regexpname);
00500 match_item = map_to_conf(conf);
00501 MyFree(match_item->user);
00502 MyFree(match_item->host);
00503 MyFree(match_item->reason);
00504 MyFree(match_item->oper_reason);
00505 dlinkDelete(&conf->node, &rxconf_items);
00506 MyFree(conf);
00507 break;
00508
00509 case NRESV_TYPE:
00510 match_item = map_to_conf(conf);
00511 MyFree(match_item->user);
00512 MyFree(match_item->host);
00513 MyFree(match_item->reason);
00514 MyFree(match_item->oper_reason);
00515 dlinkDelete(&conf->node, &nresv_items);
00516
00517 if (conf->flags & CONF_FLAGS_TEMPORARY)
00518 if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
00519 free_dlink_node(m);
00520
00521 MyFree(conf);
00522 break;
00523
00524 case GDENY_TYPE:
00525 aconf = map_to_conf(conf);
00526 MyFree(aconf->user);
00527 MyFree(aconf->host);
00528 dlinkDelete(&conf->node, &gdeny_items);
00529 MyFree(conf);
00530 break;
00531
00532 case CLUSTER_TYPE:
00533 dlinkDelete(&conf->node, &cluster_items);
00534 MyFree(conf);
00535 break;
00536
00537 case CRESV_TYPE:
00538 if (conf->flags & CONF_FLAGS_TEMPORARY)
00539 if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
00540 free_dlink_node(m);
00541
00542 MyFree(conf);
00543 break;
00544
00545 case CLASS_TYPE:
00546 dlinkDelete(&conf->node, &class_items);
00547 MyFree(conf);
00548 break;
00549
00550 default:
00551 break;
00552 }
00553 }
00554
00555
00556
00557
00558
00559
00560
00561 void
00562 free_access_item(struct AccessItem *aconf)
00563 {
00564 struct ConfItem *conf;
00565
00566 if (aconf == NULL)
00567 return;
00568 conf = unmap_conf_item(aconf);
00569 delete_conf_item(conf);
00570 }
00571
00572 static const unsigned int shared_bit_table[] =
00573 { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0};
00574
00575
00576
00577
00578
00579
00580
00581
00582 void
00583 report_confitem_types(struct Client *source_p, ConfType type, int temp)
00584 {
00585 dlink_node *ptr = NULL;
00586 struct ConfItem *conf = NULL;
00587 struct AccessItem *aconf = NULL;
00588 struct MatchItem *matchitem = NULL;
00589 struct ClassItem *classitem = NULL;
00590 char buf[12];
00591 char *p = NULL;
00592 const char *pfx = NULL;
00593
00594 switch (type)
00595 {
00596 case GDENY_TYPE:
00597 DLINK_FOREACH(ptr, gdeny_items.head)
00598 {
00599 conf = ptr->data;
00600 aconf = map_to_conf(conf);
00601
00602 p = buf;
00603
00604 if (aconf->flags & GDENY_BLOCK)
00605 *p++ = 'B';
00606 else
00607 *p++ = 'b';
00608
00609 if (aconf->flags & GDENY_REJECT)
00610 *p++ = 'R';
00611 else
00612 *p++ = 'r';
00613
00614 *p = '\0';
00615
00616 sendto_one(source_p, ":%s %d %s V %s@%s %s %s",
00617 me.name, RPL_STATSDEBUG, source_p->name,
00618 aconf->user, aconf->host, conf->name, buf);
00619 }
00620 break;
00621
00622 case XLINE_TYPE:
00623 DLINK_FOREACH(ptr, xconf_items.head)
00624 {
00625 conf = ptr->data;
00626 matchitem = map_to_conf(conf);
00627
00628 sendto_one(source_p, form_str(RPL_STATSXLINE),
00629 me.name, source_p->name,
00630 matchitem->hold ? "x": "X", matchitem->count,
00631 conf->name, matchitem->reason);
00632 }
00633 break;
00634
00635 case RXLINE_TYPE:
00636 DLINK_FOREACH(ptr, rxconf_items.head)
00637 {
00638 conf = ptr->data;
00639 matchitem = map_to_conf(conf);
00640
00641 sendto_one(source_p, form_str(RPL_STATSXLINE),
00642 me.name, source_p->name,
00643 matchitem->hold ? "xR": "XR", matchitem->count,
00644 conf->name, matchitem->reason);
00645 }
00646 break;
00647
00648 case RKLINE_TYPE:
00649 pfx = temp ? "kR" : "KR";
00650
00651 DLINK_FOREACH(ptr, rkconf_items.head)
00652 {
00653 aconf = map_to_conf((conf = ptr->data));
00654
00655 if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
00656 continue;
00657
00658 sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
00659 source_p->name, pfx, aconf->host, aconf->user,
00660 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
00661 }
00662 break;
00663
00664 case ULINE_TYPE:
00665 DLINK_FOREACH(ptr, uconf_items.head)
00666 {
00667 conf = ptr->data;
00668 matchitem = map_to_conf(conf);
00669
00670 p = buf;
00671
00672
00673
00674
00675 *p++ = 'c';
00676 flags_to_ascii(matchitem->action, shared_bit_table, p, 0);
00677
00678 sendto_one(source_p, form_str(RPL_STATSULINE),
00679 me.name, source_p->name, conf->name,
00680 matchitem->user?matchitem->user: "*",
00681 matchitem->host?matchitem->host: "*", buf);
00682 }
00683
00684 DLINK_FOREACH(ptr, cluster_items.head)
00685 {
00686 conf = ptr->data;
00687
00688 p = buf;
00689
00690 *p++ = 'C';
00691 flags_to_ascii(conf->flags, shared_bit_table, p, 0);
00692
00693 sendto_one(source_p, form_str(RPL_STATSULINE),
00694 me.name, source_p->name, conf->name,
00695 "*", "*", buf);
00696 }
00697
00698 break;
00699
00700 case OPER_TYPE:
00701 DLINK_FOREACH(ptr, oconf_items.head)
00702 {
00703 conf = ptr->data;
00704 aconf = map_to_conf(conf);
00705
00706
00707 if (IsOper(source_p))
00708 sendto_one(source_p, form_str(RPL_STATSOLINE),
00709 me.name, source_p->name, 'O', aconf->user, aconf->host,
00710 conf->name, oper_privs_as_string(aconf->port),
00711 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00712 else
00713 sendto_one(source_p, form_str(RPL_STATSOLINE),
00714 me.name, source_p->name, 'O', aconf->user, aconf->host,
00715 conf->name, "0",
00716 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00717 }
00718 break;
00719
00720 case CLASS_TYPE:
00721 DLINK_FOREACH(ptr, class_items.head)
00722 {
00723 conf = ptr->data;
00724 classitem = map_to_conf(conf);
00725 sendto_one(source_p, form_str(RPL_STATSYLINE),
00726 me.name, source_p->name, 'Y',
00727 conf->name, PingFreq(classitem),
00728 ConFreq(classitem),
00729 MaxTotal(classitem), MaxSendq(classitem),
00730 CurrUserCount(classitem),
00731 classitem->active ? "active" : "disabled");
00732 }
00733 break;
00734
00735 case CONF_TYPE:
00736 case CLIENT_TYPE:
00737 break;
00738
00739 case SERVER_TYPE:
00740 DLINK_FOREACH(ptr, server_items.head)
00741 {
00742 p = buf;
00743
00744 conf = ptr->data;
00745 aconf = map_to_conf(conf);
00746
00747 buf[0] = '\0';
00748
00749 if (IsConfAllowAutoConn(aconf))
00750 *p++ = 'A';
00751 if (IsConfCryptLink(aconf))
00752 *p++ = 'C';
00753 if (IsConfLazyLink(aconf))
00754 *p++ = 'L';
00755 if (aconf->fakename)
00756 *p++ = 'M';
00757 if (IsConfTopicBurst(aconf))
00758 *p++ = 'T';
00759 if (IsConfCompressed(aconf))
00760 *p++ = 'Z';
00761 if (buf[0] == '\0')
00762 *p++ = '*';
00763
00764 *p = '\0';
00765
00766
00767
00768
00769 if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
00770 sendto_one(source_p, form_str(RPL_STATSCLINE),
00771 me.name, source_p->name, 'C', aconf->host,
00772 buf, conf->name, aconf->port,
00773 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00774 else
00775 sendto_one(source_p, form_str(RPL_STATSCLINE),
00776 me.name, source_p->name, 'C',
00777 "*@127.0.0.1", buf, conf->name, aconf->port,
00778 aconf->class_ptr ? aconf->class_ptr->name : "<default>");
00779 }
00780 break;
00781
00782 case HUB_TYPE:
00783 DLINK_FOREACH(ptr, hub_items.head)
00784 {
00785 conf = ptr->data;
00786 matchitem = map_to_conf(conf);
00787 sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
00788 source_p->name, 'H', matchitem->host, conf->name, 0, "*");
00789 }
00790 break;
00791
00792 case LEAF_TYPE:
00793 DLINK_FOREACH(ptr, leaf_items.head)
00794 {
00795 conf = ptr->data;
00796 matchitem = map_to_conf(conf);
00797 sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
00798 source_p->name, 'L', matchitem->host, conf->name, 0, "*");
00799 }
00800 break;
00801
00802 case GLINE_TYPE:
00803 case KLINE_TYPE:
00804 case DLINE_TYPE:
00805 case EXEMPTDLINE_TYPE:
00806 case CRESV_TYPE:
00807 case NRESV_TYPE:
00808 case CLUSTER_TYPE:
00809 break;
00810 }
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 static void *
00827 check_client(va_list args)
00828 {
00829 struct Client *source_p = va_arg(args, struct Client *);
00830 const char *username = va_arg(args, const char *);
00831 int i;
00832
00833
00834 if ((i = verify_access(source_p, username)))
00835 ilog(L_INFO, "Access denied: %s[%s]",
00836 source_p->name, source_p->sockhost);
00837
00838 switch (i)
00839 {
00840 case TOO_MANY:
00841 sendto_realops_flags(UMODE_FULL, L_ALL,
00842 "Too many on IP for %s (%s).",
00843 get_client_name(source_p, SHOW_IP),
00844 source_p->sockhost);
00845 ilog(L_INFO,"Too many connections on IP from %s.",
00846 get_client_name(source_p, SHOW_IP));
00847 ServerStats->is_ref++;
00848 exit_client(source_p, &me, "No more connections allowed on that IP");
00849 break;
00850
00851 case I_LINE_FULL:
00852 sendto_realops_flags(UMODE_FULL, L_ALL,
00853 "I-line is full for %s (%s).",
00854 get_client_name(source_p, SHOW_IP),
00855 source_p->sockhost);
00856 ilog(L_INFO,"Too many connections from %s.",
00857 get_client_name(source_p, SHOW_IP));
00858 ServerStats->is_ref++;
00859 exit_client(source_p, &me,
00860 "No more connections allowed in your connection class");
00861 break;
00862
00863 case NOT_AUTHORIZED:
00864 {
00865 static char ipaddr[HOSTIPLEN];
00866 ServerStats->is_ref++;
00867
00868
00869 irc_getnameinfo((struct sockaddr*)&source_p->localClient->ip,
00870 source_p->localClient->ip.ss_len, ipaddr, HOSTIPLEN, NULL, 0,
00871 NI_NUMERICHOST);
00872 sendto_realops_flags(UMODE_UNAUTH, L_ALL,
00873 "Unauthorized client connection from %s [%s] on [%s/%u].",
00874 get_client_name(source_p, SHOW_IP),
00875 ipaddr,
00876 source_p->localClient->listener->name,
00877 source_p->localClient->listener->port);
00878 ilog(L_INFO,
00879 "Unauthorized client connection from %s on [%s/%u].",
00880 get_client_name(source_p, SHOW_IP),
00881 source_p->localClient->listener->name,
00882 source_p->localClient->listener->port);
00883
00884
00885
00886
00887
00888 if (REJECT_HOLD_TIME > 0)
00889 {
00890 sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
00891 me.name, source_p->name);
00892 source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
00893 SetCaptured(source_p);
00894 }
00895 else
00896 exit_client(source_p, &me, "You are not authorized to use this server");
00897 break;
00898 }
00899
00900 case BANNED_CLIENT:
00901
00902
00903
00904
00905 if (REJECT_HOLD_TIME > 0)
00906 {
00907 source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
00908 SetCaptured(source_p);
00909 }
00910 else
00911 exit_client(source_p, &me, "Banned");
00912 ServerStats->is_ref++;
00913 break;
00914
00915 case 0:
00916 default:
00917 break;
00918 }
00919
00920 return (i < 0 ? NULL : source_p);
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930 static int
00931 verify_access(struct Client *client_p, const char *username)
00932 {
00933 struct AccessItem *aconf = NULL, *rkconf = NULL;
00934 struct ConfItem *conf = NULL;
00935 char non_ident[USERLEN + 1] = { '~', '\0' };
00936 const char *uhi[3];
00937
00938 if (IsGotId(client_p))
00939 {
00940 aconf = find_address_conf(client_p->host, client_p->username,
00941 &client_p->localClient->ip,
00942 client_p->localClient->aftype,
00943 client_p->localClient->passwd);
00944 }
00945 else
00946 {
00947 strlcpy(non_ident+1, username, sizeof(non_ident)-1);
00948 aconf = find_address_conf(client_p->host,non_ident,
00949 &client_p->localClient->ip,
00950 client_p->localClient->aftype,
00951 client_p->localClient->passwd);
00952 }
00953
00954 uhi[0] = IsGotId(client_p) ? client_p->username : non_ident;
00955 uhi[1] = client_p->host;
00956 uhi[2] = client_p->sockhost;
00957
00958 rkconf = find_regexp_kline(uhi);
00959
00960 if (aconf != NULL)
00961 {
00962 if (IsConfClient(aconf) && !rkconf)
00963 {
00964 conf = unmap_conf_item(aconf);
00965
00966 if (IsConfRedir(aconf))
00967 {
00968 sendto_one(client_p, form_str(RPL_REDIR),
00969 me.name, client_p->name,
00970 conf->name ? conf->name : "",
00971 aconf->port);
00972 return(NOT_AUTHORIZED);
00973 }
00974
00975 if (IsConfDoIdentd(aconf))
00976 SetNeedId(client_p);
00977
00978
00979 if (IsConfDoSpoofIp(aconf))
00980 {
00981 conf = unmap_conf_item(aconf);
00982
00983 if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf))
00984 sendto_realops_flags(UMODE_ALL, L_ADMIN, "%s spoofing: %s as %s",
00985 client_p->name, client_p->host, conf->name);
00986 strlcpy(client_p->host, conf->name, sizeof(client_p->host));
00987 SetIPSpoof(client_p);
00988 }
00989
00990 return(attach_iline(client_p, conf));
00991 }
00992 else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf)))
00993 {
00994
00995 aconf = rkconf ? rkconf : aconf;
00996 if (IsConfGline(aconf))
00997 sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
00998 client_p->name);
00999 if (ConfigFileEntry.kline_with_reason)
01000 sendto_one(client_p, ":%s NOTICE %s :*** Banned %s",
01001 me.name, client_p->name, aconf->reason);
01002 return(BANNED_CLIENT);
01003 }
01004 }
01005
01006 return(NOT_AUTHORIZED);
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016 static int
01017 attach_iline(struct Client *client_p, struct ConfItem *conf)
01018 {
01019 struct AccessItem *aconf;
01020 struct ClassItem *aclass;
01021 struct ip_entry *ip_found;
01022 int a_limit_reached = 0;
01023 int local = 0, global = 0, ident = 0;
01024
01025 ip_found = find_or_add_ip(&client_p->localClient->ip);
01026 ip_found->count++;
01027 SetIpHash(client_p);
01028
01029 aconf = map_to_conf(conf);
01030 if (aconf->class_ptr == NULL)
01031 return NOT_AUTHORIZED;
01032
01033 aclass = map_to_conf(aconf->class_ptr);
01034
01035 count_user_host(client_p->username, client_p->host,
01036 &global, &local, &ident);
01037
01038
01039
01040
01041
01042 if (MaxTotal(aclass) != 0 && CurrUserCount(aclass) >= MaxTotal(aclass))
01043 a_limit_reached = 1;
01044 else if (MaxPerIp(aclass) != 0 && ip_found->count > MaxPerIp(aclass))
01045 a_limit_reached = 1;
01046 else if (MaxLocal(aclass) != 0 && local >= MaxLocal(aclass))
01047 a_limit_reached = 1;
01048 else if (MaxGlobal(aclass) != 0 && global >= MaxGlobal(aclass))
01049 a_limit_reached = 1;
01050 else if (MaxIdent(aclass) != 0 && ident >= MaxIdent(aclass) &&
01051 client_p->username[0] != '~')
01052 a_limit_reached = 1;
01053
01054 if (a_limit_reached)
01055 {
01056 if (!IsConfExemptLimits(aconf))
01057 return TOO_MANY;
01058
01059 sendto_one(client_p,
01060 ":%s NOTICE %s :*** Your connection class is full, "
01061 "but you have exceed_limit = yes;", me.name, client_p->name);
01062 }
01063
01064 return attach_conf(client_p, conf);
01065 }
01066
01067
01068
01069
01070
01071
01072
01073
01074 void
01075 init_ip_hash_table(void)
01076 {
01077 ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry),
01078 2 * hard_fdlimit);
01079 memset(ip_hash_table, 0, sizeof(ip_hash_table));
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 static struct ip_entry *
01092 find_or_add_ip(struct irc_ssaddr *ip_in)
01093 {
01094 struct ip_entry *ptr, *newptr;
01095 int hash_index = hash_ip(ip_in), res;
01096 struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
01097 #ifdef IPV6
01098 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
01099 #endif
01100
01101 for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
01102 {
01103 #ifdef IPV6
01104 if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
01105 continue;
01106 if (ip_in->ss.ss_family == AF_INET6)
01107 {
01108 ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
01109 res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
01110 }
01111 else
01112 #endif
01113 {
01114 ptr_v4 = (struct sockaddr_in *)&ptr->ip;
01115 res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
01116 }
01117 if (res == 0)
01118 {
01119
01120 return ptr;
01121 }
01122 }
01123
01124 if (ip_entries_count >= 2 * hard_fdlimit)
01125 garbage_collect_ip_entries();
01126
01127 newptr = BlockHeapAlloc(ip_entry_heap);
01128 ip_entries_count++;
01129 memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
01130
01131 newptr->next = ip_hash_table[hash_index];
01132 ip_hash_table[hash_index] = newptr;
01133
01134 return newptr;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 void
01147 remove_one_ip(struct irc_ssaddr *ip_in)
01148 {
01149 struct ip_entry *ptr;
01150 struct ip_entry *last_ptr = NULL;
01151 int hash_index = hash_ip(ip_in), res;
01152 struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
01153 #ifdef IPV6
01154 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
01155 #endif
01156
01157 for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
01158 {
01159 #ifdef IPV6
01160 if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
01161 continue;
01162 if (ip_in->ss.ss_family == AF_INET6)
01163 {
01164 ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
01165 res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
01166 }
01167 else
01168 #endif
01169 {
01170 ptr_v4 = (struct sockaddr_in *)&ptr->ip;
01171 res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
01172 }
01173 if (res)
01174 continue;
01175 if (ptr->count > 0)
01176 ptr->count--;
01177 if (ptr->count == 0 &&
01178 (CurrentTime-ptr->last_attempt) >= ConfigFileEntry.throttle_time)
01179 {
01180 if (last_ptr != NULL)
01181 last_ptr->next = ptr->next;
01182 else
01183 ip_hash_table[hash_index] = ptr->next;
01184
01185 BlockHeapFree(ip_entry_heap, ptr);
01186 ip_entries_count--;
01187 return;
01188 }
01189 last_ptr = ptr;
01190 }
01191 }
01192
01193
01194
01195
01196
01197
01198
01199 static int
01200 hash_ip(struct irc_ssaddr *addr)
01201 {
01202 if (addr->ss.ss_family == AF_INET)
01203 {
01204 struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
01205 int hash;
01206 u_int32_t ip;
01207
01208 ip = ntohl(v4->sin_addr.s_addr);
01209 hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
01210 return hash;
01211 }
01212 #ifdef IPV6
01213 else
01214 {
01215 int hash;
01216 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
01217 u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
01218
01219 hash = ip[0] ^ ip[3];
01220 hash ^= hash >> 16;
01221 hash ^= hash >> 8;
01222 hash = hash & (IP_HASH_SIZE - 1);
01223 return hash;
01224 }
01225 #else
01226 return 0;
01227 #endif
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 void
01241 count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
01242 {
01243 struct ip_entry *ptr;
01244 int i;
01245
01246 *number_ips_stored = 0;
01247 *mem_ips_stored = 0;
01248
01249 for (i = 0; i < IP_HASH_SIZE; i++)
01250 {
01251 for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next)
01252 {
01253 *number_ips_stored += 1;
01254 *mem_ips_stored += sizeof(struct ip_entry);
01255 }
01256 }
01257 }
01258
01259
01260
01261
01262
01263
01264
01265 static void
01266 garbage_collect_ip_entries(void)
01267 {
01268 struct ip_entry *ptr;
01269 struct ip_entry *last_ptr;
01270 struct ip_entry *next_ptr;
01271 int i;
01272
01273 for (i = 0; i < IP_HASH_SIZE; i++)
01274 {
01275 last_ptr = NULL;
01276
01277 for (ptr = ip_hash_table[i]; ptr; ptr = next_ptr)
01278 {
01279 next_ptr = ptr->next;
01280
01281 if (ptr->count == 0 &&
01282 (CurrentTime - ptr->last_attempt) >= ConfigFileEntry.throttle_time)
01283 {
01284 if (last_ptr != NULL)
01285 last_ptr->next = ptr->next;
01286 else
01287 ip_hash_table[i] = ptr->next;
01288 BlockHeapFree(ip_entry_heap, ptr);
01289 ip_entries_count--;
01290 }
01291 else
01292 last_ptr = ptr;
01293 }
01294 }
01295 }
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 int
01306 detach_conf(struct Client *client_p, ConfType type)
01307 {
01308 dlink_node *ptr, *next_ptr;
01309 struct ConfItem *conf;
01310 struct ClassItem *aclass;
01311 struct AccessItem *aconf;
01312 struct ConfItem *aclass_conf;
01313 struct MatchItem *match_item;
01314
01315 DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
01316 {
01317 conf = ptr->data;
01318
01319 if (type == CONF_TYPE || conf->type == type)
01320 {
01321 dlinkDelete(ptr, &client_p->localClient->confs);
01322 free_dlink_node(ptr);
01323
01324 switch (conf->type)
01325 {
01326 case CLIENT_TYPE:
01327 case OPER_TYPE:
01328 case SERVER_TYPE:
01329 aconf = map_to_conf(conf);
01330
01331 assert(aconf->clients > 0);
01332
01333 if ((aclass_conf = ClassPtr(aconf)) != NULL)
01334 {
01335 aclass = map_to_conf(aclass_conf);
01336
01337 assert(aclass->curr_user_count > 0);
01338
01339 if (conf->type == CLIENT_TYPE)
01340 remove_from_cidr_check(&client_p->localClient->ip, aclass);
01341 if (--aclass->curr_user_count == 0 && aclass->active == 0)
01342 delete_conf_item(aclass_conf);
01343 }
01344
01345 if (--aconf->clients == 0 && IsConfIllegal(aconf))
01346 delete_conf_item(conf);
01347
01348 break;
01349
01350 case LEAF_TYPE:
01351 case HUB_TYPE:
01352 match_item = map_to_conf(conf);
01353 if (match_item->ref_count == 0 && match_item->illegal)
01354 delete_conf_item(conf);
01355 break;
01356 default:
01357 break;
01358 }
01359
01360 if (type != CONF_TYPE)
01361 return 0;
01362 }
01363 }
01364
01365 return -1;
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 int
01379 attach_conf(struct Client *client_p, struct ConfItem *conf)
01380 {
01381 if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
01382 return 1;
01383
01384 if (conf->type == CLIENT_TYPE ||
01385 conf->type == SERVER_TYPE ||
01386 conf->type == OPER_TYPE)
01387 {
01388 struct AccessItem *aconf = map_to_conf(conf);
01389 struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
01390
01391 if (IsConfIllegal(aconf))
01392 return NOT_AUTHORIZED;
01393
01394 if (conf->type == CLIENT_TYPE)
01395 if (cidr_limit_reached(IsConfExemptLimits(aconf),
01396 &client_p->localClient->ip, aclass))
01397 return TOO_MANY;
01398
01399 CurrUserCount(aclass)++;
01400 aconf->clients++;
01401 }
01402 else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
01403 {
01404 struct MatchItem *match_item = map_to_conf(conf);
01405 match_item->ref_count++;
01406 }
01407
01408 dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
01409
01410 return 0;
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421 int
01422 attach_connect_block(struct Client *client_p, const char *name,
01423 const char *host)
01424 {
01425 dlink_node *ptr;
01426 struct ConfItem *conf;
01427 struct AccessItem *aconf;
01428
01429 assert(client_p != NULL);
01430 assert(host != NULL);
01431
01432 if (client_p == NULL || host == NULL)
01433 return 0;
01434
01435 DLINK_FOREACH(ptr, server_items.head)
01436 {
01437 conf = ptr->data;
01438 aconf = map_to_conf(conf);
01439
01440 if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
01441 continue;
01442
01443 attach_conf(client_p, conf);
01444 return -1;
01445 }
01446
01447 return 0;
01448 }
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 struct ConfItem *
01461 find_conf_exact(ConfType type, const char *name, const char *user,
01462 const char *host)
01463 {
01464 dlink_node *ptr;
01465 dlink_list *list_p;
01466 struct ConfItem *conf = NULL;
01467 struct AccessItem *aconf;
01468
01469
01470 list_p = map_to_list(type);
01471
01472 DLINK_FOREACH(ptr, (*list_p).head)
01473 {
01474 conf = ptr->data;
01475
01476 if (conf->name == NULL)
01477 continue;
01478 aconf = map_to_conf(conf);
01479 if (aconf->host == NULL)
01480 continue;
01481 if (irccmp(conf->name, name) != 0)
01482 continue;
01483
01484
01485
01486
01487
01488
01489 if (!match(aconf->host, host) || !match(aconf->user, user))
01490 continue;
01491 if (type == OPER_TYPE)
01492 {
01493 struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
01494
01495 if (aconf->clients >= MaxTotal(aclass))
01496 continue;
01497 }
01498
01499 return conf;
01500 }
01501
01502 return NULL;
01503 }
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514 struct ConfItem *
01515 find_conf_name(dlink_list *list, const char *name, ConfType type)
01516 {
01517 dlink_node *ptr;
01518 struct ConfItem* conf;
01519
01520 DLINK_FOREACH(ptr, list->head)
01521 {
01522 conf = ptr->data;
01523
01524 if (conf->type == type)
01525 {
01526 if (conf->name && (irccmp(conf->name, name) == 0 ||
01527 match(conf->name, name)))
01528 return conf;
01529 }
01530 }
01531
01532 return NULL;
01533 }
01534
01535
01536
01537
01538
01539
01540
01541 static dlink_list *
01542 map_to_list(ConfType type)
01543 {
01544 switch(type)
01545 {
01546 case RXLINE_TYPE:
01547 return(&rxconf_items);
01548 break;
01549 case XLINE_TYPE:
01550 return(&xconf_items);
01551 break;
01552 case ULINE_TYPE:
01553 return(&uconf_items);
01554 break;
01555 case NRESV_TYPE:
01556 return(&nresv_items);
01557 break;
01558 case OPER_TYPE:
01559 return(&oconf_items);
01560 break;
01561 case CLASS_TYPE:
01562 return(&class_items);
01563 break;
01564 case SERVER_TYPE:
01565 return(&server_items);
01566 break;
01567 case CLUSTER_TYPE:
01568 return(&cluster_items);
01569 break;
01570 case CONF_TYPE:
01571 case GLINE_TYPE:
01572 case KLINE_TYPE:
01573 case DLINE_TYPE:
01574 case CRESV_TYPE:
01575 default:
01576 return NULL;
01577 }
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590 struct ConfItem *
01591 find_matching_name_conf(ConfType type, const char *name, const char *user,
01592 const char *host, int action)
01593 {
01594 dlink_node *ptr=NULL;
01595 struct ConfItem *conf=NULL;
01596 struct AccessItem *aconf=NULL;
01597 struct MatchItem *match_item=NULL;
01598 dlink_list *list_p = map_to_list(type);
01599
01600 switch (type)
01601 {
01602 case RXLINE_TYPE:
01603 DLINK_FOREACH(ptr, list_p->head)
01604 {
01605 conf = ptr->data;
01606 assert(conf->regexpname);
01607
01608 if (!ircd_pcre_exec(conf->regexpname, name))
01609 return conf;
01610 }
01611 break;
01612
01613 case XLINE_TYPE:
01614 case ULINE_TYPE:
01615 case NRESV_TYPE:
01616 DLINK_FOREACH(ptr, list_p->head)
01617 {
01618 conf = ptr->data;
01619
01620 match_item = map_to_conf(conf);
01621 if (EmptyString(conf->name))
01622 continue;
01623 if ((name != NULL) && match_esc(conf->name, name))
01624 {
01625 if ((user == NULL && (host == NULL)))
01626 return conf;
01627 if ((match_item->action & action) != action)
01628 continue;
01629 if (EmptyString(match_item->user) || EmptyString(match_item->host))
01630 return conf;
01631 if (match(match_item->user, user) && match(match_item->host, host))
01632 return conf;
01633 }
01634 }
01635 break;
01636
01637 case SERVER_TYPE:
01638 DLINK_FOREACH(ptr, list_p->head)
01639 {
01640 conf = ptr->data;
01641 aconf = map_to_conf(conf);
01642
01643 if ((name != NULL) && match_esc(name, conf->name))
01644 return conf;
01645 else if ((host != NULL) && match_esc(host, aconf->host))
01646 return conf;
01647 }
01648 break;
01649
01650 default:
01651 break;
01652 }
01653 return NULL;
01654 }
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665 struct ConfItem *
01666 find_exact_name_conf(ConfType type, const char *name,
01667 const char *user, const char *host)
01668 {
01669 dlink_node *ptr = NULL;
01670 struct AccessItem *aconf;
01671 struct ConfItem *conf;
01672 struct MatchItem *match_item;
01673 dlink_list *list_p;
01674
01675 list_p = map_to_list(type);
01676
01677 switch(type)
01678 {
01679 case RXLINE_TYPE:
01680 case XLINE_TYPE:
01681 case ULINE_TYPE:
01682 case NRESV_TYPE:
01683
01684 DLINK_FOREACH(ptr, list_p->head)
01685 {
01686 conf = ptr->data;
01687 match_item = (struct MatchItem *)map_to_conf(conf);
01688 if (EmptyString(conf->name))
01689 continue;
01690
01691 if (irccmp(conf->name, name) == 0)
01692 {
01693 if ((user == NULL && (host == NULL)))
01694 return (conf);
01695 if (EmptyString(match_item->user) || EmptyString(match_item->host))
01696 return (conf);
01697 if (match(match_item->user, user) && match(match_item->host, host))
01698 return (conf);
01699 }
01700 }
01701 break;
01702
01703 case OPER_TYPE:
01704 DLINK_FOREACH(ptr, list_p->head)
01705 {
01706 conf = ptr->data;
01707 aconf = (struct AccessItem *)map_to_conf(conf);
01708 if (EmptyString(conf->name))
01709 continue;
01710
01711 if (irccmp(conf->name, name) == 0)
01712 {
01713 if ((user == NULL && (host == NULL)))
01714 return (conf);
01715 if (EmptyString(aconf->user) || EmptyString(aconf->host))
01716 return (conf);
01717 if (match(aconf->user, user) && match(aconf->host, host))
01718 return (conf);
01719 }
01720 }
01721 break;
01722
01723 case SERVER_TYPE:
01724 DLINK_FOREACH(ptr, list_p->head)
01725 {
01726 conf = ptr->data;
01727 aconf = (struct AccessItem *)map_to_conf(conf);
01728 if (EmptyString(conf->name))
01729 continue;
01730
01731 if (name == NULL)
01732 {
01733 if (EmptyString(aconf->host))
01734 continue;
01735 if (irccmp(aconf->host, host) == 0)
01736 return(conf);
01737 }
01738 else if (irccmp(conf->name, name) == 0)
01739 {
01740 return (conf);
01741 }
01742 }
01743 break;
01744
01745 case CLASS_TYPE:
01746 DLINK_FOREACH(ptr, list_p->head)
01747 {
01748 conf = ptr->data;
01749 if (EmptyString(conf->name))
01750 continue;
01751
01752 if (irccmp(conf->name, name) == 0)
01753 return (conf);
01754 }
01755 break;
01756
01757 default:
01758 break;
01759 }
01760 return(NULL);
01761 }
01762
01763
01764
01765
01766
01767
01768
01769 int
01770 rehash(int sig)
01771 {
01772 if (sig != 0)
01773 sendto_realops_flags(UMODE_ALL, L_ALL,
01774 "Got signal SIGHUP, reloading ircd.conf file");
01775
01776 #ifndef _WIN32
01777 restart_resolver();
01778 #endif
01779
01780
01781
01782 check_can_use_v6();
01783
01784 read_conf_files(0);
01785
01786 if (ServerInfo.description != NULL)
01787 strlcpy(me.info, ServerInfo.description, sizeof(me.info));
01788
01789 #ifndef STATIC_MODULES
01790 load_conf_modules();
01791 #endif
01792
01793 flush_deleted_I_P();
01794
01795 rehashed_klines = 1;
01796
01797 if (ConfigLoggingEntry.use_logging)
01798 reopen_log(logFileName);
01799
01800 return(0);
01801 }
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812 static void
01813 set_default_conf(void)
01814 {
01815
01816
01817
01818 assert(class_default == (struct ConfItem *) class_items.tail->data);
01819
01820 #ifdef HAVE_LIBCRYPTO
01821 ServerInfo.rsa_private_key = NULL;
01822 ServerInfo.rsa_private_key_file = NULL;
01823 #endif
01824
01825
01826
01827 ServerInfo.description = NULL;
01828 DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
01829 DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
01830
01831 memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
01832 ServerInfo.specific_ipv4_vhost = 0;
01833 memset(&ServerInfo.ip6, 0, sizeof(ServerInfo.ip6));
01834 ServerInfo.specific_ipv6_vhost = 0;
01835
01836 ServerInfo.max_clients = MAXCLIENTS_MAX;
01837
01838
01839 ServerInfo.dns_host.sin_addr.s_addr = 0;
01840 ServerInfo.dns_host.sin_port = 0;
01841 AdminInfo.name = NULL;
01842 AdminInfo.email = NULL;
01843 AdminInfo.description = NULL;
01844
01845 set_log_level(L_NOTICE);
01846 ConfigLoggingEntry.use_logging = 1;
01847 ConfigLoggingEntry.operlog[0] = '\0';
01848 ConfigLoggingEntry.userlog[0] = '\0';
01849 ConfigLoggingEntry.klinelog[0] = '\0';
01850 ConfigLoggingEntry.glinelog[0] = '\0';
01851 ConfigLoggingEntry.killlog[0] = '\0';
01852 ConfigLoggingEntry.operspylog[0] = '\0';
01853 ConfigLoggingEntry.ioerrlog[0] = '\0';
01854 ConfigLoggingEntry.failed_operlog[0] = '\0';
01855
01856 ConfigChannel.disable_fake_channels = NO;
01857 ConfigChannel.restrict_channels = NO;
01858 ConfigChannel.disable_local_channels = NO;
01859 ConfigChannel.use_invex = YES;
01860 ConfigChannel.use_except = YES;
01861 ConfigChannel.use_knock = YES;
01862 ConfigChannel.knock_delay = 300;
01863 ConfigChannel.knock_delay_channel = 60;
01864 ConfigChannel.max_chans_per_user = 15;
01865 ConfigChannel.quiet_on_ban = YES;
01866 ConfigChannel.max_bans = 25;
01867 ConfigChannel.default_split_user_count = 0;
01868 ConfigChannel.default_split_server_count = 0;
01869 ConfigChannel.no_join_on_split = NO;
01870 ConfigChannel.no_create_on_split = NO;
01871 ConfigChannel.burst_topicwho = YES;
01872
01873 ConfigServerHide.flatten_links = NO;
01874 ConfigServerHide.links_delay = 300;
01875 ConfigServerHide.hidden = NO;
01876 ConfigServerHide.disable_hidden = NO;
01877 ConfigServerHide.hide_servers = NO;
01878 DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
01879 ConfigServerHide.hide_server_ips = NO;
01880
01881 ConfigFileEntry.gline_min_cidr = 16;
01882 ConfigFileEntry.gline_min_cidr6 = 48;
01883 ConfigFileEntry.invisible_on_connect = YES;
01884 ConfigFileEntry.burst_away = NO;
01885 ConfigFileEntry.use_whois_actually = YES;
01886 ConfigFileEntry.tkline_expire_notices = YES;
01887 ConfigFileEntry.hide_spoof_ips = YES;
01888 ConfigFileEntry.ignore_bogus_ts = NO;
01889 ConfigFileEntry.disable_auth = NO;
01890 ConfigFileEntry.disable_remote = NO;
01891 ConfigFileEntry.kill_chase_time_limit = 90;
01892 ConfigFileEntry.default_floodcount = 8;
01893 ConfigFileEntry.failed_oper_notice = YES;
01894 ConfigFileEntry.dots_in_ident = 0;
01895 ConfigFileEntry.dot_in_ip6_addr = YES;
01896 ConfigFileEntry.min_nonwildcard = 4;
01897 ConfigFileEntry.min_nonwildcard_simple = 3;
01898 ConfigFileEntry.max_accept = 20;
01899 ConfigFileEntry.anti_nick_flood = NO;
01900 ConfigFileEntry.max_nick_time = 20;
01901 ConfigFileEntry.max_nick_changes = 5;
01902 ConfigFileEntry.anti_spam_exit_message_time = 0;
01903 ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
01904 ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
01905 ConfigFileEntry.kline_with_reason = YES;
01906 ConfigFileEntry.kline_reason = NULL;
01907 ConfigFileEntry.warn_no_nline = YES;
01908 ConfigFileEntry.stats_o_oper_only = NO;
01909 ConfigFileEntry.stats_k_oper_only = 1;
01910 ConfigFileEntry.stats_i_oper_only = 1;
01911 ConfigFileEntry.stats_P_oper_only = NO;
01912 ConfigFileEntry.caller_id_wait = 60;
01913 ConfigFileEntry.opers_bypass_callerid = NO;
01914 ConfigFileEntry.pace_wait = 10;
01915 ConfigFileEntry.pace_wait_simple = 1;
01916 ConfigFileEntry.short_motd = NO;
01917 ConfigFileEntry.ping_cookie = NO;
01918 ConfigFileEntry.no_oper_flood = NO;
01919 ConfigFileEntry.true_no_oper_flood = NO;
01920 ConfigFileEntry.oper_pass_resv = YES;
01921 ConfigFileEntry.glines = NO;
01922 ConfigFileEntry.gline_time = 12 * 3600;
01923 ConfigFileEntry.idletime = 0;
01924 ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
01925 ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
01926 ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
01927 ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
01928 UMODE_OPERWALL | UMODE_WALLOP;
01929 DupString(ConfigFileEntry.servlink_path, SLPATH);
01930 #ifdef HAVE_LIBCRYPTO
01931
01932
01933
01934
01935
01936
01937
01938
01939 ConfigFileEntry.default_cipher_preference = &CipherTable[1];
01940 #endif
01941 ConfigFileEntry.use_egd = NO;
01942 ConfigFileEntry.egdpool_path = NULL;
01943 #ifdef HAVE_LIBZ
01944 ConfigFileEntry.compression_level = 0;
01945 #endif
01946 ConfigFileEntry.throttle_time = 10;
01947 }
01948
01949
01950
01951
01952
01953
01954
01955 static void
01956 read_conf(FBFILE *file)
01957 {
01958 lineno = 0;
01959
01960 set_default_conf();
01961 ypass = 1;
01962 yyparse();
01963
01964 fbrewind(file);
01965
01966 ypass = 2;
01967 yyparse();
01968 validate_conf();
01969
01970 check_class();
01971 }
01972
01973 static void
01974 validate_conf(void)
01975 {
01976 if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
01977 ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
01978
01979 if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
01980 ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
01981
01982 if (ConfigFileEntry.servlink_path == NULL)
01983 DupString(ConfigFileEntry.servlink_path, SLPATH);
01984
01985 if (ServerInfo.network_name == NULL)
01986 DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
01987
01988 if (ServerInfo.network_desc == NULL)
01989 DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
01990
01991 if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
01992 (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
01993 ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
01994 }
01995
01996
01997
01998
01999
02000
02001 static void
02002 lookup_confhost(struct ConfItem *conf)
02003 {
02004 struct AccessItem *aconf;
02005 struct addrinfo hints, *res;
02006
02007 aconf = map_to_conf(conf);
02008
02009 if (EmptyString(aconf->host) ||
02010 EmptyString(aconf->user))
02011 {
02012 ilog(L_ERROR, "Host/server name error: (%s) (%s)",
02013 aconf->host, conf->name);
02014 return;
02015 }
02016
02017 if (strchr(aconf->host, '*') ||
02018 strchr(aconf->host, '?'))
02019 return;
02020
02021
02022
02023
02024 memset(&hints, 0, sizeof(hints));
02025
02026 hints.ai_family = AF_UNSPEC;
02027 hints.ai_socktype = SOCK_STREAM;
02028
02029
02030 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
02031
02032 if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
02033 {
02034 conf_dns_lookup(aconf);
02035 return;
02036 }
02037
02038 assert(res != NULL);
02039
02040 memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
02041 aconf->ipnum.ss_len = res->ai_addrlen;
02042 aconf->ipnum.ss.ss_family = res->ai_family;
02043 irc_freeaddrinfo(res);
02044 }
02045
02046
02047
02048
02049
02050
02051
02052
02053 int
02054 conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
02055 {
02056 struct ip_entry *ip_found;
02057 struct AccessItem *aconf = find_dline_conf(addr, aftype);
02058
02059
02060 if (aconf && (aconf->status & CONF_EXEMPTDLINE))
02061 return 0;
02062
02063 if (aconf != NULL)
02064 return BANNED_CLIENT;
02065
02066 ip_found = find_or_add_ip(addr);
02067
02068 if ((CurrentTime - ip_found->last_attempt) <
02069 ConfigFileEntry.throttle_time)
02070 {
02071 ip_found->last_attempt = CurrentTime;
02072 return TOO_FAST;
02073 }
02074
02075 ip_found->last_attempt = CurrentTime;
02076 return 0;
02077 }
02078
02079 static struct AccessItem *
02080 find_regexp_kline(const char *uhi[])
02081 {
02082 const dlink_node *ptr = NULL;
02083
02084 DLINK_FOREACH(ptr, rkconf_items.head)
02085 {
02086 struct AccessItem *aptr = map_to_conf(ptr->data);
02087
02088 assert(aptr->regexuser);
02089 assert(aptr->regexhost);
02090
02091 if (!ircd_pcre_exec(aptr->regexuser, uhi[0]) &&
02092 (!ircd_pcre_exec(aptr->regexhost, uhi[1]) ||
02093 !ircd_pcre_exec(aptr->regexhost, uhi[2])))
02094 return aptr;
02095 }
02096
02097 return NULL;
02098 }
02099
02100
02101
02102
02103
02104
02105
02106
02107 struct AccessItem *
02108 find_kill(struct Client *client_p)
02109 {
02110 struct AccessItem *aconf = NULL;
02111 const char *uhi[3];
02112
02113 uhi[0] = client_p->username;
02114 uhi[1] = client_p->host;
02115 uhi[2] = client_p->sockhost;
02116
02117 assert(client_p != NULL);
02118
02119 aconf = find_kline_conf(client_p->host, client_p->username,
02120 &client_p->localClient->ip,
02121 client_p->localClient->aftype);
02122 if (aconf == NULL)
02123 aconf = find_regexp_kline(uhi);
02124
02125 if (aconf && (aconf->status & CONF_KLINE))
02126 return aconf;
02127
02128 return NULL;
02129 }
02130
02131 struct AccessItem *
02132 find_gline(struct Client *client_p)
02133 {
02134 struct AccessItem *aconf;
02135
02136 assert(client_p != NULL);
02137
02138 aconf = find_gline_conf(client_p->host, client_p->username,
02139 &client_p->localClient->ip,
02140 client_p->localClient->aftype);
02141
02142 if (aconf && (aconf->status & CONF_GLINE))
02143 return aconf;
02144
02145 return NULL;
02146 }
02147
02148
02149
02150
02151
02152
02153
02154
02155 void
02156 add_temp_line(struct ConfItem *conf)
02157 {
02158 struct AccessItem *aconf;
02159
02160 if (conf->type == DLINE_TYPE)
02161 {
02162 aconf = map_to_conf(conf);
02163 SetConfTemporary(aconf);
02164 dlinkAdd(conf, &conf->node, &temporary_dlines);
02165 MyFree(aconf->user);
02166 aconf->user = NULL;
02167 add_conf_by_address(CONF_DLINE, aconf);
02168 }
02169 else if (conf->type == KLINE_TYPE)
02170 {
02171 aconf = map_to_conf(conf);
02172 SetConfTemporary(aconf);
02173 dlinkAdd(conf, &conf->node, &temporary_klines);
02174 add_conf_by_address(CONF_KILL, aconf);
02175 }
02176 else if (conf->type == GLINE_TYPE)
02177 {
02178 aconf = map_to_conf(conf);
02179 SetConfTemporary(aconf);
02180 dlinkAdd(conf, &conf->node, &temporary_glines);
02181 add_conf_by_address(CONF_GLINE, aconf);
02182 }
02183 else if (conf->type == XLINE_TYPE)
02184 {
02185 conf->flags |= CONF_FLAGS_TEMPORARY;
02186 dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
02187 }
02188 else if (conf->type == RXLINE_TYPE)
02189 {
02190 conf->flags |= CONF_FLAGS_TEMPORARY;
02191 dlinkAdd(conf, make_dlink_node(), &temporary_rxlines);
02192 }
02193 else if (conf->type == RKLINE_TYPE)
02194 {
02195 conf->flags |= CONF_FLAGS_TEMPORARY;
02196 dlinkAdd(conf, make_dlink_node(), &temporary_rklines);
02197 }
02198 else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
02199 {
02200 conf->flags |= CONF_FLAGS_TEMPORARY;
02201 dlinkAdd(conf, make_dlink_node(), &temporary_resv);
02202 }
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212 void
02213 cleanup_tklines(void *notused)
02214 {
02215 expire_tklines(&temporary_glines);
02216 expire_tklines(&temporary_klines);
02217 expire_tklines(&temporary_dlines);
02218 expire_tklines(&temporary_xlines);
02219 expire_tklines(&temporary_rxlines);
02220 expire_tklines(&temporary_rklines);
02221 expire_tklines(&temporary_resv);
02222 }
02223
02224
02225
02226
02227
02228
02229
02230 static void
02231 expire_tklines(dlink_list *tklist)
02232 {
02233 dlink_node *ptr;
02234 dlink_node *next_ptr;
02235 struct ConfItem *conf;
02236 struct MatchItem *xconf;
02237 struct MatchItem *nconf;
02238 struct AccessItem *aconf;
02239 struct ResvChannel *cconf;
02240
02241 DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
02242 {
02243 conf = ptr->data;
02244 if (conf->type == GLINE_TYPE ||
02245 conf->type == KLINE_TYPE ||
02246 conf->type == DLINE_TYPE)
02247 {
02248 aconf = (struct AccessItem *)map_to_conf(conf);
02249 if (aconf->hold <= CurrentTime)
02250 {
02251
02252
02253 if (ConfigFileEntry.tkline_expire_notices)
02254 {
02255 if (aconf->status & CONF_KILL)
02256 {
02257 sendto_realops_flags(UMODE_ALL, L_ALL,
02258 "Temporary K-line for [%s@%s] expired",
02259 (aconf->user) ? aconf->user : "*",
02260 (aconf->host) ? aconf->host : "*");
02261 }
02262 else if (conf->type == DLINE_TYPE)
02263 {
02264 sendto_realops_flags(UMODE_ALL, L_ALL,
02265 "Temporary D-line for [%s] expired",
02266 (aconf->host) ? aconf->host : "*");
02267 }
02268 }
02269
02270 dlinkDelete(ptr, tklist);
02271 delete_one_address_conf(aconf->host, aconf);
02272 }
02273 }
02274 else if (conf->type == XLINE_TYPE ||
02275 conf->type == RXLINE_TYPE)
02276 {
02277 xconf = (struct MatchItem *)map_to_conf(conf);
02278 if (xconf->hold <= CurrentTime)
02279 {
02280 if (ConfigFileEntry.tkline_expire_notices)
02281 sendto_realops_flags(UMODE_ALL, L_ALL,
02282 "Temporary X-line for [%s] %sexpired", conf->name,
02283 conf->type == RXLINE_TYPE ? "(REGEX) " : "");
02284 dlinkDelete(ptr, tklist);
02285 free_dlink_node(ptr);
02286 delete_conf_item(conf);
02287 }
02288 }
02289 else if (conf->type == RKLINE_TYPE)
02290 {
02291 aconf = map_to_conf(conf);
02292 if (aconf->hold <= CurrentTime)
02293 {
02294 if (ConfigFileEntry.tkline_expire_notices)
02295 sendto_realops_flags(UMODE_ALL, L_ALL,
02296 "Temporary K-line for [%s@%s] (REGEX) expired",
02297 (aconf->user) ? aconf->user : "*",
02298 (aconf->host) ? aconf->host : "*");
02299 dlinkDelete(ptr, tklist);
02300 free_dlink_node(ptr);
02301 delete_conf_item(conf);
02302 }
02303 }
02304 else if (conf->type == NRESV_TYPE)
02305 {
02306 nconf = (struct MatchItem *)map_to_conf(conf);
02307 if (nconf->hold <= CurrentTime)
02308 {
02309 if (ConfigFileEntry.tkline_expire_notices)
02310 sendto_realops_flags(UMODE_ALL, L_ALL,
02311 "Temporary RESV for [%s] expired", conf->name);
02312 dlinkDelete(ptr, tklist);
02313 free_dlink_node(ptr);
02314 delete_conf_item(conf);
02315 }
02316 }
02317 else if (conf->type == CRESV_TYPE)
02318 {
02319 cconf = (struct ResvChannel *)map_to_conf(conf);
02320 if (cconf->hold <= CurrentTime)
02321 {
02322 if (ConfigFileEntry.tkline_expire_notices)
02323 sendto_realops_flags(UMODE_ALL, L_ALL,
02324 "Temporary RESV for [%s] expired", cconf->name);
02325 delete_channel_resv(cconf);
02326 }
02327 }
02328 }
02329 }
02330
02331
02332
02333
02334
02335
02336
02337 static const struct oper_privs
02338 {
02339 const unsigned int oprivs;
02340 const unsigned int hidden;
02341 const unsigned char c;
02342 } flag_list[] = {
02343 { OPER_FLAG_ADMIN, OPER_FLAG_HIDDEN_ADMIN, 'A' },
02344 { OPER_FLAG_REMOTEBAN, 0, 'B' },
02345 { OPER_FLAG_DIE, 0, 'D' },
02346 { OPER_FLAG_GLINE, 0, 'G' },
02347 { OPER_FLAG_REHASH, 0, 'H' },
02348 { OPER_FLAG_K, 0, 'K' },
02349 { OPER_FLAG_OPERWALL, 0, 'L' },
02350 { OPER_FLAG_N, 0, 'N' },
02351 { OPER_FLAG_GLOBAL_KILL, 0, 'O' },
02352 { OPER_FLAG_REMOTE, 0, 'R' },
02353 { OPER_FLAG_OPER_SPY, 0, 'S' },
02354 { OPER_FLAG_UNKLINE, 0, 'U' },
02355 { OPER_FLAG_X, 0, 'X' },
02356 { 0, 0, '\0' }
02357 };
02358
02359 char *
02360 oper_privs_as_string(const unsigned int port)
02361 {
02362 static char privs_out[16];
02363 char *privs_ptr = privs_out;
02364 unsigned int i = 0;
02365
02366 for (; flag_list[i].oprivs; ++i)
02367 {
02368 if ((port & flag_list[i].oprivs) &&
02369 (port & flag_list[i].hidden) == 0)
02370 *privs_ptr++ = flag_list[i].c;
02371 else
02372 *privs_ptr++ = ToLowerTab[flag_list[i].c];
02373 }
02374
02375 *privs_ptr = '\0';
02376
02377 return privs_out;
02378 }
02379
02380
02381
02382
02383
02384
02385
02386 char *
02387 get_oper_name(const struct Client *client_p)
02388 {
02389 dlink_node *cnode;
02390 struct ConfItem *conf;
02391 struct AccessItem *aconf;
02392
02393
02394 static char buffer[NICKLEN+USERLEN+HOSTLEN+HOSTLEN+5];
02395
02396 if (MyConnect(client_p))
02397 {
02398 DLINK_FOREACH(cnode, client_p->localClient->confs.head)
02399 {
02400 conf = cnode->data;
02401 aconf = map_to_conf(conf);
02402
02403 if (IsConfOperator(aconf))
02404 {
02405 ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
02406 client_p->username, client_p->host,
02407 conf->name);
02408 return buffer;
02409 }
02410 }
02411
02412
02413
02414
02415 assert(0);
02416 }
02417
02418 ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
02419 client_p->username, client_p->host, client_p->servptr->name);
02420 return buffer;
02421 }
02422
02423
02424
02425
02426
02427
02428
02429 void
02430 read_conf_files(int cold)
02431 {
02432 const char *filename;
02433 char chanmodes[32];
02434 char chanlimit[32];
02435
02436 filename = get_conf_name(CONF_TYPE);
02437
02438
02439
02440
02441
02442
02443
02444 strlcpy(conffilebuf, filename, sizeof(conffilebuf));
02445
02446 if ((conf_fbfile_in = fbopen(filename, "r")) == NULL)
02447 {
02448 if (cold)
02449 {
02450 ilog(L_CRIT, "Unable to read configuration file '%s': %s",
02451 filename, strerror(errno));
02452 exit(-1);
02453 }
02454 else
02455 {
02456 sendto_realops_flags(UMODE_ALL, L_ALL,
02457 "Unable to read configuration file '%s': %s",
02458 filename, strerror(errno));
02459 return;
02460 }
02461 }
02462
02463 if (!cold)
02464 clear_out_old_conf();
02465
02466 read_conf(conf_fbfile_in);
02467 fbclose(conf_fbfile_in);
02468
02469 add_isupport("NETWORK", ServerInfo.network_name, -1);
02470 ircsprintf(chanmodes, "b%s%s:%d", ConfigChannel.use_except ? "e" : "",
02471 ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
02472 add_isupport("MAXLIST", chanmodes, -1);
02473 add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
02474 if (ConfigChannel.disable_local_channels)
02475 add_isupport("CHANTYPES", "#", -1);
02476 else
02477 add_isupport("CHANTYPES", "#&", -1);
02478 ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
02479 ConfigChannel.max_chans_per_user);
02480 add_isupport("CHANLIMIT", chanlimit, -1);
02481 ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
02482 ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
02483 add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
02484 if (ConfigChannel.use_except)
02485 add_isupport("EXCEPTS", "e", -1);
02486 if (ConfigChannel.use_invex)
02487 add_isupport("INVEX", "I", -1);
02488 add_isupport("CHANMODES", "cCeIb,k,l,imnOpst", -1);
02489
02490
02491
02492
02493
02494 rebuild_isupport_message_line();
02495
02496 parse_conf_file(KLINE_TYPE, cold);
02497 parse_conf_file(RKLINE_TYPE, cold);
02498 parse_conf_file(DLINE_TYPE, cold);
02499 parse_conf_file(XLINE_TYPE, cold);
02500 parse_conf_file(RXLINE_TYPE, cold);
02501 parse_conf_file(NRESV_TYPE, cold);
02502 parse_conf_file(CRESV_TYPE, cold);
02503 }
02504
02505
02506
02507
02508
02509
02510
02511 static void
02512 parse_conf_file(int type, int cold)
02513 {
02514 FBFILE *file = NULL;
02515 const char *filename = get_conf_name(type);
02516
02517 if ((file = fbopen(filename, "r")) == NULL)
02518 {
02519 if (cold)
02520 ilog(L_ERROR, "Unable to read configuration file '%s': %s",
02521 filename, strerror(errno));
02522 else
02523 sendto_realops_flags(UMODE_ALL, L_ALL,
02524 "Unable to read configuration file '%s': %s",
02525 filename, strerror(errno));
02526 }
02527 else
02528 {
02529 parse_csv_file(file, type);
02530 fbclose(file);
02531 }
02532 }
02533
02534
02535
02536
02537
02538
02539
02540 static void
02541 clear_out_old_conf(void)
02542 {
02543 dlink_node *ptr = NULL, *next_ptr = NULL;
02544 struct ConfItem *conf;
02545 struct AccessItem *aconf;
02546 struct ClassItem *cltmp;
02547 struct MatchItem *match_item;
02548 dlink_list *free_items [] = {
02549 &server_items, &oconf_items, &hub_items, &leaf_items,
02550 &uconf_items, &xconf_items, &rxconf_items, &rkconf_items,
02551 &nresv_items, &cluster_items, &gdeny_items, NULL
02552 };
02553
02554 dlink_list ** iterator = free_items;
02555
02556
02557
02558
02559
02560 for (; *iterator != NULL; iterator++)
02561 {
02562 DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
02563 {
02564 conf = ptr->data;
02565
02566 if (conf->type == SERVER_TYPE)
02567 {
02568 aconf = map_to_conf(conf);
02569
02570 if (aconf->clients != 0)
02571 {
02572 SetConfIllegal(aconf);
02573 dlinkDelete(&conf->node, &server_items);
02574 }
02575 else
02576 {
02577 delete_conf_item(conf);
02578 }
02579 }
02580 else if (conf->type == OPER_TYPE)
02581 {
02582 aconf = map_to_conf(conf);
02583
02584 if (aconf->clients != 0)
02585 {
02586 SetConfIllegal(aconf);
02587 dlinkDelete(&conf->node, &oconf_items);
02588 }
02589 else
02590 {
02591 delete_conf_item(conf);
02592 }
02593 }
02594 else if (conf->type == CLIENT_TYPE)
02595 {
02596 aconf = map_to_conf(conf);
02597
02598 if (aconf->clients != 0)
02599 {
02600 SetConfIllegal(aconf);
02601 }
02602 else
02603 {
02604 delete_conf_item(conf);
02605 }
02606 }
02607 else if (conf->type == XLINE_TYPE ||
02608 conf->type == RXLINE_TYPE ||
02609 conf->type == RKLINE_TYPE)
02610 {
02611
02612
02613 if (conf->flags & CONF_FLAGS_TEMPORARY)
02614 continue;
02615
02616 delete_conf_item(conf);
02617 }
02618 else
02619 {
02620 if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
02621 {
02622 match_item = map_to_conf(conf);
02623 if (match_item->ref_count <= 0)
02624 delete_conf_item(conf);
02625 else
02626 {
02627 match_item->illegal = 1;
02628 dlinkDelete(&conf->node, *iterator);
02629 }
02630 }
02631 else
02632 delete_conf_item(conf);
02633 }
02634 }
02635 }
02636
02637
02638
02639
02640
02641 DLINK_FOREACH(ptr, class_items.head)
02642 {
02643 cltmp = map_to_conf(ptr->data);
02644
02645 if (ptr != class_items.tail)
02646 cltmp->active = 0;
02647 }
02648
02649 clear_out_address_conf();
02650
02651
02652 #ifndef STATIC_MODULES
02653 mod_clear_paths();
02654 #endif
02655
02656
02657 MyFree(ServerInfo.description);
02658 ServerInfo.description = NULL;
02659 MyFree(ServerInfo.network_name);
02660 ServerInfo.network_name = NULL;
02661 MyFree(ServerInfo.network_desc);
02662 ServerInfo.network_desc = NULL;
02663 MyFree(ConfigFileEntry.egdpool_path);
02664 ConfigFileEntry.egdpool_path = NULL;
02665
02666 #ifdef HAVE_LIBCRYPTO
02667 if (ServerInfo.rsa_private_key != NULL)
02668 {
02669 RSA_free(ServerInfo.rsa_private_key);
02670 ServerInfo.rsa_private_key = NULL;
02671 }
02672
02673 MyFree(ServerInfo.rsa_private_key_file);
02674 ServerInfo.rsa_private_key_file = NULL;
02675 #endif
02676
02677
02678 clear_conf_resv();
02679
02680
02681 MyFree(AdminInfo.name);
02682 AdminInfo.name = NULL;
02683 MyFree(AdminInfo.email);
02684 AdminInfo.email = NULL;
02685 MyFree(AdminInfo.description);
02686 AdminInfo.description = NULL;
02687
02688
02689
02690 close_listeners();
02691
02692
02693
02694
02695
02696
02697 MyFree(ConfigFileEntry.servlink_path);
02698 ConfigFileEntry.servlink_path = NULL;
02699 #ifdef HAVE_LIBCRYPTO
02700 ConfigFileEntry.default_cipher_preference = NULL;
02701 #endif
02702 delete_isupport("INVEX");
02703 delete_isupport("EXCEPTS");
02704 }
02705
02706
02707
02708
02709
02710
02711
02712 static void
02713 flush_deleted_I_P(void)
02714 {
02715 dlink_node *ptr;
02716 dlink_node *next_ptr;
02717 struct ConfItem *conf;
02718 struct AccessItem *aconf;
02719 dlink_list * free_items [] = {
02720 &server_items, &oconf_items, NULL
02721 };
02722 dlink_list ** iterator = free_items;
02723
02724
02725
02726
02727 for (; *iterator != NULL; iterator++)
02728 {
02729 DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
02730 {
02731 conf = ptr->data;
02732 aconf = (struct AccessItem *)map_to_conf(conf);
02733
02734 if (IsConfIllegal(aconf))
02735 {
02736 dlinkDelete(ptr, *iterator);
02737
02738 if (aconf->clients == 0)
02739 delete_conf_item(conf);
02740 }
02741 }
02742 }
02743 }
02744
02745
02746
02747
02748
02749
02750
02751 const char *
02752 get_conf_name(ConfType type)
02753 {
02754 switch (type)
02755 {
02756 case CONF_TYPE:
02757 return ConfigFileEntry.configfile;
02758 break;
02759 case KLINE_TYPE:
02760 return ConfigFileEntry.klinefile;
02761 break;
02762 case RKLINE_TYPE:
02763 return ConfigFileEntry.rklinefile;
02764 break;
02765 case DLINE_TYPE:
02766 return ConfigFileEntry.dlinefile;
02767 break;
02768 case XLINE_TYPE:
02769 return ConfigFileEntry.xlinefile;
02770 break;
02771 case RXLINE_TYPE:
02772 return ConfigFileEntry.rxlinefile;
02773 break;
02774 case CRESV_TYPE:
02775 return ConfigFileEntry.cresvfile;
02776 break;
02777 case NRESV_TYPE:
02778 return ConfigFileEntry.nresvfile;
02779 break;
02780 case GLINE_TYPE:
02781 return ConfigFileEntry.glinefile;
02782 break;
02783
02784 default:
02785 return NULL;
02786
02787
02788 }
02789 }
02790
02791 #define BAD_PING (-1)
02792
02793
02794
02795
02796
02797
02798
02799
02800 static int
02801 get_conf_ping(struct ConfItem *conf, int *pingwarn)
02802 {
02803 struct ClassItem *aclass;
02804 struct AccessItem *aconf;
02805
02806 if (conf != NULL)
02807 {
02808 aconf = (struct AccessItem *)map_to_conf(conf);
02809 if (aconf->class_ptr != NULL)
02810 {
02811 aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
02812 *pingwarn = PingWarning(aclass);
02813 return PingFreq(aclass);
02814 }
02815 }
02816
02817 return BAD_PING;
02818 }
02819
02820
02821
02822
02823
02824
02825
02826 const char *
02827 get_client_class(struct Client *target_p)
02828 {
02829 dlink_node *ptr;
02830 struct ConfItem *conf;
02831 struct AccessItem *aconf;
02832
02833 if (target_p != NULL && !IsMe(target_p) &&
02834 target_p->localClient->confs.head != NULL)
02835 {
02836 DLINK_FOREACH(ptr, target_p->localClient->confs.head)
02837 {
02838 conf = ptr->data;
02839
02840 if (conf->type == CLIENT_TYPE || conf->type == SERVER_TYPE ||
02841 conf->type == OPER_TYPE)
02842 {
02843 aconf = (struct AccessItem *) map_to_conf(conf);
02844 if (aconf->class_ptr != NULL)
02845 return aconf->class_ptr->name;
02846 }
02847 }
02848 }
02849
02850 return "default";
02851 }
02852
02853
02854
02855
02856
02857
02858
02859
02860 int
02861 get_client_ping(struct Client *target_p, int *pingwarn)
02862 {
02863 int ping;
02864 struct ConfItem *conf;
02865 dlink_node *nlink;
02866
02867 if (target_p->localClient->confs.head != NULL)
02868 DLINK_FOREACH(nlink, target_p->localClient->confs.head)
02869 {
02870 conf = nlink->data;
02871
02872 if ((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
02873 (conf->type == OPER_TYPE))
02874 {
02875 ping = get_conf_ping(conf, pingwarn);
02876 if (ping > 0)
02877 return ping;
02878 }
02879 }
02880
02881 *pingwarn = 0;
02882 return DEFAULT_PINGFREQUENCY;
02883 }
02884
02885
02886
02887
02888
02889
02890
02891 struct ConfItem *
02892 find_class(const char *classname)
02893 {
02894 struct ConfItem *conf;
02895
02896 if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
02897 return conf;
02898
02899 return class_default;
02900 }
02901
02902
02903
02904
02905
02906
02907
02908 void
02909 check_class(void)
02910 {
02911 dlink_node *ptr = NULL, *next_ptr = NULL;
02912
02913 DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
02914 {
02915 struct ClassItem *aclass = map_to_conf(ptr->data);
02916
02917 if (!aclass->active && !CurrUserCount(aclass))
02918 {
02919 destroy_cidr_class(aclass);
02920 delete_conf_item(ptr->data);
02921 }
02922 }
02923 }
02924
02925
02926
02927
02928
02929
02930
02931 void
02932 init_class(void)
02933 {
02934 struct ClassItem *aclass;
02935
02936 class_default = make_conf_item(CLASS_TYPE);
02937
02938 aclass = map_to_conf(class_default);
02939 aclass->active = 1;
02940 DupString(class_default->name, "default");
02941 ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
02942 PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
02943 MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
02944 MaxSendq(aclass) = DEFAULT_SENDQ;
02945
02946 client_check_cb = register_callback("check_client", check_client);
02947 }
02948
02949
02950
02951
02952
02953
02954
02955 unsigned long
02956 get_sendq(struct Client *client_p)
02957 {
02958 unsigned long sendq = DEFAULT_SENDQ;
02959 dlink_node *ptr;
02960 struct ConfItem *conf;
02961 struct ConfItem *class_conf;
02962 struct ClassItem *aclass;
02963 struct AccessItem *aconf;
02964
02965 if (client_p && !IsMe(client_p) && (client_p->localClient->confs.head))
02966 {
02967 DLINK_FOREACH(ptr, client_p->localClient->confs.head)
02968 {
02969 conf = ptr->data;
02970 if ((conf->type == SERVER_TYPE) || (conf->type == OPER_TYPE)
02971 || (conf->type == CLIENT_TYPE))
02972 {
02973 aconf = (struct AccessItem *)map_to_conf(conf);
02974 if ((class_conf = aconf->class_ptr) == NULL)
02975 continue;
02976 aclass = (struct ClassItem *)map_to_conf(class_conf);
02977 sendq = MaxSendq(aclass);
02978 return sendq;
02979 }
02980 }
02981 }
02982
02983
02984
02985
02986 return DEFAULT_SENDQ;
02987 }
02988
02989
02990
02991
02992
02993
02994
02995 void
02996 conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
02997 {
02998 struct AccessItem *aconf = map_to_conf(conf);
02999 struct ClassItem *class = NULL;
03000
03001 if (class_name == NULL)
03002 {
03003 aconf->class_ptr = class_default;
03004
03005 if (conf->type == CLIENT_TYPE)
03006 sendto_realops_flags(UMODE_ALL, L_ALL,
03007 "Warning *** Defaulting to default class for %s@%s",
03008 aconf->user, aconf->host);
03009 else
03010 sendto_realops_flags(UMODE_ALL, L_ALL,
03011 "Warning *** Defaulting to default class for %s",
03012 conf->name);
03013 }
03014 else
03015 aconf->class_ptr = find_class(class_name);
03016
03017 if (aconf->class_ptr)
03018 class = map_to_conf(aconf->class_ptr);
03019
03020 if (aconf->class_ptr == NULL || !class->active)
03021 {
03022 if (conf->type == CLIENT_TYPE)
03023 sendto_realops_flags(UMODE_ALL, L_ALL,
03024 "Warning *** Defaulting to default class for %s@%s",
03025 aconf->user, aconf->host);
03026 else
03027 sendto_realops_flags(UMODE_ALL, L_ALL,
03028 "Warning *** Defaulting to default class for %s",
03029 conf->name);
03030 aconf->class_ptr = class_default;
03031 }
03032 }
03033
03034
03035
03036
03037
03038
03039
03040
03041 int
03042 conf_add_server(struct ConfItem *conf, const char *class_name)
03043 {
03044 struct AccessItem *aconf;
03045 struct split_nuh_item nuh;
03046 char conf_user[USERLEN + 1];
03047 char conf_host[HOSTLEN + 1];
03048
03049 aconf = map_to_conf(conf);
03050
03051 conf_add_class_to_conf(conf, class_name);
03052
03053 if (!aconf->host || !conf->name)
03054 {
03055 sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
03056 ilog(L_WARN, "Bad connect block");
03057 return -1;
03058 }
03059
03060 if (EmptyString(aconf->passwd) && !IsConfCryptLink(aconf))
03061 {
03062 sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s",
03063 conf->name);
03064 ilog(L_WARN, "Bad connect block, host %s", conf->name);
03065 return -1;
03066 }
03067
03068 nuh.nuhmask = aconf->host;
03069 nuh.nickptr = NULL;
03070 nuh.userptr = conf_user;
03071 nuh.hostptr = conf_host;
03072
03073 nuh.nicksize = 0;
03074 nuh.usersize = sizeof(conf_user);
03075 nuh.hostsize = sizeof(conf_host);
03076
03077 split_nuh(&nuh);
03078
03079 MyFree(aconf->host);
03080 aconf->host = NULL;
03081
03082 DupString(aconf->user, conf_user);
03083
03084 DupString(aconf->host, conf_host);
03085
03086 lookup_confhost(conf);
03087
03088 return 0;
03089 }
03090
03091
03092
03093
03094
03095
03096
03097 void
03098 conf_add_d_conf(struct AccessItem *aconf)
03099 {
03100 if (aconf->host == NULL)
03101 return;
03102
03103 aconf->user = NULL;
03104
03105
03106
03107
03108 if (parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
03109 {
03110 ilog(L_WARN, "Invalid Dline %s ignored", aconf->host);
03111 free_access_item(aconf);
03112 }
03113 else
03114 {
03115
03116 MyFree(aconf->user);
03117 aconf->user = NULL;
03118 add_conf_by_address(CONF_DLINE, aconf);
03119 }
03120 }
03121
03122
03123
03124
03125
03126
03127
03128 void
03129 yyerror(const char *msg)
03130 {
03131 char newlinebuf[IRCD_BUFSIZE];
03132
03133 if (ypass != 1)
03134 return;
03135
03136 strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
03137 sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
03138 conffilebuf, lineno + 1, msg, newlinebuf);
03139 ilog(L_WARN, "\"%s\", line %u: %s: %s",
03140 conffilebuf, lineno + 1, msg, newlinebuf);
03141 }
03142
03143 int
03144 conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
03145 {
03146 if (fbgets(lbuf, max_size, fb) == NULL)
03147 return 0;
03148
03149 return strlen(lbuf);
03150 }
03151
03152 int
03153 conf_yy_fatal_error(const char *msg)
03154 {
03155 return 0;
03156 }
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168 time_t
03169 valid_tkline(char *p, int minutes)
03170 {
03171 time_t result = 0;
03172
03173 while (*p)
03174 {
03175 if (IsDigit(*p))
03176 {
03177 result *= 10;
03178 result += ((*p) & 0xF);
03179 p++;
03180 }
03181 else
03182 return 0;
03183 }
03184
03185
03186
03187
03188
03189
03190 if (result == 0)
03191 result = 1;
03192
03193
03194
03195
03196
03197 if (!minutes)
03198 result = result / (time_t)60;
03199
03200 if (result > MAX_TDKLINE_TIME)
03201 result = MAX_TDKLINE_TIME;
03202
03203 result = result * (time_t)60;
03204
03205 return result;
03206 }
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216 int
03217 valid_wild_card(struct Client *source_p, int warn, int count, ...)
03218 {
03219 char *p;
03220 char tmpch;
03221 int nonwild = 0;
03222 va_list args;
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236 va_start(args, count);
03237
03238 while (count--)
03239 {
03240 p = va_arg(args, char *);
03241 if (p == NULL)
03242 continue;
03243
03244 while ((tmpch = *p++))
03245 {
03246 if (!IsKWildChar(tmpch))
03247 {
03248
03249
03250
03251
03252 if (++nonwild >= ConfigFileEntry.min_nonwildcard)
03253 return 1;
03254 }
03255 }
03256 }
03257
03258 if (warn)
03259 sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the mask",
03260 me.name, source_p->name, ConfigFileEntry.min_nonwildcard);
03261 return 0;
03262 }
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294 int
03295 parse_aline(const char *cmd, struct Client *source_p,
03296 int parc, char **parv,
03297 int parse_flags, char **up_p, char **h_p, time_t *tkline_time,
03298 char **target_server, char **reason)
03299 {
03300 int found_tkline_time=0;
03301 static char def_reason[] = "No Reason";
03302 static char user[USERLEN*4+1];
03303 static char host[HOSTLEN*4+1];
03304
03305 parv++;
03306 parc--;
03307
03308 found_tkline_time = valid_tkline(*parv, TK_MINUTES);
03309
03310 if (found_tkline_time != 0)
03311 {
03312 parv++;
03313 parc--;
03314
03315 if (tkline_time != NULL)
03316 *tkline_time = found_tkline_time;
03317 else
03318 {
03319 sendto_one(source_p, ":%s NOTICE %s :temp_line not supported by %s",
03320 me.name, source_p->name, cmd);
03321 return -1;
03322 }
03323 }
03324
03325 if (parc == 0)
03326 {
03327 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
03328 me.name, source_p->name, cmd);
03329 return -1;
03330 }
03331
03332 if (h_p == NULL)
03333 *up_p = *parv;
03334 else
03335 {
03336 if (find_user_host(source_p, *parv, user, host, parse_flags) == 0)
03337 return -1;
03338
03339 *up_p = user;
03340 *h_p = host;
03341 }
03342
03343 parc--;
03344 parv++;
03345
03346 if (parc != 0)
03347 {
03348 if (irccmp(*parv, "ON") == 0)
03349 {
03350 parc--;
03351 parv++;
03352
03353 if (target_server == NULL)
03354 {
03355 sendto_one(source_p, ":%s NOTICE %s :ON server not supported by %s",
03356 me.name, source_p->name, cmd);
03357 return -1;
03358 }
03359
03360 if (!IsOperRemoteBan(source_p))
03361 {
03362 sendto_one(source_p, form_str(ERR_NOPRIVS),
03363 me.name, source_p->name, "remoteban");
03364 return -1;
03365 }
03366
03367 if (parc == 0 || EmptyString(*parv))
03368 {
03369 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
03370 me.name, source_p->name, cmd);
03371 return -1;
03372 }
03373
03374 *target_server = *parv;
03375 parc--;
03376 parv++;
03377 }
03378 else
03379 {
03380
03381
03382
03383 if (target_server != NULL)
03384 *target_server = NULL;
03385 }
03386 }
03387
03388 if (h_p != NULL)
03389 {
03390 if (strchr(user, '!') != NULL)
03391 {
03392 sendto_one(source_p, ":%s NOTICE %s :Invalid character '!' in kline",
03393 me.name, source_p->name);
03394 return -1;
03395 }
03396
03397 if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
03398 return -1;
03399 }
03400 else
03401 if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
03402 return -1;
03403
03404 if (reason != NULL)
03405 {
03406 if (parc != 0)
03407 {
03408 *reason = *parv;
03409 if (!valid_comment(source_p, *reason, YES))
03410 return -1;
03411 }
03412 else
03413 *reason = def_reason;
03414 }
03415
03416 return 1;
03417 }
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428 static int
03429 find_user_host(struct Client *source_p, char *user_host_or_nick,
03430 char *luser, char *lhost, unsigned int flags)
03431 {
03432 struct Client *target_p = NULL;
03433 char *hostp = NULL;
03434
03435 if (lhost == NULL)
03436 {
03437 strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
03438 return 1;
03439 }
03440
03441 if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*')
03442 {
03443
03444
03445 if (hostp != NULL)
03446 {
03447 *(hostp++) = '\0';
03448 if (*user_host_or_nick)
03449 strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
03450 else
03451 strcpy(luser, "*");
03452 if (*hostp)
03453 strlcpy(lhost, hostp, HOSTLEN + 1);
03454 else
03455 strcpy(lhost, "*");
03456 }
03457 else
03458 {
03459 luser[0] = '*';
03460 luser[1] = '\0';
03461 strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1);
03462 }
03463
03464 return 1;
03465 }
03466 else if (!(flags & NOUSERLOOKUP))
03467 {
03468
03469
03470 if ((target_p =
03471 find_chasing(source_p, source_p, user_host_or_nick, NULL)) == NULL)
03472 return 0;
03473
03474 if (IsExemptKline(target_p))
03475 {
03476 if (!IsServer(source_p))
03477 sendto_one(source_p,
03478 ":%s NOTICE %s :%s is E-lined",
03479 me.name, source_p->name, target_p->name);
03480 return 0;
03481 }
03482
03483
03484
03485
03486
03487 strlcpy(luser, target_p->username, USERLEN*4 + 1);
03488
03489 if (target_p->username[0] == '~')
03490 luser[0] = '*';
03491
03492 if (target_p->sockhost[0] == '\0' ||
03493 (target_p->sockhost[0] == '0' && target_p->sockhost[1] == '\0'))
03494 strlcpy(lhost, target_p->host, HOSTLEN*4 + 1);
03495 else
03496 strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1);
03497 return 1;
03498 }
03499
03500 return 0;
03501 }
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511 int
03512 valid_comment(struct Client *source_p, char *comment, int warn)
03513 {
03514 if (strchr(comment, '"'))
03515 {
03516 if (warn)
03517 sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
03518 me.name, source_p->name);
03519 return 0;
03520 }
03521
03522 if (strlen(comment) > REASONLEN)
03523 comment[REASONLEN-1] = '\0';
03524
03525 return 1;
03526 }
03527
03528
03529
03530
03531
03532
03533
03534
03535 int
03536 match_conf_password(const char *password, const struct AccessItem *aconf)
03537 {
03538 const char *encr = NULL;
03539
03540 if (password == NULL || aconf->passwd == NULL)
03541 return 0;
03542
03543 if (aconf->flags & CONF_FLAGS_ENCRYPTED)
03544 {
03545
03546
03547
03548
03549
03550
03551 if (*aconf->passwd)
03552 encr = crypt(password, aconf->passwd);
03553 else
03554 encr = "";
03555 }
03556 else
03557 encr = password;
03558
03559 return !strcmp(encr, aconf->passwd);
03560 }
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574 void
03575 cluster_a_line(struct Client *source_p, const char *command,
03576 int capab, int cluster_type, const char *pattern, ...)
03577 {
03578 va_list args;
03579 char buffer[IRCD_BUFSIZE];
03580 const dlink_node *ptr = NULL;
03581
03582 va_start(args, pattern);
03583 vsnprintf(buffer, sizeof(buffer), pattern, args);
03584 va_end(args);
03585
03586 DLINK_FOREACH(ptr, cluster_items.head)
03587 {
03588 const struct ConfItem *conf = ptr->data;
03589
03590 if (conf->flags & cluster_type)
03591 sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
03592 "%s %s %s", command, conf->name, buffer);
03593 }
03594 }
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624 void
03625 split_nuh(struct split_nuh_item *const iptr)
03626 {
03627 char *p = NULL, *q = NULL;
03628
03629 if (iptr->nickptr)
03630 strlcpy(iptr->nickptr, "*", iptr->nicksize);
03631 if (iptr->userptr)
03632 strlcpy(iptr->userptr, "*", iptr->usersize);
03633 if (iptr->hostptr)
03634 strlcpy(iptr->hostptr, "*", iptr->hostsize);
03635
03636 if ((p = strchr(iptr->nuhmask, '!')))
03637 {
03638 *p = '\0';
03639
03640 if (iptr->nickptr && *iptr->nuhmask != '\0')
03641 strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
03642
03643 if ((q = strchr(++p, '@'))) {
03644 *q++ = '\0';
03645
03646 if (*p != '\0')
03647 strlcpy(iptr->userptr, p, iptr->usersize);
03648
03649 if (*q != '\0')
03650 strlcpy(iptr->hostptr, q, iptr->hostsize);
03651 }
03652 else
03653 {
03654 if (*p != '\0')
03655 strlcpy(iptr->userptr, p, iptr->usersize);
03656 }
03657 }
03658 else
03659 {
03660
03661 if ((p = strchr(iptr->nuhmask, '@')))
03662 {
03663
03664 *p++ = '\0';
03665
03666 if (*iptr->nuhmask != '\0')
03667 strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
03668
03669 if (*p != '\0')
03670 strlcpy(iptr->hostptr, p, iptr->hostsize);
03671 }
03672 else
03673 {
03674
03675 if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
03676 strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
03677 else
03678 strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
03679 }
03680 }
03681 }
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694 static void
03695 flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
03696 int lowerit)
03697 {
03698 unsigned int mask = 1;
03699 int i = 0;
03700
03701 for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
03702 {
03703 if (flags & mask)
03704 *p++ = bit_table[i];
03705 else if (lowerit)
03706 *p++ = ToLower(bit_table[i]);
03707 }
03708 *p = '\0';
03709 }
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721 static int
03722 cidr_limit_reached(int over_rule,
03723 struct irc_ssaddr *ip, struct ClassItem *aclass)
03724 {
03725 dlink_node *ptr = NULL;
03726 struct CidrItem *cidr;
03727
03728 if (NumberPerCidr(aclass) <= 0)
03729 return 0;
03730
03731 if (ip->ss.ss_family == AF_INET)
03732 {
03733 if (CidrBitlenIPV4(aclass) <= 0)
03734 return 0;
03735
03736 DLINK_FOREACH(ptr, aclass->list_ipv4.head)
03737 {
03738 cidr = ptr->data;
03739 if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
03740 {
03741 if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
03742 return -1;
03743 cidr->number_on_this_cidr++;
03744 return 0;
03745 }
03746 }
03747 cidr = MyMalloc(sizeof(struct CidrItem));
03748 cidr->number_on_this_cidr = 1;
03749 cidr->mask = *ip;
03750 mask_addr(&cidr->mask, CidrBitlenIPV4(aclass));
03751 dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
03752 }
03753 #ifdef IPV6
03754 else if (CidrBitlenIPV6(aclass) > 0)
03755 {
03756 DLINK_FOREACH(ptr, aclass->list_ipv6.head)
03757 {
03758 cidr = ptr->data;
03759 if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
03760 {
03761 if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
03762 return -1;
03763 cidr->number_on_this_cidr++;
03764 return 0;
03765 }
03766 }
03767 cidr = MyMalloc(sizeof(struct CidrItem));
03768 cidr->number_on_this_cidr = 1;
03769 cidr->mask = *ip;
03770 mask_addr(&cidr->mask, CidrBitlenIPV6(aclass));
03771 dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
03772 }
03773 #endif
03774 return 0;
03775 }
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785 static void
03786 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
03787 {
03788 dlink_node *ptr = NULL;
03789 dlink_node *next_ptr = NULL;
03790 struct CidrItem *cidr;
03791
03792 if (NumberPerCidr(aclass) == 0)
03793 return;
03794
03795 if (ip->ss.ss_family == AF_INET)
03796 {
03797 if (CidrBitlenIPV4(aclass) <= 0)
03798 return;
03799
03800 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
03801 {
03802 cidr = ptr->data;
03803 if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
03804 {
03805 cidr->number_on_this_cidr--;
03806 if (cidr->number_on_this_cidr == 0)
03807 {
03808 dlinkDelete(ptr, &aclass->list_ipv4);
03809 MyFree(cidr);
03810 return;
03811 }
03812 }
03813 }
03814 }
03815 #ifdef IPV6
03816 else if (CidrBitlenIPV6(aclass) > 0)
03817 {
03818 DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
03819 {
03820 cidr = ptr->data;
03821 if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
03822 {
03823 cidr->number_on_this_cidr--;
03824 if (cidr->number_on_this_cidr == 0)
03825 {
03826 dlinkDelete(ptr, &aclass->list_ipv6);
03827 MyFree(cidr);
03828 return;
03829 }
03830 }
03831 }
03832 }
03833 #endif
03834 }
03835
03836 static void
03837 rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
03838 dlink_list *old_list, dlink_list *new_list, int changed)
03839 {
03840 dlink_node *ptr;
03841 struct Client *client_p;
03842 struct ConfItem *conf;
03843 struct AccessItem *aconf;
03844
03845 if (!changed)
03846 {
03847 *new_list = *old_list;
03848 old_list->head = old_list->tail = NULL;
03849 old_list->length = 0;
03850 return;
03851 }
03852
03853 DLINK_FOREACH(ptr, local_client_list.head)
03854 {
03855 client_p = ptr->data;
03856 if (client_p->localClient->aftype != aftype)
03857 continue;
03858 if (dlink_list_length(&client_p->localClient->confs) == 0)
03859 continue;
03860
03861 conf = client_p->localClient->confs.tail->data;
03862 if (conf->type == CLIENT_TYPE)
03863 {
03864 aconf = map_to_conf(conf);
03865 if (aconf->class_ptr == oldcl)
03866 cidr_limit_reached(1, &client_p->localClient->ip, newcl);
03867 }
03868 }
03869 }
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879 void
03880 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
03881 {
03882 struct ClassItem *old_class = map_to_conf(conf);
03883
03884 if (NumberPerCidr(old_class) > 0 && NumberPerCidr(new_class) > 0)
03885 {
03886 if (CidrBitlenIPV4(old_class) > 0 && CidrBitlenIPV4(new_class) > 0)
03887 rebuild_cidr_list(AF_INET, conf, new_class,
03888 &old_class->list_ipv4, &new_class->list_ipv4,
03889 CidrBitlenIPV4(old_class) != CidrBitlenIPV4(new_class));
03890
03891 #ifdef IPV6
03892 if (CidrBitlenIPV6(old_class) > 0 && CidrBitlenIPV6(new_class) > 0)
03893 rebuild_cidr_list(AF_INET6, conf, new_class,
03894 &old_class->list_ipv6, &new_class->list_ipv6,
03895 CidrBitlenIPV6(old_class) != CidrBitlenIPV6(new_class));
03896 #endif
03897 }
03898
03899 destroy_cidr_class(old_class);
03900 }
03901
03902
03903
03904
03905
03906
03907
03908
03909 static void
03910 destroy_cidr_list(dlink_list *list)
03911 {
03912 dlink_node *ptr = NULL, *next_ptr = NULL;
03913
03914 DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
03915 {
03916 dlinkDelete(ptr, list);
03917 MyFree(ptr->data);
03918 }
03919 }
03920
03921
03922
03923
03924
03925
03926
03927
03928 static void
03929 destroy_cidr_class(struct ClassItem *aclass)
03930 {
03931 destroy_cidr_list(&aclass->list_ipv4);
03932 destroy_cidr_list(&aclass->list_ipv6);
03933 }