ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf.c
Revision: 1858
Committed: Thu Apr 25 15:00:52 2013 UTC (12 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 64863 byte(s)
Log Message:
- Added basic support for libGeoIP
- Added exempt configuration option to resv{} blocks

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 michael 1309 * conf.c: Configuration file functions.
4 adx 30 *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26 michael 1011 #include "list.h"
27 adx 30 #include "ircd_defs.h"
28 michael 1309 #include "conf.h"
29 adx 30 #include "s_serv.h"
30     #include "resv.h"
31     #include "channel.h"
32     #include "client.h"
33     #include "event.h"
34     #include "hook.h"
35     #include "irc_string.h"
36     #include "s_bsd.h"
37     #include "ircd.h"
38     #include "listener.h"
39     #include "hostmask.h"
40     #include "modules.h"
41     #include "numeric.h"
42     #include "fdlist.h"
43 michael 1309 #include "log.h"
44 adx 30 #include "send.h"
45     #include "s_gline.h"
46     #include "memory.h"
47 michael 1654 #include "mempool.h"
48 adx 30 #include "irc_res.h"
49     #include "userhost.h"
50     #include "s_user.h"
51     #include "channel_mode.h"
52 michael 1243 #include "parse.h"
53     #include "s_misc.h"
54 michael 1622 #include "conf_db.h"
55 michael 1632 #include "conf_class.h"
56 adx 30
57     struct config_server_hide ConfigServerHide;
58    
59     /* general conf items link list root, other than k lines etc. */
60 michael 1157 dlink_list service_items = { NULL, NULL, 0 };
61 adx 30 dlink_list server_items = { NULL, NULL, 0 };
62     dlink_list cluster_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 };
66     dlink_list rxconf_items = { NULL, NULL, 0 };
67     dlink_list rkconf_items = { NULL, NULL, 0 };
68     dlink_list nresv_items = { NULL, NULL, 0 };
69     dlink_list temporary_resv = { NULL, NULL, 0 };
70    
71     extern unsigned int lineno;
72     extern char linebuf[];
73     extern char conffilebuf[IRCD_BUFSIZE];
74     extern int yyparse(); /* defined in y.tab.c */
75    
76 michael 967 struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };
77    
78 adx 30 /* internally defined functions */
79 michael 1325 static void read_conf(FILE *);
80 adx 30 static void clear_out_old_conf(void);
81     static void expire_tklines(dlink_list *);
82     static void garbage_collect_ip_entries(void);
83     static int hash_ip(struct irc_ssaddr *);
84 michael 1644 static int verify_access(struct Client *);
85 michael 1632 static int attach_iline(struct Client *, struct MaskItem *);
86 adx 30 static struct ip_entry *find_or_add_ip(struct irc_ssaddr *);
87 michael 1632 static dlink_list *map_to_list(enum maskitem_type);
88     static struct MaskItem *find_regexp_kline(const char *[]);
89 adx 30 static int find_user_host(struct Client *, char *, char *, char *, unsigned int);
90    
91    
92     /* usually, with hash tables, you use a prime number...
93     * but in this case I am dealing with ip addresses,
94     * not ascii strings.
95     */
96     #define IP_HASH_SIZE 0x1000
97    
98     struct ip_entry
99     {
100     struct irc_ssaddr ip;
101 michael 1644 unsigned int count;
102 adx 30 time_t last_attempt;
103     struct ip_entry *next;
104     };
105    
106     static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
107 michael 1654 static mp_pool_t *ip_entry_pool = NULL;
108 adx 30 static int ip_entries_count = 0;
109    
110    
111     /* conf_dns_callback()
112     *
113 michael 1632 * inputs - pointer to struct MaskItem
114 adx 30 * - pointer to DNSReply reply
115     * output - none
116     * side effects - called when resolver query finishes
117     * if the query resulted in a successful search, hp will contain
118     * a non-null pointer, otherwise hp will be null.
119     * if successful save hp in the conf item it was called with
120     */
121     static void
122 michael 992 conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
123 adx 30 {
124 michael 1632 struct MaskItem *conf = vptr;
125 adx 30
126 michael 1632 conf->dns_pending = 0;
127 adx 30
128 michael 992 if (addr != NULL)
129 michael 1632 memcpy(&conf->addr, addr, sizeof(conf->addr));
130 michael 992 else
131 michael 1632 conf->dns_failed = 1;
132 adx 30 }
133    
134     /* conf_dns_lookup()
135     *
136     * do a nameserver lookup of the conf host
137     * if the conf entry is currently doing a ns lookup do nothing, otherwise
138     * allocate a dns_query and start ns lookup.
139     */
140     static void
141 michael 1632 conf_dns_lookup(struct MaskItem *conf)
142 adx 30 {
143 michael 1632 if (!conf->dns_pending)
144 adx 30 {
145 michael 1632 conf->dns_pending = 1;
146     gethost_byname(conf_dns_callback, conf, conf->host);
147 adx 30 }
148     }
149    
150 michael 1632 struct MaskItem *
151     conf_make(enum maskitem_type type)
152     {
153     struct MaskItem *conf = MyMalloc(sizeof(*conf));
154     dlink_list *list = NULL;
155    
156     conf->type = type;
157     conf->active = 1;
158     conf->aftype = AF_INET;
159    
160     if ((list = map_to_list(type)))
161     dlinkAdd(conf, &conf->node, list);
162     return conf;
163     }
164    
165     void
166     conf_free(struct MaskItem *conf)
167     {
168     dlink_node *ptr = NULL, *ptr_next = NULL;
169 michael 1636 dlink_list *list = NULL;
170    
171     if (conf->node.next)
172     if ((list = map_to_list(conf->type)))
173     dlinkDelete(&conf->node, list);
174    
175 michael 1632 MyFree(conf->name);
176    
177     if (conf->dns_pending)
178     delete_resolver_queries(conf);
179     if (conf->passwd != NULL)
180     memset(conf->passwd, 0, strlen(conf->passwd));
181     if (conf->spasswd != NULL)
182     memset(conf->spasswd, 0, strlen(conf->spasswd));
183    
184     conf->class = NULL;
185    
186     MyFree(conf->passwd);
187     MyFree(conf->spasswd);
188     MyFree(conf->reason);
189     MyFree(conf->user);
190     MyFree(conf->host);
191 michael 1636 MyFree(conf->regexuser);
192     MyFree(conf->regexhost);
193 michael 1632 #ifdef HAVE_LIBCRYPTO
194     MyFree(conf->cipher_list);
195    
196     if (conf->rsa_public_key)
197     RSA_free(conf->rsa_public_key);
198     #endif
199     DLINK_FOREACH_SAFE(ptr, ptr_next, conf->hub_list.head)
200     {
201     MyFree(ptr->data);
202     free_dlink_node(ptr);
203     }
204    
205     DLINK_FOREACH_SAFE(ptr, ptr_next, conf->leaf_list.head)
206     {
207     MyFree(ptr->data);
208     free_dlink_node(ptr);
209     }
210 adx 30
211 michael 1858 DLINK_FOREACH_SAFE(ptr, ptr_next, conf->exempt_list.head)
212     {
213     struct exempt *exptr = ptr->data;
214    
215     MyFree(exptr->name);
216     MyFree(exptr->user);
217     MyFree(exptr->host);
218     MyFree(exptr);
219     free_dlink_node(ptr);
220     }
221    
222 michael 1636 MyFree(conf);
223 adx 30 }
224    
225 michael 1644 static const struct shared_flags
226     {
227     const unsigned int type;
228     const unsigned char letter;
229     } flag_table[] = {
230     { SHARED_KLINE, 'K' },
231     { SHARED_UNKLINE, 'U' },
232     { SHARED_XLINE, 'X' },
233     { SHARED_UNXLINE, 'Y' },
234     { SHARED_RESV, 'Q' },
235     { SHARED_UNRESV, 'R' },
236     { SHARED_LOCOPS, 'L' },
237     { SHARED_DLINE, 'D' },
238     { SHARED_UNDLINE, 'E' },
239     { 0, '\0' }
240     };
241 adx 30
242 michael 1644 /*
243 adx 30 * inputs - pointer to client requesting confitem report
244     * - ConfType to report
245     * output - none
246     * side effects -
247     */
248     void
249 michael 1632 report_confitem_types(struct Client *source_p, enum maskitem_type type)
250 adx 30 {
251 michael 1383 dlink_node *ptr = NULL, *dptr = NULL;
252 michael 1632 struct MaskItem *conf = NULL;
253     const struct ClassItem *class = NULL;
254 michael 1644 const struct shared_flags *shared = NULL;
255 adx 30 char buf[12];
256     char *p = NULL;
257    
258     switch (type)
259     {
260 michael 1632 case CONF_XLINE:
261 adx 30 DLINK_FOREACH(ptr, xconf_items.head)
262     {
263     conf = ptr->data;
264    
265 michael 1834 sendto_one(source_p, form_str(RPL_STATSXLINE),
266 adx 30 me.name, source_p->name,
267 michael 1649 conf->until ? "x": "X", conf->count,
268 michael 1632 conf->name, conf->reason);
269 adx 30 }
270     break;
271    
272 michael 1009 #ifdef HAVE_LIBPCRE
273 michael 1632 case CONF_RXLINE:
274 adx 30 DLINK_FOREACH(ptr, rxconf_items.head)
275     {
276     conf = ptr->data;
277    
278 michael 1834 sendto_one(source_p, form_str(RPL_STATSXLINE),
279 adx 30 me.name, source_p->name,
280 michael 1632 "XR", conf->count,
281     conf->name, conf->reason);
282 adx 30 }
283     break;
284    
285 michael 1632 case CONF_RKLINE:
286 adx 30 DLINK_FOREACH(ptr, rkconf_items.head)
287     {
288 michael 1632 conf = ptr->data;
289 adx 30
290 michael 1834 sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
291 michael 1632 source_p->name, "KR", conf->host, conf->user,
292     conf->reason);
293 adx 30 }
294     break;
295 michael 1009 #endif
296 adx 30
297 michael 1632 case CONF_ULINE:
298 michael 1644 shared = flag_table;
299 adx 30 DLINK_FOREACH(ptr, uconf_items.head)
300     {
301     conf = ptr->data;
302    
303     p = buf;
304    
305     *p++ = 'c';
306 michael 1644 for (; shared->type; ++shared)
307     if (shared->type & conf->flags)
308     *p++ = shared->letter;
309     else
310     *p++ = ToLower(shared->letter);
311 adx 30
312 michael 1834 sendto_one(source_p, form_str(RPL_STATSULINE),
313 adx 30 me.name, source_p->name, conf->name,
314 michael 1632 conf->user?conf->user: "*",
315     conf->host?conf->host: "*", buf);
316 adx 30 }
317    
318 michael 1644 shared = flag_table;
319 adx 30 DLINK_FOREACH(ptr, cluster_items.head)
320     {
321     conf = ptr->data;
322    
323     p = buf;
324    
325     *p++ = 'C';
326 michael 1644 for (; shared->type; ++shared)
327     if (shared->type & conf->flags)
328     *p++ = shared->letter;
329     else
330     *p++ = ToLower(shared->letter);
331 adx 30
332 michael 1834 sendto_one(source_p, form_str(RPL_STATSULINE),
333 adx 30 me.name, source_p->name, conf->name,
334     "*", "*", buf);
335     }
336    
337     break;
338    
339 michael 1632 case CONF_OPER:
340 adx 30 DLINK_FOREACH(ptr, oconf_items.head)
341     {
342     conf = ptr->data;
343    
344     /* Don't allow non opers to see oper privs */
345 michael 1219 if (HasUMode(source_p, UMODE_OPER))
346 michael 1834 sendto_one(source_p, form_str(RPL_STATSOLINE),
347 michael 1632 me.name, source_p->name, 'O', conf->user, conf->host,
348     conf->name, oper_privs_as_string(conf->port),
349     conf->class ? conf->class->name : "<default>");
350 adx 30 else
351 michael 1834 sendto_one(source_p, form_str(RPL_STATSOLINE),
352 michael 1632 me.name, source_p->name, 'O', conf->user, conf->host,
353 adx 30 conf->name, "0",
354 michael 1632 conf->class ? conf->class->name : "<default>");
355 adx 30 }
356     break;
357    
358 michael 1632 case CONF_CLASS:
359     DLINK_FOREACH(ptr, class_get_list()->head)
360 adx 30 {
361 michael 1632 class = ptr->data;
362 michael 1834 sendto_one(source_p, form_str(RPL_STATSYLINE),
363 adx 30 me.name, source_p->name, 'Y',
364 michael 1632 class->name, class->ping_freq,
365     class->con_freq,
366     class->max_total, class->max_sendq,
367     class->max_recvq,
368     class->ref_count,
369     class->number_per_cidr, class->cidr_bitlen_ipv4,
370     class->number_per_cidr, class->cidr_bitlen_ipv6,
371     class->active ? "active" : "disabled");
372 adx 30 }
373     break;
374    
375 michael 1632 case CONF_SERVICE:
376 michael 1157 DLINK_FOREACH(ptr, service_items.head)
377     {
378     conf = ptr->data;
379 michael 1834 sendto_one(source_p, form_str(RPL_STATSSERVICE),
380 michael 1175 me.name, source_p->name, 'S', "*", conf->name, 0, 0);
381 michael 1157 }
382     break;
383    
384 michael 1632 case CONF_SERVER:
385 adx 30 DLINK_FOREACH(ptr, server_items.head)
386     {
387     p = buf;
388     conf = ptr->data;
389    
390     buf[0] = '\0';
391    
392 michael 1632 if (IsConfAllowAutoConn(conf))
393 adx 30 *p++ = 'A';
394 michael 1632 if (IsConfSSL(conf))
395 michael 1303 *p++ = 'S';
396 adx 30 if (buf[0] == '\0')
397     *p++ = '*';
398    
399     *p = '\0';
400    
401 michael 671 /*
402     * Allow admins to see actual ips unless hide_server_ips is enabled
403 adx 30 */
404 michael 1219 if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
405 michael 1834 sendto_one(source_p, form_str(RPL_STATSCLINE),
406 michael 1632 me.name, source_p->name, 'C', conf->host,
407     buf, conf->name, conf->port,
408     conf->class ? conf->class->name : "<default>");
409 adx 30 else
410 michael 1834 sendto_one(source_p, form_str(RPL_STATSCLINE),
411 adx 30 me.name, source_p->name, 'C',
412 michael 1632 "*@127.0.0.1", buf, conf->name, conf->port,
413     conf->class ? conf->class->name : "<default>");
414 adx 30 }
415     break;
416    
417 michael 1632 case CONF_HUB:
418 michael 1383 DLINK_FOREACH(ptr, server_items.head)
419 adx 30 {
420     conf = ptr->data;
421 michael 1383
422 michael 1632 DLINK_FOREACH(dptr, conf->hub_list.head)
423 michael 1834 sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
424 michael 1383 source_p->name, 'H', dptr->data, conf->name, 0, "*");
425 adx 30 }
426    
427 michael 1383 DLINK_FOREACH(ptr, server_items.head)
428 adx 30 {
429     conf = ptr->data;
430 michael 1383
431 michael 1632 DLINK_FOREACH(dptr, conf->leaf_list.head)
432 michael 1834 sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
433 michael 1383 source_p->name, 'L', dptr->data, conf->name, 0, "*");
434 adx 30 }
435 michael 1632
436 adx 30 break;
437    
438 michael 1009 default:
439 adx 30 break;
440     }
441     }
442    
443     /* check_client()
444     *
445     * inputs - pointer to client
446     * output - 0 = Success
447     * NOT_AUTHORIZED (-1) = Access denied (no I line match)
448     * IRCD_SOCKET_ERROR (-2) = Bad socket.
449     * I_LINE_FULL (-3) = I-line is full
450     * TOO_MANY (-4) = Too many connections from hostname
451     * BANNED_CLIENT (-5) = K-lined
452     * side effects - Ordinary client access check.
453     * Look for conf lines which have the same
454     * status as the flags passed.
455     */
456 michael 1644 int
457     check_client(struct Client *source_p)
458 adx 30 {
459     int i;
460    
461 michael 1644 if ((i = verify_access(source_p)))
462 michael 1247 ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
463 adx 30 source_p->name, source_p->sockhost);
464    
465     switch (i)
466     {
467     case TOO_MANY:
468 michael 1618 sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
469 adx 30 "Too many on IP for %s (%s).",
470     get_client_name(source_p, SHOW_IP),
471     source_p->sockhost);
472 michael 1247 ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
473 adx 30 get_client_name(source_p, SHOW_IP));
474 michael 896 ++ServerStats.is_ref;
475 adx 30 exit_client(source_p, &me, "No more connections allowed on that IP");
476     break;
477    
478     case I_LINE_FULL:
479 michael 1618 sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
480     "auth{} block is full for %s (%s).",
481 adx 30 get_client_name(source_p, SHOW_IP),
482     source_p->sockhost);
483 michael 1247 ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
484 adx 30 get_client_name(source_p, SHOW_IP));
485 michael 896 ++ServerStats.is_ref;
486 adx 30 exit_client(source_p, &me,
487     "No more connections allowed in your connection class");
488     break;
489    
490     case NOT_AUTHORIZED:
491 michael 896 ++ServerStats.is_ref;
492 adx 30 /* jdc - lists server name & port connections are on */
493     /* a purely cosmetical change */
494 michael 1618 sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
495 adx 30 "Unauthorized client connection from %s [%s] on [%s/%u].",
496     get_client_name(source_p, SHOW_IP),
497 michael 891 source_p->sockhost,
498 adx 30 source_p->localClient->listener->name,
499     source_p->localClient->listener->port);
500 michael 1247 ilog(LOG_TYPE_IRCD,
501 adx 30 "Unauthorized client connection from %s on [%s/%u].",
502     get_client_name(source_p, SHOW_IP),
503     source_p->localClient->listener->name,
504     source_p->localClient->listener->port);
505    
506 michael 1549 exit_client(source_p, &me, "You are not authorized to use this server");
507 adx 30 break;
508 michael 891
509 adx 30 case BANNED_CLIENT:
510 michael 1549 exit_client(source_p, &me, "Banned");
511 michael 896 ++ServerStats.is_ref;
512 adx 30 break;
513    
514     case 0:
515     default:
516     break;
517     }
518    
519 michael 1644 return (i < 0 ? 0 : 1);
520 adx 30 }
521    
522     /* verify_access()
523     *
524     * inputs - pointer to client to verify
525     * output - 0 if success -'ve if not
526     * side effect - find the first (best) I line to attach.
527     */
528     static int
529 michael 1644 verify_access(struct Client *client_p)
530 adx 30 {
531 michael 1632 struct MaskItem *conf = NULL, *rkconf = NULL;
532 adx 30 char non_ident[USERLEN + 1] = { '~', '\0' };
533     const char *uhi[3];
534    
535     if (IsGotId(client_p))
536     {
537 michael 1632 conf = find_address_conf(client_p->host, client_p->username,
538 adx 30 &client_p->localClient->ip,
539     client_p->localClient->aftype,
540     client_p->localClient->passwd);
541     }
542     else
543     {
544 michael 1644 strlcpy(non_ident+1, client_p->username, sizeof(non_ident)-1);
545 michael 1632 conf = find_address_conf(client_p->host,non_ident,
546 adx 30 &client_p->localClient->ip,
547     client_p->localClient->aftype,
548     client_p->localClient->passwd);
549     }
550    
551     uhi[0] = IsGotId(client_p) ? client_p->username : non_ident;
552     uhi[1] = client_p->host;
553     uhi[2] = client_p->sockhost;
554    
555     rkconf = find_regexp_kline(uhi);
556    
557 michael 1632 if (conf != NULL)
558 adx 30 {
559 michael 1632 if (IsConfClient(conf) && !rkconf)
560 adx 30 {
561 michael 1632 if (IsConfRedir(conf))
562 adx 30 {
563 michael 1834 sendto_one(client_p, form_str(RPL_REDIR),
564 adx 30 me.name, client_p->name,
565     conf->name ? conf->name : "",
566 michael 1632 conf->port);
567 adx 30 return(NOT_AUTHORIZED);
568     }
569    
570 michael 1632 if (IsConfDoIdentd(conf))
571 adx 30 SetNeedId(client_p);
572    
573     /* Thanks for spoof idea amm */
574 michael 1632 if (IsConfDoSpoofIp(conf))
575 adx 30 {
576 michael 1632 if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(conf))
577 michael 1618 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
578     "%s spoofing: %s as %s",
579 adx 30 client_p->name, client_p->host, conf->name);
580     strlcpy(client_p->host, conf->name, sizeof(client_p->host));
581     SetIPSpoof(client_p);
582     }
583    
584     return(attach_iline(client_p, conf));
585     }
586 michael 1632 else if (rkconf || IsConfKill(conf) || (ConfigFileEntry.glines && IsConfGline(conf)))
587 adx 30 {
588     /* XXX */
589 michael 1632 conf = rkconf ? rkconf : conf;
590     if (IsConfGline(conf))
591 adx 30 sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
592     client_p->name);
593 michael 1549 sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s",
594 michael 1632 me.name, client_p->name, conf->reason);
595 adx 30 return(BANNED_CLIENT);
596     }
597     }
598    
599     return(NOT_AUTHORIZED);
600     }
601    
602     /* attach_iline()
603     *
604     * inputs - client pointer
605     * - conf pointer
606     * output -
607     * side effects - do actual attach
608     */
609     static int
610 michael 1632 attach_iline(struct Client *client_p, struct MaskItem *conf)
611 adx 30 {
612 michael 1632 struct ClassItem *class = NULL;
613 adx 30 struct ip_entry *ip_found;
614     int a_limit_reached = 0;
615 michael 1644 unsigned int local = 0, global = 0, ident = 0;
616 adx 30
617     ip_found = find_or_add_ip(&client_p->localClient->ip);
618     ip_found->count++;
619     SetIpHash(client_p);
620    
621 michael 1632 if (conf->class == NULL)
622 adx 30 return NOT_AUTHORIZED; /* If class is missing, this is best */
623    
624 michael 1632 class = conf->class;
625 adx 30
626     count_user_host(client_p->username, client_p->host,
627     &global, &local, &ident);
628    
629     /* XXX blah. go down checking the various silly limits
630     * setting a_limit_reached if any limit is reached.
631     * - Dianora
632     */
633 michael 1632 if (class->max_total != 0 && class->ref_count >= class->max_total)
634 adx 30 a_limit_reached = 1;
635 michael 1632 else if (class->max_perip != 0 && ip_found->count > class->max_perip)
636 adx 30 a_limit_reached = 1;
637 michael 1632 else if (class->max_local != 0 && local >= class->max_local)
638 adx 30 a_limit_reached = 1;
639 michael 1632 else if (class->max_global != 0 && global >= class->max_global)
640 adx 30 a_limit_reached = 1;
641 michael 1632 else if (class->max_ident != 0 && ident >= class->max_ident &&
642 adx 30 client_p->username[0] != '~')
643     a_limit_reached = 1;
644    
645     if (a_limit_reached)
646     {
647 michael 1632 if (!IsConfExemptLimits(conf))
648 michael 624 return TOO_MANY; /* Already at maximum allowed */
649 adx 30
650     sendto_one(client_p,
651     ":%s NOTICE %s :*** Your connection class is full, "
652     "but you have exceed_limit = yes;", me.name, client_p->name);
653     }
654    
655     return attach_conf(client_p, conf);
656     }
657    
658     /* init_ip_hash_table()
659     *
660     * inputs - NONE
661     * output - NONE
662     * side effects - allocate memory for ip_entry(s)
663     * - clear the ip hash table
664     */
665     void
666     init_ip_hash_table(void)
667     {
668 michael 1654 ip_entry_pool = mp_pool_new(sizeof(struct ip_entry),
669 adx 30 2 * hard_fdlimit);
670     memset(ip_hash_table, 0, sizeof(ip_hash_table));
671     }
672    
673     /* find_or_add_ip()
674     *
675     * inputs - pointer to struct irc_ssaddr
676     * output - pointer to a struct ip_entry
677     * side effects -
678     *
679     * If the ip # was not found, a new struct ip_entry is created, and the ip
680     * count set to 0.
681     */
682     static struct ip_entry *
683     find_or_add_ip(struct irc_ssaddr *ip_in)
684     {
685     struct ip_entry *ptr, *newptr;
686     int hash_index = hash_ip(ip_in), res;
687     struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
688     #ifdef IPV6
689     struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
690     #endif
691    
692     for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
693     {
694     #ifdef IPV6
695     if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
696     continue;
697     if (ip_in->ss.ss_family == AF_INET6)
698     {
699     ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
700     res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
701     }
702     else
703     #endif
704     {
705     ptr_v4 = (struct sockaddr_in *)&ptr->ip;
706     res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
707     }
708     if (res == 0)
709     {
710     /* Found entry already in hash, return it. */
711     return ptr;
712     }
713     }
714    
715     if (ip_entries_count >= 2 * hard_fdlimit)
716     garbage_collect_ip_entries();
717    
718 michael 1654 newptr = mp_pool_get(ip_entry_pool);
719     memset(newptr, 0, sizeof(*newptr));
720 adx 30 ip_entries_count++;
721     memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
722    
723     newptr->next = ip_hash_table[hash_index];
724     ip_hash_table[hash_index] = newptr;
725    
726     return newptr;
727     }
728    
729     /* remove_one_ip()
730     *
731     * inputs - unsigned long IP address value
732     * output - NONE
733     * side effects - The ip address given, is looked up in ip hash table
734     * and number of ip#'s for that ip decremented.
735     * If ip # count reaches 0 and has expired,
736     * the struct ip_entry is returned to the ip_entry_heap
737     */
738     void
739     remove_one_ip(struct irc_ssaddr *ip_in)
740     {
741     struct ip_entry *ptr;
742     struct ip_entry *last_ptr = NULL;
743     int hash_index = hash_ip(ip_in), res;
744     struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
745     #ifdef IPV6
746     struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
747     #endif
748    
749     for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
750     {
751     #ifdef IPV6
752     if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
753     continue;
754     if (ip_in->ss.ss_family == AF_INET6)
755     {
756     ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
757     res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
758     }
759     else
760     #endif
761     {
762     ptr_v4 = (struct sockaddr_in *)&ptr->ip;
763     res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
764     }
765     if (res)
766     continue;
767     if (ptr->count > 0)
768     ptr->count--;
769     if (ptr->count == 0 &&
770     (CurrentTime-ptr->last_attempt) >= ConfigFileEntry.throttle_time)
771     {
772     if (last_ptr != NULL)
773     last_ptr->next = ptr->next;
774     else
775     ip_hash_table[hash_index] = ptr->next;
776    
777 michael 1654 mp_pool_release(ptr);
778 adx 30 ip_entries_count--;
779     return;
780     }
781     last_ptr = ptr;
782     }
783     }
784    
785     /* hash_ip()
786     *
787     * input - pointer to an irc_inaddr
788     * output - integer value used as index into hash table
789     * side effects - hopefully, none
790     */
791     static int
792     hash_ip(struct irc_ssaddr *addr)
793     {
794     if (addr->ss.ss_family == AF_INET)
795     {
796     struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
797     int hash;
798 michael 1032 uint32_t ip;
799 adx 30
800     ip = ntohl(v4->sin_addr.s_addr);
801     hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
802     return hash;
803     }
804     #ifdef IPV6
805     else
806     {
807     int hash;
808     struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
809 michael 1032 uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
810 adx 30
811     hash = ip[0] ^ ip[3];
812     hash ^= hash >> 16;
813     hash ^= hash >> 8;
814     hash = hash & (IP_HASH_SIZE - 1);
815     return hash;
816     }
817     #else
818     return 0;
819     #endif
820     }
821    
822     /* count_ip_hash()
823     *
824     * inputs - pointer to counter of number of ips hashed
825     * - pointer to memory used for ip hash
826     * output - returned via pointers input
827     * side effects - NONE
828     *
829     * number of hashed ip #'s is counted up, plus the amount of memory
830     * used in the hash.
831     */
832     void
833 michael 948 count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
834 adx 30 {
835     struct ip_entry *ptr;
836     int i;
837    
838     *number_ips_stored = 0;
839     *mem_ips_stored = 0;
840    
841     for (i = 0; i < IP_HASH_SIZE; i++)
842     {
843     for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next)
844     {
845     *number_ips_stored += 1;
846     *mem_ips_stored += sizeof(struct ip_entry);
847     }
848     }
849     }
850    
851     /* garbage_collect_ip_entries()
852     *
853     * input - NONE
854     * output - NONE
855     * side effects - free up all ip entries with no connections
856     */
857     static void
858     garbage_collect_ip_entries(void)
859     {
860     struct ip_entry *ptr;
861     struct ip_entry *last_ptr;
862     struct ip_entry *next_ptr;
863     int i;
864    
865     for (i = 0; i < IP_HASH_SIZE; i++)
866     {
867     last_ptr = NULL;
868    
869     for (ptr = ip_hash_table[i]; ptr; ptr = next_ptr)
870     {
871     next_ptr = ptr->next;
872    
873     if (ptr->count == 0 &&
874     (CurrentTime - ptr->last_attempt) >= ConfigFileEntry.throttle_time)
875     {
876     if (last_ptr != NULL)
877     last_ptr->next = ptr->next;
878     else
879     ip_hash_table[i] = ptr->next;
880 michael 1654 mp_pool_release(ptr);
881 adx 30 ip_entries_count--;
882     }
883     else
884     last_ptr = ptr;
885     }
886     }
887     }
888    
889     /* detach_conf()
890     *
891     * inputs - pointer to client to detach
892     * - type of conf to detach
893     * output - 0 for success, -1 for failure
894     * side effects - Disassociate configuration from the client.
895     * Also removes a class from the list if marked for deleting.
896     */
897 michael 1632 void
898     detach_conf(struct Client *client_p, enum maskitem_type type)
899 adx 30 {
900 michael 1632 dlink_node *ptr = NULL, *next_ptr = NULL;
901 adx 30
902     DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
903     {
904 michael 1645 struct MaskItem *conf = ptr->data;
905 adx 30
906 michael 1645 assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
907     assert(conf->ref_count > 0);
908     assert(conf->class->ref_count > 0);
909 adx 30
910 michael 1645 if (!(conf->type & type))
911     continue;
912 michael 671
913 michael 1645 dlinkDelete(ptr, &client_p->localClient->confs);
914     free_dlink_node(ptr);
915 michael 1644
916 michael 1645 if (conf->type == CONF_CLIENT)
917     remove_from_cidr_check(&client_p->localClient->ip, conf->class);
918 adx 30
919 michael 1645 if (--conf->class->ref_count == 0 && conf->class->active == 0)
920     {
921     class_free(conf->class);
922     conf->class = NULL;
923 adx 30 }
924 michael 1645
925     if (--conf->ref_count == 0 && conf->active == 0)
926     conf_free(conf);
927 adx 30 }
928     }
929    
930     /* attach_conf()
931     *
932     * inputs - client pointer
933     * - conf pointer
934     * output -
935     * side effects - Associate a specific configuration entry to a *local*
936     * client (this is the one which used in accepting the
937     * connection). Note, that this automatically changes the
938     * attachment if there was an old one...
939     */
940     int
941 michael 1632 attach_conf(struct Client *client_p, struct MaskItem *conf)
942 adx 30 {
943     if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
944     return 1;
945    
946 michael 1632 if (conf->type == CONF_CLIENT)
947     if (cidr_limit_reached(IsConfExemptLimits(conf),
948     &client_p->localClient->ip, conf->class))
949 michael 1394 return TOO_MANY; /* Already at maximum allowed */
950 adx 30
951 michael 1632 conf->class->ref_count++;
952 michael 1644 conf->ref_count++;
953 adx 30
954     dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
955    
956     return 0;
957     }
958    
959     /* attach_connect_block()
960     *
961     * inputs - pointer to server to attach
962     * - name of server
963     * - hostname of server
964     * output - true (1) if both are found, otherwise return false (0)
965     * side effects - find connect block and attach them to connecting client
966     */
967     int
968     attach_connect_block(struct Client *client_p, const char *name,
969     const char *host)
970     {
971     dlink_node *ptr;
972 michael 1632 struct MaskItem *conf = NULL;
973 adx 30
974     assert(client_p != NULL);
975     assert(host != NULL);
976    
977     if (client_p == NULL || host == NULL)
978     return 0;
979    
980     DLINK_FOREACH(ptr, server_items.head)
981     {
982     conf = ptr->data;
983    
984 michael 1652 if (match(conf->name, name) || match(conf->host, host))
985 adx 30 continue;
986    
987     attach_conf(client_p, conf);
988     return -1;
989     }
990    
991     return 0;
992     }
993    
994     /* find_conf_name()
995     *
996     * inputs - pointer to conf link list to search
997     * - pointer to name to find
998     * - int mask of type of conf to find
999     * output - NULL or pointer to conf found
1000     * side effects - find a conf entry which matches the name
1001     * and has the given mask.
1002     */
1003 michael 1632 struct MaskItem *
1004     find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
1005 adx 30 {
1006     dlink_node *ptr;
1007 michael 1632 struct MaskItem* conf;
1008 adx 30
1009     DLINK_FOREACH(ptr, list->head)
1010     {
1011     conf = ptr->data;
1012    
1013     if (conf->type == type)
1014     {
1015     if (conf->name && (irccmp(conf->name, name) == 0 ||
1016 michael 1652 !match(conf->name, name)))
1017 adx 30 return conf;
1018     }
1019     }
1020    
1021     return NULL;
1022     }
1023    
1024     /* map_to_list()
1025     *
1026     * inputs - ConfType conf
1027     * output - pointer to dlink_list to use
1028     * side effects - none
1029     */
1030     static dlink_list *
1031 michael 1632 map_to_list(enum maskitem_type type)
1032 adx 30 {
1033     switch(type)
1034     {
1035 michael 1644 case CONF_RKLINE:
1036     return(&rkconf_items);
1037     break;
1038 michael 1632 case CONF_RXLINE:
1039 adx 30 return(&rxconf_items);
1040     break;
1041 michael 1632 case CONF_XLINE:
1042 adx 30 return(&xconf_items);
1043     break;
1044 michael 1632 case CONF_ULINE:
1045 adx 30 return(&uconf_items);
1046     break;
1047 michael 1632 case CONF_NRESV:
1048 adx 30 return(&nresv_items);
1049     break;
1050 michael 1825 case CONF_CRESV:
1051     return(&resv_channel_list);
1052 michael 1632 case CONF_OPER:
1053 adx 30 return(&oconf_items);
1054     break;
1055 michael 1632 case CONF_SERVER:
1056 adx 30 return(&server_items);
1057     break;
1058 michael 1632 case CONF_SERVICE:
1059 michael 1172 return(&service_items);
1060     break;
1061 michael 1632 case CONF_CLUSTER:
1062 adx 30 return(&cluster_items);
1063     break;
1064     default:
1065     return NULL;
1066     }
1067     }
1068    
1069     /* find_matching_name_conf()
1070     *
1071     * inputs - type of link list to look in
1072     * - pointer to name string to find
1073     * - pointer to user
1074     * - pointer to host
1075 michael 1644 * - optional flags to match on as well
1076 michael 1632 * output - NULL or pointer to found struct MaskItem
1077 adx 30 * side effects - looks for a match on name field
1078     */
1079 michael 1632 struct MaskItem *
1080     find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1081 michael 1644 const char *host, unsigned int flags)
1082 adx 30 {
1083     dlink_node *ptr=NULL;
1084 michael 1632 struct MaskItem *conf=NULL;
1085 adx 30 dlink_list *list_p = map_to_list(type);
1086    
1087     switch (type)
1088     {
1089 michael 1009 #ifdef HAVE_LIBPCRE
1090 michael 1632 case CONF_RXLINE:
1091 adx 30 DLINK_FOREACH(ptr, list_p->head)
1092     {
1093     conf = ptr->data;
1094 michael 1654 assert(conf->regexuser);
1095 adx 30
1096 michael 1632 if (!ircd_pcre_exec(conf->regexuser, name))
1097 adx 30 return conf;
1098     }
1099     break;
1100 michael 1009 #endif
1101 michael 1632 case CONF_SERVICE:
1102 michael 1157 DLINK_FOREACH(ptr, list_p->head)
1103     {
1104     conf = ptr->data;
1105    
1106     if (EmptyString(conf->name))
1107     continue;
1108     if ((name != NULL) && !irccmp(name, conf->name))
1109     return conf;
1110     }
1111     break;
1112    
1113 michael 1632 case CONF_XLINE:
1114     case CONF_ULINE:
1115     case CONF_NRESV:
1116 michael 1825 case CONF_CRESV:
1117 adx 30 DLINK_FOREACH(ptr, list_p->head)
1118     {
1119     conf = ptr->data;
1120    
1121     if (EmptyString(conf->name))
1122     continue;
1123 michael 1653 if ((name != NULL) && !match(conf->name, name))
1124 adx 30 {
1125     if ((user == NULL && (host == NULL)))
1126     return conf;
1127 michael 1644 if ((conf->flags & flags) != flags)
1128 adx 30 continue;
1129 michael 1632 if (EmptyString(conf->user) || EmptyString(conf->host))
1130 adx 30 return conf;
1131 michael 1652 if (!match(conf->user, user) && !match(conf->host, host))
1132 adx 30 return conf;
1133     }
1134     }
1135     break;
1136    
1137 michael 1632 case CONF_SERVER:
1138 adx 30 DLINK_FOREACH(ptr, list_p->head)
1139     {
1140     conf = ptr->data;
1141    
1142 michael 1652 if ((name != NULL) && !match(name, conf->name))
1143 adx 30 return conf;
1144 michael 1652 else if ((host != NULL) && !match(host, conf->host))
1145 adx 30 return conf;
1146     }
1147     break;
1148    
1149     default:
1150     break;
1151     }
1152     return NULL;
1153     }
1154    
1155     /* find_exact_name_conf()
1156     *
1157     * inputs - type of link list to look in
1158     * - pointer to name string to find
1159     * - pointer to user
1160     * - pointer to host
1161 michael 1632 * output - NULL or pointer to found struct MaskItem
1162 adx 30 * side effects - looks for an exact match on name field
1163     */
1164 michael 1632 struct MaskItem *
1165     find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1166 adx 30 const char *user, const char *host)
1167     {
1168     dlink_node *ptr = NULL;
1169 michael 1632 struct MaskItem *conf;
1170     dlink_list *list_p = map_to_list(type);
1171 adx 30
1172     switch(type)
1173     {
1174 michael 1632 case CONF_RXLINE:
1175     case CONF_XLINE:
1176     case CONF_ULINE:
1177     case CONF_NRESV:
1178 michael 1825 case CONF_CRESV:
1179 adx 30
1180     DLINK_FOREACH(ptr, list_p->head)
1181     {
1182     conf = ptr->data;
1183 michael 1632
1184 adx 30 if (EmptyString(conf->name))
1185     continue;
1186    
1187     if (irccmp(conf->name, name) == 0)
1188     {
1189     if ((user == NULL && (host == NULL)))
1190     return (conf);
1191 michael 1632 if (EmptyString(conf->user) || EmptyString(conf->host))
1192 adx 30 return (conf);
1193 michael 1652 if (!match(conf->user, user) && !match(conf->host, host))
1194 adx 30 return (conf);
1195     }
1196     }
1197     break;
1198    
1199 michael 1632 case CONF_OPER:
1200 adx 30 DLINK_FOREACH(ptr, list_p->head)
1201     {
1202     conf = ptr->data;
1203 michael 1285
1204 adx 30 if (EmptyString(conf->name))
1205 michael 1285 continue;
1206    
1207     if (!irccmp(conf->name, name))
1208 adx 30 {
1209 michael 1285 if (!who)
1210     return conf;
1211 michael 1632 if (EmptyString(conf->user) || EmptyString(conf->host))
1212 michael 1636 return NULL;
1213 michael 1652 if (!match(conf->user, who->username))
1214 michael 1285 {
1215 michael 1632 switch (conf->htype)
1216 michael 1285 {
1217     case HM_HOST:
1218 michael 1652 if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
1219 michael 1637 if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1220     return conf;
1221 michael 1285 break;
1222     case HM_IPV4:
1223     if (who->localClient->aftype == AF_INET)
1224 michael 1632 if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1225 michael 1637 if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1226     return conf;
1227 michael 1285 break;
1228     #ifdef IPV6
1229     case HM_IPV6:
1230     if (who->localClient->aftype == AF_INET6)
1231 michael 1632 if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1232 michael 1637 if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1233     return conf;
1234 michael 1285 break;
1235     #endif
1236     default:
1237     assert(0);
1238     }
1239     }
1240 adx 30 }
1241     }
1242 michael 1285
1243 adx 30 break;
1244    
1245 michael 1632 case CONF_SERVER:
1246 adx 30 DLINK_FOREACH(ptr, list_p->head)
1247     {
1248     conf = ptr->data;
1249 michael 1632
1250 adx 30 if (EmptyString(conf->name))
1251     continue;
1252    
1253     if (name == NULL)
1254     {
1255 michael 1632 if (EmptyString(conf->host))
1256 adx 30 continue;
1257 michael 1632 if (irccmp(conf->host, host) == 0)
1258 adx 30 return(conf);
1259     }
1260     else if (irccmp(conf->name, name) == 0)
1261     {
1262     return (conf);
1263     }
1264     }
1265     break;
1266    
1267     default:
1268     break;
1269     }
1270     return(NULL);
1271     }
1272    
1273     /* rehash()
1274     *
1275     * Actual REHASH service routine. Called with sig == 0 if it has been called
1276     * as a result of an operator issuing this command, else assume it has been
1277     * called as a result of the server receiving a HUP signal.
1278     */
1279     int
1280     rehash(int sig)
1281     {
1282     if (sig != 0)
1283 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1284 adx 30 "Got signal SIGHUP, reloading ircd.conf file");
1285    
1286     restart_resolver();
1287 michael 1001
1288 adx 30 /* don't close listeners until we know we can go ahead with the rehash */
1289    
1290     /* Check to see if we magically got(or lost) IPv6 support */
1291     check_can_use_v6();
1292    
1293     read_conf_files(0);
1294    
1295     if (ServerInfo.description != NULL)
1296     strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1297    
1298     load_conf_modules();
1299    
1300     rehashed_klines = 1;
1301    
1302 michael 1831 return 0;
1303 adx 30 }
1304    
1305     /* set_default_conf()
1306     *
1307     * inputs - NONE
1308     * output - NONE
1309     * side effects - Set default values here.
1310     * This is called **PRIOR** to parsing the
1311     * configuration file. If you want to do some validation
1312     * of values later, put them in validate_conf().
1313     */
1314     static void
1315     set_default_conf(void)
1316     {
1317     /* verify init_class() ran, this should be an unnecessary check
1318     * but its not much work.
1319     */
1320 michael 1644 assert(class_default == class_get_list()->tail->data);
1321 adx 30
1322     #ifdef HAVE_LIBCRYPTO
1323     ServerInfo.rsa_private_key = NULL;
1324     ServerInfo.rsa_private_key_file = NULL;
1325     #endif
1326    
1327     /* ServerInfo.name is not rehashable */
1328     /* ServerInfo.name = ServerInfo.name; */
1329     ServerInfo.description = NULL;
1330 michael 1646 ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1331     ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1332 adx 30
1333     memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1334     ServerInfo.specific_ipv4_vhost = 0;
1335     memset(&ServerInfo.ip6, 0, sizeof(ServerInfo.ip6));
1336     ServerInfo.specific_ipv6_vhost = 0;
1337    
1338     ServerInfo.max_clients = MAXCLIENTS_MAX;
1339 michael 1751 ServerInfo.max_nick_length = 9;
1340     ServerInfo.max_topic_length = 80;
1341 michael 956
1342     ServerInfo.hub = 0;
1343 adx 30 ServerInfo.dns_host.sin_addr.s_addr = 0;
1344     ServerInfo.dns_host.sin_port = 0;
1345     AdminInfo.name = NULL;
1346     AdminInfo.email = NULL;
1347     AdminInfo.description = NULL;
1348    
1349 michael 1831 log_del_all();
1350 michael 1247
1351 adx 30 ConfigLoggingEntry.use_logging = 1;
1352    
1353 michael 1243 ConfigChannel.disable_fake_channels = 0;
1354 adx 30 ConfigChannel.knock_delay = 300;
1355     ConfigChannel.knock_delay_channel = 60;
1356 michael 1432 ConfigChannel.max_chans_per_user = 25;
1357 michael 1444 ConfigChannel.max_chans_per_oper = 50;
1358 michael 1243 ConfigChannel.quiet_on_ban = 1;
1359 adx 30 ConfigChannel.max_bans = 25;
1360     ConfigChannel.default_split_user_count = 0;
1361     ConfigChannel.default_split_server_count = 0;
1362 michael 1243 ConfigChannel.no_join_on_split = 0;
1363     ConfigChannel.no_create_on_split = 0;
1364 adx 30
1365 michael 1243 ConfigServerHide.flatten_links = 0;
1366 adx 30 ConfigServerHide.links_delay = 300;
1367 michael 1243 ConfigServerHide.hidden = 0;
1368     ConfigServerHide.hide_servers = 0;
1369 michael 1851 ConfigServerHide.hide_services = 0;
1370 michael 1646 ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1371 michael 1243 ConfigServerHide.hide_server_ips = 0;
1372 adx 30
1373 michael 876
1374 michael 1646 ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1375 michael 876 ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1376 michael 1459 ConfigFileEntry.glines = 0;
1377     ConfigFileEntry.gline_time = 12 * 3600;
1378     ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1379 adx 30 ConfigFileEntry.gline_min_cidr = 16;
1380     ConfigFileEntry.gline_min_cidr6 = 48;
1381 michael 1243 ConfigFileEntry.invisible_on_connect = 1;
1382     ConfigFileEntry.tkline_expire_notices = 1;
1383     ConfigFileEntry.hide_spoof_ips = 1;
1384     ConfigFileEntry.ignore_bogus_ts = 0;
1385     ConfigFileEntry.disable_auth = 0;
1386     ConfigFileEntry.disable_remote = 0;
1387 adx 30 ConfigFileEntry.kill_chase_time_limit = 90;
1388 michael 1119 ConfigFileEntry.default_floodcount = 8;
1389 michael 1243 ConfigFileEntry.failed_oper_notice = 1;
1390 michael 1119 ConfigFileEntry.dots_in_ident = 0;
1391 adx 30 ConfigFileEntry.min_nonwildcard = 4;
1392     ConfigFileEntry.min_nonwildcard_simple = 3;
1393     ConfigFileEntry.max_accept = 20;
1394 michael 1243 ConfigFileEntry.anti_nick_flood = 0;
1395 adx 30 ConfigFileEntry.max_nick_time = 20;
1396     ConfigFileEntry.max_nick_changes = 5;
1397 michael 1119 ConfigFileEntry.anti_spam_exit_message_time = 0;
1398 adx 30 ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1399 michael 1119 ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1400 michael 1243 ConfigFileEntry.warn_no_nline = 1;
1401     ConfigFileEntry.stats_o_oper_only = 0;
1402 adx 30 ConfigFileEntry.stats_k_oper_only = 1; /* masked */
1403     ConfigFileEntry.stats_i_oper_only = 1; /* masked */
1404 michael 1243 ConfigFileEntry.stats_P_oper_only = 0;
1405 adx 30 ConfigFileEntry.caller_id_wait = 60;
1406 michael 1243 ConfigFileEntry.opers_bypass_callerid = 0;
1407 adx 30 ConfigFileEntry.pace_wait = 10;
1408     ConfigFileEntry.pace_wait_simple = 1;
1409 michael 1243 ConfigFileEntry.short_motd = 0;
1410     ConfigFileEntry.ping_cookie = 0;
1411     ConfigFileEntry.no_oper_flood = 0;
1412     ConfigFileEntry.true_no_oper_flood = 0;
1413     ConfigFileEntry.oper_pass_resv = 1;
1414 adx 30 ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1415 michael 1119 ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1416 adx 264 ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1417 michael 1119 UMODE_OPERWALL | UMODE_WALLOP;
1418 michael 1243 ConfigFileEntry.use_egd = 0;
1419 adx 30 ConfigFileEntry.egdpool_path = NULL;
1420     ConfigFileEntry.throttle_time = 10;
1421     }
1422    
1423     static void
1424     validate_conf(void)
1425     {
1426     if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1427     ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1428    
1429     if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1430     ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1431    
1432     if (ServerInfo.network_name == NULL)
1433 michael 1646 ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1434 adx 30
1435     if (ServerInfo.network_desc == NULL)
1436 michael 1646 ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1437 adx 30
1438 michael 1157 if (ConfigFileEntry.service_name == NULL)
1439 michael 1646 ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1440 michael 1157
1441 michael 876 ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1442 adx 30 }
1443    
1444 michael 1363 /* read_conf()
1445     *
1446     * inputs - file descriptor pointing to config file to use
1447     * output - None
1448     * side effects - Read configuration file.
1449     */
1450     static void
1451     read_conf(FILE *file)
1452     {
1453     lineno = 0;
1454    
1455     set_default_conf(); /* Set default values prior to conf parsing */
1456     conf_parser_ctx.pass = 1;
1457     yyparse(); /* pick up the classes first */
1458    
1459     rewind(file);
1460    
1461     conf_parser_ctx.pass = 2;
1462     yyparse(); /* Load the values from the conf */
1463     validate_conf(); /* Check to make sure some values are still okay. */
1464     /* Some global values are also loaded here. */
1465 michael 1632 class_delete_marked(); /* Make sure classes are valid */
1466 michael 1363 }
1467    
1468 adx 30 /* lookup_confhost()
1469     *
1470     * start DNS lookups of all hostnames in the conf
1471     * line and convert an IP addresses in a.b.c.d number for to IP#s.
1472     */
1473 michael 1647 void
1474 michael 1632 lookup_confhost(struct MaskItem *conf)
1475 adx 30 {
1476     struct addrinfo hints, *res;
1477    
1478     /* Do name lookup now on hostnames given and store the
1479     * ip numbers in conf structure.
1480     */
1481     memset(&hints, 0, sizeof(hints));
1482    
1483     hints.ai_family = AF_UNSPEC;
1484     hints.ai_socktype = SOCK_STREAM;
1485    
1486     /* Get us ready for a bind() and don't bother doing dns lookup */
1487     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1488    
1489 michael 1632 if (getaddrinfo(conf->host, NULL, &hints, &res))
1490 adx 30 {
1491 michael 1632 conf_dns_lookup(conf);
1492 adx 30 return;
1493     }
1494    
1495     assert(res != NULL);
1496    
1497 michael 1632 memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1498     conf->addr.ss_len = res->ai_addrlen;
1499     conf->addr.ss.ss_family = res->ai_family;
1500    
1501 michael 1123 freeaddrinfo(res);
1502 adx 30 }
1503    
1504     /* conf_connect_allowed()
1505     *
1506     * inputs - pointer to inaddr
1507     * - int type ipv4 or ipv6
1508     * output - BANNED or accepted
1509     * side effects - none
1510     */
1511     int
1512     conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1513     {
1514     struct ip_entry *ip_found;
1515 michael 1632 struct MaskItem *conf = find_dline_conf(addr, aftype);
1516 adx 30
1517     /* DLINE exempt also gets you out of static limits/pacing... */
1518 michael 1636 if (conf && (conf->type == CONF_EXEMPT))
1519 adx 30 return 0;
1520    
1521 michael 1632 if (conf != NULL)
1522 adx 30 return BANNED_CLIENT;
1523    
1524     ip_found = find_or_add_ip(addr);
1525    
1526     if ((CurrentTime - ip_found->last_attempt) <
1527     ConfigFileEntry.throttle_time)
1528     {
1529     ip_found->last_attempt = CurrentTime;
1530     return TOO_FAST;
1531     }
1532    
1533     ip_found->last_attempt = CurrentTime;
1534     return 0;
1535     }
1536    
1537 michael 1632 static struct MaskItem *
1538 adx 30 find_regexp_kline(const char *uhi[])
1539     {
1540 michael 1009 #ifdef HAVE_LIBPCRE
1541 adx 30 const dlink_node *ptr = NULL;
1542    
1543     DLINK_FOREACH(ptr, rkconf_items.head)
1544     {
1545 michael 1632 struct MaskItem *aptr = ptr->data;
1546 adx 30
1547     assert(aptr->regexuser);
1548     assert(aptr->regexhost);
1549    
1550     if (!ircd_pcre_exec(aptr->regexuser, uhi[0]) &&
1551     (!ircd_pcre_exec(aptr->regexhost, uhi[1]) ||
1552     !ircd_pcre_exec(aptr->regexhost, uhi[2])))
1553     return aptr;
1554     }
1555 michael 1009 #endif
1556 adx 30 return NULL;
1557     }
1558    
1559     /* find_kill()
1560     *
1561     * inputs - pointer to client structure
1562 michael 1632 * output - pointer to struct MaskItem if found
1563 adx 30 * side effects - See if this user is klined already,
1564 michael 1632 * and if so, return struct MaskItem pointer
1565 adx 30 */
1566 michael 1632 struct MaskItem *
1567 adx 30 find_kill(struct Client *client_p)
1568     {
1569 michael 1632 struct MaskItem *conf = NULL;
1570 adx 30 const char *uhi[3];
1571    
1572     uhi[0] = client_p->username;
1573     uhi[1] = client_p->host;
1574     uhi[2] = client_p->sockhost;
1575    
1576     assert(client_p != NULL);
1577    
1578 michael 1632 conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1579     CONF_KLINE, client_p->localClient->aftype,
1580     client_p->username, NULL, 1);
1581     if (conf == NULL)
1582     conf = find_regexp_kline(uhi);
1583 adx 30
1584 michael 1632 return conf;
1585 adx 30 }
1586    
1587 michael 1632 struct MaskItem *
1588 adx 30 find_gline(struct Client *client_p)
1589     {
1590 michael 1632 struct MaskItem *conf;
1591 adx 30
1592     assert(client_p != NULL);
1593    
1594 michael 1632 conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1595     CONF_GLINE, client_p->localClient->aftype,
1596     client_p->username, NULL, 1);
1597     return conf;
1598 adx 30 }
1599    
1600     /* cleanup_tklines()
1601     *
1602     * inputs - NONE
1603     * output - NONE
1604     * side effects - call function to expire temporary k/d lines
1605     * This is an event started off in ircd.c
1606     */
1607     void
1608     cleanup_tklines(void *notused)
1609     {
1610 michael 1369 hostmask_expire_temporary();
1611 michael 1622 expire_tklines(&xconf_items);
1612 michael 1628 expire_tklines(&nresv_items);
1613     expire_tklines(&resv_channel_list);
1614 adx 30 }
1615    
1616     /* expire_tklines()
1617     *
1618     * inputs - tkline list pointer
1619     * output - NONE
1620     * side effects - expire tklines
1621     */
1622     static void
1623     expire_tklines(dlink_list *tklist)
1624     {
1625     dlink_node *ptr;
1626     dlink_node *next_ptr;
1627 michael 1632 struct MaskItem *conf;
1628 adx 30
1629     DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1630     {
1631     conf = ptr->data;
1632    
1633 michael 1649 if (!conf->until || conf->until > CurrentTime)
1634 michael 1644 continue;
1635    
1636 michael 1632 if (conf->type == CONF_XLINE)
1637 adx 30 {
1638 michael 1644 if (ConfigFileEntry.tkline_expire_notices)
1639     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1640 michael 1618 "Temporary X-line for [%s] expired", conf->name);
1641 michael 1644 conf_free(conf);
1642 adx 30 }
1643 michael 1825 else if (conf->type == CONF_NRESV || conf->type == CONF_CRESV)
1644 adx 30 {
1645 michael 1644 if (ConfigFileEntry.tkline_expire_notices)
1646     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1647 adx 30 "Temporary RESV for [%s] expired", conf->name);
1648 michael 1644 conf_free(conf);
1649 adx 30 }
1650     }
1651     }
1652    
1653     /* oper_privs_as_string()
1654     *
1655 michael 58 * inputs - pointer to client_p
1656 adx 30 * output - pointer to static string showing oper privs
1657     * side effects - return as string, the oper privs as derived from port
1658     */
1659 michael 58 static const struct oper_privs
1660     {
1661 michael 1644 const unsigned int flag;
1662 michael 58 const unsigned char c;
1663     } flag_list[] = {
1664 michael 1294 { OPER_FLAG_ADMIN, 'A' },
1665     { OPER_FLAG_REMOTEBAN, 'B' },
1666     { OPER_FLAG_DIE, 'D' },
1667     { OPER_FLAG_GLINE, 'G' },
1668     { OPER_FLAG_REHASH, 'H' },
1669     { OPER_FLAG_K, 'K' },
1670     { OPER_FLAG_OPERWALL, 'L' },
1671     { OPER_FLAG_N, 'N' },
1672     { OPER_FLAG_GLOBAL_KILL, 'O' },
1673     { OPER_FLAG_REMOTE, 'R' },
1674     { OPER_FLAG_OPER_SPY, 'S' },
1675     { OPER_FLAG_UNKLINE, 'U' },
1676     { OPER_FLAG_X, 'X' },
1677     { 0, '\0' }
1678 michael 58 };
1679 adx 30
1680     char *
1681     oper_privs_as_string(const unsigned int port)
1682     {
1683 michael 58 static char privs_out[16];
1684     char *privs_ptr = privs_out;
1685 michael 1644 const struct oper_privs *opriv = flag_list;
1686 adx 30
1687 michael 1644 for (; opriv->flag; ++opriv)
1688 michael 58 {
1689 michael 1644 if (port & opriv->flag)
1690     *privs_ptr++ = opriv->c;
1691 michael 58 else
1692 michael 1644 *privs_ptr++ = ToLower(opriv->c);
1693 michael 58 }
1694    
1695     *privs_ptr = '\0';
1696    
1697 adx 30 return privs_out;
1698     }
1699    
1700     /*
1701     * Input: A client to find the active oper{} name for.
1702     * Output: The nick!user@host{oper} of the oper.
1703     * "oper" is server name for remote opers
1704     * Side effects: None.
1705     */
1706 michael 1364 const char *
1707 adx 30 get_oper_name(const struct Client *client_p)
1708     {
1709 michael 1364 dlink_node *cnode = NULL;
1710 adx 30 /* +5 for !,@,{,} and null */
1711 michael 1147 static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
1712 adx 30
1713     if (MyConnect(client_p))
1714     {
1715 michael 1364 if ((cnode = client_p->localClient->confs.head))
1716 adx 30 {
1717 michael 1632 struct MaskItem *conf = cnode->data;
1718 adx 30
1719 michael 1632 if (IsConfOperator(conf))
1720 adx 30 {
1721 michael 1147 snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1722     client_p->username, client_p->host, conf->name);
1723 adx 30 return buffer;
1724     }
1725     }
1726    
1727     /* Probably should assert here for now. If there is an oper out there
1728     * with no oper{} conf attached, it would be good for us to know...
1729     */
1730     assert(0); /* Oper without oper conf! */
1731     }
1732    
1733 michael 1147 snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1734     client_p->username, client_p->host, client_p->servptr->name);
1735 adx 30 return buffer;
1736     }
1737    
1738     /* read_conf_files()
1739     *
1740     * inputs - cold start YES or NO
1741     * output - none
1742     * side effects - read all conf files needed, ircd.conf kline.conf etc.
1743     */
1744     void
1745     read_conf_files(int cold)
1746     {
1747     const char *filename;
1748     char chanmodes[32];
1749     char chanlimit[32];
1750    
1751 michael 967 conf_parser_ctx.boot = cold;
1752 michael 1622 filename = ConfigFileEntry.configfile;
1753 adx 30
1754     /* We need to know the initial filename for the yyerror() to report
1755     FIXME: The full path is in conffilenamebuf first time since we
1756     dont know anything else
1757    
1758     - Gozem 2002-07-21
1759     */
1760     strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1761    
1762 michael 1325 if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1763 adx 30 {
1764     if (cold)
1765     {
1766 michael 1247 ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1767 adx 30 filename, strerror(errno));
1768     exit(-1);
1769     }
1770     else
1771     {
1772 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1773 adx 30 "Unable to read configuration file '%s': %s",
1774     filename, strerror(errno));
1775     return;
1776     }
1777     }
1778    
1779     if (!cold)
1780     clear_out_old_conf();
1781    
1782 michael 967 read_conf(conf_parser_ctx.conf_file);
1783 michael 1325 fclose(conf_parser_ctx.conf_file);
1784 adx 30
1785 michael 1831 log_reopen_all();
1786    
1787 michael 1751 add_isupport("NICKLEN", NULL, ServerInfo.max_nick_length);
1788 adx 30 add_isupport("NETWORK", ServerInfo.network_name, -1);
1789 michael 1751
1790     snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1791 adx 30 add_isupport("MAXLIST", chanmodes, -1);
1792     add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
1793 michael 1474 add_isupport("CHANTYPES", "#", -1);
1794 michael 1147
1795 michael 1474 snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1796 michael 1751 ConfigChannel.max_chans_per_user);
1797 adx 30 add_isupport("CHANLIMIT", chanlimit, -1);
1798 michael 1751 snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1799 michael 100 add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1800 michael 1751 add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1801 michael 1495 add_isupport("EXCEPTS", "e", -1);
1802     add_isupport("INVEX", "I", -1);
1803 adx 30 add_isupport("CHANMODES", chanmodes, -1);
1804    
1805     /*
1806     * message_locale may have changed. rebuild isupport since it relies
1807     * on strlen(form_str(RPL_ISUPPORT))
1808     */
1809     rebuild_isupport_message_line();
1810     }
1811    
1812     /* clear_out_old_conf()
1813     *
1814     * inputs - none
1815     * output - none
1816     * side effects - Clear out the old configuration
1817     */
1818     static void
1819     clear_out_old_conf(void)
1820     {
1821     dlink_node *ptr = NULL, *next_ptr = NULL;
1822 michael 1632 struct MaskItem *conf;
1823 adx 30 dlink_list *free_items [] = {
1824 michael 1383 &server_items, &oconf_items,
1825 adx 30 &uconf_items, &xconf_items, &rxconf_items, &rkconf_items,
1826 michael 1825 &nresv_items, &cluster_items, &service_items, &resv_channel_list, NULL
1827 adx 30 };
1828    
1829     dlink_list ** iterator = free_items; /* C is dumb */
1830    
1831     /* We only need to free anything allocated by yyparse() here.
1832     * Resetting structs, etc, is taken care of by set_default_conf().
1833     */
1834    
1835     for (; *iterator != NULL; iterator++)
1836     {
1837     DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1838     {
1839     conf = ptr->data;
1840 michael 1632
1841     dlinkDelete(&conf->node, map_to_list(conf->type));
1842    
1843 adx 30 /* XXX This is less than pretty */
1844 michael 1632 if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1845 adx 30 {
1846 michael 1644 if (!conf->ref_count)
1847 michael 1632 conf_free(conf);
1848 adx 30 }
1849 michael 1632 else if (conf->type == CONF_XLINE ||
1850     conf->type == CONF_RXLINE ||
1851     conf->type == CONF_RKLINE)
1852 adx 30 {
1853 michael 1649 if (!conf->until)
1854 michael 1632 conf_free(conf);
1855 adx 30 }
1856     else
1857 michael 1632 conf_free(conf);
1858 adx 30 }
1859     }
1860    
1861 michael 671 /*
1862     * don't delete the class table, rather mark all entries
1863 michael 1632 * for deletion. The table is cleaned up by class_delete_marked. - avalon
1864 adx 30 */
1865 michael 1632 class_mark_for_deletion();
1866 michael 671
1867 adx 30 clear_out_address_conf();
1868    
1869     /* clean out module paths */
1870     mod_clear_paths();
1871    
1872     /* clean out ServerInfo */
1873     MyFree(ServerInfo.description);
1874     ServerInfo.description = NULL;
1875     MyFree(ServerInfo.network_name);
1876     ServerInfo.network_name = NULL;
1877     MyFree(ServerInfo.network_desc);
1878     ServerInfo.network_desc = NULL;
1879     MyFree(ConfigFileEntry.egdpool_path);
1880     ConfigFileEntry.egdpool_path = NULL;
1881     #ifdef HAVE_LIBCRYPTO
1882     if (ServerInfo.rsa_private_key != NULL)
1883     {
1884     RSA_free(ServerInfo.rsa_private_key);
1885     ServerInfo.rsa_private_key = NULL;
1886     }
1887    
1888     MyFree(ServerInfo.rsa_private_key_file);
1889     ServerInfo.rsa_private_key_file = NULL;
1890 michael 1316
1891     if (ServerInfo.server_ctx)
1892     SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1893     SSL_OP_NO_SSLv3|
1894     SSL_OP_NO_TLSv1);
1895     if (ServerInfo.client_ctx)
1896     SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1897     SSL_OP_NO_SSLv3|
1898     SSL_OP_NO_TLSv1);
1899 adx 30 #endif
1900    
1901     /* clean out AdminInfo */
1902     MyFree(AdminInfo.name);
1903     AdminInfo.name = NULL;
1904     MyFree(AdminInfo.email);
1905     AdminInfo.email = NULL;
1906     MyFree(AdminInfo.description);
1907     AdminInfo.description = NULL;
1908    
1909     /* clean out listeners */
1910     close_listeners();
1911    
1912     /* clean out general */
1913 michael 1157 MyFree(ConfigFileEntry.service_name);
1914     ConfigFileEntry.service_name = NULL;
1915    
1916 adx 30 delete_isupport("INVEX");
1917     delete_isupport("EXCEPTS");
1918     }
1919    
1920     /* conf_add_class_to_conf()
1921     *
1922     * inputs - pointer to config item
1923     * output - NONE
1924     * side effects - Add a class pointer to a conf
1925     */
1926     void
1927 michael 1632 conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1928 adx 30 {
1929     if (class_name == NULL)
1930     {
1931 michael 1632 conf->class = class_default;
1932 michael 671
1933 michael 1632 if (conf->type == CONF_CLIENT)
1934 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1935 adx 30 "Warning *** Defaulting to default class for %s@%s",
1936 michael 1632 conf->user, conf->host);
1937 adx 30 else
1938 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1939 adx 30 "Warning *** Defaulting to default class for %s",
1940     conf->name);
1941     }
1942     else
1943 michael 1632 conf->class = class_find(class_name, 1);
1944 adx 30
1945 michael 1632 if (conf->class == NULL)
1946 adx 30 {
1947 michael 1632 if (conf->type == CONF_CLIENT)
1948 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1949 adx 30 "Warning *** Defaulting to default class for %s@%s",
1950 michael 1632 conf->user, conf->host);
1951 adx 30 else
1952 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1953 adx 30 "Warning *** Defaulting to default class for %s",
1954     conf->name);
1955 michael 1632 conf->class = class_default;
1956 adx 30 }
1957     }
1958    
1959     /* yyerror()
1960     *
1961     * inputs - message from parser
1962     * output - NONE
1963     * side effects - message to opers and log file entry is made
1964     */
1965     void
1966     yyerror(const char *msg)
1967     {
1968     char newlinebuf[IRCD_BUFSIZE];
1969    
1970 michael 967 if (conf_parser_ctx.pass != 1)
1971 adx 30 return;
1972    
1973     strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1974 michael 1751 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1975 michael 1618 "\"%s\", line %u: %s: %s",
1976 adx 30 conffilebuf, lineno + 1, msg, newlinebuf);
1977 michael 1247 ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1978 adx 30 conffilebuf, lineno + 1, msg, newlinebuf);
1979     }
1980    
1981 michael 1751 void
1982     conf_error_report(const char *msg)
1983     {
1984     char newlinebuf[IRCD_BUFSIZE];
1985    
1986     strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1987     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1988     "\"%s\", line %u: %s: %s",
1989     conffilebuf, lineno + 1, msg, newlinebuf);
1990     ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1991     conffilebuf, lineno + 1, msg, newlinebuf);
1992     }
1993    
1994 adx 30 /*
1995     * valid_tkline()
1996     *
1997     * inputs - pointer to ascii string to check
1998     * - whether the specified time is in seconds or minutes
1999     * output - -1 not enough parameters
2000     * - 0 if not an integer number, else the number
2001     * side effects - none
2002     * Originally written by Dianora (Diane, db@db.net)
2003     */
2004     time_t
2005 michael 1120 valid_tkline(const char *p, int minutes)
2006 adx 30 {
2007     time_t result = 0;
2008    
2009 michael 1120 for (; *p; ++p)
2010 adx 30 {
2011 michael 1120 if (!IsDigit(*p))
2012 michael 1121 return 0;
2013 michael 1120
2014     result *= 10;
2015     result += ((*p) & 0xF);
2016 adx 30 }
2017    
2018 michael 1120 /*
2019     * In the degenerate case where oper does a /quote kline 0 user@host :reason
2020 adx 30 * i.e. they specifically use 0, I am going to return 1 instead
2021     * as a return value of non-zero is used to flag it as a temporary kline
2022     */
2023     if (result == 0)
2024     result = 1;
2025    
2026     /*
2027     * If the incoming time is in seconds convert it to minutes for the purpose
2028     * of this calculation
2029     */
2030     if (!minutes)
2031     result = result / (time_t)60;
2032    
2033     if (result > MAX_TDKLINE_TIME)
2034     result = MAX_TDKLINE_TIME;
2035    
2036     result = result * (time_t)60; /* turn it into seconds */
2037    
2038     return result;
2039     }
2040    
2041     /* valid_wild_card()
2042     *
2043     * input - pointer to client
2044     * - int flag, 0 for no warning oper 1 for warning oper
2045     * - count of following varargs to check
2046     * output - 0 if not valid, 1 if valid
2047     * side effects - NOTICE is given to source_p if warn is 1
2048     */
2049     int
2050     valid_wild_card(struct Client *source_p, int warn, int count, ...)
2051     {
2052     char *p;
2053     char tmpch;
2054     int nonwild = 0;
2055     va_list args;
2056    
2057     /*
2058     * Now we must check the user and host to make sure there
2059     * are at least NONWILDCHARS non-wildcard characters in
2060     * them, otherwise assume they are attempting to kline
2061     * *@* or some variant of that. This code will also catch
2062     * people attempting to kline *@*.tld, as long as NONWILDCHARS
2063     * is greater than 3. In that case, there are only 3 non-wild
2064     * characters (tld), so if NONWILDCHARS is 4, the kline will
2065     * be disallowed.
2066     * -wnder
2067     */
2068    
2069     va_start(args, count);
2070    
2071     while (count--)
2072     {
2073     p = va_arg(args, char *);
2074     if (p == NULL)
2075     continue;
2076    
2077     while ((tmpch = *p++))
2078     {
2079     if (!IsKWildChar(tmpch))
2080     {
2081     /*
2082     * If we find enough non-wild characters, we can
2083     * break - no point in searching further.
2084     */
2085     if (++nonwild >= ConfigFileEntry.min_nonwildcard)
2086     return 1;
2087     }
2088     }
2089     }
2090    
2091     if (warn)
2092     sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the mask",
2093     me.name, source_p->name, ConfigFileEntry.min_nonwildcard);
2094     return 0;
2095     }
2096    
2097     /* XXX should this go into a separate file ? -Dianora */
2098     /* parse_aline
2099     *
2100     * input - pointer to cmd name being used
2101     * - pointer to client using cmd
2102     * - parc parameter count
2103     * - parv[] list of parameters to parse
2104     * - parse_flags bit map of things to test
2105     * - pointer to user or string to parse into
2106     * - pointer to host or NULL to parse into if non NULL
2107     * - pointer to optional tkline time or NULL
2108     * - pointer to target_server to parse into if non NULL
2109     * - pointer to reason to parse into
2110     *
2111     * output - 1 if valid, -1 if not valid
2112     * side effects - A generalised k/d/x etc. line parser,
2113     * "ALINE [time] user@host|string [ON] target :reason"
2114     * will parse returning a parsed user, host if
2115     * h_p pointer is non NULL, string otherwise.
2116     * if tkline_time pointer is non NULL a tk line will be set
2117     * to non zero if found.
2118     * if tkline_time pointer is NULL and tk line is found,
2119     * error is reported.
2120     * if target_server is NULL and an "ON" is found error
2121     * is reported.
2122     * if reason pointer is NULL ignore pointer,
2123 db 936 * this allows use of parse_a_line in unkline etc.
2124 adx 30 *
2125     * - Dianora
2126     */
2127     int
2128     parse_aline(const char *cmd, struct Client *source_p,
2129     int parc, char **parv,
2130     int parse_flags, char **up_p, char **h_p, time_t *tkline_time,
2131     char **target_server, char **reason)
2132     {
2133     int found_tkline_time=0;
2134     static char def_reason[] = "No Reason";
2135     static char user[USERLEN*4+1];
2136     static char host[HOSTLEN*4+1];
2137    
2138     parv++;
2139     parc--;
2140    
2141     found_tkline_time = valid_tkline(*parv, TK_MINUTES);
2142    
2143     if (found_tkline_time != 0)
2144     {
2145     parv++;
2146     parc--;
2147    
2148     if (tkline_time != NULL)
2149     *tkline_time = found_tkline_time;
2150     else
2151     {
2152     sendto_one(source_p, ":%s NOTICE %s :temp_line not supported by %s",
2153     me.name, source_p->name, cmd);
2154     return -1;
2155     }
2156     }
2157    
2158     if (parc == 0)
2159     {
2160 michael 1834 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
2161 adx 30 me.name, source_p->name, cmd);
2162     return -1;
2163     }
2164    
2165     if (h_p == NULL)
2166     *up_p = *parv;
2167     else
2168     {
2169     if (find_user_host(source_p, *parv, user, host, parse_flags) == 0)
2170     return -1;
2171    
2172     *up_p = user;
2173     *h_p = host;
2174     }
2175    
2176     parc--;
2177     parv++;
2178    
2179     if (parc != 0)
2180     {
2181     if (irccmp(*parv, "ON") == 0)
2182     {
2183     parc--;
2184     parv++;
2185    
2186     if (target_server == NULL)
2187     {
2188     sendto_one(source_p, ":%s NOTICE %s :ON server not supported by %s",
2189     me.name, source_p->name, cmd);
2190     return -1;
2191     }
2192    
2193 michael 1219 if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
2194 adx 30 {
2195 michael 1834 sendto_one(source_p, form_str(ERR_NOPRIVS),
2196 adx 30 me.name, source_p->name, "remoteban");
2197     return -1;
2198     }
2199    
2200     if (parc == 0 || EmptyString(*parv))
2201     {
2202 michael 1834 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
2203 adx 30 me.name, source_p->name, cmd);
2204     return -1;
2205     }
2206    
2207     *target_server = *parv;
2208     parc--;
2209     parv++;
2210     }
2211     else
2212     {
2213     /* Make sure target_server *is* NULL if no ON server found
2214     * caller probably NULL'd it first, but no harm to do it again -db
2215     */
2216     if (target_server != NULL)
2217     *target_server = NULL;
2218     }
2219     }
2220    
2221     if (h_p != NULL)
2222     {
2223     if (strchr(user, '!') != NULL)
2224     {
2225     sendto_one(source_p, ":%s NOTICE %s :Invalid character '!' in kline",
2226     me.name, source_p->name);
2227     return -1;
2228     }
2229    
2230 michael 1243 if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
2231 adx 30 return -1;
2232     }
2233     else
2234 michael 1243 if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
2235 adx 30 return -1;
2236    
2237     if (reason != NULL)
2238     {
2239 michael 867 if (parc != 0 && !EmptyString(*parv))
2240 adx 30 {
2241     *reason = *parv;
2242 michael 1243 if (!valid_comment(source_p, *reason, 1))
2243 adx 30 return -1;
2244     }
2245     else
2246     *reason = def_reason;
2247     }
2248    
2249     return 1;
2250     }
2251    
2252     /* find_user_host()
2253     *
2254     * inputs - pointer to client placing kline
2255     * - pointer to user_host_or_nick
2256     * - pointer to user buffer
2257     * - pointer to host buffer
2258     * output - 0 if not ok to kline, 1 to kline i.e. if valid user host
2259     * side effects -
2260     */
2261     static int
2262     find_user_host(struct Client *source_p, char *user_host_or_nick,
2263     char *luser, char *lhost, unsigned int flags)
2264     {
2265     struct Client *target_p = NULL;
2266     char *hostp = NULL;
2267    
2268     if (lhost == NULL)
2269     {
2270     strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
2271     return 1;
2272     }
2273    
2274     if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*')
2275     {
2276     /* Explicit user@host mask given */
2277    
2278 michael 593 if (hostp != NULL) /* I'm a little user@host */
2279 adx 30 {
2280     *(hostp++) = '\0'; /* short and squat */
2281     if (*user_host_or_nick)
2282     strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); /* here is my user */
2283     else
2284     strcpy(luser, "*");
2285     if (*hostp)
2286     strlcpy(lhost, hostp, HOSTLEN + 1); /* here is my host */
2287     else
2288     strcpy(lhost, "*");
2289     }
2290     else
2291     {
2292     luser[0] = '*'; /* no @ found, assume its *@somehost */
2293     luser[1] = '\0';
2294     strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1);
2295     }
2296    
2297     return 1;
2298     }
2299 michael 1518 else
2300 adx 30 {
2301     /* Try to find user@host mask from nick */
2302     /* Okay to use source_p as the first param, because source_p == client_p */
2303     if ((target_p =
2304     find_chasing(source_p, source_p, user_host_or_nick, NULL)) == NULL)
2305     return 0;
2306    
2307     if (IsExemptKline(target_p))
2308     {
2309     if (!IsServer(source_p))
2310     sendto_one(source_p,
2311     ":%s NOTICE %s :%s is E-lined",
2312     me.name, source_p->name, target_p->name);
2313     return 0;
2314     }
2315    
2316     /*
2317     * turn the "user" bit into "*user", blow away '~'
2318     * if found in original user name (non-idented)
2319     */
2320     strlcpy(luser, target_p->username, USERLEN*4 + 1);
2321    
2322     if (target_p->username[0] == '~')
2323     luser[0] = '*';
2324    
2325     if (target_p->sockhost[0] == '\0' ||
2326     (target_p->sockhost[0] == '0' && target_p->sockhost[1] == '\0'))
2327     strlcpy(lhost, target_p->host, HOSTLEN*4 + 1);
2328     else
2329     strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1);
2330     return 1;
2331     }
2332    
2333     return 0;
2334     }
2335    
2336     /* valid_comment()
2337     *
2338     * inputs - pointer to client
2339     * - pointer to comment
2340     * output - 0 if no valid comment,
2341     * - 1 if valid
2342     * side effects - truncates reason where necessary
2343     */
2344     int
2345     valid_comment(struct Client *source_p, char *comment, int warn)
2346     {
2347     if (strlen(comment) > REASONLEN)
2348     comment[REASONLEN-1] = '\0';
2349    
2350     return 1;
2351     }
2352    
2353     /* match_conf_password()
2354     *
2355     * inputs - pointer to given password
2356     * - pointer to Conf
2357     * output - 1 or 0 if match
2358     * side effects - none
2359     */
2360     int
2361 michael 1632 match_conf_password(const char *password, const struct MaskItem *conf)
2362 adx 30 {
2363     const char *encr = NULL;
2364    
2365 michael 1632 if (EmptyString(password) || EmptyString(conf->passwd))
2366 adx 30 return 0;
2367    
2368 michael 1632 if (conf->flags & CONF_FLAGS_ENCRYPTED)
2369     encr = crypt(password, conf->passwd);
2370 adx 30 else
2371     encr = password;
2372    
2373 michael 1632 return !strcmp(encr, conf->passwd);
2374 adx 30 }
2375    
2376     /*
2377     * cluster_a_line
2378     *
2379     * inputs - client sending the cluster
2380     * - command name "KLINE" "XLINE" etc.
2381     * - capab -- CAP_KLN etc. from s_serv.h
2382 michael 1309 * - cluster type -- CLUSTER_KLINE etc. from conf.h
2383 adx 30 * - pattern and args to send along
2384     * output - none
2385     * side effects - Take source_p send the pattern with args given
2386     * along to all servers that match capab and cluster type
2387     */
2388     void
2389     cluster_a_line(struct Client *source_p, const char *command,
2390 michael 593 int capab, int cluster_type, const char *pattern, ...)
2391 adx 30 {
2392     va_list args;
2393     char buffer[IRCD_BUFSIZE];
2394 michael 593 const dlink_node *ptr = NULL;
2395 adx 30
2396     va_start(args, pattern);
2397     vsnprintf(buffer, sizeof(buffer), pattern, args);
2398     va_end(args);
2399    
2400     DLINK_FOREACH(ptr, cluster_items.head)
2401     {
2402 michael 1632 const struct MaskItem *conf = ptr->data;
2403 adx 30
2404     if (conf->flags & cluster_type)
2405     sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
2406     "%s %s %s", command, conf->name, buffer);
2407     }
2408     }
2409    
2410     /*
2411     * split_nuh
2412     *
2413     * inputs - pointer to original mask (modified in place)
2414     * - pointer to pointer where nick should go
2415     * - pointer to pointer where user should go
2416     * - pointer to pointer where host should go
2417     * output - NONE
2418     * side effects - mask is modified in place
2419     * If nick pointer is NULL, ignore writing to it
2420     * this allows us to use this function elsewhere.
2421     *
2422     * mask nick user host
2423     * ---------------------- ------- ------- ------
2424     * Dianora!db@db.net Dianora db db.net
2425     * Dianora Dianora * *
2426     * db.net * * db.net
2427     * OR if nick pointer is NULL
2428     * Dianora - * Dianora
2429     * Dianora! Dianora * *
2430     * Dianora!@ Dianora * *
2431     * Dianora!db Dianora db *
2432     * Dianora!@db.net Dianora * db.net
2433     * db@db.net * db db.net
2434     * !@ * * *
2435     * @ * * *
2436     * ! * * *
2437     */
2438     void
2439 michael 593 split_nuh(struct split_nuh_item *const iptr)
2440 adx 30 {
2441     char *p = NULL, *q = NULL;
2442    
2443 michael 593 if (iptr->nickptr)
2444     strlcpy(iptr->nickptr, "*", iptr->nicksize);
2445     if (iptr->userptr)
2446     strlcpy(iptr->userptr, "*", iptr->usersize);
2447     if (iptr->hostptr)
2448     strlcpy(iptr->hostptr, "*", iptr->hostsize);
2449    
2450     if ((p = strchr(iptr->nuhmask, '!')))
2451 adx 30 {
2452     *p = '\0';
2453    
2454 michael 593 if (iptr->nickptr && *iptr->nuhmask != '\0')
2455     strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2456 adx 30
2457 michael 593 if ((q = strchr(++p, '@'))) {
2458     *q++ = '\0';
2459    
2460 adx 30 if (*p != '\0')
2461 michael 593 strlcpy(iptr->userptr, p, iptr->usersize);
2462 adx 30
2463 michael 593 if (*q != '\0')
2464     strlcpy(iptr->hostptr, q, iptr->hostsize);
2465 adx 30 }
2466     else
2467     {
2468     if (*p != '\0')
2469 michael 593 strlcpy(iptr->userptr, p, iptr->usersize);
2470 adx 30 }
2471     }
2472 michael 593 else
2473 adx 30 {
2474 michael 593 /* No ! found so lets look for a user@host */
2475     if ((p = strchr(iptr->nuhmask, '@')))
2476 adx 30 {
2477 michael 593 /* if found a @ */
2478     *p++ = '\0';
2479 adx 30
2480 michael 593 if (*iptr->nuhmask != '\0')
2481     strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
2482 adx 30
2483 michael 593 if (*p != '\0')
2484     strlcpy(iptr->hostptr, p, iptr->hostsize);
2485 adx 30 }
2486 michael 593 else
2487 adx 30 {
2488 michael 593 /* no @ found */
2489     if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
2490     strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
2491 adx 30 else
2492 michael 593 strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2493 adx 30 }
2494     }
2495     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision