ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf.c
(Generate patch)

Comparing:
ircd-hybrid-8/src/s_conf.c (file contents), Revision 1176 by michael, Sun Aug 14 11:24:24 2011 UTC vs.
ircd-hybrid/trunk/src/conf.c (file contents), Revision 2012 by michael, Sun May 12 14:47:26 2013 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_conf.c: Configuration file functions.
3 > *  conf.c: Configuration file functions.
4   *
5   *  Copyright (C) 2002 by the past and present ircd coders, and others.
6   *
# Line 25 | Line 25
25   #include "stdinc.h"
26   #include "list.h"
27   #include "ircd_defs.h"
28 < #include "balloc.h"
29 < #include "s_conf.h"
28 > #include "conf.h"
29   #include "s_serv.h"
30   #include "resv.h"
31   #include "channel.h"
32   #include "client.h"
34 #include "common.h"
33   #include "event.h"
36 #include "hash.h"
34   #include "hook.h"
35   #include "irc_string.h"
39 #include "sprintf_irc.h"
36   #include "s_bsd.h"
37   #include "ircd.h"
38   #include "listener.h"
# Line 44 | Line 40
40   #include "modules.h"
41   #include "numeric.h"
42   #include "fdlist.h"
43 < #include "s_log.h"
43 > #include "log.h"
44   #include "send.h"
45   #include "s_gline.h"
50 #include "fileio.h"
46   #include "memory.h"
47 + #include "mempool.h"
48   #include "irc_res.h"
49   #include "userhost.h"
50   #include "s_user.h"
51   #include "channel_mode.h"
52 + #include "parse.h"
53 + #include "s_misc.h"
54 + #include "conf_db.h"
55 + #include "conf_class.h"
56  
57 struct Callback *client_check_cb = NULL;
57   struct config_server_hide ConfigServerHide;
58  
59   /* general conf items link list root, other than k lines etc. */
60   dlink_list service_items = { NULL, NULL, 0 };
61   dlink_list server_items  = { NULL, NULL, 0 };
62   dlink_list cluster_items = { NULL, NULL, 0 };
64 dlink_list hub_items     = { NULL, NULL, 0 };
65 dlink_list leaf_items    = { NULL, NULL, 0 };
63   dlink_list oconf_items   = { NULL, NULL, 0 };
64   dlink_list uconf_items   = { NULL, NULL, 0 };
65   dlink_list xconf_items   = { NULL, NULL, 0 };
69 dlink_list rxconf_items  = { NULL, NULL, 0 };
70 dlink_list rkconf_items  = { NULL, NULL, 0 };
66   dlink_list nresv_items   = { NULL, NULL, 0 };
72 dlink_list class_items   = { NULL, NULL, 0 };
73 dlink_list gdeny_items   = { NULL, NULL, 0 };
74
75 dlink_list temporary_klines  = { NULL, NULL, 0 };
76 dlink_list temporary_dlines  = { NULL, NULL, 0 };
77 dlink_list temporary_xlines  = { NULL, NULL, 0 };
78 dlink_list temporary_rklines = { NULL, NULL, 0 };
79 dlink_list temporary_glines  = { NULL, NULL, 0 };
80 dlink_list temporary_rxlines = { NULL, NULL, 0 };
67   dlink_list temporary_resv = { NULL, NULL, 0 };
68  
69   extern unsigned int lineno;
70   extern char linebuf[];
71   extern char conffilebuf[IRCD_BUFSIZE];
86 extern char yytext[];
72   extern int yyparse(); /* defined in y.tab.c */
73  
74   struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };
75  
76   /* internally defined functions */
77 < static void lookup_confhost(struct ConfItem *);
93 < static void set_default_conf(void);
94 < static void validate_conf(void);
95 < static void read_conf(FBFILE *);
77 > static void read_conf(FILE *);
78   static void clear_out_old_conf(void);
97 static void flush_deleted_I_P(void);
79   static void expire_tklines(dlink_list *);
80   static void garbage_collect_ip_entries(void);
81   static int hash_ip(struct irc_ssaddr *);
82 < static int verify_access(struct Client *, const char *);
83 < static int attach_iline(struct Client *, struct ConfItem *);
82 > static int verify_access(struct Client *);
83 > static int attach_iline(struct Client *, struct MaskItem *);
84   static struct ip_entry *find_or_add_ip(struct irc_ssaddr *);
85 < static void parse_conf_file(int, int);
105 < static dlink_list *map_to_list(ConfType);
106 < static struct AccessItem *find_regexp_kline(const char *[]);
85 > static dlink_list *map_to_list(enum maskitem_type);
86   static int find_user_host(struct Client *, char *, char *, char *, unsigned int);
87  
109 /*
110 * bit_len
111 */
112 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
113 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
114 static void destroy_cidr_class(struct ClassItem *);
115
116 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
117
118 /* address of default class conf */
119 static struct ConfItem *class_default;
88  
89   /* usually, with hash tables, you use a prime number...
90   * but in this case I am dealing with ip addresses,
# Line 127 | Line 95 | static struct ConfItem *class_default;
95   struct ip_entry
96   {
97    struct irc_ssaddr ip;
98 <  int count;
98 >  unsigned int count;
99    time_t last_attempt;
100    struct ip_entry *next;
101   };
102  
103   static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
104 < static BlockHeap *ip_entry_heap = NULL;
104 > static mp_pool_t *ip_entry_pool = NULL;
105   static int ip_entries_count = 0;
106  
107  
140 void *
141 map_to_conf(struct ConfItem *aconf)
142 {
143  void *conf;
144  conf = (void *)((uintptr_t)aconf +
145                  (uintptr_t)sizeof(struct ConfItem));
146  return(conf);
147 }
148
149 struct ConfItem *
150 unmap_conf_item(void *aconf)
151 {
152  struct ConfItem *conf;
153
154  conf = (struct ConfItem *)((uintptr_t)aconf -
155                             (uintptr_t)sizeof(struct ConfItem));
156  return(conf);
157 }
158
108   /* conf_dns_callback()
109   *
110 < * inputs       - pointer to struct AccessItem
110 > * inputs       - pointer to struct MaskItem
111   *              - pointer to DNSReply reply
112   * output       - none
113   * side effects - called when resolver query finishes
# Line 169 | Line 118 | unmap_conf_item(void *aconf)
118   static void
119   conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
120   {
121 <  struct AccessItem *aconf = vptr;
121 >  struct MaskItem *conf = vptr;
122  
123 <  aconf->dns_pending = 0;
123 >  conf->dns_pending = 0;
124  
125    if (addr != NULL)
126 <    memcpy(&aconf->ipnum, addr, sizeof(aconf->ipnum));
126 >    memcpy(&conf->addr, addr, sizeof(conf->addr));
127    else
128 <    aconf->dns_failed = 1;
128 >    conf->dns_failed = 1;
129   }
130  
131   /* conf_dns_lookup()
# Line 186 | Line 135 | conf_dns_callback(void *vptr, const stru
135   * allocate a dns_query and start ns lookup.
136   */
137   static void
138 < conf_dns_lookup(struct AccessItem *aconf)
138 > conf_dns_lookup(struct MaskItem *conf)
139   {
140 <  if (!aconf->dns_pending)
140 >  if (!conf->dns_pending)
141    {
142 <    aconf->dns_pending = 1;
143 <    gethost_byname(conf_dns_callback, aconf, aconf->host);
142 >    conf->dns_pending = 1;
143 >    gethost_byname(conf_dns_callback, conf, conf->host);
144    }
145   }
146  
147 < /* make_conf_item()
148 < *
200 < * inputs       - type of item
201 < * output       - pointer to new conf entry
202 < * side effects - none
203 < */
204 < struct ConfItem *
205 < make_conf_item(ConfType type)
147 > struct MaskItem *
148 > conf_make(enum maskitem_type type)
149   {
150 <  struct ConfItem *conf = NULL;
151 <  struct AccessItem *aconf = NULL;
209 <  struct ClassItem *aclass = NULL;
210 <  int status = 0;
211 <
212 <  switch (type)
213 <  {
214 <  case DLINE_TYPE:
215 <  case EXEMPTDLINE_TYPE:
216 <  case GLINE_TYPE:
217 <  case KLINE_TYPE:
218 <  case CLIENT_TYPE:
219 <  case OPER_TYPE:
220 <  case SERVER_TYPE:
221 <    conf = MyMalloc(sizeof(struct ConfItem) +
222 <                    sizeof(struct AccessItem));
223 <    aconf = map_to_conf(conf);
224 <    aconf->aftype = AF_INET;
225 <
226 <    /* Yes, sigh. switch on type again */
227 <    switch (type)
228 <    {
229 <    case EXEMPTDLINE_TYPE:
230 <      status = CONF_EXEMPTDLINE;
231 <      break;
232 <
233 <    case DLINE_TYPE:
234 <      status = CONF_DLINE;
235 <      break;
236 <
237 <    case KLINE_TYPE:
238 <      status = CONF_KLINE;
239 <      break;
240 <
241 <    case GLINE_TYPE:
242 <      status = CONF_GLINE;
243 <      break;
244 <
245 <    case CLIENT_TYPE:
246 <      status = CONF_CLIENT;
247 <      break;
248 <
249 <    case OPER_TYPE:
250 <      status = CONF_OPERATOR;
251 <      dlinkAdd(conf, &conf->node, &oconf_items);
252 <      break;
253 <
254 <    case SERVER_TYPE:
255 <      status = CONF_SERVER;
256 <      dlinkAdd(conf, &conf->node, &server_items);
257 <      break;
258 <
259 <    default:
260 <      break;
261 <    }
262 <    aconf->status = status;
263 <    break;
264 <
265 <  case LEAF_TYPE:
266 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
267 <                                       sizeof(struct MatchItem));
268 <    dlinkAdd(conf, &conf->node, &leaf_items);
269 <    break;
270 <
271 <  case HUB_TYPE:
272 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
273 <                                       sizeof(struct MatchItem));
274 <    dlinkAdd(conf, &conf->node, &hub_items);
275 <    break;
276 <
277 <  case ULINE_TYPE:
278 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
279 <                                       sizeof(struct MatchItem));
280 <    dlinkAdd(conf, &conf->node, &uconf_items);
281 <    break;
282 <
283 <  case GDENY_TYPE:
284 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
285 <                                       sizeof(struct AccessItem));
286 <    dlinkAdd(conf, &conf->node, &gdeny_items);
287 <    break;
288 <
289 <  case XLINE_TYPE:
290 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
291 <                                       sizeof(struct MatchItem));
292 <    dlinkAdd(conf, &conf->node, &xconf_items);
293 <    break;
294 < #ifdef HAVE_LIBPCRE
295 <  case RXLINE_TYPE:
296 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
297 <                                       sizeof(struct MatchItem));
298 <    dlinkAdd(conf, &conf->node, &rxconf_items);
299 <    break;
300 <
301 <  case RKLINE_TYPE:
302 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
303 <                                       sizeof(struct AccessItem));
304 <    aconf = map_to_conf(conf);
305 <    aconf->status = CONF_KLINE;
306 <    dlinkAdd(conf, &conf->node, &rkconf_items);
307 <    break;
308 < #endif
309 <  case CLUSTER_TYPE:
310 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
311 <    dlinkAdd(conf, &conf->node, &cluster_items);
312 <    break;
313 <
314 <  case CRESV_TYPE:
315 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
316 <                                       sizeof(struct ResvChannel));
317 <    break;
150 >  struct MaskItem *conf = MyMalloc(sizeof(*conf));
151 >  dlink_list *list = NULL;
152  
153 <  case NRESV_TYPE:
154 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
155 <                                       sizeof(struct MatchItem));
322 <    dlinkAdd(conf, &conf->node, &nresv_items);
323 <    break;
324 <
325 <  case SERVICE_TYPE:
326 <    status = CONF_SERVICE;
327 <    conf = MyMalloc(sizeof(struct ConfItem));
328 <    dlinkAdd(conf, &conf->node, &service_items);
329 <    break;
330 <
331 <  case CLASS_TYPE:
332 <    conf = MyMalloc(sizeof(struct ConfItem) +
333 <                           sizeof(struct ClassItem));
334 <    dlinkAdd(conf, &conf->node, &class_items);
335 <
336 <    aclass = map_to_conf(conf);
337 <    aclass->active = 1;
338 <    ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
339 <    PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
340 <    MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
341 <    MaxSendq(aclass) = DEFAULT_SENDQ;
342 <
343 <    break;
344 <
345 <  default:
346 <    conf = NULL;
347 <    break;
348 <  }
349 <
350 <  /* XXX Yes, this will core if default is hit. I want it to for now - db */
351 <  conf->type = type;
153 >  conf->type   = type;
154 >  conf->active = 1;
155 >  conf->aftype = AF_INET;
156  
157 +  if ((list = map_to_list(type)))
158 +    dlinkAdd(conf, &conf->node, list);
159    return conf;
160   }
161  
162   void
163 < delete_conf_item(struct ConfItem *conf)
163 > conf_free(struct MaskItem *conf)
164   {
165 <  dlink_node *m = NULL;
166 <  struct MatchItem *match_item;
167 <  struct AccessItem *aconf;
168 <  ConfType type = conf->type;
165 >  dlink_node *ptr = NULL, *ptr_next = NULL;
166 >  dlink_list *list = NULL;
167 >
168 >  if (conf->node.next)
169 >    if ((list = map_to_list(conf->type)))
170 >      dlinkDelete(&conf->node, list);
171  
172    MyFree(conf->name);
365  conf->name = NULL;
173  
174 <  switch(type)
175 <  {
176 <  case DLINE_TYPE:
177 <  case EXEMPTDLINE_TYPE:
178 <  case GLINE_TYPE:
179 <  case KLINE_TYPE:
180 <  case CLIENT_TYPE:
181 <  case OPER_TYPE:
182 <  case SERVER_TYPE:
183 <    aconf = map_to_conf(conf);
184 <
185 <    if (aconf->dns_pending)
186 <      delete_resolver_queries(aconf);
187 <    if (aconf->passwd != NULL)
381 <      memset(aconf->passwd, 0, strlen(aconf->passwd));
382 <    if (aconf->spasswd != NULL)
383 <      memset(aconf->spasswd, 0, strlen(aconf->spasswd));
384 <    aconf->class_ptr = NULL;
385 <
386 <    MyFree(aconf->passwd);
387 <    MyFree(aconf->spasswd);
388 <    MyFree(aconf->reason);
389 <    MyFree(aconf->oper_reason);
390 <    MyFree(aconf->user);
391 <    MyFree(aconf->host);
174 >  if (conf->dns_pending)
175 >    delete_resolver_queries(conf);
176 >  if (conf->passwd != NULL)
177 >    memset(conf->passwd, 0, strlen(conf->passwd));
178 >  if (conf->spasswd != NULL)
179 >    memset(conf->spasswd, 0, strlen(conf->spasswd));
180 >
181 >  conf->class = NULL;
182 >
183 >  MyFree(conf->passwd);
184 >  MyFree(conf->spasswd);
185 >  MyFree(conf->reason);
186 >  MyFree(conf->user);
187 >  MyFree(conf->host);
188   #ifdef HAVE_LIBCRYPTO
189 <    if (aconf->rsa_public_key)
394 <      RSA_free(aconf->rsa_public_key);
395 <    MyFree(aconf->rsa_public_key_file);
396 < #endif
397 <
398 <    /* Yes, sigh. switch on type again */
399 <    switch(type)
400 <    {
401 <    case EXEMPTDLINE_TYPE:
402 <    case DLINE_TYPE:
403 <    case GLINE_TYPE:
404 <    case KLINE_TYPE:
405 <    case CLIENT_TYPE:
406 <      MyFree(conf);
407 <      break;
408 <
409 <    case OPER_TYPE:
410 <      aconf = map_to_conf(conf);
411 <      if (!IsConfIllegal(aconf))
412 <        dlinkDelete(&conf->node, &oconf_items);
413 <      MyFree(conf);
414 <      break;
415 <
416 <    case SERVER_TYPE:
417 <      aconf = map_to_conf(conf);
418 <      if (!IsConfIllegal(aconf))
419 <        dlinkDelete(&conf->node, &server_items);
420 <      MyFree(conf);
421 <      break;
422 <
423 <    default:
424 <      break;
425 <    }
426 <    break;
427 <
428 <  case HUB_TYPE:
429 <    match_item = map_to_conf(conf);
430 <    MyFree(match_item->user);
431 <    MyFree(match_item->host);
432 <    MyFree(match_item->reason);
433 <    MyFree(match_item->oper_reason);
434 <    /* If marked illegal, its already been pulled off of the hub_items list */
435 <    if (!match_item->illegal)
436 <      dlinkDelete(&conf->node, &hub_items);
437 <    MyFree(conf);
438 <    break;
189 >  MyFree(conf->cipher_list);
190  
191 <  case LEAF_TYPE:
192 <    match_item = map_to_conf(conf);
442 <    MyFree(match_item->user);
443 <    MyFree(match_item->host);
444 <    MyFree(match_item->reason);
445 <    MyFree(match_item->oper_reason);
446 <    /* If marked illegal, its already been pulled off of the leaf_items list */
447 <    if (!match_item->illegal)
448 <      dlinkDelete(&conf->node, &leaf_items);
449 <    MyFree(conf);
450 <    break;
451 <
452 <  case ULINE_TYPE:
453 <    match_item = map_to_conf(conf);
454 <    MyFree(match_item->user);
455 <    MyFree(match_item->host);
456 <    MyFree(match_item->reason);
457 <    MyFree(match_item->oper_reason);
458 <    dlinkDelete(&conf->node, &uconf_items);
459 <    MyFree(conf);
460 <    break;
461 <
462 <  case XLINE_TYPE:
463 <    match_item = map_to_conf(conf);
464 <    MyFree(match_item->user);
465 <    MyFree(match_item->host);
466 <    MyFree(match_item->reason);
467 <    MyFree(match_item->oper_reason);
468 <    dlinkDelete(&conf->node, &xconf_items);
469 <    MyFree(conf);
470 <    break;
471 < #ifdef HAVE_LIBPCRE
472 <  case RKLINE_TYPE:
473 <    aconf = map_to_conf(conf);
474 <    MyFree(aconf->regexuser);
475 <    MyFree(aconf->regexhost);
476 <    MyFree(aconf->user);
477 <    MyFree(aconf->host);
478 <    MyFree(aconf->reason);
479 <    MyFree(aconf->oper_reason);
480 <    dlinkDelete(&conf->node, &rkconf_items);
481 <    MyFree(conf);
482 <    break;
483 <
484 <  case RXLINE_TYPE:
485 <    MyFree(conf->regexpname);
486 <    match_item = map_to_conf(conf);
487 <    MyFree(match_item->user);
488 <    MyFree(match_item->host);
489 <    MyFree(match_item->reason);
490 <    MyFree(match_item->oper_reason);
491 <    dlinkDelete(&conf->node, &rxconf_items);
492 <    MyFree(conf);
493 <    break;
191 >  if (conf->rsa_public_key)
192 >    RSA_free(conf->rsa_public_key);
193   #endif
194 <  case NRESV_TYPE:
195 <    match_item = map_to_conf(conf);
196 <    MyFree(match_item->user);
197 <    MyFree(match_item->host);
499 <    MyFree(match_item->reason);
500 <    MyFree(match_item->oper_reason);
501 <    dlinkDelete(&conf->node, &nresv_items);
502 <
503 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
504 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
505 <        free_dlink_node(m);
506 <
507 <    MyFree(conf);
508 <    break;
509 <
510 <  case GDENY_TYPE:
511 <    aconf = map_to_conf(conf);
512 <    MyFree(aconf->user);
513 <    MyFree(aconf->host);
514 <    dlinkDelete(&conf->node, &gdeny_items);
515 <    MyFree(conf);
516 <    break;
517 <
518 <  case CLUSTER_TYPE:
519 <    dlinkDelete(&conf->node, &cluster_items);
520 <    MyFree(conf);
521 <    break;
522 <
523 <  case CRESV_TYPE:
524 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
525 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
526 <        free_dlink_node(m);
527 <
528 <    MyFree(conf);
529 <    break;
530 <
531 <  case CLASS_TYPE:
532 <    dlinkDelete(&conf->node, &class_items);
533 <    MyFree(conf);
534 <    break;
535 <
536 <  case SERVICE_TYPE:
537 <    dlinkDelete(&conf->node, &service_items);
538 <    MyFree(conf);
539 <    break;
540 <
541 <  default:
542 <    break;
194 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->hub_list.head)
195 >  {
196 >    MyFree(ptr->data);
197 >    free_dlink_node(ptr);
198    }
544 }
545
546 /* free_access_item()
547 *
548 * inputs       - pointer to conf to free
549 * output       - none
550 * side effects - crucial password fields are zeroed, conf is freed
551 */
552 void
553 free_access_item(struct AccessItem *aconf)
554 {
555  struct ConfItem *conf;
556
557  if (aconf == NULL)
558    return;
559  conf = unmap_conf_item(aconf);
560  delete_conf_item(conf);
561 }
562
563 static const unsigned int shared_bit_table[] =
564  { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0};
565
566 /* report_confitem_types()
567 *
568 * inputs       - pointer to client requesting confitem report
569 *              - ConfType to report
570 * output       - none
571 * side effects -
572 */
573 void
574 report_confitem_types(struct Client *source_p, ConfType type, int temp)
575 {
576  dlink_node *ptr = NULL;
577  struct ConfItem *conf = NULL;
578  struct AccessItem *aconf = NULL;
579  struct MatchItem *matchitem = NULL;
580  struct ClassItem *classitem = NULL;
581  char buf[12];
582  char *p = NULL;
583  const char *pfx = NULL;
199  
200 <  switch (type)
200 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->leaf_list.head)
201    {
202 <  case GDENY_TYPE:
203 <    DLINK_FOREACH(ptr, gdeny_items.head)
204 <    {
590 <      conf = ptr->data;
591 <      aconf = map_to_conf(conf);
592 <
593 <      p = buf;
594 <
595 <      if (aconf->flags & GDENY_BLOCK)
596 <        *p++ = 'B';
597 <      else
598 <        *p++ = 'b';
599 <
600 <      if (aconf->flags & GDENY_REJECT)
601 <        *p++ = 'R';
602 <      else
603 <        *p++ = 'r';
604 <
605 <      *p = '\0';
606 <
607 <      sendto_one(source_p, ":%s %d %s V %s@%s %s %s",
608 <                 me.name, RPL_STATSDEBUG, source_p->name,
609 <                 aconf->user, aconf->host, conf->name, buf);
610 <    }
611 <    break;
612 <
613 <  case XLINE_TYPE:
614 <    DLINK_FOREACH(ptr, xconf_items.head)
615 <    {
616 <      conf = ptr->data;
617 <      matchitem = map_to_conf(conf);
618 <
619 <      sendto_one(source_p, form_str(RPL_STATSXLINE),
620 <                 me.name, source_p->name,
621 <                 matchitem->hold ? "x": "X", matchitem->count,
622 <                 conf->name, matchitem->reason);
623 <    }
624 <    break;
625 <
626 < #ifdef HAVE_LIBPCRE
627 <  case RXLINE_TYPE:
628 <    DLINK_FOREACH(ptr, rxconf_items.head)
629 <    {
630 <      conf = ptr->data;
631 <      matchitem = map_to_conf(conf);
632 <
633 <      sendto_one(source_p, form_str(RPL_STATSXLINE),
634 <                 me.name, source_p->name,
635 <                 matchitem->hold ? "xR": "XR", matchitem->count,
636 <                 conf->name, matchitem->reason);
637 <    }
638 <    break;
639 <
640 <  case RKLINE_TYPE:
641 <    pfx = temp ? "kR" : "KR";
642 <
643 <    DLINK_FOREACH(ptr, rkconf_items.head)
644 <    {
645 <      aconf = map_to_conf((conf = ptr->data));
646 <
647 <      if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
648 <        continue;
649 <
650 <      sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
651 <                 source_p->name, pfx, aconf->host, aconf->user,
652 <                 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
653 <    }
654 <    break;
655 < #endif
656 <
657 <  case ULINE_TYPE:
658 <    DLINK_FOREACH(ptr, uconf_items.head)
659 <    {
660 <      conf = ptr->data;
661 <      matchitem = map_to_conf(conf);
662 <
663 <      p = buf;
664 <
665 <      /* some of these are redundant for the sake of
666 <       * consistency with cluster{} flags
667 <       */
668 <      *p++ = 'c';
669 <      flags_to_ascii(matchitem->action, shared_bit_table, p, 0);
670 <
671 <      sendto_one(source_p, form_str(RPL_STATSULINE),
672 <                 me.name, source_p->name, conf->name,
673 <                 matchitem->user?matchitem->user: "*",
674 <                 matchitem->host?matchitem->host: "*", buf);
675 <    }
676 <
677 <    DLINK_FOREACH(ptr, cluster_items.head)
678 <    {
679 <      conf = ptr->data;
680 <
681 <      p = buf;
682 <
683 <      *p++ = 'C';
684 <      flags_to_ascii(conf->flags, shared_bit_table, p, 0);
685 <
686 <      sendto_one(source_p, form_str(RPL_STATSULINE),
687 <                 me.name, source_p->name, conf->name,
688 <                 "*", "*", buf);
689 <    }
690 <
691 <    break;
692 <
693 <  case OPER_TYPE:
694 <    DLINK_FOREACH(ptr, oconf_items.head)
695 <    {
696 <      conf = ptr->data;
697 <      aconf = map_to_conf(conf);
698 <
699 <      /* Don't allow non opers to see oper privs */
700 <      if (IsOper(source_p))
701 <        sendto_one(source_p, form_str(RPL_STATSOLINE),
702 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
703 <                   conf->name, oper_privs_as_string(aconf->port),
704 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
705 <      else
706 <        sendto_one(source_p, form_str(RPL_STATSOLINE),
707 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
708 <                   conf->name, "0",
709 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
710 <    }
711 <    break;
712 <
713 <  case CLASS_TYPE:
714 <    DLINK_FOREACH(ptr, class_items.head)
715 <    {
716 <      conf = ptr->data;
717 <      classitem = map_to_conf(conf);
718 <      sendto_one(source_p, form_str(RPL_STATSYLINE),
719 <                 me.name, source_p->name, 'Y',
720 <                 conf->name, PingFreq(classitem),
721 <                 ConFreq(classitem),
722 <                 MaxTotal(classitem), MaxSendq(classitem),
723 <                 CurrUserCount(classitem),
724 <                 classitem->active ? "active" : "disabled");
725 <    }
726 <    break;
727 <
728 <  case CONF_TYPE:
729 <  case CLIENT_TYPE:
730 <    break;
731 <
732 <  case SERVICE_TYPE:
733 <    DLINK_FOREACH(ptr, service_items.head)
734 <    {
735 <      conf = ptr->data;
736 <      sendto_one(source_p, form_str(RPL_STATSSERVICE),
737 <                 me.name, source_p->name, 'S', "*", conf->name, 0, 0);
738 <    }
739 <    break;
740 <
741 <  case SERVER_TYPE:
742 <    DLINK_FOREACH(ptr, server_items.head)
743 <    {
744 <      p = buf;
745 <
746 <      conf = ptr->data;
747 <      aconf = map_to_conf(conf);
748 <
749 <      buf[0] = '\0';
750 <
751 <      if (IsConfAllowAutoConn(aconf))
752 <        *p++ = 'A';
753 <      if (IsConfCryptLink(aconf))
754 <        *p++ = 'C';
755 <      if (IsConfTopicBurst(aconf))
756 <        *p++ = 'T';
757 <      if (IsConfCompressed(aconf))
758 <        *p++ = 'Z';
759 <      if (buf[0] == '\0')
760 <        *p++ = '*';
761 <
762 <      *p = '\0';
763 <
764 <      /*
765 <       * Allow admins to see actual ips unless hide_server_ips is enabled
766 <       */
767 <      if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
768 <        sendto_one(source_p, form_str(RPL_STATSCLINE),
769 <                   me.name, source_p->name, 'C', aconf->host,
770 <                   buf, conf->name, aconf->port,
771 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
772 <        else
773 <          sendto_one(source_p, form_str(RPL_STATSCLINE),
774 <                     me.name, source_p->name, 'C',
775 <                     "*@127.0.0.1", buf, conf->name, aconf->port,
776 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
777 <    }
778 <    break;
779 <
780 <  case HUB_TYPE:
781 <    DLINK_FOREACH(ptr, hub_items.head)
782 <    {
783 <      conf = ptr->data;
784 <      matchitem = map_to_conf(conf);
785 <      sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
786 <                 source_p->name, 'H', matchitem->host, conf->name, 0, "*");
787 <    }
788 <    break;
202 >    MyFree(ptr->data);
203 >    free_dlink_node(ptr);
204 >  }
205  
206 <  case LEAF_TYPE:
207 <    DLINK_FOREACH(ptr, leaf_items.head)
208 <    {
793 <      conf = ptr->data;
794 <      matchitem = map_to_conf(conf);
795 <      sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
796 <                 source_p->name, 'L', matchitem->host, conf->name, 0, "*");
797 <    }
798 <    break;
206 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->exempt_list.head)
207 >  {
208 >    struct exempt *exptr = ptr->data;
209  
210 <  case GLINE_TYPE:
211 <  case KLINE_TYPE:
212 <  case DLINE_TYPE:
213 <  case EXEMPTDLINE_TYPE:
804 <  case CRESV_TYPE:
805 <  case NRESV_TYPE:
806 <  case CLUSTER_TYPE:
807 <  default:
808 <    break;
210 >    MyFree(exptr->name);
211 >    MyFree(exptr->user);
212 >    MyFree(exptr->host);
213 >    MyFree(exptr);
214    }
215 +
216 +  MyFree(conf);
217   }
218  
219   /* check_client()
# Line 822 | Line 229 | report_confitem_types(struct Client *sou
229   *                Look for conf lines which have the same
230   *                status as the flags passed.
231   */
232 < static void *
233 < check_client(va_list args)
232 > int
233 > check_client(struct Client *source_p)
234   {
828  struct Client *source_p = va_arg(args, struct Client *);
829  const char *username = va_arg(args, const char *);
235    int i;
236  
237 <  /* I'm already in big trouble if source_p->localClient is NULL -db */
238 <  if ((i = verify_access(source_p, username)))
834 <    ilog(L_INFO, "Access denied: %s[%s]",
237 >  if ((i = verify_access(source_p)))
238 >    ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
239           source_p->name, source_p->sockhost);
240  
241    switch (i)
242    {
243      case TOO_MANY:
244 <      sendto_realops_flags(UMODE_FULL, L_ALL,
244 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
245                             "Too many on IP for %s (%s).",
246                             get_client_name(source_p, SHOW_IP),
247                             source_p->sockhost);
248 <      ilog(L_INFO,"Too many connections on IP from %s.",
248 >      ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
249             get_client_name(source_p, SHOW_IP));
250        ++ServerStats.is_ref;
251        exit_client(source_p, &me, "No more connections allowed on that IP");
252        break;
253  
254      case I_LINE_FULL:
255 <      sendto_realops_flags(UMODE_FULL, L_ALL,
256 <                           "I-line is full for %s (%s).",
255 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
256 >                           "auth{} block is full for %s (%s).",
257                             get_client_name(source_p, SHOW_IP),
258                             source_p->sockhost);
259 <      ilog(L_INFO,"Too many connections from %s.",
259 >      ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
260             get_client_name(source_p, SHOW_IP));
261        ++ServerStats.is_ref;
262        exit_client(source_p, &me,
# Line 863 | Line 267 | check_client(va_list args)
267        ++ServerStats.is_ref;
268        /* jdc - lists server name & port connections are on */
269        /*       a purely cosmetical change */
270 <      sendto_realops_flags(UMODE_UNAUTH, L_ALL,
270 >      sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
271                             "Unauthorized client connection from %s [%s] on [%s/%u].",
272                             get_client_name(source_p, SHOW_IP),
273                             source_p->sockhost,
274                             source_p->localClient->listener->name,
275                             source_p->localClient->listener->port);
276 <      ilog(L_INFO,
276 >      ilog(LOG_TYPE_IRCD,
277            "Unauthorized client connection from %s on [%s/%u].",
278            get_client_name(source_p, SHOW_IP),
279            source_p->localClient->listener->name,
280            source_p->localClient->listener->port);
281  
282 <      /* XXX It is prolematical whether it is better to use the
879 <       * capture reject code here or rely on the connecting too fast code.
880 <       * - Dianora
881 <       */
882 <      if (REJECT_HOLD_TIME > 0)
883 <      {
884 <        sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
885 <                   me.name, source_p->name);
886 <        source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
887 <        SetCaptured(source_p);
888 <      }
889 <      else
890 <        exit_client(source_p, &me, "You are not authorized to use this server");
282 >      exit_client(source_p, &me, "You are not authorized to use this server");
283        break;
284  
285     case BANNED_CLIENT:
286 <     /*
895 <      * Don't exit them immediately, play with them a bit.
896 <      * - Dianora
897 <      */
898 <     if (REJECT_HOLD_TIME > 0)
899 <     {
900 <       source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
901 <       SetCaptured(source_p);
902 <     }
903 <     else
904 <       exit_client(source_p, &me, "Banned");
286 >     exit_client(source_p, &me, "Banned");
287       ++ServerStats.is_ref;
288       break;
289  
# Line 910 | Line 292 | check_client(va_list args)
292       break;
293    }
294  
295 <  return (i < 0 ? NULL : source_p);
295 >  return (i < 0 ? 0 : 1);
296   }
297  
298   /* verify_access()
299   *
300   * inputs       - pointer to client to verify
919 *              - pointer to proposed username
301   * output       - 0 if success -'ve if not
302   * side effect  - find the first (best) I line to attach.
303   */
304   static int
305 < verify_access(struct Client *client_p, const char *username)
305 > verify_access(struct Client *client_p)
306   {
307 <  struct AccessItem *aconf = NULL, *rkconf = NULL;
927 <  struct ConfItem *conf = NULL;
307 >  struct MaskItem *conf = NULL;
308    char non_ident[USERLEN + 1] = { '~', '\0' };
929  const char *uhi[3];
309  
310    if (IsGotId(client_p))
311    {
312 <    aconf = find_address_conf(client_p->host, client_p->username,
312 >    conf = find_address_conf(client_p->host, client_p->username,
313                               &client_p->localClient->ip,
314                               client_p->localClient->aftype,
315                               client_p->localClient->passwd);
316    }
317    else
318    {
319 <    strlcpy(non_ident+1, username, sizeof(non_ident)-1);
320 <    aconf = find_address_conf(client_p->host,non_ident,
319 >    strlcpy(non_ident+1, client_p->username, sizeof(non_ident)-1);
320 >    conf = find_address_conf(client_p->host,non_ident,
321                               &client_p->localClient->ip,
322                               client_p->localClient->aftype,
323                               client_p->localClient->passwd);
324    }
325  
326 <  uhi[0] = IsGotId(client_p) ? client_p->username : non_ident;
948 <  uhi[1] = client_p->host;
949 <  uhi[2] = client_p->sockhost;
950 <
951 <  rkconf = find_regexp_kline(uhi);
952 <
953 <  if (aconf != NULL)
326 >  if (conf != NULL)
327    {
328 <    if (IsConfClient(aconf) && !rkconf)
328 >    if (IsConfClient(conf))
329      {
330 <      conf = unmap_conf_item(aconf);
958 <
959 <      if (IsConfRedir(aconf))
330 >      if (IsConfRedir(conf))
331        {
332          sendto_one(client_p, form_str(RPL_REDIR),
333                     me.name, client_p->name,
334                     conf->name ? conf->name : "",
335 <                   aconf->port);
335 >                   conf->port);
336          return(NOT_AUTHORIZED);
337        }
338  
339 <      if (IsConfDoIdentd(aconf))
339 >      if (IsConfDoIdentd(conf))
340          SetNeedId(client_p);
341  
342        /* Thanks for spoof idea amm */
343 <      if (IsConfDoSpoofIp(aconf))
343 >      if (IsConfDoSpoofIp(conf))
344        {
345 <        conf = unmap_conf_item(aconf);
346 <
347 <        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf))
977 <          sendto_realops_flags(UMODE_ALL, L_ADMIN, "%s spoofing: %s as %s",
345 >        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(conf))
346 >          sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
347 >                               "%s spoofing: %s as %s",
348                                 client_p->name, client_p->host, conf->name);
349          strlcpy(client_p->host, conf->name, sizeof(client_p->host));
350          SetIPSpoof(client_p);
# Line 982 | Line 352 | verify_access(struct Client *client_p, c
352  
353        return(attach_iline(client_p, conf));
354      }
355 <    else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf)))
355 >    else if (IsConfKill(conf) || (ConfigFileEntry.glines && IsConfGline(conf)))
356      {
357 <      /* XXX */
988 <      aconf = rkconf ? rkconf : aconf;
989 <      if (IsConfGline(aconf))
357 >      if (IsConfGline(conf))
358          sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
359                     client_p->name);
360 <      if (ConfigFileEntry.kline_with_reason)
361 <        sendto_one(client_p, ":%s NOTICE %s :*** Banned %s",
994 <                  me.name, client_p->name, aconf->reason);
360 >      sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s",
361 >                 me.name, client_p->name, conf->reason);
362        return(BANNED_CLIENT);
363      }
364    }
# Line 1007 | Line 374 | verify_access(struct Client *client_p, c
374   * side effects - do actual attach
375   */
376   static int
377 < attach_iline(struct Client *client_p, struct ConfItem *conf)
377 > attach_iline(struct Client *client_p, struct MaskItem *conf)
378   {
379 <  struct AccessItem *aconf;
1013 <  struct ClassItem *aclass;
379 >  struct ClassItem *class = NULL;
380    struct ip_entry *ip_found;
381    int a_limit_reached = 0;
382 <  int local = 0, global = 0, ident = 0;
382 >  unsigned int local = 0, global = 0, ident = 0;
383  
384    ip_found = find_or_add_ip(&client_p->localClient->ip);
385    ip_found->count++;
386    SetIpHash(client_p);
387  
388 <  aconf = map_to_conf(conf);
1023 <  if (aconf->class_ptr == NULL)
388 >  if (conf->class == NULL)
389      return NOT_AUTHORIZED;  /* If class is missing, this is best */
390  
391 <  aclass = map_to_conf(aconf->class_ptr);
391 >  class = conf->class;
392  
393    count_user_host(client_p->username, client_p->host,
394                    &global, &local, &ident);
# Line 1032 | Line 397 | attach_iline(struct Client *client_p, st
397     * setting a_limit_reached if any limit is reached.
398     * - Dianora
399     */
400 <  if (MaxTotal(aclass) != 0 && CurrUserCount(aclass) >= MaxTotal(aclass))
400 >  if (class->max_total != 0 && class->ref_count >= class->max_total)
401      a_limit_reached = 1;
402 <  else if (MaxPerIp(aclass) != 0 && ip_found->count > MaxPerIp(aclass))
402 >  else if (class->max_perip != 0 && ip_found->count > class->max_perip)
403      a_limit_reached = 1;
404 <  else if (MaxLocal(aclass) != 0 && local >= MaxLocal(aclass))
404 >  else if (class->max_local != 0 && local >= class->max_local)
405      a_limit_reached = 1;
406 <  else if (MaxGlobal(aclass) != 0 && global >= MaxGlobal(aclass))
406 >  else if (class->max_global != 0 && global >= class->max_global)
407      a_limit_reached = 1;
408 <  else if (MaxIdent(aclass) != 0 && ident >= MaxIdent(aclass) &&
408 >  else if (class->max_ident != 0 && ident >= class->max_ident &&
409             client_p->username[0] != '~')
410      a_limit_reached = 1;
411  
412    if (a_limit_reached)
413    {
414 <    if (!IsConfExemptLimits(aconf))
414 >    if (!IsConfExemptLimits(conf))
415        return TOO_MANY;   /* Already at maximum allowed */
416  
417      sendto_one(client_p,
# Line 1067 | Line 432 | attach_iline(struct Client *client_p, st
432   void
433   init_ip_hash_table(void)
434   {
435 <  ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry),
1071 <    2 * hard_fdlimit);
435 >  ip_entry_pool = mp_pool_new(sizeof(struct ip_entry), MP_CHUNK_SIZE_IP_ENTRY);
436    memset(ip_hash_table, 0, sizeof(ip_hash_table));
437   }
438  
# Line 1117 | Line 481 | find_or_add_ip(struct irc_ssaddr *ip_in)
481    if (ip_entries_count >= 2 * hard_fdlimit)
482      garbage_collect_ip_entries();
483  
484 <  newptr = BlockHeapAlloc(ip_entry_heap);
484 >  newptr = mp_pool_get(ip_entry_pool);
485 >  memset(newptr, 0, sizeof(*newptr));
486    ip_entries_count++;
487    memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
488  
# Line 1175 | Line 540 | remove_one_ip(struct irc_ssaddr *ip_in)
540        else
541          ip_hash_table[hash_index] = ptr->next;
542  
543 <      BlockHeapFree(ip_entry_heap, ptr);
543 >      mp_pool_release(ptr);
544        ip_entries_count--;
545        return;
546      }
# Line 1278 | Line 643 | garbage_collect_ip_entries(void)
643            last_ptr->next = ptr->next;
644          else
645            ip_hash_table[i] = ptr->next;
646 <        BlockHeapFree(ip_entry_heap, ptr);
646 >        mp_pool_release(ptr);
647          ip_entries_count--;
648        }
649        else
# Line 1295 | Line 660 | garbage_collect_ip_entries(void)
660   * side effects - Disassociate configuration from the client.
661   *                Also removes a class from the list if marked for deleting.
662   */
663 < int
664 < detach_conf(struct Client *client_p, ConfType type)
663 > void
664 > detach_conf(struct Client *client_p, enum maskitem_type type)
665   {
666 <  dlink_node *ptr, *next_ptr;
1302 <  struct ConfItem *conf;
1303 <  struct ClassItem *aclass;
1304 <  struct AccessItem *aconf;
1305 <  struct ConfItem *aclass_conf;
1306 <  struct MatchItem *match_item;
666 >  dlink_node *ptr = NULL, *next_ptr = NULL;
667  
668    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
669    {
670 <    conf = ptr->data;
670 >    struct MaskItem *conf = ptr->data;
671  
672 <    if (type == CONF_TYPE || conf->type == type)
673 <    {
674 <      dlinkDelete(ptr, &client_p->localClient->confs);
1315 <      free_dlink_node(ptr);
672 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
673 >    assert(conf->ref_count > 0);
674 >    assert(conf->class->ref_count > 0);
675  
676 <      switch (conf->type)
677 <      {
1319 <      case CLIENT_TYPE:
1320 <      case OPER_TYPE:
1321 <      case SERVER_TYPE:
1322 <        aconf = map_to_conf(conf);
1323 <
1324 <        assert(aconf->clients > 0);
1325 <
1326 <        if ((aclass_conf = ClassPtr(aconf)) != NULL)
1327 <        {
1328 <          aclass = map_to_conf(aclass_conf);
1329 <
1330 <          assert(aclass->curr_user_count > 0);
1331 <
1332 <          if (conf->type == CLIENT_TYPE)
1333 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
1334 <          if (--aclass->curr_user_count == 0 && aclass->active == 0)
1335 <            delete_conf_item(aclass_conf);
1336 <        }
1337 <
1338 <        if (--aconf->clients == 0 && IsConfIllegal(aconf))
1339 <          delete_conf_item(conf);
676 >    if (!(conf->type & type))
677 >      continue;
678  
679 <        break;
679 >    dlinkDelete(ptr, &client_p->localClient->confs);
680 >    free_dlink_node(ptr);
681  
682 <      case LEAF_TYPE:
683 <      case HUB_TYPE:
1345 <        match_item = map_to_conf(conf);
1346 <        if (match_item->ref_count == 0 && match_item->illegal)
1347 <          delete_conf_item(conf);
1348 <        break;
1349 <      default:
1350 <        break;
1351 <      }
682 >    if (conf->type == CONF_CLIENT)
683 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
684  
685 <      if (type != CONF_TYPE)
686 <        return 0;
685 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
686 >    {
687 >      class_free(conf->class);
688 >      conf->class = NULL;
689      }
1356  }
690  
691 <  return -1;
691 >    if (--conf->ref_count == 0 && conf->active == 0)
692 >      conf_free(conf);
693 >  }
694   }
695  
696   /* attach_conf()
# Line 1369 | Line 704 | detach_conf(struct Client *client_p, Con
704   *                attachment if there was an old one...
705   */
706   int
707 < attach_conf(struct Client *client_p, struct ConfItem *conf)
707 > attach_conf(struct Client *client_p, struct MaskItem *conf)
708   {
709    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
710      return 1;
711  
712 <  if (conf->type == CLIENT_TYPE ||
713 <      conf->type == SERVER_TYPE ||
714 <      conf->type == OPER_TYPE)
715 <  {
1381 <    struct AccessItem *aconf = map_to_conf(conf);
1382 <    struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1383 <
1384 <    if (IsConfIllegal(aconf))
1385 <      return NOT_AUTHORIZED;
1386 <
1387 <    if (conf->type == CLIENT_TYPE)
1388 <      if (cidr_limit_reached(IsConfExemptLimits(aconf),
1389 <                             &client_p->localClient->ip, aclass))
1390 <        return TOO_MANY;    /* Already at maximum allowed */
712 >  if (conf->type == CONF_CLIENT)
713 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
714 >                           &client_p->localClient->ip, conf->class))
715 >      return TOO_MANY;    /* Already at maximum allowed */
716  
717 <    CurrUserCount(aclass)++;
718 <    aconf->clients++;
1394 <  }
1395 <  else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
1396 <  {
1397 <    struct MatchItem *match_item = map_to_conf(conf);
1398 <    match_item->ref_count++;
1399 <  }
717 >  conf->class->ref_count++;
718 >  conf->ref_count++;
719  
720    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
721  
# Line 1416 | Line 735 | attach_connect_block(struct Client *clie
735                       const char *host)
736   {
737    dlink_node *ptr;
738 <  struct ConfItem *conf;
1420 <  struct AccessItem *aconf;
738 >  struct MaskItem *conf = NULL;
739  
740    assert(client_p != NULL);
741    assert(host != NULL);
# Line 1428 | Line 746 | attach_connect_block(struct Client *clie
746    DLINK_FOREACH(ptr, server_items.head)
747    {
748      conf = ptr->data;
1431    aconf = map_to_conf(conf);
749  
750 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
750 >    if (match(conf->name, name) || match(conf->host, host))
751        continue;
752  
753      attach_conf(client_p, conf);
# Line 1440 | Line 757 | attach_connect_block(struct Client *clie
757    return 0;
758   }
759  
1443 /* find_conf_exact()
1444 *
1445 * inputs       - type of ConfItem
1446 *              - pointer to name to find
1447 *              - pointer to username to find
1448 *              - pointer to host to find
1449 * output       - NULL or pointer to conf found
1450 * side effects - find a conf entry which matches the hostname
1451 *                and has the same name.
1452 */
1453 struct ConfItem *
1454 find_conf_exact(ConfType type, const char *name, const char *user,
1455                const char *host)
1456 {
1457  dlink_node *ptr;
1458  dlink_list *list_p;
1459  struct ConfItem *conf = NULL;
1460  struct AccessItem *aconf;
1461
1462  /* Only valid for OPER_TYPE and ...? */
1463  list_p = map_to_list(type);
1464
1465  DLINK_FOREACH(ptr, (*list_p).head)
1466  {
1467    conf = ptr->data;
1468
1469    if (conf->name == NULL)
1470      continue;
1471    aconf = map_to_conf(conf);
1472    if (aconf->host == NULL)
1473      continue;
1474    if (irccmp(conf->name, name) != 0)
1475      continue;
1476
1477    /*
1478    ** Accept if the *real* hostname (usually sockethost)
1479    ** socket host) matches *either* host or name field
1480    ** of the configuration.
1481    */
1482    if (!match(aconf->host, host) || !match(aconf->user, user))
1483      continue;
1484    if (type == OPER_TYPE)
1485    {
1486      struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1487
1488      if (aconf->clients >= MaxTotal(aclass))
1489        continue;
1490    }
1491
1492    return conf;
1493  }
1494
1495  return NULL;
1496 }
1497
760   /* find_conf_name()
761   *
762   * inputs       - pointer to conf link list to search
# Line 1504 | Line 766 | find_conf_exact(ConfType type, const cha
766   * side effects - find a conf entry which matches the name
767   *                and has the given mask.
768   */
769 < struct ConfItem *
770 < find_conf_name(dlink_list *list, const char *name, ConfType type)
769 > struct MaskItem *
770 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
771   {
772    dlink_node *ptr;
773 <  struct ConfItem* conf;
773 >  struct MaskItem* conf;
774  
775    DLINK_FOREACH(ptr, list->head)
776    {
# Line 1517 | Line 779 | find_conf_name(dlink_list *list, const c
779      if (conf->type == type)
780      {
781        if (conf->name && (irccmp(conf->name, name) == 0 ||
782 <                         match(conf->name, name)))
782 >                         !match(conf->name, name)))
783        return conf;
784      }
785    }
# Line 1532 | Line 794 | find_conf_name(dlink_list *list, const c
794   * side effects - none
795   */
796   static dlink_list *
797 < map_to_list(ConfType type)
797 > map_to_list(enum maskitem_type type)
798   {
799    switch(type)
800    {
801 <  case RXLINE_TYPE:
1540 <    return(&rxconf_items);
1541 <    break;
1542 <  case XLINE_TYPE:
801 >  case CONF_XLINE:
802      return(&xconf_items);
803      break;
804 <  case ULINE_TYPE:
804 >  case CONF_ULINE:
805      return(&uconf_items);
806      break;
807 <  case NRESV_TYPE:
807 >  case CONF_NRESV:
808      return(&nresv_items);
809      break;
810 <  case OPER_TYPE:
810 >  case CONF_CRESV:
811 >    return(&resv_channel_list);
812 >  case CONF_OPER:
813      return(&oconf_items);
814      break;
815 <  case CLASS_TYPE:
1555 <    return(&class_items);
1556 <    break;
1557 <  case SERVER_TYPE:
815 >  case CONF_SERVER:
816      return(&server_items);
817      break;
818 <  case SERVICE_TYPE:
818 >  case CONF_SERVICE:
819      return(&service_items);
820      break;
821 <  case CLUSTER_TYPE:
821 >  case CONF_CLUSTER:
822      return(&cluster_items);
823      break;
1566  case CONF_TYPE:
1567  case GLINE_TYPE:
1568  case KLINE_TYPE:
1569  case DLINE_TYPE:
1570  case CRESV_TYPE:
824    default:
825      return NULL;
826    }
# Line 1579 | Line 832 | map_to_list(ConfType type)
832   *              - pointer to name string to find
833   *              - pointer to user
834   *              - pointer to host
835 < *              - optional action to match on as well
836 < * output       - NULL or pointer to found struct MatchItem
835 > *              - optional flags to match on as well
836 > * output       - NULL or pointer to found struct MaskItem
837   * side effects - looks for a match on name field
838   */
839 < struct ConfItem *
840 < find_matching_name_conf(ConfType type, const char *name, const char *user,
841 <                        const char *host, int action)
839 > struct MaskItem *
840 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
841 >                        const char *host, unsigned int flags)
842   {
843    dlink_node *ptr=NULL;
844 <  struct ConfItem *conf=NULL;
1592 <  struct AccessItem *aconf=NULL;
1593 <  struct MatchItem *match_item=NULL;
844 >  struct MaskItem *conf=NULL;
845    dlink_list *list_p = map_to_list(type);
846  
847    switch (type)
848    {
849 < #ifdef HAVE_LIBPCRE
1599 <  case RXLINE_TYPE:
1600 <      DLINK_FOREACH(ptr, list_p->head)
1601 <      {
1602 <        conf = ptr->data;
1603 <        assert(conf->regexpname);
1604 <
1605 <        if (!ircd_pcre_exec(conf->regexpname, name))
1606 <          return conf;
1607 <      }
1608 <      break;
1609 < #endif
1610 <  case SERVICE_TYPE:
849 >  case CONF_SERVICE:
850      DLINK_FOREACH(ptr, list_p->head)
851      {
852        conf = ptr->data;
# Line 1619 | Line 858 | find_matching_name_conf(ConfType type, c
858      }
859      break;
860  
861 <  case XLINE_TYPE:
862 <  case ULINE_TYPE:
863 <  case NRESV_TYPE:
861 >  case CONF_XLINE:
862 >  case CONF_ULINE:
863 >  case CONF_NRESV:
864 >  case CONF_CRESV:
865      DLINK_FOREACH(ptr, list_p->head)
866      {
867        conf = ptr->data;
868  
1629      match_item = map_to_conf(conf);
869        if (EmptyString(conf->name))
870          continue;
871 <      if ((name != NULL) && match_esc(conf->name, name))
871 >      if ((name != NULL) && !match(conf->name, name))
872        {
873          if ((user == NULL && (host == NULL)))
874            return conf;
875 <        if ((match_item->action & action) != action)
875 >        if ((conf->flags & flags) != flags)
876            continue;
877 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
877 >        if (EmptyString(conf->user) || EmptyString(conf->host))
878            return conf;
879 <        if (match(match_item->user, user) && match(match_item->host, host))
879 >        if (!match(conf->user, user) && !match(conf->host, host))
880            return conf;
881        }
882      }
883        break;
884  
885 <  case SERVER_TYPE:
885 >  case CONF_SERVER:
886      DLINK_FOREACH(ptr, list_p->head)
887      {
888        conf = ptr->data;
1650      aconf = map_to_conf(conf);
889  
890 <      if ((name != NULL) && match_esc(name, conf->name))
890 >      if ((name != NULL) && !match(name, conf->name))
891          return conf;
892 <      else if ((host != NULL) && match_esc(host, aconf->host))
892 >      else if ((host != NULL) && !match(host, conf->host))
893          return conf;
894      }
895      break;
# Line 1668 | Line 906 | find_matching_name_conf(ConfType type, c
906   *              - pointer to name string to find
907   *              - pointer to user
908   *              - pointer to host
909 < * output       - NULL or pointer to found struct MatchItem
909 > * output       - NULL or pointer to found struct MaskItem
910   * side effects - looks for an exact match on name field
911   */
912 < struct ConfItem *
913 < find_exact_name_conf(ConfType type, const char *name,
912 > struct MaskItem *
913 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
914                       const char *user, const char *host)
915   {
916    dlink_node *ptr = NULL;
917 <  struct AccessItem *aconf;
918 <  struct ConfItem *conf;
1681 <  struct MatchItem *match_item;
1682 <  dlink_list *list_p;
1683 <
1684 <  list_p = map_to_list(type);
917 >  struct MaskItem *conf;
918 >  dlink_list *list_p = map_to_list(type);
919  
920    switch(type)
921    {
922 <  case RXLINE_TYPE:
923 <  case XLINE_TYPE:
924 <  case ULINE_TYPE:
925 <  case NRESV_TYPE:
922 >  case CONF_XLINE:
923 >  case CONF_ULINE:
924 >  case CONF_NRESV:
925 >  case CONF_CRESV:
926  
927      DLINK_FOREACH(ptr, list_p->head)
928      {
929        conf = ptr->data;
930 <      match_item = (struct MatchItem *)map_to_conf(conf);
930 >
931        if (EmptyString(conf->name))
932          continue;
933      
# Line 1701 | Line 935 | find_exact_name_conf(ConfType type, cons
935        {
936          if ((user == NULL && (host == NULL)))
937            return (conf);
938 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
938 >        if (EmptyString(conf->user) || EmptyString(conf->host))
939            return (conf);
940 <        if (match(match_item->user, user) && match(match_item->host, host))
940 >        if (!match(conf->user, user) && !match(conf->host, host))
941            return (conf);
942        }
943      }
944      break;
945  
946 <  case OPER_TYPE:
946 >  case CONF_OPER:
947      DLINK_FOREACH(ptr, list_p->head)
948      {
949        conf = ptr->data;
950 <      aconf = (struct AccessItem *)map_to_conf(conf);
950 >
951        if (EmptyString(conf->name))
952 <        continue;
953 <    
954 <      if (irccmp(conf->name, name) == 0)
952 >        continue;
953 >
954 >      if (!irccmp(conf->name, name))
955        {
956 <        if ((user == NULL && (host == NULL)))
957 <          return (conf);
958 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
959 <          return (conf);
960 <        if (match(aconf->user, user) && match(aconf->host, host))
961 <          return (conf);
956 >        if (!who)
957 >          return conf;
958 >        if (EmptyString(conf->user) || EmptyString(conf->host))
959 >          return NULL;
960 >        if (!match(conf->user, who->username))
961 >        {
962 >          switch (conf->htype)
963 >          {
964 >            case HM_HOST:
965 >              if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
966 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
967 >                  return conf;
968 >              break;
969 >            case HM_IPV4:
970 >              if (who->localClient->aftype == AF_INET)
971 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
972 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
973 >                    return conf;
974 >              break;
975 > #ifdef IPV6
976 >            case HM_IPV6:
977 >              if (who->localClient->aftype == AF_INET6)
978 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
979 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
980 >                    return conf;
981 >              break;
982 > #endif
983 >            default:
984 >              assert(0);
985 >          }
986 >        }
987        }
988      }
989 +
990      break;
991  
992 <  case SERVER_TYPE:
992 >  case CONF_SERVER:
993      DLINK_FOREACH(ptr, list_p->head)
994      {
995        conf = ptr->data;
996 <      aconf = (struct AccessItem *)map_to_conf(conf);
996 >
997        if (EmptyString(conf->name))
998          continue;
999      
1000        if (name == NULL)
1001        {
1002 <        if (EmptyString(aconf->host))
1002 >        if (EmptyString(conf->host))
1003            continue;
1004 <        if (irccmp(aconf->host, host) == 0)
1004 >        if (irccmp(conf->host, host) == 0)
1005            return(conf);
1006        }
1007        else if (irccmp(conf->name, name) == 0)
# Line 1751 | Line 1011 | find_exact_name_conf(ConfType type, cons
1011      }
1012      break;
1013  
1754  case CLASS_TYPE:
1755    DLINK_FOREACH(ptr, list_p->head)
1756    {
1757      conf = ptr->data;
1758      if (EmptyString(conf->name))
1759        continue;
1760    
1761      if (irccmp(conf->name, name) == 0)
1762        return (conf);
1763    }
1764    break;
1765
1014    default:
1015      break;
1016    }
# Line 1779 | Line 1027 | int
1027   rehash(int sig)
1028   {
1029    if (sig != 0)
1030 <    sendto_realops_flags(UMODE_ALL, L_ALL,
1030 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1031                           "Got signal SIGHUP, reloading ircd.conf file");
1032  
1033    restart_resolver();
# Line 1796 | Line 1044 | rehash(int sig)
1044  
1045    load_conf_modules();
1046  
1799  flush_deleted_I_P();
1800
1047    rehashed_klines = 1;
1048  
1049 <  if (ConfigLoggingEntry.use_logging)
1804 <    reopen_log(logFileName);
1805 <
1806 <  return(0);
1049 >  return 0;
1050   }
1051  
1052   /* set_default_conf()
# Line 1821 | Line 1064 | set_default_conf(void)
1064    /* verify init_class() ran, this should be an unnecessary check
1065     * but its not much work.
1066     */
1067 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1067 >  assert(class_default == class_get_list()->tail->data);
1068  
1069   #ifdef HAVE_LIBCRYPTO
1070    ServerInfo.rsa_private_key = NULL;
# Line 1831 | Line 1074 | set_default_conf(void)
1074    /* ServerInfo.name is not rehashable */
1075    /* ServerInfo.name = ServerInfo.name; */
1076    ServerInfo.description = NULL;
1077 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1078 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1077 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1078 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1079  
1080    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1081    ServerInfo.specific_ipv4_vhost = 0;
# Line 1840 | Line 1083 | set_default_conf(void)
1083    ServerInfo.specific_ipv6_vhost = 0;
1084  
1085    ServerInfo.max_clients = MAXCLIENTS_MAX;
1086 +  ServerInfo.max_nick_length = 9;
1087 +  ServerInfo.max_topic_length = 80;
1088  
1089    ServerInfo.hub = 0;
1090    ServerInfo.dns_host.sin_addr.s_addr = 0;
# Line 1848 | Line 1093 | set_default_conf(void)
1093    AdminInfo.email = NULL;
1094    AdminInfo.description = NULL;
1095  
1096 <  set_log_level(L_NOTICE);
1096 >  log_del_all();
1097 >
1098    ConfigLoggingEntry.use_logging = 1;
1099 <  ConfigLoggingEntry.operlog[0] = '\0';
1100 <  ConfigLoggingEntry.userlog[0] = '\0';
1855 <  ConfigLoggingEntry.klinelog[0] = '\0';
1856 <  ConfigLoggingEntry.glinelog[0] = '\0';
1857 <  ConfigLoggingEntry.killlog[0] = '\0';
1858 <  ConfigLoggingEntry.operspylog[0] = '\0';
1859 <  ConfigLoggingEntry.ioerrlog[0] = '\0';
1860 <  ConfigLoggingEntry.failed_operlog[0] = '\0';
1861 <
1862 <  ConfigChannel.disable_fake_channels = NO;
1863 <  ConfigChannel.restrict_channels = NO;
1864 <  ConfigChannel.disable_local_channels = NO;
1865 <  ConfigChannel.use_invex = YES;
1866 <  ConfigChannel.use_except = YES;
1867 <  ConfigChannel.use_knock = YES;
1099 >
1100 >  ConfigChannel.disable_fake_channels = 0;
1101    ConfigChannel.knock_delay = 300;
1102    ConfigChannel.knock_delay_channel = 60;
1103 <  ConfigChannel.max_chans_per_user = 15;
1104 <  ConfigChannel.quiet_on_ban = YES;
1103 >  ConfigChannel.max_chans_per_user = 25;
1104 >  ConfigChannel.max_chans_per_oper = 50;
1105    ConfigChannel.max_bans = 25;
1106    ConfigChannel.default_split_user_count = 0;
1107    ConfigChannel.default_split_server_count = 0;
1108 <  ConfigChannel.no_join_on_split = NO;
1109 <  ConfigChannel.no_create_on_split = NO;
1877 <  ConfigChannel.burst_topicwho = YES;
1108 >  ConfigChannel.no_join_on_split = 0;
1109 >  ConfigChannel.no_create_on_split = 0;
1110  
1111 <  ConfigServerHide.flatten_links = NO;
1111 >  ConfigServerHide.flatten_links = 0;
1112    ConfigServerHide.links_delay = 300;
1113 <  ConfigServerHide.hidden = NO;
1114 <  ConfigServerHide.disable_hidden = NO;
1115 <  ConfigServerHide.hide_servers = NO;
1116 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1117 <  ConfigServerHide.hide_server_ips = NO;
1113 >  ConfigServerHide.hidden = 0;
1114 >  ConfigServerHide.hide_servers = 0;
1115 >  ConfigServerHide.hide_services = 0;
1116 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1117 >  ConfigServerHide.hide_server_ips = 0;
1118  
1119    
1120 <  DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
1120 >  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1121    ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1122 +  ConfigFileEntry.glines = 0;
1123 +  ConfigFileEntry.gline_time = 12 * 3600;
1124 +  ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1125    ConfigFileEntry.gline_min_cidr = 16;
1126    ConfigFileEntry.gline_min_cidr6 = 48;
1127 <  ConfigFileEntry.invisible_on_connect = YES;
1128 <  ConfigFileEntry.burst_away = NO;
1129 <  ConfigFileEntry.use_whois_actually = YES;
1130 <  ConfigFileEntry.tkline_expire_notices = YES;
1131 <  ConfigFileEntry.hide_spoof_ips = YES;
1132 <  ConfigFileEntry.ignore_bogus_ts = NO;
1898 <  ConfigFileEntry.disable_auth = NO;
1899 <  ConfigFileEntry.disable_remote = NO;
1127 >  ConfigFileEntry.invisible_on_connect = 1;
1128 >  ConfigFileEntry.tkline_expire_notices = 1;
1129 >  ConfigFileEntry.hide_spoof_ips = 1;
1130 >  ConfigFileEntry.ignore_bogus_ts = 0;
1131 >  ConfigFileEntry.disable_auth = 0;
1132 >  ConfigFileEntry.disable_remote = 0;
1133    ConfigFileEntry.kill_chase_time_limit = 90;
1134    ConfigFileEntry.default_floodcount = 8;
1135 <  ConfigFileEntry.failed_oper_notice = YES;
1135 >  ConfigFileEntry.failed_oper_notice = 1;
1136    ConfigFileEntry.dots_in_ident = 0;
1137    ConfigFileEntry.min_nonwildcard = 4;
1138    ConfigFileEntry.min_nonwildcard_simple = 3;
1139    ConfigFileEntry.max_accept = 20;
1140 <  ConfigFileEntry.anti_nick_flood = NO;
1140 >  ConfigFileEntry.anti_nick_flood = 0;
1141    ConfigFileEntry.max_nick_time = 20;
1142    ConfigFileEntry.max_nick_changes = 5;
1143    ConfigFileEntry.anti_spam_exit_message_time = 0;
1144    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1145    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1146 <  ConfigFileEntry.kline_with_reason = YES;
1147 <  ConfigFileEntry.kline_reason = NULL;
1915 <  ConfigFileEntry.warn_no_nline = YES;
1916 <  ConfigFileEntry.stats_o_oper_only = NO;
1146 >  ConfigFileEntry.warn_no_nline = 1;
1147 >  ConfigFileEntry.stats_o_oper_only = 0;
1148    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1149    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1150 <  ConfigFileEntry.stats_P_oper_only = NO;
1150 >  ConfigFileEntry.stats_P_oper_only = 0;
1151    ConfigFileEntry.caller_id_wait = 60;
1152 <  ConfigFileEntry.opers_bypass_callerid = NO;
1152 >  ConfigFileEntry.opers_bypass_callerid = 0;
1153    ConfigFileEntry.pace_wait = 10;
1154    ConfigFileEntry.pace_wait_simple = 1;
1155 <  ConfigFileEntry.short_motd = NO;
1156 <  ConfigFileEntry.ping_cookie = NO;
1157 <  ConfigFileEntry.no_oper_flood = NO;
1158 <  ConfigFileEntry.true_no_oper_flood = NO;
1159 <  ConfigFileEntry.oper_pass_resv = YES;
1929 <  ConfigFileEntry.glines = NO;
1930 <  ConfigFileEntry.gline_time = 12 * 3600;
1155 >  ConfigFileEntry.short_motd = 0;
1156 >  ConfigFileEntry.ping_cookie = 0;
1157 >  ConfigFileEntry.no_oper_flood = 0;
1158 >  ConfigFileEntry.true_no_oper_flood = 0;
1159 >  ConfigFileEntry.oper_pass_resv = 1;
1160    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1932  ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1161    ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1162    ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1163      UMODE_OPERWALL | UMODE_WALLOP;
1164 <  DupString(ConfigFileEntry.servlink_path, SLPATH);
1937 < #ifdef HAVE_LIBCRYPTO
1938 <  /* jdc -- This is our default value for a cipher.  According to the
1939 <   *        CRYPTLINK document (doc/cryptlink.txt), BF/128 must be supported
1940 <   *        under all circumstances if cryptlinks are enabled.  So,
1941 <   *        this will be our default.
1942 <   *
1943 <   *        NOTE: I apologise for the hard-coded value of "1" (BF/128).
1944 <   *              This should be moved into a find_cipher() routine.
1945 <   */
1946 <  ConfigFileEntry.default_cipher_preference = &CipherTable[1];
1947 < #endif
1948 <  ConfigFileEntry.use_egd = NO;
1164 >  ConfigFileEntry.use_egd = 0;
1165    ConfigFileEntry.egdpool_path = NULL;
1950 #ifdef HAVE_LIBZ
1951  ConfigFileEntry.compression_level = 0;
1952 #endif
1166    ConfigFileEntry.throttle_time = 10;
1167   }
1168  
1169 + static void
1170 + validate_conf(void)
1171 + {
1172 +  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1173 +    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1174 +
1175 +  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1176 +    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1177 +
1178 +  if (ServerInfo.network_name == NULL)
1179 +    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1180 +
1181 +  if (ServerInfo.network_desc == NULL)
1182 +    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1183 +
1184 +  if (ConfigFileEntry.service_name == NULL)
1185 +    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1186 +
1187 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1188 + }
1189 +
1190   /* read_conf()
1191   *
1192   * inputs       - file descriptor pointing to config file to use
# Line 1960 | Line 1194 | set_default_conf(void)
1194   * side effects - Read configuration file.
1195   */
1196   static void
1197 < read_conf(FBFILE *file)
1197 > read_conf(FILE *file)
1198   {
1199    lineno = 0;
1200  
# Line 1968 | Line 1202 | read_conf(FBFILE *file)
1202    conf_parser_ctx.pass = 1;
1203    yyparse();          /* pick up the classes first */
1204  
1205 <  fbrewind(file);
1205 >  rewind(file);
1206  
1207    conf_parser_ctx.pass = 2;
1208    yyparse();          /* Load the values from the conf */
1209    validate_conf();    /* Check to make sure some values are still okay. */
1210                        /* Some global values are also loaded here. */
1211 <  check_class();      /* Make sure classes are valid */
1978 < }
1979 <
1980 < static void
1981 < validate_conf(void)
1982 < {
1983 <  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1984 <    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1985 <
1986 <  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1987 <    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1988 <
1989 <  if (ConfigFileEntry.servlink_path == NULL)
1990 <    DupString(ConfigFileEntry.servlink_path, SLPATH);
1991 <
1992 <  if (ServerInfo.network_name == NULL)
1993 <    DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
1994 <
1995 <  if (ServerInfo.network_desc == NULL)
1996 <    DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1997 <
1998 <  if (ConfigFileEntry.service_name == NULL)
1999 <    DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
2000 <
2001 <  if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
2002 <      (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
2003 <    ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
2004 <
2005 <  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1211 >  class_delete_marked();      /* Make sure classes are valid */
1212   }
1213  
1214   /* lookup_confhost()
# Line 2010 | Line 1216 | validate_conf(void)
1216   * start DNS lookups of all hostnames in the conf
1217   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1218   */
1219 < static void
1220 < lookup_confhost(struct ConfItem *conf)
1219 > void
1220 > lookup_confhost(struct MaskItem *conf)
1221   {
2016  struct AccessItem *aconf;
1222    struct addrinfo hints, *res;
1223  
2019  aconf = map_to_conf(conf);
2020
2021  if (EmptyString(aconf->host) ||
2022      EmptyString(aconf->user))
2023  {
2024    ilog(L_ERROR, "Host/server name error: (%s) (%s)",
2025         aconf->host, conf->name);
2026    return;
2027  }
2028
2029  if (strchr(aconf->host, '*') ||
2030      strchr(aconf->host, '?'))
2031    return;
2032
1224    /* Do name lookup now on hostnames given and store the
1225     * ip numbers in conf structure.
1226     */
# Line 2041 | Line 1232 | lookup_confhost(struct ConfItem *conf)
1232    /* Get us ready for a bind() and don't bother doing dns lookup */
1233    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1234  
1235 <  if (getaddrinfo(aconf->host, NULL, &hints, &res))
1235 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1236    {
1237 <    conf_dns_lookup(aconf);
1237 >    conf_dns_lookup(conf);
1238      return;
1239    }
1240  
1241    assert(res != NULL);
1242  
1243 <  memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
1244 <  aconf->ipnum.ss_len = res->ai_addrlen;
1245 <  aconf->ipnum.ss.ss_family = res->ai_family;
1243 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1244 >  conf->addr.ss_len = res->ai_addrlen;
1245 >  conf->addr.ss.ss_family = res->ai_family;
1246 >
1247    freeaddrinfo(res);
1248   }
1249  
# Line 2066 | Line 1258 | int
1258   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1259   {
1260    struct ip_entry *ip_found;
1261 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1261 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1262  
1263    /* DLINE exempt also gets you out of static limits/pacing... */
1264 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1264 >  if (conf && (conf->type == CONF_EXEMPT))
1265      return 0;
1266  
1267 <  if (aconf != NULL)
1267 >  if (conf != NULL)
1268      return BANNED_CLIENT;
1269  
1270    ip_found = find_or_add_ip(addr);
# Line 2088 | Line 1280 | conf_connect_allowed(struct irc_ssaddr *
1280    return 0;
1281   }
1282  
2091 static struct AccessItem *
2092 find_regexp_kline(const char *uhi[])
2093 {
2094 #ifdef HAVE_LIBPCRE
2095  const dlink_node *ptr = NULL;
2096
2097  DLINK_FOREACH(ptr, rkconf_items.head)
2098  {
2099    struct AccessItem *aptr = map_to_conf(ptr->data);
2100
2101    assert(aptr->regexuser);
2102    assert(aptr->regexhost);
2103
2104    if (!ircd_pcre_exec(aptr->regexuser, uhi[0]) &&
2105        (!ircd_pcre_exec(aptr->regexhost, uhi[1]) ||
2106         !ircd_pcre_exec(aptr->regexhost, uhi[2])))
2107      return aptr;
2108  }
2109 #endif
2110  return NULL;
2111 }
2112
1283   /* find_kill()
1284   *
1285   * inputs       - pointer to client structure
1286 < * output       - pointer to struct AccessItem if found
1286 > * output       - pointer to struct MaskItem if found
1287   * side effects - See if this user is klined already,
1288 < *                and if so, return struct AccessItem pointer
1288 > *                and if so, return struct MaskItem pointer
1289   */
1290 < struct AccessItem *
1290 > struct MaskItem *
1291   find_kill(struct Client *client_p)
1292   {
1293 <  struct AccessItem *aconf = NULL;
2124 <  const char *uhi[3];
2125 <
2126 <  uhi[0] = client_p->username;
2127 <  uhi[1] = client_p->host;
2128 <  uhi[2] = client_p->sockhost;
1293 >  struct MaskItem *conf = NULL;
1294  
1295    assert(client_p != NULL);
1296  
1297 <  aconf = find_kline_conf(client_p->host, client_p->username,
1298 <                          &client_p->localClient->ip,
1299 <                          client_p->localClient->aftype);
1300 <  if (aconf == NULL)
2136 <    aconf = find_regexp_kline(uhi);
2137 <
2138 <  if (aconf && (aconf->status & CONF_KLINE))
2139 <    return aconf;
2140 <
2141 <  return NULL;
1297 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1298 >                              CONF_KLINE, client_p->localClient->aftype,
1299 >                              client_p->username, NULL, 1);
1300 >  return conf;
1301   }
1302  
1303 < struct AccessItem *
1303 > struct MaskItem *
1304   find_gline(struct Client *client_p)
1305   {
1306 <  struct AccessItem *aconf;
1306 >  struct MaskItem *conf;
1307  
1308    assert(client_p != NULL);
1309  
1310 <  aconf = find_gline_conf(client_p->host, client_p->username,
1311 <                          &client_p->localClient->ip,
1312 <                          client_p->localClient->aftype);
1313 <
2155 <  if (aconf && (aconf->status & CONF_GLINE))
2156 <    return aconf;
2157 <
2158 <  return NULL;
2159 < }
2160 <
2161 < /* add_temp_line()
2162 < *
2163 < * inputs        - pointer to struct ConfItem
2164 < * output        - none
2165 < * Side effects  - links in given struct ConfItem into
2166 < *                 temporary *line link list
2167 < */
2168 < void
2169 < add_temp_line(struct ConfItem *conf)
2170 < {
2171 <  struct AccessItem *aconf;
2172 <
2173 <  if (conf->type == DLINE_TYPE)
2174 <  {
2175 <    aconf = map_to_conf(conf);
2176 <    SetConfTemporary(aconf);
2177 <    dlinkAdd(conf, &conf->node, &temporary_dlines);
2178 <    MyFree(aconf->user);
2179 <    aconf->user = NULL;
2180 <    add_conf_by_address(CONF_DLINE, aconf);
2181 <  }
2182 <  else if (conf->type == KLINE_TYPE)
2183 <  {
2184 <    aconf = map_to_conf(conf);
2185 <    SetConfTemporary(aconf);
2186 <    dlinkAdd(conf, &conf->node, &temporary_klines);
2187 <    add_conf_by_address(CONF_KILL, aconf);
2188 <  }
2189 <  else if (conf->type == GLINE_TYPE)
2190 <  {
2191 <    aconf = map_to_conf(conf);
2192 <    SetConfTemporary(aconf);
2193 <    dlinkAdd(conf, &conf->node, &temporary_glines);
2194 <    add_conf_by_address(CONF_GLINE, aconf);
2195 <  }
2196 <  else if (conf->type == XLINE_TYPE)
2197 <  {
2198 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2199 <    dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
2200 <  }
2201 <  else if (conf->type == RXLINE_TYPE)
2202 <  {
2203 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2204 <    dlinkAdd(conf, make_dlink_node(), &temporary_rxlines);
2205 <  }
2206 <  else if (conf->type == RKLINE_TYPE)
2207 <  {
2208 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2209 <    dlinkAdd(conf, make_dlink_node(), &temporary_rklines);
2210 <  }
2211 <  else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
2212 <  {
2213 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2214 <    dlinkAdd(conf, make_dlink_node(), &temporary_resv);
2215 <  }
1310 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1311 >                              CONF_GLINE, client_p->localClient->aftype,
1312 >                              client_p->username, NULL, 1);
1313 >  return conf;
1314   }
1315  
1316   /* cleanup_tklines()
# Line 2225 | Line 1323 | add_temp_line(struct ConfItem *conf)
1323   void
1324   cleanup_tklines(void *notused)
1325   {
1326 <  expire_tklines(&temporary_glines);
1327 <  expire_tklines(&temporary_klines);
1328 <  expire_tklines(&temporary_dlines);
1329 <  expire_tklines(&temporary_xlines);
2232 <  expire_tklines(&temporary_rxlines);
2233 <  expire_tklines(&temporary_rklines);
2234 <  expire_tklines(&temporary_resv);
1326 >  hostmask_expire_temporary();
1327 >  expire_tklines(&xconf_items);
1328 >  expire_tklines(&nresv_items);
1329 >  expire_tklines(&resv_channel_list);
1330   }
1331  
1332   /* expire_tklines()
# Line 2245 | Line 1340 | expire_tklines(dlink_list *tklist)
1340   {
1341    dlink_node *ptr;
1342    dlink_node *next_ptr;
1343 <  struct ConfItem *conf;
2249 <  struct MatchItem *xconf;
2250 <  struct MatchItem *nconf;
2251 <  struct AccessItem *aconf;
2252 <  struct ResvChannel *cconf;
1343 >  struct MaskItem *conf;
1344  
1345    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1346    {
1347      conf = ptr->data;
2257    if (conf->type == GLINE_TYPE ||
2258        conf->type == KLINE_TYPE ||
2259        conf->type == DLINE_TYPE)
2260    {
2261      aconf = (struct AccessItem *)map_to_conf(conf);
2262      if (aconf->hold <= CurrentTime)
2263      {
2264        /* XXX - Do we want GLINE expiry notices?? */
2265        /* Alert opers that a TKline expired - Hwy */
2266        if (ConfigFileEntry.tkline_expire_notices)
2267        {
2268          if (aconf->status & CONF_KILL)
2269          {
2270            sendto_realops_flags(UMODE_ALL, L_ALL,
2271                                 "Temporary K-line for [%s@%s] expired",
2272                                 (aconf->user) ? aconf->user : "*",
2273                                 (aconf->host) ? aconf->host : "*");
2274          }
2275          else if (conf->type == DLINE_TYPE)
2276          {
2277            sendto_realops_flags(UMODE_ALL, L_ALL,
2278                                 "Temporary D-line for [%s] expired",
2279                                 (aconf->host) ? aconf->host : "*");
2280          }
2281        }
1348  
1349 <        dlinkDelete(ptr, tklist);
1350 <        delete_one_address_conf(aconf->host, aconf);
1351 <      }
1352 <    }
2287 <    else if (conf->type == XLINE_TYPE ||
2288 <             conf->type == RXLINE_TYPE)
2289 <    {
2290 <      xconf = (struct MatchItem *)map_to_conf(conf);
2291 <      if (xconf->hold <= CurrentTime)
2292 <      {
2293 <        if (ConfigFileEntry.tkline_expire_notices)
2294 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2295 <                               "Temporary X-line for [%s] %sexpired", conf->name,
2296 <                               conf->type == RXLINE_TYPE ? "(REGEX) " : "");
2297 <        dlinkDelete(ptr, tklist);
2298 <        free_dlink_node(ptr);
2299 <        delete_conf_item(conf);
2300 <      }
2301 <    }
2302 <    else if (conf->type == RKLINE_TYPE)
1349 >    if (!conf->until || conf->until > CurrentTime)
1350 >      continue;
1351 >
1352 >    if (conf->type == CONF_XLINE)
1353      {
1354 <      aconf = map_to_conf(conf);
1355 <      if (aconf->hold <= CurrentTime)
1356 <      {
1357 <        if (ConfigFileEntry.tkline_expire_notices)
2308 <           sendto_realops_flags(UMODE_ALL, L_ALL,
2309 <                                "Temporary K-line for [%s@%s] (REGEX) expired",
2310 <                                (aconf->user) ? aconf->user : "*",
2311 <                                (aconf->host) ? aconf->host : "*");
2312 <        dlinkDelete(ptr, tklist);
2313 <        free_dlink_node(ptr);
2314 <        delete_conf_item(conf);
2315 <      }
1354 >      if (ConfigFileEntry.tkline_expire_notices)
1355 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1356 >                               "Temporary X-line for [%s] expired", conf->name);
1357 >      conf_free(conf);
1358      }
1359 <    else if (conf->type == NRESV_TYPE)
1359 >    else if (conf->type == CONF_NRESV || conf->type == CONF_CRESV)
1360      {
1361 <      nconf = (struct MatchItem *)map_to_conf(conf);
1362 <      if (nconf->hold <= CurrentTime)
2321 <      {
2322 <        if (ConfigFileEntry.tkline_expire_notices)
2323 <          sendto_realops_flags(UMODE_ALL, L_ALL,
1361 >      if (ConfigFileEntry.tkline_expire_notices)
1362 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1363                                 "Temporary RESV for [%s] expired", conf->name);
1364 <        dlinkDelete(ptr, tklist);
2326 <        free_dlink_node(ptr);
2327 <        delete_conf_item(conf);
2328 <      }
2329 <    }
2330 <    else if (conf->type == CRESV_TYPE)
2331 <    {
2332 <      cconf = (struct ResvChannel *)map_to_conf(conf);
2333 <      if (cconf->hold <= CurrentTime)
2334 <      {
2335 <        if (ConfigFileEntry.tkline_expire_notices)
2336 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2337 <                               "Temporary RESV for [%s] expired", cconf->name);
2338 <        delete_channel_resv(cconf);
2339 <      }
1364 >      conf_free(conf);
1365      }
1366    }
1367   }
# Line 2349 | Line 1374 | expire_tklines(dlink_list *tklist)
1374   */
1375   static const struct oper_privs
1376   {
1377 <  const unsigned int oprivs;
2353 <  const unsigned int hidden;
1377 >  const unsigned int flag;
1378    const unsigned char c;
1379   } flag_list[] = {
1380 <  { OPER_FLAG_ADMIN,       OPER_FLAG_HIDDEN_ADMIN,  'A' },
1381 <  { OPER_FLAG_REMOTEBAN,   0,                       'B' },
1382 <  { OPER_FLAG_DIE,         0,                       'D' },
1383 <  { OPER_FLAG_GLINE,       0,                       'G' },
1384 <  { OPER_FLAG_REHASH,      0,                       'H' },
1385 <  { OPER_FLAG_K,           0,                       'K' },
1386 <  { OPER_FLAG_OPERWALL,    0,                       'L' },
1387 <  { OPER_FLAG_N,           0,                       'N' },
1388 <  { OPER_FLAG_GLOBAL_KILL, 0,                       'O' },
1389 <  { OPER_FLAG_REMOTE,      0,                       'R' },
1390 <  { OPER_FLAG_OPER_SPY,    0,                       'S' },
1391 <  { OPER_FLAG_UNKLINE,     0,                       'U' },
1392 <  { OPER_FLAG_X,           0,                       'X' },
1393 <  { 0, 0, '\0' }
1380 >  { OPER_FLAG_ADMIN,          'A' },
1381 >  { OPER_FLAG_REMOTEBAN,      'B' },
1382 >  { OPER_FLAG_DIE,            'D' },
1383 >  { OPER_FLAG_GLINE,          'G' },
1384 >  { OPER_FLAG_REHASH,         'H' },
1385 >  { OPER_FLAG_K,              'K' },
1386 >  { OPER_FLAG_OPERWALL,       'L' },
1387 >  { OPER_FLAG_KILL,           'N' },
1388 >  { OPER_FLAG_KILL_REMOTE,    'O' },
1389 >  { OPER_FLAG_CONNECT,        'P' },
1390 >  { OPER_FLAG_CONNECT_REMOTE, 'Q' },
1391 >  { OPER_FLAG_SQUIT,          'R' },
1392 >  { OPER_FLAG_SQUIT_REMOTE,   'S' },
1393 >  { OPER_FLAG_UNKLINE,        'U' },
1394 >  { OPER_FLAG_X,              'X' },
1395 >  { 0, '\0' }
1396   };
1397  
1398   char *
# Line 2374 | Line 1400 | oper_privs_as_string(const unsigned int
1400   {
1401    static char privs_out[16];
1402    char *privs_ptr = privs_out;
1403 <  unsigned int i = 0;
1403 >  const struct oper_privs *opriv = flag_list;
1404  
1405 <  for (; flag_list[i].oprivs; ++i)
1405 >  for (; opriv->flag; ++opriv)
1406    {
1407 <    if ((port & flag_list[i].oprivs) &&
1408 <        (port & flag_list[i].hidden) == 0)
2383 <      *privs_ptr++ = flag_list[i].c;
1407 >    if (port & opriv->flag)
1408 >      *privs_ptr++ = opriv->c;
1409      else
1410 <      *privs_ptr++ = ToLowerTab[flag_list[i].c];
1410 >      *privs_ptr++ = ToLower(opriv->c);
1411    }
1412  
1413    *privs_ptr = '\0';
# Line 2396 | Line 1421 | oper_privs_as_string(const unsigned int
1421   *         "oper" is server name for remote opers
1422   * Side effects: None.
1423   */
1424 < char *
1424 > const char *
1425   get_oper_name(const struct Client *client_p)
1426   {
1427 <  dlink_node *cnode;
2403 <  struct ConfItem *conf;
2404 <  struct AccessItem *aconf;
2405 <
1427 >  dlink_node *cnode = NULL;
1428    /* +5 for !,@,{,} and null */
1429    static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
1430  
1431    if (MyConnect(client_p))
1432    {
1433 <    DLINK_FOREACH(cnode, client_p->localClient->confs.head)
1433 >    if ((cnode = client_p->localClient->confs.head))
1434      {
1435 <      conf = cnode->data;
2414 <      aconf = map_to_conf(conf);
1435 >      struct MaskItem *conf = cnode->data;
1436  
1437 <      if (IsConfOperator(aconf))
1437 >      if (IsConfOperator(conf))
1438        {
1439          snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1440                   client_p->username, client_p->host, conf->name);
# Line 2446 | Line 1467 | read_conf_files(int cold)
1467    char chanlimit[32];
1468  
1469    conf_parser_ctx.boot = cold;
1470 <  filename = get_conf_name(CONF_TYPE);
1470 >  filename = ConfigFileEntry.configfile;
1471  
1472    /* We need to know the initial filename for the yyerror() to report
1473       FIXME: The full path is in conffilenamebuf first time since we
# Line 2456 | Line 1477 | read_conf_files(int cold)
1477    */
1478    strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1479  
1480 <  if ((conf_parser_ctx.conf_file = fbopen(filename, "r")) == NULL)
1480 >  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1481    {
1482      if (cold)
1483      {
1484 <      ilog(L_CRIT, "Unable to read configuration file '%s': %s",
1484 >      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1485             filename, strerror(errno));
1486        exit(-1);
1487      }
1488      else
1489      {
1490 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1490 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1491                             "Unable to read configuration file '%s': %s",
1492                             filename, strerror(errno));
1493        return;
# Line 2477 | Line 1498 | read_conf_files(int cold)
1498      clear_out_old_conf();
1499  
1500    read_conf(conf_parser_ctx.conf_file);
1501 <  fbclose(conf_parser_ctx.conf_file);
1501 >  fclose(conf_parser_ctx.conf_file);
1502  
1503 +  log_reopen_all();
1504 +
1505 +  add_isupport("NICKLEN", NULL, ServerInfo.max_nick_length);
1506    add_isupport("NETWORK", ServerInfo.network_name, -1);
1507 <  snprintf(chanmodes, sizeof(chanmodes), "b%s%s:%d",
1508 <           ConfigChannel.use_except ? "e" : "",
2485 <           ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
1507 >
1508 >  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1509    add_isupport("MAXLIST", chanmodes, -1);
1510    add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
1511 +  add_isupport("CHANTYPES", "#", -1);
1512  
1513 <  if (ConfigChannel.disable_local_channels)
1514 <    add_isupport("CHANTYPES", "#", -1);
2491 <  else
2492 <    add_isupport("CHANTYPES", "#&", -1);
2493 <
2494 <  snprintf(chanlimit, sizeof(chanlimit), "%s:%d",
2495 <           ConfigChannel.disable_local_channels ? "#" : "#&",
2496 <           ConfigChannel.max_chans_per_user);
1513 >  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1514 >           ConfigChannel.max_chans_per_user);
1515    add_isupport("CHANLIMIT", chanlimit, -1);
1516 <  snprintf(chanmodes, sizeof(chanmodes), "%s%s%s",
2499 <           ConfigChannel.use_except ? "e" : "",
2500 <           ConfigChannel.use_invex ? "I" : "", "b,k,l,imnprstORS");
1516 >  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1517    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1518 <
1519 <  if (ConfigChannel.use_except)
1520 <    add_isupport("EXCEPTS", "e", -1);
2505 <  if (ConfigChannel.use_invex)
2506 <    add_isupport("INVEX", "I", -1);
1518 >  add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1519 >  add_isupport("EXCEPTS", "e", -1);
1520 >  add_isupport("INVEX", "I", -1);
1521    add_isupport("CHANMODES", chanmodes, -1);
1522  
1523    /*
# Line 2511 | Line 1525 | read_conf_files(int cold)
1525     * on strlen(form_str(RPL_ISUPPORT))
1526     */
1527    rebuild_isupport_message_line();
2514
2515 #ifdef HAVE_LIBPCRE
2516  parse_conf_file(RKLINE_TYPE, cold);
2517  parse_conf_file(RXLINE_TYPE, cold);
2518 #endif
2519  parse_conf_file(KLINE_TYPE, cold);
2520  parse_conf_file(DLINE_TYPE, cold);
2521  parse_conf_file(XLINE_TYPE, cold);
2522  parse_conf_file(NRESV_TYPE, cold);
2523  parse_conf_file(CRESV_TYPE, cold);
2524 }
2525
2526 /* parse_conf_file()
2527 *
2528 * inputs       - type of conf file to parse
2529 * output       - none
2530 * side effects - conf file for givenconf type is opened and read then parsed
2531 */
2532 static void
2533 parse_conf_file(int type, int cold)
2534 {
2535  FBFILE *file = NULL;
2536  const char *filename = get_conf_name(type);
2537
2538  if ((file = fbopen(filename, "r")) == NULL)
2539  {
2540    if (cold)
2541      ilog(L_ERROR, "Unable to read configuration file '%s': %s",
2542           filename, strerror(errno));
2543    else
2544      sendto_realops_flags(UMODE_ALL, L_ALL,
2545                    "Unable to read configuration file '%s': %s",
2546                           filename, strerror(errno));
2547  }
2548  else
2549  {
2550    parse_csv_file(file, type);
2551    fbclose(file);
2552  }
1528   }
1529  
1530   /* clear_out_old_conf()
# Line 2562 | Line 1537 | static void
1537   clear_out_old_conf(void)
1538   {
1539    dlink_node *ptr = NULL, *next_ptr = NULL;
1540 <  struct ConfItem *conf;
2566 <  struct AccessItem *aconf;
2567 <  struct ClassItem *cltmp;
2568 <  struct MatchItem *match_item;
1540 >  struct MaskItem *conf;
1541    dlink_list *free_items [] = {
1542 <    &server_items,   &oconf_items,    &hub_items, &leaf_items,
1543 <     &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
1544 <     &nresv_items, &cluster_items,  &gdeny_items, &service_items, NULL
1542 >    &server_items,   &oconf_items,
1543 >     &uconf_items,   &xconf_items,
1544 >     &nresv_items, &cluster_items,  &service_items, &resv_channel_list, NULL
1545    };
1546  
1547    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2583 | Line 1555 | clear_out_old_conf(void)
1555      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1556      {
1557        conf = ptr->data;
2586      /* XXX This is less than pretty */
2587      if (conf->type == SERVER_TYPE)
2588      {
2589        aconf = map_to_conf(conf);
1558  
1559 <        if (aconf->clients != 0)
2592 <        {
2593 <          SetConfIllegal(aconf);
2594 <          dlinkDelete(&conf->node, &server_items);
2595 <        }
2596 <        else
2597 <        {
2598 <          delete_conf_item(conf);
2599 <        }
2600 <      }
2601 <      else if (conf->type == OPER_TYPE)
2602 <      {
2603 <        aconf = map_to_conf(conf);
1559 >      dlinkDelete(&conf->node, map_to_list(conf->type));
1560  
1561 <        if (aconf->clients != 0)
1562 <        {
2607 <          SetConfIllegal(aconf);
2608 <          dlinkDelete(&conf->node, &oconf_items);
2609 <        }
2610 <        else
2611 <        {
2612 <          delete_conf_item(conf);
2613 <        }
2614 <      }
2615 <      else if (conf->type == CLIENT_TYPE)
1561 >      /* XXX This is less than pretty */
1562 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1563        {
1564 <        aconf = map_to_conf(conf);
1565 <
2619 <        if (aconf->clients != 0)
2620 <        {
2621 <          SetConfIllegal(aconf);
2622 <        }
2623 <        else
2624 <        {
2625 <          delete_conf_item(conf);
2626 <        }
1564 >        if (!conf->ref_count)
1565 >          conf_free(conf);
1566        }
1567 <      else if (conf->type == XLINE_TYPE  ||
2629 <               conf->type == RXLINE_TYPE ||
2630 <               conf->type == RKLINE_TYPE)
1567 >      else if (conf->type == CONF_XLINE)
1568        {
1569 <        /* temporary (r)xlines are also on
1570 <         * the (r)xconf items list */
2634 <        if (conf->flags & CONF_FLAGS_TEMPORARY)
2635 <          continue;
2636 <
2637 <        delete_conf_item(conf);
1569 >        if (!conf->until)
1570 >          conf_free(conf);
1571        }
1572        else
1573 <      {
2641 <        if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
2642 <        {
2643 <          match_item = map_to_conf(conf);
2644 <          if (match_item->ref_count <= 0)
2645 <            delete_conf_item(conf);
2646 <          else
2647 <          {
2648 <            match_item->illegal = 1;
2649 <            dlinkDelete(&conf->node, *iterator);
2650 <          }
2651 <        }
2652 <        else
2653 <          delete_conf_item(conf);
2654 <      }
1573 >        conf_free(conf);
1574      }
1575    }
1576  
1577    /*
1578     * don't delete the class table, rather mark all entries
1579 <   * for deletion. The table is cleaned up by check_class. - avalon
1579 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1580     */
1581 <  DLINK_FOREACH(ptr, class_items.head)
2663 <  {
2664 <    cltmp = map_to_conf(ptr->data);
2665 <
2666 <    if (ptr != class_items.tail)  /* never mark the "default" class */
2667 <      cltmp->active = 0;
2668 <  }
1581 >  class_mark_for_deletion();
1582  
1583    clear_out_address_conf();
1584  
# Line 2690 | Line 1603 | clear_out_old_conf(void)
1603  
1604    MyFree(ServerInfo.rsa_private_key_file);
1605    ServerInfo.rsa_private_key_file = NULL;
2693 #endif
1606  
1607 <  /* clean out old resvs from the conf */
1608 <  clear_conf_resv();
1607 >  if (ServerInfo.server_ctx)
1608 >    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1609 >                                               SSL_OP_NO_SSLv3|
1610 >                                               SSL_OP_NO_TLSv1);
1611 >  if (ServerInfo.client_ctx)
1612 >    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1613 >                                               SSL_OP_NO_SSLv3|
1614 >                                               SSL_OP_NO_TLSv1);
1615 > #endif
1616  
1617    /* clean out AdminInfo */
1618    MyFree(AdminInfo.name);
# Line 2703 | Line 1622 | clear_out_old_conf(void)
1622    MyFree(AdminInfo.description);
1623    AdminInfo.description = NULL;
1624  
2706  /* operator{} and class{} blocks are freed above */
1625    /* clean out listeners */
1626    close_listeners();
1627  
2710  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2711   * exempt{} and gecos{} blocks are freed above too
2712   */
2713
1628    /* clean out general */
1629    MyFree(ConfigFileEntry.service_name);
1630    ConfigFileEntry.service_name = NULL;
1631  
2718  MyFree(ConfigFileEntry.servlink_path);
2719  ConfigFileEntry.servlink_path = NULL;
2720 #ifdef HAVE_LIBCRYPTO
2721  ConfigFileEntry.default_cipher_preference = NULL;
2722 #endif /* HAVE_LIBCRYPTO */
1632    delete_isupport("INVEX");
1633    delete_isupport("EXCEPTS");
1634   }
1635  
2727 /* flush_deleted_I_P()
2728 *
2729 * inputs       - none
2730 * output       - none
2731 * side effects - This function removes I/P conf items
2732 */
2733 static void
2734 flush_deleted_I_P(void)
2735 {
2736  dlink_node *ptr;
2737  dlink_node *next_ptr;
2738  struct ConfItem *conf;
2739  struct AccessItem *aconf;
2740  dlink_list * free_items [] = {
2741    &server_items, &oconf_items, NULL
2742  };
2743  dlink_list ** iterator = free_items; /* C is dumb */
2744
2745  /* flush out deleted I and P lines
2746   * although still in use.
2747   */
2748  for (; *iterator != NULL; iterator++)
2749  {
2750    DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
2751    {
2752      conf = ptr->data;
2753      aconf = (struct AccessItem *)map_to_conf(conf);
2754
2755      if (IsConfIllegal(aconf))
2756      {
2757        dlinkDelete(ptr, *iterator);
2758
2759        if (aconf->clients == 0)
2760          delete_conf_item(conf);
2761      }
2762    }
2763  }
2764 }
2765
2766 /* get_conf_name()
2767 *
2768 * inputs       - type of conf file to return name of file for
2769 * output       - pointer to filename for type of conf
2770 * side effects - none
2771 */
2772 const char *
2773 get_conf_name(ConfType type)
2774 {
2775  switch (type)
2776  {
2777    case CONF_TYPE:
2778      return ConfigFileEntry.configfile;
2779      break;
2780    case KLINE_TYPE:
2781      return ConfigFileEntry.klinefile;
2782      break;
2783    case RKLINE_TYPE:
2784      return ConfigFileEntry.rklinefile;
2785      break;
2786    case DLINE_TYPE:
2787      return ConfigFileEntry.dlinefile;
2788      break;
2789    case XLINE_TYPE:
2790      return ConfigFileEntry.xlinefile;
2791      break;
2792    case RXLINE_TYPE:
2793      return ConfigFileEntry.rxlinefile;
2794      break;
2795    case CRESV_TYPE:
2796      return ConfigFileEntry.cresvfile;
2797      break;
2798    case NRESV_TYPE:
2799      return ConfigFileEntry.nresvfile;
2800      break;
2801    case GLINE_TYPE:
2802      return ConfigFileEntry.glinefile;
2803      break;
2804
2805    default:
2806      return NULL;  /* This should NEVER HAPPEN since we call this function
2807                       only with the above values, this will cause us to core
2808                       at some point if this happens so we know where it was */
2809  }
2810 }
2811
2812 #define BAD_PING (-1)
2813
2814 /* get_conf_ping()
2815 *
2816 * inputs       - pointer to struct AccessItem
2817 *              - pointer to a variable that receives ping warning time
2818 * output       - ping frequency
2819 * side effects - NONE
2820 */
2821 static int
2822 get_conf_ping(struct ConfItem *conf, int *pingwarn)
2823 {
2824  struct ClassItem *aclass;
2825  struct AccessItem *aconf;
2826
2827  if (conf != NULL)
2828  {
2829    aconf = (struct AccessItem *)map_to_conf(conf);
2830    if (aconf->class_ptr != NULL)
2831    {
2832      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
2833      *pingwarn = PingWarning(aclass);
2834      return PingFreq(aclass);
2835    }
2836  }
2837
2838  return BAD_PING;
2839 }
2840
2841 /* get_client_class()
2842 *
2843 * inputs       - pointer to client struct
2844 * output       - pointer to name of class
2845 * side effects - NONE
2846 */
2847 const char *
2848 get_client_class(struct Client *target_p)
2849 {
2850  dlink_node *ptr;
2851  struct ConfItem *conf;
2852  struct AccessItem *aconf;
2853
2854  if (target_p != NULL && !IsMe(target_p) &&
2855      target_p->localClient->confs.head != NULL)
2856  {
2857    DLINK_FOREACH(ptr, target_p->localClient->confs.head)
2858    {
2859      conf = ptr->data;
2860
2861      if (conf->type == CLIENT_TYPE || conf->type == SERVER_TYPE ||
2862          conf->type == OPER_TYPE)
2863      {
2864        aconf = (struct AccessItem *) map_to_conf(conf);
2865        if (aconf->class_ptr != NULL)
2866          return aconf->class_ptr->name;
2867      }
2868    }
2869  }
2870
2871  return "default";
2872 }
2873
2874 /* get_client_ping()
2875 *
2876 * inputs       - pointer to client struct
2877 *              - pointer to a variable that receives ping warning time
2878 * output       - ping frequency
2879 * side effects - NONE
2880 */
2881 int
2882 get_client_ping(struct Client *target_p, int *pingwarn)
2883 {
2884  int ping;
2885  struct ConfItem *conf;
2886  dlink_node *nlink;
2887
2888  if (target_p->localClient->confs.head != NULL)
2889    DLINK_FOREACH(nlink, target_p->localClient->confs.head)
2890    {
2891      conf = nlink->data;
2892
2893      if ((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2894          (conf->type == OPER_TYPE))
2895      {
2896        ping = get_conf_ping(conf, pingwarn);
2897        if (ping > 0)
2898          return ping;
2899      }
2900    }
2901
2902  *pingwarn = 0;
2903  return DEFAULT_PINGFREQUENCY;
2904 }
2905
2906 /* find_class()
2907 *
2908 * inputs       - string name of class
2909 * output       - corresponding Class pointer
2910 * side effects - NONE
2911 */
2912 struct ConfItem *
2913 find_class(const char *classname)
2914 {
2915  struct ConfItem *conf;
2916
2917  if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
2918    return conf;
2919
2920  return class_default;
2921 }
2922
2923 /* check_class()
2924 *
2925 * inputs       - NONE
2926 * output       - NONE
2927 * side effects -
2928 */
2929 void
2930 check_class(void)
2931 {
2932  dlink_node *ptr = NULL, *next_ptr = NULL;
2933
2934  DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2935  {
2936    struct ClassItem *aclass = map_to_conf(ptr->data);
2937
2938    if (!aclass->active && !CurrUserCount(aclass))
2939    {
2940      destroy_cidr_class(aclass);
2941      delete_conf_item(ptr->data);
2942    }
2943  }
2944 }
2945
2946 /* init_class()
2947 *
2948 * inputs       - NONE
2949 * output       - NONE
2950 * side effects -
2951 */
2952 void
2953 init_class(void)
2954 {
2955  struct ClassItem *aclass;
2956
2957  class_default = make_conf_item(CLASS_TYPE);
2958
2959  aclass = map_to_conf(class_default);
2960  aclass->active = 1;
2961  DupString(class_default->name, "default");
2962  ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
2963  PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
2964  MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
2965  MaxSendq(aclass) = DEFAULT_SENDQ;
2966
2967  client_check_cb = register_callback("check_client", check_client);
2968 }
2969
2970 /* get_sendq()
2971 *
2972 * inputs       - pointer to client
2973 * output       - sendq for this client as found from its class
2974 * side effects - NONE
2975 */
2976 unsigned int
2977 get_sendq(struct Client *client_p)
2978 {
2979  unsigned int sendq = DEFAULT_SENDQ;
2980  dlink_node *ptr;
2981  struct ConfItem *conf;
2982  struct ConfItem *class_conf;
2983  struct ClassItem *aclass;
2984  struct AccessItem *aconf;
2985
2986  if (client_p && !IsMe(client_p) && (client_p->localClient->confs.head))
2987  {
2988    DLINK_FOREACH(ptr, client_p->localClient->confs.head)
2989    {
2990      conf = ptr->data;
2991      if ((conf->type == SERVER_TYPE) || (conf->type == OPER_TYPE)
2992          || (conf->type == CLIENT_TYPE))
2993      {
2994        aconf = (struct AccessItem *)map_to_conf(conf);
2995        if ((class_conf = aconf->class_ptr) == NULL)
2996          continue;
2997        aclass = (struct ClassItem *)map_to_conf(class_conf);
2998        sendq = MaxSendq(aclass);
2999        return sendq;
3000      }
3001    }
3002  }
3003  /* XXX return a default?
3004   * if here, then there wasn't an attached conf with a sendq
3005   * that is very bad -Dianora
3006   */
3007  return DEFAULT_SENDQ;
3008 }
3009
1636   /* conf_add_class_to_conf()
1637   *
1638   * inputs       - pointer to config item
# Line 3014 | Line 1640 | get_sendq(struct Client *client_p)
1640   * side effects - Add a class pointer to a conf
1641   */
1642   void
1643 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1643 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1644   {
3019  struct AccessItem *aconf = map_to_conf(conf);
3020  struct ClassItem *class = NULL;
3021
1645    if (class_name == NULL)
1646    {
1647 <    aconf->class_ptr = class_default;
1647 >    conf->class = class_default;
1648  
1649 <    if (conf->type == CLIENT_TYPE)
1650 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1649 >    if (conf->type == CONF_CLIENT)
1650 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1651                             "Warning *** Defaulting to default class for %s@%s",
1652 <                           aconf->user, aconf->host);
1652 >                           conf->user, conf->host);
1653      else
1654 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1654 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1655                             "Warning *** Defaulting to default class for %s",
1656                             conf->name);
1657    }
1658    else
1659 <    aconf->class_ptr = find_class(class_name);
1659 >    conf->class = class_find(class_name, 1);
1660  
1661 <  if (aconf->class_ptr)
3039 <    class = map_to_conf(aconf->class_ptr);
3040 <
3041 <  if (aconf->class_ptr == NULL || !class->active)
1661 >  if (conf->class == NULL)
1662    {
1663 <    if (conf->type == CLIENT_TYPE)
1664 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1663 >    if (conf->type == CONF_CLIENT)
1664 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1665                             "Warning *** Defaulting to default class for %s@%s",
1666 <                           aconf->user, aconf->host);
1666 >                           conf->user, conf->host);
1667      else
1668 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1668 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1669                             "Warning *** Defaulting to default class for %s",
1670                             conf->name);
1671 <    aconf->class_ptr = class_default;
3052 <  }
3053 < }
3054 <
3055 < /* conf_add_server()
3056 < *
3057 < * inputs       - pointer to config item
3058 < *              - pointer to link count already on this conf
3059 < * output       - NONE
3060 < * side effects - Add a connect block
3061 < */
3062 < int
3063 < conf_add_server(struct ConfItem *conf, const char *class_name)
3064 < {
3065 <  struct AccessItem *aconf;
3066 <  struct split_nuh_item nuh;
3067 <  char conf_user[USERLEN + 1];
3068 <  char conf_host[HOSTLEN + 1];
3069 <
3070 <  aconf = map_to_conf(conf);
3071 <
3072 <  conf_add_class_to_conf(conf, class_name);
3073 <
3074 <  if (!aconf->host || !conf->name)
3075 <  {
3076 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
3077 <    ilog(L_WARN, "Bad connect block");
3078 <    return -1;
3079 <  }
3080 <
3081 <  if (EmptyString(aconf->passwd) && !IsConfCryptLink(aconf))
3082 <  {
3083 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s",
3084 <                         conf->name);
3085 <    ilog(L_WARN, "Bad connect block, host %s", conf->name);
3086 <    return -1;
1671 >    conf->class = class_default;
1672    }
3088
3089  nuh.nuhmask  = aconf->host;
3090  nuh.nickptr  = NULL;
3091  nuh.userptr  = conf_user;
3092  nuh.hostptr  = conf_host;
3093
3094  nuh.nicksize = 0;
3095  nuh.usersize = sizeof(conf_user);
3096  nuh.hostsize = sizeof(conf_host);
3097
3098  split_nuh(&nuh);
3099
3100  MyFree(aconf->host);
3101  aconf->host = NULL;
3102
3103  DupString(aconf->user, conf_user); /* somehow username checking for servers
3104                                 got lost in H6/7, will have to be re-added */
3105  DupString(aconf->host, conf_host);
3106
3107  lookup_confhost(conf);
3108
3109  return 0;
1673   }
1674  
1675   /* yyerror()
# Line 3124 | Line 1687 | yyerror(const char *msg)
1687      return;
1688  
1689    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1690 <  sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
1690 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1691 >                       "\"%s\", line %u: %s: %s",
1692                         conffilebuf, lineno + 1, msg, newlinebuf);
1693 <  ilog(L_WARN, "\"%s\", line %u: %s: %s",
1693 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1694         conffilebuf, lineno + 1, msg, newlinebuf);
1695   }
1696  
1697 < int
1698 < conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
1697 > void
1698 > conf_error_report(const char *msg)
1699   {
1700 <  if (fbgets(lbuf, max_size, fb) == NULL)
3137 <    return 0;
3138 <
3139 <  return strlen(lbuf);
3140 < }
1700 >  char newlinebuf[IRCD_BUFSIZE];
1701  
1702 < int
1703 < conf_yy_fatal_error(const char *msg)
1704 < {
1705 <  return 0;
1702 >  strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1703 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1704 >                       "\"%s\", line %u: %s: %s",
1705 >                       conffilebuf, lineno + 1, msg, newlinebuf);
1706 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1707 >       conffilebuf, lineno + 1, msg, newlinebuf);
1708   }
1709  
1710   /*
# Line 3344 | Line 1906 | parse_aline(const char *cmd, struct Clie
1906          return -1;
1907        }
1908  
1909 <      if (!IsOperRemoteBan(source_p))
1909 >      if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
1910        {
1911          sendto_one(source_p, form_str(ERR_NOPRIVS),
1912                     me.name, source_p->name, "remoteban");
# Line 3381 | Line 1943 | parse_aline(const char *cmd, struct Clie
1943        return -1;
1944      }
1945  
1946 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
1946 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
1947        return -1;
1948    }
1949    else
1950 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
1950 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
1951        return -1;
1952  
1953    if (reason != NULL)
# Line 3393 | Line 1955 | parse_aline(const char *cmd, struct Clie
1955      if (parc != 0 && !EmptyString(*parv))
1956      {
1957        *reason = *parv;
1958 <      if (!valid_comment(source_p, *reason, YES))
1958 >      if (!valid_comment(source_p, *reason, 1))
1959          return -1;
1960      }
1961      else
# Line 3450 | Line 2012 | find_user_host(struct Client *source_p,
2012      
2013      return 1;
2014    }
2015 <  else if (!(flags & NOUSERLOOKUP))
2015 >  else
2016    {
2017      /* Try to find user@host mask from nick */
2018      /* Okay to use source_p as the first param, because source_p == client_p */
# Line 3498 | Line 2060 | find_user_host(struct Client *source_p,
2060   int
2061   valid_comment(struct Client *source_p, char *comment, int warn)
2062   {
3501  if (strchr(comment, '"'))
3502  {
3503    if (warn)
3504      sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
3505                 me.name, source_p->name);
3506    return 0;
3507  }
3508
2063    if (strlen(comment) > REASONLEN)
2064      comment[REASONLEN-1] = '\0';
2065  
# Line 3520 | Line 2074 | valid_comment(struct Client *source_p, c
2074   * side effects - none
2075   */
2076   int
2077 < match_conf_password(const char *password, const struct AccessItem *aconf)
2077 > match_conf_password(const char *password, const struct MaskItem *conf)
2078   {
2079    const char *encr = NULL;
2080  
2081 <  if (password == NULL || aconf->passwd == NULL)
2081 >  if (EmptyString(password) || EmptyString(conf->passwd))
2082      return 0;
2083  
2084 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2085 <  {
3532 <    /* use first two chars of the password they send in as salt */
3533 <    /* If the password in the conf is MD5, and ircd is linked
3534 <     * to scrypt on FreeBSD, or the standard crypt library on
3535 <     * glibc Linux, then this code will work fine on generating
3536 <     * the proper encrypted hash for comparison.
3537 <     */
3538 <    if (*aconf->passwd)
3539 <      encr = crypt(password, aconf->passwd);
3540 <    else
3541 <      encr = "";
3542 <  }
2084 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2085 >    encr = crypt(password, conf->passwd);
2086    else
2087      encr = password;
2088  
2089 <  return !strcmp(encr, aconf->passwd);
2089 >  return !strcmp(encr, conf->passwd);
2090   }
2091  
2092   /*
# Line 3552 | Line 2095 | match_conf_password(const char *password
2095   * inputs       - client sending the cluster
2096   *              - command name "KLINE" "XLINE" etc.
2097   *              - capab -- CAP_KLN etc. from s_serv.h
2098 < *              - cluster type -- CLUSTER_KLINE etc. from s_conf.h
2098 > *              - cluster type -- CLUSTER_KLINE etc. from conf.h
2099   *              - pattern and args to send along
2100   * output       - none
2101   * side effects - Take source_p send the pattern with args given
# Line 3572 | Line 2115 | cluster_a_line(struct Client *source_p,
2115  
2116    DLINK_FOREACH(ptr, cluster_items.head)
2117    {
2118 <    const struct ConfItem *conf = ptr->data;
2118 >    const struct MaskItem *conf = ptr->data;
2119  
2120      if (conf->flags & cluster_type)
2121        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
# Line 3666 | Line 2209 | split_nuh(struct split_nuh_item *const i
2209      }
2210    }
2211   }
3669
3670 /*
3671 * flags_to_ascii
3672 *
3673 * inputs       - flags is a bitmask
3674 *              - pointer to table of ascii letters corresponding
3675 *                to each bit
3676 *              - flag 1 for convert ToLower if bit missing
3677 *                0 if ignore.
3678 * output       - none
3679 * side effects - string pointed to by p has bitmap chars written to it
3680 */
3681 static void
3682 flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
3683               int lowerit)
3684 {
3685  unsigned int mask = 1;
3686  int i = 0;
3687
3688  for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
3689  {
3690    if (flags & mask)
3691      *p++ = bit_table[i];
3692    else if (lowerit)
3693      *p++ = ToLower(bit_table[i]);
3694  }
3695  *p = '\0';
3696 }
3697
3698 /*
3699 * cidr_limit_reached
3700 *
3701 * inputs       - int flag allowing over_rule of limits
3702 *              - pointer to the ip to be added
3703 *              - pointer to the class
3704 * output       - non zero if limit reached
3705 *                0 if limit not reached
3706 * side effects -
3707 */
3708 static int
3709 cidr_limit_reached(int over_rule,
3710                   struct irc_ssaddr *ip, struct ClassItem *aclass)
3711 {
3712  dlink_node *ptr = NULL;
3713  struct CidrItem *cidr;
3714
3715  if (NumberPerCidr(aclass) <= 0)
3716    return 0;
3717
3718  if (ip->ss.ss_family == AF_INET)
3719  {
3720    if (CidrBitlenIPV4(aclass) <= 0)
3721      return 0;
3722
3723    DLINK_FOREACH(ptr, aclass->list_ipv4.head)
3724    {
3725      cidr = ptr->data;
3726      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3727      {
3728        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3729          return -1;
3730        cidr->number_on_this_cidr++;
3731        return 0;
3732      }
3733    }
3734    cidr = MyMalloc(sizeof(struct CidrItem));
3735    cidr->number_on_this_cidr = 1;
3736    cidr->mask = *ip;
3737    mask_addr(&cidr->mask, CidrBitlenIPV4(aclass));
3738    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
3739  }
3740 #ifdef IPV6
3741  else if (CidrBitlenIPV6(aclass) > 0)
3742  {
3743    DLINK_FOREACH(ptr, aclass->list_ipv6.head)
3744    {
3745      cidr = ptr->data;
3746      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3747      {
3748        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3749          return -1;
3750        cidr->number_on_this_cidr++;
3751        return 0;
3752      }
3753    }
3754    cidr = MyMalloc(sizeof(struct CidrItem));
3755    cidr->number_on_this_cidr = 1;
3756    cidr->mask = *ip;
3757    mask_addr(&cidr->mask, CidrBitlenIPV6(aclass));
3758    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
3759  }
3760 #endif
3761  return 0;
3762 }
3763
3764 /*
3765 * remove_from_cidr_check
3766 *
3767 * inputs       - pointer to the ip to be removed
3768 *              - pointer to the class
3769 * output       - NONE
3770 * side effects -
3771 */
3772 static void
3773 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
3774 {
3775  dlink_node *ptr = NULL;
3776  dlink_node *next_ptr = NULL;
3777  struct CidrItem *cidr;
3778
3779  if (NumberPerCidr(aclass) == 0)
3780    return;
3781
3782  if (ip->ss.ss_family == AF_INET)
3783  {
3784    if (CidrBitlenIPV4(aclass) <= 0)
3785      return;
3786
3787    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
3788    {
3789      cidr = ptr->data;
3790      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3791      {
3792        cidr->number_on_this_cidr--;
3793        if (cidr->number_on_this_cidr == 0)
3794        {
3795          dlinkDelete(ptr, &aclass->list_ipv4);
3796          MyFree(cidr);
3797          return;
3798        }
3799      }
3800    }
3801  }
3802 #ifdef IPV6
3803  else if (CidrBitlenIPV6(aclass) > 0)
3804  {
3805    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
3806    {
3807      cidr = ptr->data;
3808      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3809      {
3810        cidr->number_on_this_cidr--;
3811        if (cidr->number_on_this_cidr == 0)
3812        {
3813          dlinkDelete(ptr, &aclass->list_ipv6);
3814          MyFree(cidr);
3815          return;
3816        }
3817      }
3818    }
3819  }
3820 #endif
3821 }
3822
3823 static void
3824 rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
3825                  dlink_list *old_list, dlink_list *new_list, int changed)
3826 {
3827  dlink_node *ptr;
3828  struct Client *client_p;
3829  struct ConfItem *conf;
3830  struct AccessItem *aconf;
3831
3832  if (!changed)
3833  {
3834    *new_list = *old_list;
3835    old_list->head = old_list->tail = NULL;
3836    old_list->length = 0;
3837    return;
3838  }
3839
3840  DLINK_FOREACH(ptr, local_client_list.head)
3841  {
3842    client_p = ptr->data;
3843    if (client_p->localClient->aftype != aftype)
3844      continue;
3845    if (dlink_list_length(&client_p->localClient->confs) == 0)
3846      continue;
3847
3848    conf = client_p->localClient->confs.tail->data;
3849    if (conf->type == CLIENT_TYPE)
3850    {
3851      aconf = map_to_conf(conf);
3852      if (aconf->class_ptr == oldcl)
3853        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
3854    }
3855  }
3856 }
3857
3858 /*
3859 * rebuild_cidr_class
3860 *
3861 * inputs       - pointer to old conf
3862 *              - pointer to new_class
3863 * output       - none
3864 * side effects - rebuilds the class link list of cidr blocks
3865 */
3866 void
3867 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
3868 {
3869  struct ClassItem *old_class = map_to_conf(conf);
3870
3871  if (NumberPerCidr(old_class) > 0 && NumberPerCidr(new_class) > 0)
3872  {
3873    if (CidrBitlenIPV4(old_class) > 0 && CidrBitlenIPV4(new_class) > 0)
3874      rebuild_cidr_list(AF_INET, conf, new_class,
3875                        &old_class->list_ipv4, &new_class->list_ipv4,
3876                        CidrBitlenIPV4(old_class) != CidrBitlenIPV4(new_class));
3877
3878 #ifdef IPV6
3879    if (CidrBitlenIPV6(old_class) > 0 && CidrBitlenIPV6(new_class) > 0)
3880      rebuild_cidr_list(AF_INET6, conf, new_class,
3881                        &old_class->list_ipv6, &new_class->list_ipv6,
3882                        CidrBitlenIPV6(old_class) != CidrBitlenIPV6(new_class));
3883 #endif
3884  }
3885
3886  destroy_cidr_class(old_class);
3887 }
3888
3889 /*
3890 * destroy_cidr_list
3891 *
3892 * inputs       - pointer to class dlink list of cidr blocks
3893 * output       - none
3894 * side effects - completely destroys the class link list of cidr blocks
3895 */
3896 static void
3897 destroy_cidr_list(dlink_list *list)
3898 {
3899  dlink_node *ptr = NULL, *next_ptr = NULL;
3900
3901  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3902  {
3903    dlinkDelete(ptr, list);
3904    MyFree(ptr->data);
3905  }
3906 }
3907
3908 /*
3909 * destroy_cidr_class
3910 *
3911 * inputs       - pointer to class
3912 * output       - none
3913 * side effects - completely destroys the class link list of cidr blocks
3914 */
3915 static void
3916 destroy_cidr_class(struct ClassItem *aclass)
3917 {
3918  destroy_cidr_list(&aclass->list_ipv4);
3919  destroy_cidr_list(&aclass->list_ipv6);
3920 }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)