ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1009
Committed: Sun Sep 13 15:02:30 2009 UTC (15 years, 11 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94494 byte(s)
Log Message:
- add configure test for pcre lib and remove pcre sources from the tree

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * ircd_parser.y: Parses the ircd configuration file.
4 *
5 * Copyright (C) 2005 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 * $Id$
23 */
24
25 %{
26
27 #define YY_NO_UNPUT
28 #include <sys/types.h>
29 #include <string.h>
30
31 #include "config.h"
32 #ifdef HAVE_LIBPCRE
33 #include <pcre.h>
34 #endif
35 #include "stdinc.h"
36 #include "ircd.h"
37 #include "tools.h"
38 #include "list.h"
39 #include "s_conf.h"
40 #include "event.h"
41 #include "s_log.h"
42 #include "client.h" /* for UMODE_ALL only */
43 #include "irc_string.h"
44 #include "irc_getaddrinfo.h"
45 #include "sprintf_irc.h"
46 #include "memory.h"
47 #include "modules.h"
48 #include "s_serv.h"
49 #include "hostmask.h"
50 #include "send.h"
51 #include "listener.h"
52 #include "resv.h"
53 #include "numeric.h"
54 #include "s_user.h"
55
56 #ifdef HAVE_LIBCRYPTO
57 #include <openssl/rsa.h>
58 #include <openssl/bio.h>
59 #include <openssl/pem.h>
60 #endif
61
62 static char *class_name = NULL;
63 static struct ConfItem *yy_conf = NULL;
64 static struct AccessItem *yy_aconf = NULL;
65 static struct MatchItem *yy_match_item = NULL;
66 static struct ClassItem *yy_class = NULL;
67 static char *yy_class_name = NULL;
68
69 static dlink_list col_conf_list = { NULL, NULL, 0 };
70 static dlink_list hub_conf_list = { NULL, NULL, 0 };
71 static dlink_list leaf_conf_list = { NULL, NULL, 0 };
72 static unsigned int listener_flags = 0;
73 static unsigned int regex_ban = 0;
74 static char userbuf[IRCD_BUFSIZE];
75 static char hostbuf[IRCD_BUFSIZE];
76 static char reasonbuf[REASONLEN + 1];
77 static char gecos_name[REALLEN * 4];
78
79 extern dlink_list gdeny_items; /* XXX */
80
81 static char *resv_reason = NULL;
82 static char *listener_address = NULL;
83 static int not_atom = 0;
84
85 struct CollectItem
86 {
87 dlink_node node;
88 char *name;
89 char *user;
90 char *host;
91 char *passwd;
92 int port;
93 int flags;
94 #ifdef HAVE_LIBCRYPTO
95 char *rsa_public_key_file;
96 RSA *rsa_public_key;
97 #endif
98 };
99
100 static void
101 free_collect_item(struct CollectItem *item)
102 {
103 MyFree(item->name);
104 MyFree(item->user);
105 MyFree(item->host);
106 MyFree(item->passwd);
107 #ifdef HAVE_LIBCRYPTO
108 MyFree(item->rsa_public_key_file);
109 #endif
110 MyFree(item);
111 }
112
113 static void
114 unhook_hub_leaf_confs(void)
115 {
116 dlink_node *ptr;
117 dlink_node *next_ptr;
118 struct CollectItem *yy_hconf;
119 struct CollectItem *yy_lconf;
120
121 DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
122 {
123 yy_hconf = ptr->data;
124 dlinkDelete(&yy_hconf->node, &hub_conf_list);
125 free_collect_item(yy_hconf);
126 }
127
128 DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
129 {
130 yy_lconf = ptr->data;
131 dlinkDelete(&yy_lconf->node, &leaf_conf_list);
132 free_collect_item(yy_lconf);
133 }
134 }
135
136 %}
137
138 %union {
139 int number;
140 char *string;
141 }
142
143 %token ACCEPT_PASSWORD
144 %token ACTION
145 %token ADMIN
146 %token AFTYPE
147 %token T_ALLOW
148 %token ANTI_NICK_FLOOD
149 %token ANTI_SPAM_EXIT_MESSAGE_TIME
150 %token AUTOCONN
151 %token T_BLOCK
152 %token BURST_AWAY
153 %token BURST_TOPICWHO
154 %token BYTES KBYTES MBYTES GBYTES TBYTES
155 %token CALLER_ID_WAIT
156 %token CAN_FLOOD
157 %token CAN_IDLE
158 %token CHANNEL
159 %token CIDR_BITLEN_IPV4
160 %token CIDR_BITLEN_IPV6
161 %token CIPHER_PREFERENCE
162 %token CLASS
163 %token COMPRESSED
164 %token COMPRESSION_LEVEL
165 %token CONNECT
166 %token CONNECTFREQ
167 %token CRYPTLINK
168 %token DEFAULT_CIPHER_PREFERENCE
169 %token DEFAULT_FLOODCOUNT
170 %token DEFAULT_SPLIT_SERVER_COUNT
171 %token DEFAULT_SPLIT_USER_COUNT
172 %token DENY
173 %token DESCRIPTION
174 %token DIE
175 %token DISABLE_AUTH
176 %token DISABLE_FAKE_CHANNELS
177 %token DISABLE_HIDDEN
178 %token DISABLE_LOCAL_CHANNELS
179 %token DISABLE_REMOTE_COMMANDS
180 %token DOT_IN_IP6_ADDR
181 %token DOTS_IN_IDENT
182 %token DURATION
183 %token EGDPOOL_PATH
184 %token EMAIL
185 %token ENABLE
186 %token ENCRYPTED
187 %token EXCEED_LIMIT
188 %token EXEMPT
189 %token FAILED_OPER_NOTICE
190 %token FAKENAME
191 %token IRCD_FLAGS
192 %token FLATTEN_LINKS
193 %token FFAILED_OPERLOG
194 %token FKILLLOG
195 %token FKLINELOG
196 %token FGLINELOG
197 %token FIOERRLOG
198 %token FOPERLOG
199 %token FOPERSPYLOG
200 %token FUSERLOG
201 %token GECOS
202 %token GENERAL
203 %token GLINE
204 %token GLINES
205 %token GLINE_EXEMPT
206 %token GLINE_LOG
207 %token GLINE_TIME
208 %token GLINE_MIN_CIDR
209 %token GLINE_MIN_CIDR6
210 %token GLOBAL_KILL
211 %token IRCD_AUTH
212 %token NEED_IDENT
213 %token HAVENT_READ_CONF
214 %token HIDDEN
215 %token HIDDEN_ADMIN
216 %token HIDDEN_NAME
217 %token HIDDEN_OPER
218 %token HIDE_SERVER_IPS
219 %token HIDE_SERVERS
220 %token HIDE_SPOOF_IPS
221 %token HOST
222 %token HUB
223 %token HUB_MASK
224 %token IDLETIME
225 %token IGNORE_BOGUS_TS
226 %token INVISIBLE_ON_CONNECT
227 %token IP
228 %token KILL
229 %token KILL_CHASE_TIME_LIMIT
230 %token KLINE
231 %token KLINE_EXEMPT
232 %token KLINE_REASON
233 %token KLINE_WITH_REASON
234 %token KNOCK_DELAY
235 %token KNOCK_DELAY_CHANNEL
236 %token LEAF_MASK
237 %token LINKS_DELAY
238 %token LISTEN
239 %token T_LOG
240 %token LOGGING
241 %token LOG_LEVEL
242 %token MAX_ACCEPT
243 %token MAX_BANS
244 %token MAX_CHANS_PER_USER
245 %token MAX_GLOBAL
246 %token MAX_IDENT
247 %token MAX_LOCAL
248 %token MAX_NICK_CHANGES
249 %token MAX_NICK_TIME
250 %token MAX_NUMBER
251 %token MAX_TARGETS
252 %token MAX_WATCH
253 %token MESSAGE_LOCALE
254 %token MIN_NONWILDCARD
255 %token MIN_NONWILDCARD_SIMPLE
256 %token MODULE
257 %token MODULES
258 %token NAME
259 %token NEED_PASSWORD
260 %token NETWORK_DESC
261 %token NETWORK_NAME
262 %token NICK
263 %token NICK_CHANGES
264 %token NO_CREATE_ON_SPLIT
265 %token NO_JOIN_ON_SPLIT
266 %token NO_OPER_FLOOD
267 %token NO_TILDE
268 %token NOT
269 %token NUMBER
270 %token NUMBER_PER_IDENT
271 %token NUMBER_PER_CIDR
272 %token NUMBER_PER_IP
273 %token NUMBER_PER_IP_GLOBAL
274 %token OPERATOR
275 %token OPERS_BYPASS_CALLERID
276 %token OPER_LOG
277 %token OPER_ONLY_UMODES
278 %token OPER_PASS_RESV
279 %token OPER_SPY_T
280 %token OPER_UMODES
281 %token JOIN_FLOOD_COUNT
282 %token JOIN_FLOOD_TIME
283 %token PACE_WAIT
284 %token PACE_WAIT_SIMPLE
285 %token PASSWORD
286 %token PATH
287 %token PING_COOKIE
288 %token PING_TIME
289 %token PING_WARNING
290 %token PORT
291 %token QSTRING
292 %token QUIET_ON_BAN
293 %token REASON
294 %token REDIRPORT
295 %token REDIRSERV
296 %token REGEX_T
297 %token REHASH
298 %token TREJECT_HOLD_TIME
299 %token REMOTE
300 %token REMOTEBAN
301 %token RESTRICT_CHANNELS
302 %token RESTRICTED
303 %token RSA_PRIVATE_KEY_FILE
304 %token RSA_PUBLIC_KEY_FILE
305 %token SSL_CERTIFICATE_FILE
306 %token T_SSL_CONNECTION_METHOD
307 %token T_SSLV3
308 %token T_TLSV1
309 %token RESV
310 %token RESV_EXEMPT
311 %token SECONDS MINUTES HOURS DAYS WEEKS
312 %token SENDQ
313 %token SEND_PASSWORD
314 %token SERVERHIDE
315 %token SERVERINFO
316 %token SERVLINK_PATH
317 %token IRCD_SID
318 %token TKLINE_EXPIRE_NOTICES
319 %token T_SHARED
320 %token T_CLUSTER
321 %token TYPE
322 %token SHORT_MOTD
323 %token SILENT
324 %token SPOOF
325 %token SPOOF_NOTICE
326 %token STATS_E_DISABLED
327 %token STATS_I_OPER_ONLY
328 %token STATS_K_OPER_ONLY
329 %token STATS_O_OPER_ONLY
330 %token STATS_P_OPER_ONLY
331 %token TBOOL
332 %token TMASKED
333 %token T_REJECT
334 %token TS_MAX_DELTA
335 %token TS_WARN_DELTA
336 %token TWODOTS
337 %token T_ALL
338 %token T_BOTS
339 %token T_SOFTCALLERID
340 %token T_CALLERID
341 %token T_CCONN
342 %token T_CCONN_FULL
343 %token T_CLIENT_FLOOD
344 %token T_DEAF
345 %token T_DEBUG
346 %token T_DRONE
347 %token T_EXTERNAL
348 %token T_FULL
349 %token T_INVISIBLE
350 %token T_IPV4
351 %token T_IPV6
352 %token T_LOCOPS
353 %token T_LOGPATH
354 %token T_L_CRIT
355 %token T_L_DEBUG
356 %token T_L_ERROR
357 %token T_L_INFO
358 %token T_L_NOTICE
359 %token T_L_TRACE
360 %token T_L_WARN
361 %token T_MAX_CLIENTS
362 %token T_NCHANGE
363 %token T_OPERWALL
364 %token T_REJ
365 %token T_SERVER
366 %token T_SERVNOTICE
367 %token T_SKILL
368 %token T_SPY
369 %token T_SSL
370 %token T_UMODES
371 %token T_UNAUTH
372 %token T_UNRESV
373 %token T_UNXLINE
374 %token T_WALLOP
375 %token THROTTLE_TIME
376 %token TOPICBURST
377 %token TRUE_NO_OPER_FLOOD
378 %token TKLINE
379 %token TXLINE
380 %token TRESV
381 %token UNKLINE
382 %token USER
383 %token USE_EGD
384 %token USE_EXCEPT
385 %token USE_INVEX
386 %token USE_KNOCK
387 %token USE_LOGGING
388 %token USE_WHOIS_ACTUALLY
389 %token VHOST
390 %token VHOST6
391 %token XLINE
392 %token WARN
393 %token WARN_NO_NLINE
394
395 %type <string> QSTRING
396 %type <number> NUMBER
397 %type <number> timespec
398 %type <number> timespec_
399 %type <number> sizespec
400 %type <number> sizespec_
401
402 %%
403 conf:
404 | conf conf_item
405 ;
406
407 conf_item: admin_entry
408 | logging_entry
409 | oper_entry
410 | channel_entry
411 | class_entry
412 | listen_entry
413 | auth_entry
414 | serverinfo_entry
415 | serverhide_entry
416 | resv_entry
417 | shared_entry
418 | cluster_entry
419 | connect_entry
420 | kill_entry
421 | deny_entry
422 | exempt_entry
423 | general_entry
424 | gline_entry
425 | gecos_entry
426 | modules_entry
427 | error ';'
428 | error '}'
429 ;
430
431
432 timespec_: { $$ = 0; } | timespec;
433 timespec: NUMBER timespec_
434 {
435 $$ = $1 + $2;
436 }
437 | NUMBER SECONDS timespec_
438 {
439 $$ = $1 + $3;
440 }
441 | NUMBER MINUTES timespec_
442 {
443 $$ = $1 * 60 + $3;
444 }
445 | NUMBER HOURS timespec_
446 {
447 $$ = $1 * 60 * 60 + $3;
448 }
449 | NUMBER DAYS timespec_
450 {
451 $$ = $1 * 60 * 60 * 24 + $3;
452 }
453 | NUMBER WEEKS timespec_
454 {
455 $$ = $1 * 60 * 60 * 24 * 7 + $3;
456 }
457 ;
458
459 sizespec_: { $$ = 0; } | sizespec;
460 sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
461 | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
462 | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
463 | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
464 ;
465
466
467 /***************************************************************************
468 * section modules
469 ***************************************************************************/
470 modules_entry: MODULES
471 '{' modules_items '}' ';';
472
473 modules_items: modules_items modules_item | modules_item;
474 modules_item: modules_module | modules_path | error ';' ;
475
476 modules_module: MODULE '=' QSTRING ';'
477 {
478 #ifndef STATIC_MODULES /* NOOP in the static case */
479 if (conf_parser_ctx.pass == 2)
480 add_conf_module(libio_basename(yylval.string));
481 #endif
482 };
483
484 modules_path: PATH '=' QSTRING ';'
485 {
486 #ifndef STATIC_MODULES
487 if (conf_parser_ctx.pass == 2)
488 mod_add_path(yylval.string);
489 #endif
490 };
491
492
493 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
494
495 serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
496 serverinfo_item: serverinfo_name | serverinfo_vhost |
497 serverinfo_hub | serverinfo_description |
498 serverinfo_network_name | serverinfo_network_desc |
499 serverinfo_max_clients |
500 serverinfo_rsa_private_key_file | serverinfo_vhost6 |
501 serverinfo_sid | serverinfo_ssl_certificate_file |
502 serverinfo_ssl_connection_method |
503 error ';' ;
504
505
506 serverinfo_ssl_connection_method: T_SSL_CONNECTION_METHOD
507 {
508 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
509 ServerInfo.tls_version = 0;
510 } '=' method_types ';'
511 {
512 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
513 {
514 if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_SSLV3))
515 SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
516 if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_TLSV1))
517 SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
518 }
519 };
520
521 method_types: method_types ',' method_type_item | method_type_item;
522 method_type_item: T_SSLV3
523 {
524 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
525 ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_SSLV3;
526 } | T_TLSV1
527 {
528 if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
529 ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_TLSV1;
530 };
531
532 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
533 {
534 #ifdef HAVE_LIBCRYPTO
535 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
536 {
537 if (!ServerInfo.rsa_private_key_file)
538 {
539 yyerror("No rsa_private_key_file specified, SSL disabled");
540 break;
541 }
542
543 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
544 SSL_FILETYPE_PEM) <= 0)
545 {
546 yyerror(ERR_lib_error_string(ERR_get_error()));
547 break;
548 }
549
550 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
551 SSL_FILETYPE_PEM) <= 0)
552 {
553 yyerror(ERR_lib_error_string(ERR_get_error()));
554 break;
555 }
556
557 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx))
558 {
559 yyerror(ERR_lib_error_string(ERR_get_error()));
560 break;
561 }
562 }
563 #endif
564 };
565
566 serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
567 {
568 #ifdef HAVE_LIBCRYPTO
569 if (conf_parser_ctx.pass == 1)
570 {
571 BIO *file;
572
573 if (ServerInfo.rsa_private_key)
574 {
575 RSA_free(ServerInfo.rsa_private_key);
576 ServerInfo.rsa_private_key = NULL;
577 }
578
579 if (ServerInfo.rsa_private_key_file)
580 {
581 MyFree(ServerInfo.rsa_private_key_file);
582 ServerInfo.rsa_private_key_file = NULL;
583 }
584
585 DupString(ServerInfo.rsa_private_key_file, yylval.string);
586
587 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
588 {
589 yyerror("File open failed, ignoring");
590 break;
591 }
592
593 ServerInfo.rsa_private_key = (RSA *)PEM_read_bio_RSAPrivateKey(file, NULL,
594 0, NULL);
595
596 BIO_set_close(file, BIO_CLOSE);
597 BIO_free(file);
598
599 if (ServerInfo.rsa_private_key == NULL)
600 {
601 yyerror("Couldn't extract key, ignoring");
602 break;
603 }
604
605 if (!RSA_check_key(ServerInfo.rsa_private_key))
606 {
607 RSA_free(ServerInfo.rsa_private_key);
608 ServerInfo.rsa_private_key = NULL;
609
610 yyerror("Invalid key, ignoring");
611 break;
612 }
613
614 /* require 2048 bit (256 byte) key */
615 if (RSA_size(ServerInfo.rsa_private_key) != 256)
616 {
617 RSA_free(ServerInfo.rsa_private_key);
618 ServerInfo.rsa_private_key = NULL;
619
620 yyerror("Not a 2048 bit key, ignoring");
621 }
622 }
623 #endif
624 };
625
626 serverinfo_name: NAME '=' QSTRING ';'
627 {
628 /* this isn't rehashable */
629 if (conf_parser_ctx.pass == 2)
630 {
631 if (ServerInfo.name == NULL)
632 {
633 /* the ircd will exit() in main() if we dont set one */
634 if (strlen(yylval.string) <= HOSTLEN)
635 DupString(ServerInfo.name, yylval.string);
636 }
637 }
638 };
639
640 serverinfo_sid: IRCD_SID '=' QSTRING ';'
641 {
642 /* this isn't rehashable */
643 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
644 {
645 if (valid_sid(yylval.string))
646 DupString(ServerInfo.sid, yylval.string);
647 else
648 {
649 ilog(L_ERROR, "Ignoring config file entry SID -- invalid SID. Aborting.");
650 exit(0);
651 }
652 }
653 };
654
655 serverinfo_description: DESCRIPTION '=' QSTRING ';'
656 {
657 if (conf_parser_ctx.pass == 2)
658 {
659 MyFree(ServerInfo.description);
660 DupString(ServerInfo.description,yylval.string);
661 }
662 };
663
664 serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
665 {
666 if (conf_parser_ctx.pass == 2)
667 {
668 char *p;
669
670 if ((p = strchr(yylval.string, ' ')) != NULL)
671 p = '\0';
672
673 MyFree(ServerInfo.network_name);
674 DupString(ServerInfo.network_name, yylval.string);
675 }
676 };
677
678 serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
679 {
680 if (conf_parser_ctx.pass == 2)
681 {
682 MyFree(ServerInfo.network_desc);
683 DupString(ServerInfo.network_desc, yylval.string);
684 }
685 };
686
687 serverinfo_vhost: VHOST '=' QSTRING ';'
688 {
689 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
690 {
691 struct addrinfo hints, *res;
692
693 memset(&hints, 0, sizeof(hints));
694
695 hints.ai_family = AF_UNSPEC;
696 hints.ai_socktype = SOCK_STREAM;
697 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
698
699 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
700 ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
701 else
702 {
703 assert(res != NULL);
704
705 memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
706 ServerInfo.ip.ss.ss_family = res->ai_family;
707 ServerInfo.ip.ss_len = res->ai_addrlen;
708 irc_freeaddrinfo(res);
709
710 ServerInfo.specific_ipv4_vhost = 1;
711 }
712 }
713 };
714
715 serverinfo_vhost6: VHOST6 '=' QSTRING ';'
716 {
717 #ifdef IPV6
718 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
719 {
720 struct addrinfo hints, *res;
721
722 memset(&hints, 0, sizeof(hints));
723
724 hints.ai_family = AF_UNSPEC;
725 hints.ai_socktype = SOCK_STREAM;
726 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
727
728 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
729 ilog(L_ERROR, "Invalid netmask for server vhost6(%s)", yylval.string);
730 else
731 {
732 assert(res != NULL);
733
734 memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
735 ServerInfo.ip6.ss.ss_family = res->ai_family;
736 ServerInfo.ip6.ss_len = res->ai_addrlen;
737 irc_freeaddrinfo(res);
738
739 ServerInfo.specific_ipv6_vhost = 1;
740 }
741 }
742 #endif
743 };
744
745 serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
746 {
747 if (conf_parser_ctx.pass == 2)
748 {
749 recalc_fdlimit(NULL);
750
751 if ($3 < MAXCLIENTS_MIN)
752 {
753 char buf[IRCD_BUFSIZE];
754 ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
755 yyerror(buf);
756 }
757 else if ($3 > MAXCLIENTS_MAX)
758 {
759 char buf[IRCD_BUFSIZE];
760 ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
761 yyerror(buf);
762 }
763 else
764 ServerInfo.max_clients = $3;
765 }
766 };
767
768 serverinfo_hub: HUB '=' TBOOL ';'
769 {
770 if (conf_parser_ctx.pass == 2)
771 {
772 if (yylval.number)
773 {
774 ServerInfo.hub = 1;
775 delete_capability("HUB");
776 add_capability("HUB", CAP_HUB, 1);
777 }
778 else if (ServerInfo.hub)
779 {
780
781 ServerInfo.hub = 0;
782 delete_capability("HUB");
783 }
784 }
785 };
786
787 /***************************************************************************
788 * admin section
789 ***************************************************************************/
790 admin_entry: ADMIN '{' admin_items '}' ';' ;
791
792 admin_items: admin_items admin_item | admin_item;
793 admin_item: admin_name | admin_description |
794 admin_email | error ';' ;
795
796 admin_name: NAME '=' QSTRING ';'
797 {
798 if (conf_parser_ctx.pass == 2)
799 {
800 MyFree(AdminInfo.name);
801 DupString(AdminInfo.name, yylval.string);
802 }
803 };
804
805 admin_email: EMAIL '=' QSTRING ';'
806 {
807 if (conf_parser_ctx.pass == 2)
808 {
809 MyFree(AdminInfo.email);
810 DupString(AdminInfo.email, yylval.string);
811 }
812 };
813
814 admin_description: DESCRIPTION '=' QSTRING ';'
815 {
816 if (conf_parser_ctx.pass == 2)
817 {
818 MyFree(AdminInfo.description);
819 DupString(AdminInfo.description, yylval.string);
820 }
821 };
822
823 /***************************************************************************
824 * section logging
825 ***************************************************************************/
826 /* XXX */
827 logging_entry: LOGGING '{' logging_items '}' ';' ;
828
829 logging_items: logging_items logging_item |
830 logging_item ;
831
832 logging_item: logging_path | logging_oper_log |
833 logging_log_level |
834 logging_use_logging | logging_fuserlog |
835 logging_foperlog | logging_fglinelog |
836 logging_fklinelog | logging_killlog |
837 logging_foperspylog | logging_ioerrlog |
838 logging_ffailed_operlog |
839 error ';' ;
840
841 logging_path: T_LOGPATH '=' QSTRING ';'
842 {
843 };
844
845 logging_oper_log: OPER_LOG '=' QSTRING ';'
846 {
847 };
848
849 logging_fuserlog: FUSERLOG '=' QSTRING ';'
850 {
851 if (conf_parser_ctx.pass == 2)
852 strlcpy(ConfigLoggingEntry.userlog, yylval.string,
853 sizeof(ConfigLoggingEntry.userlog));
854 };
855
856 logging_ffailed_operlog: FFAILED_OPERLOG '=' QSTRING ';'
857 {
858 if (conf_parser_ctx.pass == 2)
859 strlcpy(ConfigLoggingEntry.failed_operlog, yylval.string,
860 sizeof(ConfigLoggingEntry.failed_operlog));
861 };
862
863 logging_foperlog: FOPERLOG '=' QSTRING ';'
864 {
865 if (conf_parser_ctx.pass == 2)
866 strlcpy(ConfigLoggingEntry.operlog, yylval.string,
867 sizeof(ConfigLoggingEntry.operlog));
868 };
869
870 logging_foperspylog: FOPERSPYLOG '=' QSTRING ';'
871 {
872 if (conf_parser_ctx.pass == 2)
873 strlcpy(ConfigLoggingEntry.operspylog, yylval.string,
874 sizeof(ConfigLoggingEntry.operspylog));
875 };
876
877 logging_fglinelog: FGLINELOG '=' QSTRING ';'
878 {
879 if (conf_parser_ctx.pass == 2)
880 strlcpy(ConfigLoggingEntry.glinelog, yylval.string,
881 sizeof(ConfigLoggingEntry.glinelog));
882 };
883
884 logging_fklinelog: FKLINELOG '=' QSTRING ';'
885 {
886 if (conf_parser_ctx.pass == 2)
887 strlcpy(ConfigLoggingEntry.klinelog, yylval.string,
888 sizeof(ConfigLoggingEntry.klinelog));
889 };
890
891 logging_ioerrlog: FIOERRLOG '=' QSTRING ';'
892 {
893 if (conf_parser_ctx.pass == 2)
894 strlcpy(ConfigLoggingEntry.ioerrlog, yylval.string,
895 sizeof(ConfigLoggingEntry.ioerrlog));
896 };
897
898 logging_killlog: FKILLLOG '=' QSTRING ';'
899 {
900 if (conf_parser_ctx.pass == 2)
901 strlcpy(ConfigLoggingEntry.killlog, yylval.string,
902 sizeof(ConfigLoggingEntry.killlog));
903 };
904
905 logging_log_level: LOG_LEVEL '=' T_L_CRIT ';'
906 {
907 if (conf_parser_ctx.pass == 2)
908 set_log_level(L_CRIT);
909 } | LOG_LEVEL '=' T_L_ERROR ';'
910 {
911 if (conf_parser_ctx.pass == 2)
912 set_log_level(L_ERROR);
913 } | LOG_LEVEL '=' T_L_WARN ';'
914 {
915 if (conf_parser_ctx.pass == 2)
916 set_log_level(L_WARN);
917 } | LOG_LEVEL '=' T_L_NOTICE ';'
918 {
919 if (conf_parser_ctx.pass == 2)
920 set_log_level(L_NOTICE);
921 } | LOG_LEVEL '=' T_L_TRACE ';'
922 {
923 if (conf_parser_ctx.pass == 2)
924 set_log_level(L_TRACE);
925 } | LOG_LEVEL '=' T_L_INFO ';'
926 {
927 if (conf_parser_ctx.pass == 2)
928 set_log_level(L_INFO);
929 } | LOG_LEVEL '=' T_L_DEBUG ';'
930 {
931 if (conf_parser_ctx.pass == 2)
932 set_log_level(L_DEBUG);
933 };
934
935 logging_use_logging: USE_LOGGING '=' TBOOL ';'
936 {
937 if (conf_parser_ctx.pass == 2)
938 ConfigLoggingEntry.use_logging = yylval.number;
939 };
940
941 /***************************************************************************
942 * section oper
943 ***************************************************************************/
944 oper_entry: OPERATOR
945 {
946 if (conf_parser_ctx.pass == 2)
947 {
948 yy_conf = make_conf_item(OPER_TYPE);
949 yy_aconf = map_to_conf(yy_conf);
950 SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */
951 }
952 else
953 {
954 MyFree(class_name);
955 class_name = NULL;
956 }
957 } oper_name_b '{' oper_items '}' ';'
958 {
959 if (conf_parser_ctx.pass == 2)
960 {
961 struct CollectItem *yy_tmp;
962 dlink_node *ptr;
963 dlink_node *next_ptr;
964
965 conf_add_class_to_conf(yy_conf, class_name);
966
967 /* Now, make sure there is a copy of the "base" given oper
968 * block in each of the collected copies
969 */
970
971 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
972 {
973 struct AccessItem *new_aconf;
974 struct ConfItem *new_conf;
975 yy_tmp = ptr->data;
976
977 new_conf = make_conf_item(OPER_TYPE);
978 new_aconf = (struct AccessItem *)map_to_conf(new_conf);
979
980 new_aconf->flags = yy_aconf->flags;
981
982 if (yy_conf->name != NULL)
983 DupString(new_conf->name, yy_conf->name);
984 if (yy_tmp->user != NULL)
985 DupString(new_aconf->user, yy_tmp->user);
986 else
987 DupString(new_aconf->user, "*");
988 if (yy_tmp->host != NULL)
989 DupString(new_aconf->host, yy_tmp->host);
990 else
991 DupString(new_aconf->host, "*");
992 conf_add_class_to_conf(new_conf, class_name);
993 if (yy_aconf->passwd != NULL)
994 DupString(new_aconf->passwd, yy_aconf->passwd);
995
996 new_aconf->port = yy_aconf->port;
997 #ifdef HAVE_LIBCRYPTO
998 if (yy_aconf->rsa_public_key_file != NULL)
999 {
1000 BIO *file;
1001
1002 DupString(new_aconf->rsa_public_key_file,
1003 yy_aconf->rsa_public_key_file);
1004
1005 file = BIO_new_file(yy_aconf->rsa_public_key_file, "r");
1006 new_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file,
1007 NULL, 0, NULL);
1008 BIO_set_close(file, BIO_CLOSE);
1009 BIO_free(file);
1010 }
1011 #endif
1012
1013 #ifdef HAVE_LIBCRYPTO
1014 if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key)
1015 && yy_tmp->host)
1016 #else
1017 if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host)
1018 #endif
1019 {
1020 conf_add_class_to_conf(new_conf, class_name);
1021 if (yy_tmp->name != NULL)
1022 DupString(new_conf->name, yy_tmp->name);
1023 }
1024
1025 dlinkDelete(&yy_tmp->node, &col_conf_list);
1026 free_collect_item(yy_tmp);
1027 }
1028
1029 yy_conf = NULL;
1030 yy_aconf = NULL;
1031
1032
1033 MyFree(class_name);
1034 class_name = NULL;
1035 }
1036 };
1037
1038 oper_name_b: | oper_name_t;
1039 oper_items: oper_items oper_item | oper_item;
1040 oper_item: oper_name | oper_user | oper_password | oper_hidden_admin |
1041 oper_hidden_oper | oper_umodes |
1042 oper_class | oper_global_kill | oper_remote |
1043 oper_kline | oper_xline | oper_unkline |
1044 oper_gline | oper_nick_changes | oper_remoteban |
1045 oper_die | oper_rehash | oper_admin | oper_operwall |
1046 oper_encrypted | oper_rsa_public_key_file |
1047 oper_flags | error ';' ;
1048
1049 oper_name: NAME '=' QSTRING ';'
1050 {
1051 if (conf_parser_ctx.pass == 2)
1052 {
1053 if (strlen(yylval.string) > OPERNICKLEN)
1054 yylval.string[OPERNICKLEN] = '\0';
1055
1056 MyFree(yy_conf->name);
1057 DupString(yy_conf->name, yylval.string);
1058 }
1059 };
1060
1061 oper_name_t: QSTRING
1062 {
1063 if (conf_parser_ctx.pass == 2)
1064 {
1065 if (strlen(yylval.string) > OPERNICKLEN)
1066 yylval.string[OPERNICKLEN] = '\0';
1067
1068 MyFree(yy_conf->name);
1069 DupString(yy_conf->name, yylval.string);
1070 }
1071 };
1072
1073 oper_user: USER '=' QSTRING ';'
1074 {
1075 if (conf_parser_ctx.pass == 2)
1076 {
1077 struct split_nuh_item nuh;
1078
1079 nuh.nuhmask = yylval.string;
1080 nuh.nickptr = NULL;
1081 nuh.userptr = userbuf;
1082 nuh.hostptr = hostbuf;
1083
1084 nuh.nicksize = 0;
1085 nuh.usersize = sizeof(userbuf);
1086 nuh.hostsize = sizeof(hostbuf);
1087
1088 split_nuh(&nuh);
1089
1090 if (yy_aconf->user == NULL)
1091 {
1092 DupString(yy_aconf->user, userbuf);
1093 DupString(yy_aconf->host, hostbuf);
1094 }
1095 else
1096 {
1097 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
1098
1099 DupString(yy_tmp->user, userbuf);
1100 DupString(yy_tmp->host, hostbuf);
1101
1102 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1103 }
1104 }
1105 };
1106
1107 oper_password: PASSWORD '=' QSTRING ';'
1108 {
1109 if (conf_parser_ctx.pass == 2)
1110 {
1111 if (yy_aconf->passwd != NULL)
1112 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1113
1114 MyFree(yy_aconf->passwd);
1115 DupString(yy_aconf->passwd, yylval.string);
1116 }
1117 };
1118
1119 oper_encrypted: ENCRYPTED '=' TBOOL ';'
1120 {
1121 if (conf_parser_ctx.pass == 2)
1122 {
1123 if (yylval.number)
1124 SetConfEncrypted(yy_aconf);
1125 else
1126 ClearConfEncrypted(yy_aconf);
1127 }
1128 };
1129
1130 oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1131 {
1132 #ifdef HAVE_LIBCRYPTO
1133 if (conf_parser_ctx.pass == 2)
1134 {
1135 BIO *file;
1136
1137 if (yy_aconf->rsa_public_key != NULL)
1138 {
1139 RSA_free(yy_aconf->rsa_public_key);
1140 yy_aconf->rsa_public_key = NULL;
1141 }
1142
1143 if (yy_aconf->rsa_public_key_file != NULL)
1144 {
1145 MyFree(yy_aconf->rsa_public_key_file);
1146 yy_aconf->rsa_public_key_file = NULL;
1147 }
1148
1149 DupString(yy_aconf->rsa_public_key_file, yylval.string);
1150 file = BIO_new_file(yylval.string, "r");
1151
1152 if (file == NULL)
1153 {
1154 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
1155 break;
1156 }
1157
1158 yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
1159
1160 if (yy_aconf->rsa_public_key == NULL)
1161 {
1162 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1163 break;
1164 }
1165
1166 BIO_set_close(file, BIO_CLOSE);
1167 BIO_free(file);
1168 }
1169 #endif /* HAVE_LIBCRYPTO */
1170 };
1171
1172 oper_class: CLASS '=' QSTRING ';'
1173 {
1174 if (conf_parser_ctx.pass == 2)
1175 {
1176 MyFree(class_name);
1177 DupString(class_name, yylval.string);
1178 }
1179 };
1180
1181 oper_umodes: T_UMODES
1182 {
1183 if (conf_parser_ctx.pass == 2)
1184 yy_aconf->modes = 0;
1185 } '=' oper_umodes_items ';' ;
1186
1187 oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1188 oper_umodes_item: T_BOTS
1189 {
1190 if (conf_parser_ctx.pass == 2)
1191 yy_aconf->modes |= UMODE_BOTS;
1192 } | T_CCONN
1193 {
1194 if (conf_parser_ctx.pass == 2)
1195 yy_aconf->modes |= UMODE_CCONN;
1196 } | T_CCONN_FULL
1197 {
1198 if (conf_parser_ctx.pass == 2)
1199 yy_aconf->modes |= UMODE_CCONN_FULL;
1200 } | T_DEAF
1201 {
1202 if (conf_parser_ctx.pass == 2)
1203 yy_aconf->modes |= UMODE_DEAF;
1204 } | T_DEBUG
1205 {
1206 if (conf_parser_ctx.pass == 2)
1207 yy_aconf->modes |= UMODE_DEBUG;
1208 } | T_FULL
1209 {
1210 if (conf_parser_ctx.pass == 2)
1211 yy_aconf->modes |= UMODE_FULL;
1212 } | T_SKILL
1213 {
1214 if (conf_parser_ctx.pass == 2)
1215 yy_aconf->modes |= UMODE_SKILL;
1216 } | T_NCHANGE
1217 {
1218 if (conf_parser_ctx.pass == 2)
1219 yy_aconf->modes |= UMODE_NCHANGE;
1220 } | T_REJ
1221 {
1222 if (conf_parser_ctx.pass == 2)
1223 yy_aconf->modes |= UMODE_REJ;
1224 } | T_UNAUTH
1225 {
1226 if (conf_parser_ctx.pass == 2)
1227 yy_aconf->modes |= UMODE_UNAUTH;
1228 } | T_SPY
1229 {
1230 if (conf_parser_ctx.pass == 2)
1231 yy_aconf->modes |= UMODE_SPY;
1232 } | T_EXTERNAL
1233 {
1234 if (conf_parser_ctx.pass == 2)
1235 yy_aconf->modes |= UMODE_EXTERNAL;
1236 } | T_OPERWALL
1237 {
1238 if (conf_parser_ctx.pass == 2)
1239 yy_aconf->modes |= UMODE_OPERWALL;
1240 } | T_SERVNOTICE
1241 {
1242 if (conf_parser_ctx.pass == 2)
1243 yy_aconf->modes |= UMODE_SERVNOTICE;
1244 } | T_INVISIBLE
1245 {
1246 if (conf_parser_ctx.pass == 2)
1247 yy_aconf->modes |= UMODE_INVISIBLE;
1248 } | T_WALLOP
1249 {
1250 if (conf_parser_ctx.pass == 2)
1251 yy_aconf->modes |= UMODE_WALLOP;
1252 } | T_SOFTCALLERID
1253 {
1254 if (conf_parser_ctx.pass == 2)
1255 yy_aconf->modes |= UMODE_SOFTCALLERID;
1256 } | T_CALLERID
1257 {
1258 if (conf_parser_ctx.pass == 2)
1259 yy_aconf->modes |= UMODE_CALLERID;
1260 } | T_LOCOPS
1261 {
1262 if (conf_parser_ctx.pass == 2)
1263 yy_aconf->modes |= UMODE_LOCOPS;
1264 };
1265
1266 oper_global_kill: GLOBAL_KILL '=' TBOOL ';'
1267 {
1268 if (conf_parser_ctx.pass == 2)
1269 {
1270 if (yylval.number)
1271 yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1272 else
1273 yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1274 }
1275 };
1276
1277 oper_remote: REMOTE '=' TBOOL ';'
1278 {
1279 if (conf_parser_ctx.pass == 2)
1280 {
1281 if (yylval.number)
1282 yy_aconf->port |= OPER_FLAG_REMOTE;
1283 else
1284 yy_aconf->port &= ~OPER_FLAG_REMOTE;
1285 }
1286 };
1287
1288 oper_remoteban: REMOTEBAN '=' TBOOL ';'
1289 {
1290 if (conf_parser_ctx.pass == 2)
1291 {
1292 if (yylval.number)
1293 yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1294 else
1295 yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1296 }
1297 };
1298
1299 oper_kline: KLINE '=' TBOOL ';'
1300 {
1301 if (conf_parser_ctx.pass == 2)
1302 {
1303 if (yylval.number)
1304 yy_aconf->port |= OPER_FLAG_K;
1305 else
1306 yy_aconf->port &= ~OPER_FLAG_K;
1307 }
1308 };
1309
1310 oper_xline: XLINE '=' TBOOL ';'
1311 {
1312 if (conf_parser_ctx.pass == 2)
1313 {
1314 if (yylval.number)
1315 yy_aconf->port |= OPER_FLAG_X;
1316 else
1317 yy_aconf->port &= ~OPER_FLAG_X;
1318 }
1319 };
1320
1321 oper_unkline: UNKLINE '=' TBOOL ';'
1322 {
1323 if (conf_parser_ctx.pass == 2)
1324 {
1325 if (yylval.number)
1326 yy_aconf->port |= OPER_FLAG_UNKLINE;
1327 else
1328 yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1329 }
1330 };
1331
1332 oper_gline: GLINE '=' TBOOL ';'
1333 {
1334 if (conf_parser_ctx.pass == 2)
1335 {
1336 if (yylval.number)
1337 yy_aconf->port |= OPER_FLAG_GLINE;
1338 else
1339 yy_aconf->port &= ~OPER_FLAG_GLINE;
1340 }
1341 };
1342
1343 oper_nick_changes: NICK_CHANGES '=' TBOOL ';'
1344 {
1345 if (conf_parser_ctx.pass == 2)
1346 {
1347 if (yylval.number)
1348 yy_aconf->port |= OPER_FLAG_N;
1349 else
1350 yy_aconf->port &= ~OPER_FLAG_N;
1351 }
1352 };
1353
1354 oper_die: DIE '=' TBOOL ';'
1355 {
1356 if (conf_parser_ctx.pass == 2)
1357 {
1358 if (yylval.number)
1359 yy_aconf->port |= OPER_FLAG_DIE;
1360 else
1361 yy_aconf->port &= ~OPER_FLAG_DIE;
1362 }
1363 };
1364
1365 oper_rehash: REHASH '=' TBOOL ';'
1366 {
1367 if (conf_parser_ctx.pass == 2)
1368 {
1369 if (yylval.number)
1370 yy_aconf->port |= OPER_FLAG_REHASH;
1371 else
1372 yy_aconf->port &= ~OPER_FLAG_REHASH;
1373 }
1374 };
1375
1376 oper_admin: ADMIN '=' TBOOL ';'
1377 {
1378 if (conf_parser_ctx.pass == 2)
1379 {
1380 if (yylval.number)
1381 yy_aconf->port |= OPER_FLAG_ADMIN;
1382 else
1383 yy_aconf->port &= ~OPER_FLAG_ADMIN;
1384 }
1385 };
1386
1387 oper_hidden_admin: HIDDEN_ADMIN '=' TBOOL ';'
1388 {
1389 if (conf_parser_ctx.pass == 2)
1390 {
1391 if (yylval.number)
1392 yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1393 else
1394 yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1395 }
1396 };
1397
1398 oper_hidden_oper: HIDDEN_OPER '=' TBOOL ';'
1399 {
1400 if (conf_parser_ctx.pass == 2)
1401 {
1402 if (yylval.number)
1403 yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1404 else
1405 yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1406 }
1407 };
1408
1409 oper_operwall: T_OPERWALL '=' TBOOL ';'
1410 {
1411 if (conf_parser_ctx.pass == 2)
1412 {
1413 if (yylval.number)
1414 yy_aconf->port |= OPER_FLAG_OPERWALL;
1415 else
1416 yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1417 }
1418 };
1419
1420 oper_flags: IRCD_FLAGS
1421 {
1422 } '=' oper_flags_items ';';
1423
1424 oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1425 oper_flags_item: NOT { not_atom = 1; } oper_flags_item_atom
1426 | { not_atom = 0; } oper_flags_item_atom;
1427
1428 oper_flags_item_atom: GLOBAL_KILL
1429 {
1430 if (conf_parser_ctx.pass == 2)
1431 {
1432 if (not_atom)yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1433 else yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1434 }
1435 } | REMOTE
1436 {
1437 if (conf_parser_ctx.pass == 2)
1438 {
1439 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTE;
1440 else yy_aconf->port |= OPER_FLAG_REMOTE;
1441 }
1442 } | KLINE
1443 {
1444 if (conf_parser_ctx.pass == 2)
1445 {
1446 if (not_atom) yy_aconf->port &= ~OPER_FLAG_K;
1447 else yy_aconf->port |= OPER_FLAG_K;
1448 }
1449 } | UNKLINE
1450 {
1451 if (conf_parser_ctx.pass == 2)
1452 {
1453 if (not_atom) yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1454 else yy_aconf->port |= OPER_FLAG_UNKLINE;
1455 }
1456 } | XLINE
1457 {
1458 if (conf_parser_ctx.pass == 2)
1459 {
1460 if (not_atom) yy_aconf->port &= ~OPER_FLAG_X;
1461 else yy_aconf->port |= OPER_FLAG_X;
1462 }
1463 } | GLINE
1464 {
1465 if (conf_parser_ctx.pass == 2)
1466 {
1467 if (not_atom) yy_aconf->port &= ~OPER_FLAG_GLINE;
1468 else yy_aconf->port |= OPER_FLAG_GLINE;
1469 }
1470 } | DIE
1471 {
1472 if (conf_parser_ctx.pass == 2)
1473 {
1474 if (not_atom) yy_aconf->port &= ~OPER_FLAG_DIE;
1475 else yy_aconf->port |= OPER_FLAG_DIE;
1476 }
1477 } | REHASH
1478 {
1479 if (conf_parser_ctx.pass == 2)
1480 {
1481 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REHASH;
1482 else yy_aconf->port |= OPER_FLAG_REHASH;
1483 }
1484 } | ADMIN
1485 {
1486 if (conf_parser_ctx.pass == 2)
1487 {
1488 if (not_atom) yy_aconf->port &= ~OPER_FLAG_ADMIN;
1489 else yy_aconf->port |= OPER_FLAG_ADMIN;
1490 }
1491 } | HIDDEN_ADMIN
1492 {
1493 if (conf_parser_ctx.pass == 2)
1494 {
1495 if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1496 else yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1497 }
1498 } | NICK_CHANGES
1499 {
1500 if (conf_parser_ctx.pass == 2)
1501 {
1502 if (not_atom) yy_aconf->port &= ~OPER_FLAG_N;
1503 else yy_aconf->port |= OPER_FLAG_N;
1504 }
1505 } | T_OPERWALL
1506 {
1507 if (conf_parser_ctx.pass == 2)
1508 {
1509 if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1510 else yy_aconf->port |= OPER_FLAG_OPERWALL;
1511 }
1512 } | OPER_SPY_T
1513 {
1514 if (conf_parser_ctx.pass == 2)
1515 {
1516 if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPER_SPY;
1517 else yy_aconf->port |= OPER_FLAG_OPER_SPY;
1518 }
1519 } | HIDDEN_OPER
1520 {
1521 if (conf_parser_ctx.pass == 2)
1522 {
1523 if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1524 else yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1525 }
1526 } | REMOTEBAN
1527 {
1528 if (conf_parser_ctx.pass == 2)
1529 {
1530 if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1531 else yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1532 }
1533 } | ENCRYPTED
1534 {
1535 if (conf_parser_ctx.pass == 2)
1536 {
1537 if (not_atom) ClearConfEncrypted(yy_aconf);
1538 else SetConfEncrypted(yy_aconf);
1539 }
1540 };
1541
1542
1543 /***************************************************************************
1544 * section class
1545 ***************************************************************************/
1546 class_entry: CLASS
1547 {
1548 if (conf_parser_ctx.pass == 1)
1549 {
1550 yy_conf = make_conf_item(CLASS_TYPE);
1551 yy_class = map_to_conf(yy_conf);
1552 }
1553 } class_name_b '{' class_items '}' ';'
1554 {
1555 if (conf_parser_ctx.pass == 1)
1556 {
1557 struct ConfItem *cconf = NULL;
1558 struct ClassItem *class = NULL;
1559
1560 if (yy_class_name == NULL)
1561 delete_conf_item(yy_conf);
1562 else
1563 {
1564 cconf = find_exact_name_conf(CLASS_TYPE, yy_class_name, NULL, NULL);
1565
1566 if (cconf != NULL) /* The class existed already */
1567 {
1568 int user_count = 0;
1569
1570 rebuild_cidr_class(cconf, yy_class);
1571
1572 class = map_to_conf(cconf);
1573
1574 user_count = class->curr_user_count;
1575 memcpy(class, yy_class, sizeof(*class));
1576 class->curr_user_count = user_count;
1577 class->active = 1;
1578
1579 delete_conf_item(yy_conf);
1580
1581 MyFree(cconf->name); /* Allows case change of class name */
1582 cconf->name = yy_class_name;
1583 }
1584 else /* Brand new class */
1585 {
1586 MyFree(yy_conf->name); /* just in case it was allocated */
1587 yy_conf->name = yy_class_name;
1588 yy_class->active = 1;
1589 }
1590 }
1591
1592 yy_class_name = NULL;
1593 }
1594 };
1595
1596 class_name_b: | class_name_t;
1597
1598 class_items: class_items class_item | class_item;
1599 class_item: class_name |
1600 class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1601 class_ping_time |
1602 class_ping_warning |
1603 class_number_per_cidr |
1604 class_number_per_ip |
1605 class_connectfreq |
1606 class_max_number |
1607 class_max_global |
1608 class_max_local |
1609 class_max_ident |
1610 class_sendq |
1611 error ';' ;
1612
1613 class_name: NAME '=' QSTRING ';'
1614 {
1615 if (conf_parser_ctx.pass == 1)
1616 {
1617 MyFree(yy_class_name);
1618 DupString(yy_class_name, yylval.string);
1619 }
1620 };
1621
1622 class_name_t: QSTRING
1623 {
1624 if (conf_parser_ctx.pass == 1)
1625 {
1626 MyFree(yy_class_name);
1627 DupString(yy_class_name, yylval.string);
1628 }
1629 };
1630
1631 class_ping_time: PING_TIME '=' timespec ';'
1632 {
1633 if (conf_parser_ctx.pass == 1)
1634 PingFreq(yy_class) = $3;
1635 };
1636
1637 class_ping_warning: PING_WARNING '=' timespec ';'
1638 {
1639 if (conf_parser_ctx.pass == 1)
1640 PingWarning(yy_class) = $3;
1641 };
1642
1643 class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1644 {
1645 if (conf_parser_ctx.pass == 1)
1646 MaxPerIp(yy_class) = $3;
1647 };
1648
1649 class_connectfreq: CONNECTFREQ '=' timespec ';'
1650 {
1651 if (conf_parser_ctx.pass == 1)
1652 ConFreq(yy_class) = $3;
1653 };
1654
1655 class_max_number: MAX_NUMBER '=' NUMBER ';'
1656 {
1657 if (conf_parser_ctx.pass == 1)
1658 MaxTotal(yy_class) = $3;
1659 };
1660
1661 class_max_global: MAX_GLOBAL '=' NUMBER ';'
1662 {
1663 if (conf_parser_ctx.pass == 1)
1664 MaxGlobal(yy_class) = $3;
1665 };
1666
1667 class_max_local: MAX_LOCAL '=' NUMBER ';'
1668 {
1669 if (conf_parser_ctx.pass == 1)
1670 MaxLocal(yy_class) = $3;
1671 };
1672
1673 class_max_ident: MAX_IDENT '=' NUMBER ';'
1674 {
1675 if (conf_parser_ctx.pass == 1)
1676 MaxIdent(yy_class) = $3;
1677 };
1678
1679 class_sendq: SENDQ '=' sizespec ';'
1680 {
1681 if (conf_parser_ctx.pass == 1)
1682 MaxSendq(yy_class) = $3;
1683 };
1684
1685 class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1686 {
1687 if (conf_parser_ctx.pass == 1)
1688 CidrBitlenIPV4(yy_class) = $3;
1689 };
1690
1691 class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1692 {
1693 if (conf_parser_ctx.pass == 1)
1694 CidrBitlenIPV6(yy_class) = $3;
1695 };
1696
1697 class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1698 {
1699 if (conf_parser_ctx.pass == 1)
1700 NumberPerCidr(yy_class) = $3;
1701 };
1702
1703 /***************************************************************************
1704 * section listen
1705 ***************************************************************************/
1706 listen_entry: LISTEN
1707 {
1708 if (conf_parser_ctx.pass == 2)
1709 {
1710 listener_address = NULL;
1711 listener_flags = 0;
1712 }
1713 } '{' listen_items '}' ';'
1714 {
1715 if (conf_parser_ctx.pass == 2)
1716 {
1717 MyFree(listener_address);
1718 listener_address = NULL;
1719 }
1720 };
1721
1722 listen_flags: IRCD_FLAGS
1723 {
1724 listener_flags = 0;
1725 } '=' listen_flags_items ';';
1726
1727 listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1728 listen_flags_item: T_SSL
1729 {
1730 if (conf_parser_ctx.pass == 2)
1731 listener_flags |= LISTENER_SSL;
1732 } | HIDDEN
1733 {
1734 if (conf_parser_ctx.pass == 2)
1735 listener_flags |= LISTENER_HIDDEN;
1736 } | T_SERVER
1737 {
1738 if (conf_parser_ctx.pass == 2)
1739 listener_flags |= LISTENER_SERVER;
1740 };
1741
1742
1743
1744 listen_items: listen_items listen_item | listen_item;
1745 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1746
1747 listen_port: PORT '=' port_items { listener_flags = 0; } ';';
1748
1749 port_items: port_items ',' port_item | port_item;
1750
1751 port_item: NUMBER
1752 {
1753 if (conf_parser_ctx.pass == 2)
1754 {
1755 if ((listener_flags & LISTENER_SSL))
1756 #ifdef HAVE_LIBCRYPTO
1757 if (!ServerInfo.server_ctx)
1758 #endif
1759 {
1760 yyerror("SSL not available - port closed");
1761 break;
1762 }
1763 add_listener($1, listener_address, listener_flags);
1764 }
1765 } | NUMBER TWODOTS NUMBER
1766 {
1767 if (conf_parser_ctx.pass == 2)
1768 {
1769 int i;
1770
1771 if ((listener_flags & LISTENER_SSL))
1772 #ifdef HAVE_LIBCRYPTO
1773 if (!ServerInfo.server_ctx)
1774 #endif
1775 {
1776 yyerror("SSL not available - port closed");
1777 break;
1778 }
1779
1780 for (i = $1; i <= $3; ++i)
1781 add_listener(i, listener_address, listener_flags);
1782 }
1783 };
1784
1785 listen_address: IP '=' QSTRING ';'
1786 {
1787 if (conf_parser_ctx.pass == 2)
1788 {
1789 MyFree(listener_address);
1790 DupString(listener_address, yylval.string);
1791 }
1792 };
1793
1794 listen_host: HOST '=' QSTRING ';'
1795 {
1796 if (conf_parser_ctx.pass == 2)
1797 {
1798 MyFree(listener_address);
1799 DupString(listener_address, yylval.string);
1800 }
1801 };
1802
1803 /***************************************************************************
1804 * section auth
1805 ***************************************************************************/
1806 auth_entry: IRCD_AUTH
1807 {
1808 if (conf_parser_ctx.pass == 2)
1809 {
1810 yy_conf = make_conf_item(CLIENT_TYPE);
1811 yy_aconf = map_to_conf(yy_conf);
1812 }
1813 else
1814 {
1815 MyFree(class_name);
1816 class_name = NULL;
1817 }
1818 } '{' auth_items '}' ';'
1819 {
1820 if (conf_parser_ctx.pass == 2)
1821 {
1822 struct CollectItem *yy_tmp = NULL;
1823 dlink_node *ptr = NULL, *next_ptr = NULL;
1824
1825 if (yy_aconf->user && yy_aconf->host)
1826 {
1827 conf_add_class_to_conf(yy_conf, class_name);
1828 add_conf_by_address(CONF_CLIENT, yy_aconf);
1829 }
1830 else
1831 delete_conf_item(yy_conf);
1832
1833 /* copy over settings from first struct */
1834 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
1835 {
1836 struct AccessItem *new_aconf;
1837 struct ConfItem *new_conf;
1838
1839 new_conf = make_conf_item(CLIENT_TYPE);
1840 new_aconf = map_to_conf(new_conf);
1841
1842 yy_tmp = ptr->data;
1843
1844 assert(yy_tmp->user && yy_tmp->host);
1845
1846 if (yy_aconf->passwd != NULL)
1847 DupString(new_aconf->passwd, yy_aconf->passwd);
1848 if (yy_conf->name != NULL)
1849 DupString(new_conf->name, yy_conf->name);
1850 if (yy_aconf->passwd != NULL)
1851 DupString(new_aconf->passwd, yy_aconf->passwd);
1852
1853 new_aconf->flags = yy_aconf->flags;
1854 new_aconf->port = yy_aconf->port;
1855
1856 DupString(new_aconf->user, yy_tmp->user);
1857 collapse(new_aconf->user);
1858
1859 DupString(new_aconf->host, yy_tmp->host);
1860 collapse(new_aconf->host);
1861
1862 conf_add_class_to_conf(new_conf, class_name);
1863 add_conf_by_address(CONF_CLIENT, new_aconf);
1864 dlinkDelete(&yy_tmp->node, &col_conf_list);
1865 free_collect_item(yy_tmp);
1866 }
1867
1868 MyFree(class_name);
1869 class_name = NULL;
1870 yy_conf = NULL;
1871 yy_aconf = NULL;
1872 }
1873 };
1874
1875 auth_items: auth_items auth_item | auth_item;
1876 auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1877 auth_kline_exempt | auth_need_ident |
1878 auth_exceed_limit | auth_no_tilde | auth_gline_exempt |
1879 auth_spoof | auth_spoof_notice |
1880 auth_redir_serv | auth_redir_port | auth_can_flood |
1881 auth_need_password | auth_encrypted | error ';' ;
1882
1883 auth_user: USER '=' QSTRING ';'
1884 {
1885 if (conf_parser_ctx.pass == 2)
1886 {
1887 struct CollectItem *yy_tmp = NULL;
1888 struct split_nuh_item nuh;
1889
1890 nuh.nuhmask = yylval.string;
1891 nuh.nickptr = NULL;
1892 nuh.userptr = userbuf;
1893 nuh.hostptr = hostbuf;
1894
1895 nuh.nicksize = 0;
1896 nuh.usersize = sizeof(userbuf);
1897 nuh.hostsize = sizeof(hostbuf);
1898
1899 split_nuh(&nuh);
1900
1901 if (yy_aconf->user == NULL)
1902 {
1903 DupString(yy_aconf->user, userbuf);
1904 DupString(yy_aconf->host, hostbuf);
1905 }
1906 else
1907 {
1908 yy_tmp = MyMalloc(sizeof(struct CollectItem));
1909
1910 DupString(yy_tmp->user, userbuf);
1911 DupString(yy_tmp->host, hostbuf);
1912
1913 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1914 }
1915 }
1916 };
1917
1918 /* XXX - IP/IPV6 tags don't exist anymore - put IP/IPV6 into user. */
1919
1920 auth_passwd: PASSWORD '=' QSTRING ';'
1921 {
1922 if (conf_parser_ctx.pass == 2)
1923 {
1924 /* be paranoid */
1925 if (yy_aconf->passwd != NULL)
1926 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1927
1928 MyFree(yy_aconf->passwd);
1929 DupString(yy_aconf->passwd, yylval.string);
1930 }
1931 };
1932
1933 auth_spoof_notice: SPOOF_NOTICE '=' TBOOL ';'
1934 {
1935 if (conf_parser_ctx.pass == 2)
1936 {
1937 if (yylval.number)
1938 yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1939 else
1940 yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1941 }
1942 };
1943
1944 auth_class: CLASS '=' QSTRING ';'
1945 {
1946 if (conf_parser_ctx.pass == 2)
1947 {
1948 MyFree(class_name);
1949 DupString(class_name, yylval.string);
1950 }
1951 };
1952
1953 auth_encrypted: ENCRYPTED '=' TBOOL ';'
1954 {
1955 if (conf_parser_ctx.pass == 2)
1956 {
1957 if (yylval.number)
1958 SetConfEncrypted(yy_aconf);
1959 else
1960 ClearConfEncrypted(yy_aconf);
1961 }
1962 };
1963
1964 auth_flags: IRCD_FLAGS
1965 {
1966 } '=' auth_flags_items ';';
1967
1968 auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1969 auth_flags_item: NOT { not_atom = 1; } auth_flags_item_atom
1970 | { not_atom = 0; } auth_flags_item_atom;
1971
1972 auth_flags_item_atom: SPOOF_NOTICE
1973 {
1974 if (conf_parser_ctx.pass == 2)
1975 {
1976 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1977 else yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1978 }
1979
1980 } | EXCEED_LIMIT
1981 {
1982 if (conf_parser_ctx.pass == 2)
1983 {
1984 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
1985 else yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1986 }
1987 } | KLINE_EXEMPT
1988 {
1989 if (conf_parser_ctx.pass == 2)
1990 {
1991 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
1992 else yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1993 }
1994 } | NEED_IDENT
1995 {
1996 if (conf_parser_ctx.pass == 2)
1997 {
1998 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
1999 else yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2000 }
2001 } | CAN_FLOOD
2002 {
2003 if (conf_parser_ctx.pass == 2)
2004 {
2005 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2006 else yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2007 }
2008 } | CAN_IDLE
2009 {
2010 if (conf_parser_ctx.pass == 2)
2011 {
2012 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_IDLE_LINED;
2013 else yy_aconf->flags |= CONF_FLAGS_IDLE_LINED;
2014 }
2015 } | NO_TILDE
2016 {
2017 if (conf_parser_ctx.pass == 2)
2018 {
2019 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2020 else yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2021 }
2022 } | GLINE_EXEMPT
2023 {
2024 if (conf_parser_ctx.pass == 2)
2025 {
2026 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2027 else yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2028 }
2029 } | RESV_EXEMPT
2030 {
2031 if (conf_parser_ctx.pass == 2)
2032 {
2033 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTRESV;
2034 else yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
2035 }
2036 } | NEED_PASSWORD
2037 {
2038 if (conf_parser_ctx.pass == 2)
2039 {
2040 if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2041 else yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2042 }
2043 };
2044
2045 auth_kline_exempt: KLINE_EXEMPT '=' TBOOL ';'
2046 {
2047 if (conf_parser_ctx.pass == 2)
2048 {
2049 if (yylval.number)
2050 yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
2051 else
2052 yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
2053 }
2054 };
2055
2056 auth_need_ident: NEED_IDENT '=' TBOOL ';'
2057 {
2058 if (conf_parser_ctx.pass == 2)
2059 {
2060 if (yylval.number)
2061 yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2062 else
2063 yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2064 }
2065 };
2066
2067 auth_exceed_limit: EXCEED_LIMIT '=' TBOOL ';'
2068 {
2069 if (conf_parser_ctx.pass == 2)
2070 {
2071 if (yylval.number)
2072 yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
2073 else
2074 yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
2075 }
2076 };
2077
2078 auth_can_flood: CAN_FLOOD '=' TBOOL ';'
2079 {
2080 if (conf_parser_ctx.pass == 2)
2081 {
2082 if (yylval.number)
2083 yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2084 else
2085 yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2086 }
2087 };
2088
2089 auth_no_tilde: NO_TILDE '=' TBOOL ';'
2090 {
2091 if (conf_parser_ctx.pass == 2)
2092 {
2093 if (yylval.number)
2094 yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2095 else
2096 yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2097 }
2098 };
2099
2100 auth_gline_exempt: GLINE_EXEMPT '=' TBOOL ';'
2101 {
2102 if (conf_parser_ctx.pass == 2)
2103 {
2104 if (yylval.number)
2105 yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2106 else
2107 yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2108 }
2109 };
2110
2111 /* XXX - need check for illegal hostnames here */
2112 auth_spoof: SPOOF '=' QSTRING ';'
2113 {
2114 if (conf_parser_ctx.pass == 2)
2115 {
2116 MyFree(yy_conf->name);
2117
2118 if (strlen(yylval.string) < HOSTLEN)
2119 {
2120 DupString(yy_conf->name, yylval.string);
2121 yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
2122 }
2123 else
2124 {
2125 ilog(L_ERROR, "Spoofs must be less than %d..ignoring it", HOSTLEN);
2126 yy_conf->name = NULL;
2127 }
2128 }
2129 };
2130
2131 auth_redir_serv: REDIRSERV '=' QSTRING ';'
2132 {
2133 if (conf_parser_ctx.pass == 2)
2134 {
2135 yy_aconf->flags |= CONF_FLAGS_REDIR;
2136 MyFree(yy_conf->name);
2137 DupString(yy_conf->name, yylval.string);
2138 }
2139 };
2140
2141 auth_redir_port: REDIRPORT '=' NUMBER ';'
2142 {
2143 if (conf_parser_ctx.pass == 2)
2144 {
2145 yy_aconf->flags |= CONF_FLAGS_REDIR;
2146 yy_aconf->port = $3;
2147 }
2148 };
2149
2150 auth_need_password: NEED_PASSWORD '=' TBOOL ';'
2151 {
2152 if (conf_parser_ctx.pass == 2)
2153 {
2154 if (yylval.number)
2155 yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2156 else
2157 yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2158 }
2159 };
2160
2161
2162 /***************************************************************************
2163 * section resv
2164 ***************************************************************************/
2165 resv_entry: RESV
2166 {
2167 if (conf_parser_ctx.pass == 2)
2168 {
2169 MyFree(resv_reason);
2170 resv_reason = NULL;
2171 }
2172 } '{' resv_items '}' ';'
2173 {
2174 if (conf_parser_ctx.pass == 2)
2175 {
2176 MyFree(resv_reason);
2177 resv_reason = NULL;
2178 }
2179 };
2180
2181 resv_items: resv_items resv_item | resv_item;
2182 resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
2183
2184 resv_creason: REASON '=' QSTRING ';'
2185 {
2186 if (conf_parser_ctx.pass == 2)
2187 {
2188 MyFree(resv_reason);
2189 DupString(resv_reason, yylval.string);
2190 }
2191 };
2192
2193 resv_channel: CHANNEL '=' QSTRING ';'
2194 {
2195 if (conf_parser_ctx.pass == 2)
2196 {
2197 if (IsChanPrefix(*yylval.string))
2198 {
2199 char def_reason[] = "No reason";
2200
2201 create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2202 }
2203 }
2204 /* ignore it for now.. but we really should make a warning if
2205 * its an erroneous name --fl_ */
2206 };
2207
2208 resv_nick: NICK '=' QSTRING ';'
2209 {
2210 if (conf_parser_ctx.pass == 2)
2211 {
2212 char def_reason[] = "No reason";
2213
2214 create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2215 }
2216 };
2217
2218 /***************************************************************************
2219 * section shared, for sharing remote klines etc.
2220 ***************************************************************************/
2221 shared_entry: T_SHARED
2222 {
2223 if (conf_parser_ctx.pass == 2)
2224 {
2225 yy_conf = make_conf_item(ULINE_TYPE);
2226 yy_match_item = map_to_conf(yy_conf);
2227 yy_match_item->action = SHARED_ALL;
2228 }
2229 } '{' shared_items '}' ';'
2230 {
2231 if (conf_parser_ctx.pass == 2)
2232 {
2233 yy_conf = NULL;
2234 }
2235 };
2236
2237 shared_items: shared_items shared_item | shared_item;
2238 shared_item: shared_name | shared_user | shared_type | error ';' ;
2239
2240 shared_name: NAME '=' QSTRING ';'
2241 {
2242 if (conf_parser_ctx.pass == 2)
2243 {
2244 MyFree(yy_conf->name);
2245 DupString(yy_conf->name, yylval.string);
2246 }
2247 };
2248
2249 shared_user: USER '=' QSTRING ';'
2250 {
2251 if (conf_parser_ctx.pass == 2)
2252 {
2253 struct split_nuh_item nuh;
2254
2255 nuh.nuhmask = yylval.string;
2256 nuh.nickptr = NULL;
2257 nuh.userptr = userbuf;
2258 nuh.hostptr = hostbuf;
2259
2260 nuh.nicksize = 0;
2261 nuh.usersize = sizeof(userbuf);
2262 nuh.hostsize = sizeof(hostbuf);
2263
2264 split_nuh(&nuh);
2265
2266 DupString(yy_match_item->user, userbuf);
2267 DupString(yy_match_item->host, hostbuf);
2268 }
2269 };
2270
2271 shared_type: TYPE
2272 {
2273 if (conf_parser_ctx.pass == 2)
2274 yy_match_item->action = 0;
2275 } '=' shared_types ';' ;
2276
2277 shared_types: shared_types ',' shared_type_item | shared_type_item;
2278 shared_type_item: KLINE
2279 {
2280 if (conf_parser_ctx.pass == 2)
2281 yy_match_item->action |= SHARED_KLINE;
2282 } | TKLINE
2283 {
2284 if (conf_parser_ctx.pass == 2)
2285 yy_match_item->action |= SHARED_TKLINE;
2286 } | UNKLINE
2287 {
2288 if (conf_parser_ctx.pass == 2)
2289 yy_match_item->action |= SHARED_UNKLINE;
2290 } | XLINE
2291 {
2292 if (conf_parser_ctx.pass == 2)
2293 yy_match_item->action |= SHARED_XLINE;
2294 } | TXLINE
2295 {
2296 if (conf_parser_ctx.pass == 2)
2297 yy_match_item->action |= SHARED_TXLINE;
2298 } | T_UNXLINE
2299 {
2300 if (conf_parser_ctx.pass == 2)
2301 yy_match_item->action |= SHARED_UNXLINE;
2302 } | RESV
2303 {
2304 if (conf_parser_ctx.pass == 2)
2305 yy_match_item->action |= SHARED_RESV;
2306 } | TRESV
2307 {
2308 if (conf_parser_ctx.pass == 2)
2309 yy_match_item->action |= SHARED_TRESV;
2310 } | T_UNRESV
2311 {
2312 if (conf_parser_ctx.pass == 2)
2313 yy_match_item->action |= SHARED_UNRESV;
2314 } | T_LOCOPS
2315 {
2316 if (conf_parser_ctx.pass == 2)
2317 yy_match_item->action |= SHARED_LOCOPS;
2318 } | T_ALL
2319 {
2320 if (conf_parser_ctx.pass == 2)
2321 yy_match_item->action = SHARED_ALL;
2322 };
2323
2324 /***************************************************************************
2325 * section cluster
2326 ***************************************************************************/
2327 cluster_entry: T_CLUSTER
2328 {
2329 if (conf_parser_ctx.pass == 2)
2330 {
2331 yy_conf = make_conf_item(CLUSTER_TYPE);
2332 yy_conf->flags = SHARED_ALL;
2333 }
2334 } '{' cluster_items '}' ';'
2335 {
2336 if (conf_parser_ctx.pass == 2)
2337 {
2338 if (yy_conf->name == NULL)
2339 DupString(yy_conf->name, "*");
2340 yy_conf = NULL;
2341 }
2342 };
2343
2344 cluster_items: cluster_items cluster_item | cluster_item;
2345 cluster_item: cluster_name | cluster_type | error ';' ;
2346
2347 cluster_name: NAME '=' QSTRING ';'
2348 {
2349 if (conf_parser_ctx.pass == 2)
2350 DupString(yy_conf->name, yylval.string);
2351 };
2352
2353 cluster_type: TYPE
2354 {
2355 if (conf_parser_ctx.pass == 2)
2356 yy_conf->flags = 0;
2357 } '=' cluster_types ';' ;
2358
2359 cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
2360 cluster_type_item: KLINE
2361 {
2362 if (conf_parser_ctx.pass == 2)
2363 yy_conf->flags |= SHARED_KLINE;
2364 } | TKLINE
2365 {
2366 if (conf_parser_ctx.pass == 2)
2367 yy_conf->flags |= SHARED_TKLINE;
2368 } | UNKLINE
2369 {
2370 if (conf_parser_ctx.pass == 2)
2371 yy_conf->flags |= SHARED_UNKLINE;
2372 } | XLINE
2373 {
2374 if (conf_parser_ctx.pass == 2)
2375 yy_conf->flags |= SHARED_XLINE;
2376 } | TXLINE
2377 {
2378 if (conf_parser_ctx.pass == 2)
2379 yy_conf->flags |= SHARED_TXLINE;
2380 } | T_UNXLINE
2381 {
2382 if (conf_parser_ctx.pass == 2)
2383 yy_conf->flags |= SHARED_UNXLINE;
2384 } | RESV
2385 {
2386 if (conf_parser_ctx.pass == 2)
2387 yy_conf->flags |= SHARED_RESV;
2388 } | TRESV
2389 {
2390 if (conf_parser_ctx.pass == 2)
2391 yy_conf->flags |= SHARED_TRESV;
2392 } | T_UNRESV
2393 {
2394 if (conf_parser_ctx.pass == 2)
2395 yy_conf->flags |= SHARED_UNRESV;
2396 } | T_LOCOPS
2397 {
2398 if (conf_parser_ctx.pass == 2)
2399 yy_conf->flags |= SHARED_LOCOPS;
2400 } | T_ALL
2401 {
2402 if (conf_parser_ctx.pass == 2)
2403 yy_conf->flags = SHARED_ALL;
2404 };
2405
2406 /***************************************************************************
2407 * section connect
2408 ***************************************************************************/
2409 connect_entry: CONNECT
2410 {
2411 if (conf_parser_ctx.pass == 2)
2412 {
2413 yy_conf = make_conf_item(SERVER_TYPE);
2414 yy_aconf = (struct AccessItem *)map_to_conf(yy_conf);
2415 yy_aconf->passwd = NULL;
2416 /* defaults */
2417 yy_aconf->port = PORTNUM;
2418
2419 if (ConfigFileEntry.burst_away)
2420 yy_aconf->flags = CONF_FLAGS_BURST_AWAY;
2421 }
2422 else
2423 {
2424 MyFree(class_name);
2425 class_name = NULL;
2426 }
2427 } connect_name_b '{' connect_items '}' ';'
2428 {
2429 if (conf_parser_ctx.pass == 2)
2430 {
2431 struct CollectItem *yy_hconf=NULL;
2432 struct CollectItem *yy_lconf=NULL;
2433 dlink_node *ptr;
2434 dlink_node *next_ptr;
2435 #ifdef HAVE_LIBCRYPTO
2436 if (yy_aconf->host &&
2437 ((yy_aconf->passwd && yy_aconf->spasswd) ||
2438 (yy_aconf->rsa_public_key && IsConfCryptLink(yy_aconf))))
2439 #else /* !HAVE_LIBCRYPTO */
2440 if (yy_aconf->host && !IsConfCryptLink(yy_aconf) &&
2441 yy_aconf->passwd && yy_aconf->spasswd)
2442 #endif /* !HAVE_LIBCRYPTO */
2443 {
2444 if (conf_add_server(yy_conf, class_name) == -1)
2445 {
2446 delete_conf_item(yy_conf);
2447 yy_conf = NULL;
2448 yy_aconf = NULL;
2449 }
2450 }
2451 else
2452 {
2453 /* Even if yy_conf ->name is NULL
2454 * should still unhook any hub/leaf confs still pending
2455 */
2456 unhook_hub_leaf_confs();
2457
2458 if (yy_conf->name != NULL)
2459 {
2460 #ifndef HAVE_LIBCRYPTO
2461 if (IsConfCryptLink(yy_aconf))
2462 yyerror("Ignoring connect block -- no OpenSSL support");
2463 #else
2464 if (IsConfCryptLink(yy_aconf) && !yy_aconf->rsa_public_key)
2465 yyerror("Ignoring connect block -- missing key");
2466 #endif
2467 if (yy_aconf->host == NULL)
2468 yyerror("Ignoring connect block -- missing host");
2469 else if (!IsConfCryptLink(yy_aconf) &&
2470 (!yy_aconf->passwd || !yy_aconf->spasswd))
2471 yyerror("Ignoring connect block -- missing password");
2472 }
2473
2474
2475 /* XXX
2476 * This fixes a try_connections() core (caused by invalid class_ptr
2477 * pointers) reported by metalrock. That's an ugly fix, but there
2478 * is currently no better way. The entire config subsystem needs an
2479 * rewrite ASAP. make_conf_item() shouldn't really add things onto
2480 * a doubly linked list immediately without any sanity checks! -Michael
2481 */
2482 delete_conf_item(yy_conf);
2483
2484 yy_aconf = NULL;
2485 yy_conf = NULL;
2486 }
2487
2488 /*
2489 * yy_conf is still pointing at the server that is having
2490 * a connect block built for it. This means, y_aconf->name
2491 * points to the actual irc name this server will be known as.
2492 * Now this new server has a set or even just one hub_mask (or leaf_mask)
2493 * given in the link list at yy_hconf. Fill in the HUB confs
2494 * from this link list now.
2495 */
2496 DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
2497 {
2498 struct ConfItem *new_hub_conf;
2499 struct MatchItem *match_item;
2500
2501 yy_hconf = ptr->data;
2502
2503 /* yy_conf == NULL is a fatal error for this connect block! */
2504 if ((yy_conf != NULL) && (yy_conf->name != NULL))
2505 {
2506 new_hub_conf = make_conf_item(HUB_TYPE);
2507 match_item = (struct MatchItem *)map_to_conf(new_hub_conf);
2508 DupString(new_hub_conf->name, yy_conf->name);
2509 if (yy_hconf->user != NULL)
2510 DupString(match_item->user, yy_hconf->user);
2511 else
2512 DupString(match_item->user, "*");
2513 if (yy_hconf->host != NULL)
2514 DupString(match_item->host, yy_hconf->host);
2515 else
2516 DupString(match_item->host, "*");
2517 }
2518 dlinkDelete(&yy_hconf->node, &hub_conf_list);
2519 free_collect_item(yy_hconf);
2520 }
2521
2522 /* Ditto for the LEAF confs */
2523
2524 DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
2525 {
2526 struct ConfItem *new_leaf_conf;
2527 struct MatchItem *match_item;
2528
2529 yy_lconf = ptr->data;
2530
2531 if ((yy_conf != NULL) && (yy_conf->name != NULL))
2532 {
2533 new_leaf_conf = make_conf_item(LEAF_TYPE);
2534 match_item = (struct MatchItem *)map_to_conf(new_leaf_conf);
2535 DupString(new_leaf_conf->name, yy_conf->name);
2536 if (yy_lconf->user != NULL)
2537 DupString(match_item->user, yy_lconf->user);
2538 else
2539 DupString(match_item->user, "*");
2540 if (yy_lconf->host != NULL)
2541 DupString(match_item->host, yy_lconf->host);
2542 else
2543 DupString(match_item->host, "*");
2544 }
2545 dlinkDelete(&yy_lconf->node, &leaf_conf_list);
2546 free_collect_item(yy_lconf);
2547 }
2548 MyFree(class_name);
2549 class_name = NULL;
2550 yy_conf = NULL;
2551 yy_aconf = NULL;
2552 }
2553 };
2554
2555 connect_name_b: | connect_name_t;
2556 connect_items: connect_items connect_item | connect_item;
2557 connect_item: connect_name | connect_host | connect_vhost |
2558 connect_send_password | connect_accept_password |
2559 connect_aftype | connect_port |
2560 connect_fakename | connect_flags | connect_hub_mask |
2561 connect_leaf_mask | connect_class | connect_auto |
2562 connect_encrypted | connect_compressed | connect_cryptlink |
2563 connect_rsa_public_key_file | connect_cipher_preference |
2564 connect_topicburst | error ';' ;
2565
2566 connect_name: NAME '=' QSTRING ';'
2567 {
2568 if (conf_parser_ctx.pass == 2)
2569 {
2570 if (yy_conf->name != NULL)
2571 yyerror("Multiple connect name entry");
2572
2573 MyFree(yy_conf->name);
2574 DupString(yy_conf->name, yylval.string);
2575 }
2576 };
2577
2578 connect_name_t: QSTRING
2579 {
2580 if (conf_parser_ctx.pass == 2)
2581 {
2582 if (yy_conf->name != NULL)
2583 yyerror("Multiple connect name entry");
2584
2585 MyFree(yy_conf->name);
2586 DupString(yy_conf->name, yylval.string);
2587 }
2588 };
2589
2590 connect_host: HOST '=' QSTRING ';'
2591 {
2592 if (conf_parser_ctx.pass == 2)
2593 {
2594 MyFree(yy_aconf->host);
2595 DupString(yy_aconf->host, yylval.string);
2596 }
2597 };
2598
2599 connect_vhost: VHOST '=' QSTRING ';'
2600 {
2601 if (conf_parser_ctx.pass == 2)
2602 {
2603 struct addrinfo hints, *res;
2604
2605 memset(&hints, 0, sizeof(hints));
2606
2607 hints.ai_family = AF_UNSPEC;
2608 hints.ai_socktype = SOCK_STREAM;
2609 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2610
2611 if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
2612 ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
2613 else
2614 {
2615 assert(res != NULL);
2616
2617 memcpy(&yy_aconf->my_ipnum, res->ai_addr, res->ai_addrlen);
2618 yy_aconf->my_ipnum.ss.ss_family = res->ai_family;
2619 yy_aconf->my_ipnum.ss_len = res->ai_addrlen;
2620 irc_freeaddrinfo(res);
2621 }
2622 }
2623 };
2624
2625 connect_send_password: SEND_PASSWORD '=' QSTRING ';'
2626 {
2627 if (conf_parser_ctx.pass == 2)
2628 {
2629 if ($3[0] == ':')
2630 yyerror("Server passwords cannot begin with a colon");
2631 else if (strchr($3, ' ') != NULL)
2632 yyerror("Server passwords cannot contain spaces");
2633 else {
2634 if (yy_aconf->spasswd != NULL)
2635 memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd));
2636
2637 MyFree(yy_aconf->spasswd);
2638 DupString(yy_aconf->spasswd, yylval.string);
2639 }
2640 }
2641 };
2642
2643 connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
2644 {
2645 if (conf_parser_ctx.pass == 2)
2646 {
2647 if ($3[0] == ':')
2648 yyerror("Server passwords cannot begin with a colon");
2649 else if (strchr($3, ' ') != NULL)
2650 yyerror("Server passwords cannot contain spaces");
2651 else {
2652 if (yy_aconf->passwd != NULL)
2653 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
2654
2655 MyFree(yy_aconf->passwd);
2656 DupString(yy_aconf->passwd, yylval.string);
2657 }
2658 }
2659 };
2660
2661 connect_port: PORT '=' NUMBER ';'
2662 {
2663 if (conf_parser_ctx.pass == 2)
2664 yy_aconf->port = $3;
2665 };
2666
2667 connect_aftype: AFTYPE '=' T_IPV4 ';'
2668 {
2669 if (conf_parser_ctx.pass == 2)
2670 yy_aconf->aftype = AF_INET;
2671 } | AFTYPE '=' T_IPV6 ';'
2672 {
2673 #ifdef IPV6
2674 if (conf_parser_ctx.pass == 2)
2675 yy_aconf->aftype = AF_INET6;
2676 #endif
2677 };
2678
2679 connect_fakename: FAKENAME '=' QSTRING ';'
2680 {
2681 if (conf_parser_ctx.pass == 2)
2682 {
2683 MyFree(yy_aconf->fakename);
2684 DupString(yy_aconf->fakename, yylval.string);
2685 }
2686 };
2687
2688 connect_flags: IRCD_FLAGS
2689 {
2690 } '=' connect_flags_items ';';
2691
2692 connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2693 connect_flags_item: NOT { not_atom = 1; } connect_flags_item_atom
2694 | { not_atom = 0; } connect_flags_item_atom;
2695
2696 connect_flags_item_atom: COMPRESSED
2697 {
2698 if (conf_parser_ctx.pass == 2)
2699 #ifndef HAVE_LIBZ
2700 yyerror("Ignoring flags = compressed; -- no zlib support");
2701 #else
2702 {
2703 if (not_atom)ClearConfCompressed(yy_aconf);
2704 else SetConfCompressed(yy_aconf);
2705 }
2706 #endif
2707 } | CRYPTLINK
2708 {
2709 if (conf_parser_ctx.pass == 2)
2710 {
2711 if (not_atom)ClearConfCryptLink(yy_aconf);
2712 else SetConfCryptLink(yy_aconf);
2713 }
2714 } | AUTOCONN
2715 {
2716 if (conf_parser_ctx.pass == 2)
2717 {
2718 if (not_atom)ClearConfAllowAutoConn(yy_aconf);
2719 else SetConfAllowAutoConn(yy_aconf);
2720 }
2721 } | BURST_AWAY
2722 {
2723 if (conf_parser_ctx.pass == 2)
2724 {
2725 if (not_atom)ClearConfAwayBurst(yy_aconf);
2726 else SetConfAwayBurst(yy_aconf);
2727 }
2728 } | TOPICBURST
2729 {
2730 if (conf_parser_ctx.pass == 2)
2731 {
2732 if (not_atom)ClearConfTopicBurst(yy_aconf);
2733 else SetConfTopicBurst(yy_aconf);
2734 }
2735 }
2736 ;
2737
2738 connect_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
2739 {
2740 #ifdef HAVE_LIBCRYPTO
2741 if (conf_parser_ctx.pass == 2)
2742 {
2743 BIO *file;
2744
2745 if (yy_aconf->rsa_public_key != NULL)
2746 {
2747 RSA_free(yy_aconf->rsa_public_key);
2748 yy_aconf->rsa_public_key = NULL;
2749 }
2750
2751 if (yy_aconf->rsa_public_key_file != NULL)
2752 {
2753 MyFree(yy_aconf->rsa_public_key_file);
2754 yy_aconf->rsa_public_key_file = NULL;
2755 }
2756
2757 DupString(yy_aconf->rsa_public_key_file, yylval.string);
2758
2759 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
2760 {
2761 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
2762 break;
2763 }
2764
2765 yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
2766
2767 if (yy_aconf->rsa_public_key == NULL)
2768 {
2769 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
2770 break;
2771 }
2772
2773 BIO_set_close(file, BIO_CLOSE);
2774 BIO_free(file);
2775 }
2776 #endif /* HAVE_LIBCRYPTO */
2777 };
2778
2779 connect_encrypted: ENCRYPTED '=' TBOOL ';'
2780 {
2781 if (conf_parser_ctx.pass == 2)
2782 {
2783 if (yylval.number)
2784 yy_aconf->flags |= CONF_FLAGS_ENCRYPTED;
2785 else
2786 yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED;
2787 }
2788 };
2789
2790 connect_cryptlink: CRYPTLINK '=' TBOOL ';'
2791 {
2792 if (conf_parser_ctx.pass == 2)
2793 {
2794 if (yylval.number)
2795 yy_aconf->flags |= CONF_FLAGS_CRYPTLINK;
2796 else
2797 yy_aconf->flags &= ~CONF_FLAGS_CRYPTLINK;
2798 }
2799 };
2800
2801 connect_compressed: COMPRESSED '=' TBOOL ';'
2802 {
2803 if (conf_parser_ctx.pass == 2)
2804 {
2805 if (yylval.number)
2806 #ifndef HAVE_LIBZ
2807 yyerror("Ignoring compressed=yes; -- no zlib support");
2808 #else
2809 yy_aconf->flags |= CONF_FLAGS_COMPRESSED;
2810 #endif
2811 else
2812 yy_aconf->flags &= ~CONF_FLAGS_COMPRESSED;
2813 }
2814 };
2815
2816 connect_auto: AUTOCONN '=' TBOOL ';'
2817 {
2818 if (conf_parser_ctx.pass == 2)
2819 {
2820 if (yylval.number)
2821 yy_aconf->flags |= CONF_FLAGS_ALLOW_AUTO_CONN;
2822 else
2823 yy_aconf->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN;
2824 }
2825 };
2826
2827 connect_topicburst: TOPICBURST '=' TBOOL ';'
2828 {
2829 if (conf_parser_ctx.pass == 2)
2830 {
2831 if (yylval.number)
2832 SetConfTopicBurst(yy_aconf);
2833 else
2834 ClearConfTopicBurst(yy_aconf);
2835 }
2836 };
2837
2838 connect_hub_mask: HUB_MASK '=' QSTRING ';'
2839 {
2840 if (conf_parser_ctx.pass == 2)
2841 {
2842 struct CollectItem *yy_tmp;
2843
2844 yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2845 DupString(yy_tmp->host, yylval.string);
2846 DupString(yy_tmp->user, "*");
2847 dlinkAdd(yy_tmp, &yy_tmp->node, &hub_conf_list);
2848 }
2849 };
2850
2851 connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2852 {
2853 if (conf_parser_ctx.pass == 2)
2854 {
2855 struct CollectItem *yy_tmp;
2856
2857 yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2858 DupString(yy_tmp->host, yylval.string);
2859 DupString(yy_tmp->user, "*");
2860 dlinkAdd(yy_tmp, &yy_tmp->node, &leaf_conf_list);
2861 }
2862 };
2863
2864 connect_class: CLASS '=' QSTRING ';'
2865 {
2866 if (conf_parser_ctx.pass == 2)
2867 {
2868 MyFree(class_name);
2869 DupString(class_name, yylval.string);
2870 }
2871 };
2872
2873 connect_cipher_preference: CIPHER_PREFERENCE '=' QSTRING ';'
2874 {
2875 #ifdef HAVE_LIBCRYPTO
2876 if (conf_parser_ctx.pass == 2)
2877 {
2878 struct EncCapability *ecap;
2879 const char *cipher_name;
2880 int found = 0;
2881
2882 yy_aconf->cipher_preference = NULL;
2883 cipher_name = yylval.string;
2884
2885 for (ecap = CipherTable; ecap->name; ecap++)
2886 {
2887 if ((irccmp(ecap->name, cipher_name) == 0) &&
2888 (ecap->cap & CAP_ENC_MASK))
2889 {
2890 yy_aconf->cipher_preference = ecap;
2891 found = 1;
2892 break;
2893 }
2894 }
2895
2896 if (!found)
2897 yyerror("Invalid cipher");
2898 }
2899 #else
2900 if (conf_parser_ctx.pass == 2)
2901 yyerror("Ignoring cipher_preference -- no OpenSSL support");
2902 #endif
2903 };
2904
2905 /***************************************************************************
2906 * section kill
2907 ***************************************************************************/
2908 kill_entry: KILL
2909 {
2910 if (conf_parser_ctx.pass == 2)
2911 {
2912 userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0';
2913 regex_ban = 0;
2914 }
2915 } '{' kill_items '}' ';'
2916 {
2917 if (conf_parser_ctx.pass == 2)
2918 {
2919 if (userbuf[0] && hostbuf[0])
2920 {
2921 if (regex_ban)
2922 {
2923 #ifdef HAVE_LIBPCRE
2924 void *exp_user = NULL;
2925 void *exp_host = NULL;
2926 const char *errptr = NULL;
2927
2928 if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2929 !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2930 {
2931 ilog(L_ERROR, "Failed to add regular expression based K-Line: %s",
2932 errptr);
2933 break;
2934 }
2935
2936 yy_aconf = map_to_conf(make_conf_item(RKLINE_TYPE));
2937 yy_aconf->regexuser = exp_user;
2938 yy_aconf->regexhost = exp_host;
2939
2940 DupString(yy_aconf->user, userbuf);
2941 DupString(yy_aconf->host, hostbuf);
2942
2943 if (reasonbuf[0])
2944 DupString(yy_aconf->reason, reasonbuf);
2945 else
2946 DupString(yy_aconf->reason, "No reason");
2947 #else
2948 ilog(L_ERROR, "Failed to add regular expression based K-Line: no PCRE support");
2949 break;
2950 #endif
2951 }
2952 else
2953 {
2954 yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE));
2955
2956 DupString(yy_aconf->user, userbuf);
2957 DupString(yy_aconf->host, hostbuf);
2958
2959 if (reasonbuf[0])
2960 DupString(yy_aconf->reason, reasonbuf);
2961 else
2962 DupString(yy_aconf->reason, "No reason");
2963 add_conf_by_address(CONF_KILL, yy_aconf);
2964 }
2965 }
2966
2967 yy_aconf = NULL;
2968 }
2969 };
2970
2971 kill_type: TYPE
2972 {
2973 } '=' kill_type_items ';';
2974
2975 kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2976 kill_type_item: REGEX_T
2977 {
2978 if (conf_parser_ctx.pass == 2)
2979 regex_ban = 1;
2980 };
2981
2982 kill_items: kill_items kill_item | kill_item;
2983 kill_item: kill_user | kill_reason | kill_type | error;
2984
2985 kill_user: USER '=' QSTRING ';'
2986 {
2987 if (conf_parser_ctx.pass == 2)
2988 {
2989 struct split_nuh_item nuh;
2990
2991 nuh.nuhmask = yylval.string;
2992 nuh.nickptr = NULL;
2993 nuh.userptr = userbuf;
2994 nuh.hostptr = hostbuf;
2995
2996 nuh.nicksize = 0;
2997 nuh.usersize = sizeof(userbuf);
2998 nuh.hostsize = sizeof(hostbuf);
2999
3000 split_nuh(&nuh);
3001 }
3002 };
3003
3004 kill_reason: REASON '=' QSTRING ';'
3005 {
3006 if (conf_parser_ctx.pass == 2)
3007 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3008 };
3009
3010 /***************************************************************************
3011 * section deny
3012 ***************************************************************************/
3013 deny_entry: DENY
3014 {
3015 if (conf_parser_ctx.pass == 2)
3016 hostbuf[0] = reasonbuf[0] = '\0';
3017 } '{' deny_items '}' ';'
3018 {
3019 if (conf_parser_ctx.pass == 2)
3020 {
3021 if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST)
3022 {
3023 yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE));
3024 DupString(yy_aconf->host, hostbuf);
3025
3026 if (reasonbuf[0])
3027 DupString(yy_aconf->reason, reasonbuf);
3028 else
3029 DupString(yy_aconf->reason, "No reason");
3030 add_conf_by_address(CONF_DLINE, yy_aconf);
3031 yy_aconf = NULL;
3032 }
3033 }
3034 };
3035
3036 deny_items: deny_items deny_item | deny_item;
3037 deny_item: deny_ip | deny_reason | error;
3038
3039 deny_ip: IP '=' QSTRING ';'
3040 {
3041 if (conf_parser_ctx.pass == 2)
3042 strlcpy(hostbuf, yylval.string, sizeof(hostbuf));
3043 };
3044
3045 deny_reason: REASON '=' QSTRING ';'
3046 {
3047 if (conf_parser_ctx.pass == 2)
3048 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3049 };
3050
3051 /***************************************************************************
3052 * section exempt
3053 ***************************************************************************/
3054 exempt_entry: EXEMPT '{' exempt_items '}' ';';
3055
3056 exempt_items: exempt_items exempt_item | exempt_item;
3057 exempt_item: exempt_ip | error;
3058
3059 exempt_ip: IP '=' QSTRING ';'
3060 {
3061 if (conf_parser_ctx.pass == 2)
3062 {
3063 if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
3064 {
3065 yy_aconf = map_to_conf(make_conf_item(EXEMPTDLINE_TYPE));
3066 DupString(yy_aconf->host, yylval.string);
3067
3068 add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf);
3069 yy_aconf = NULL;
3070 }
3071 }
3072 };
3073
3074 /***************************************************************************
3075 * section gecos
3076 ***************************************************************************/
3077 gecos_entry: GECOS
3078 {
3079 if (conf_parser_ctx.pass == 2)
3080 {
3081 regex_ban = 0;
3082 reasonbuf[0] = gecos_name[0] = '\0';
3083 }
3084 } '{' gecos_items '}' ';'
3085 {
3086 if (conf_parser_ctx.pass == 2)
3087 {
3088 if (gecos_name[0])
3089 {
3090 if (regex_ban)
3091 {
3092 #ifdef HAVE_LIBPCRE
3093 void *exp_p = NULL;
3094 const char *errptr = NULL;
3095
3096 if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr)))
3097 {
3098 ilog(L_ERROR, "Failed to add regular expression based X-Line: %s",
3099 errptr);
3100 break;
3101 }
3102
3103 yy_conf = make_conf_item(RXLINE_TYPE);
3104 yy_conf->regexpname = exp_p;
3105 #else
3106 ilog(L_ERROR, "Failed to add regular expression based X-Line: no PCRE support");
3107 break;
3108 #endif
3109 }
3110 else
3111 yy_conf = make_conf_item(XLINE_TYPE);
3112
3113 yy_match_item = map_to_conf(yy_conf);
3114 DupString(yy_conf->name, gecos_name);
3115
3116 if (reasonbuf[0])
3117 DupString(yy_match_item->reason, reasonbuf);
3118 else
3119 DupString(yy_match_item->reason, "No reason");
3120 }
3121 }
3122 };
3123
3124 gecos_flags: TYPE
3125 {
3126 } '=' gecos_flags_items ';';
3127
3128 gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
3129 gecos_flags_item: REGEX_T
3130 {
3131 if (conf_parser_ctx.pass == 2)
3132 regex_ban = 1;
3133 };
3134
3135 gecos_items: gecos_items gecos_item | gecos_item;
3136 gecos_item: gecos_name | gecos_reason | gecos_flags | error;
3137
3138 gecos_name: NAME '=' QSTRING ';'
3139 {
3140 if (conf_parser_ctx.pass == 2)
3141 strlcpy(gecos_name, yylval.string, sizeof(gecos_name));
3142 };
3143
3144 gecos_reason: REASON '=' QSTRING ';'
3145 {
3146 if (conf_parser_ctx.pass == 2)
3147 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3148 };
3149
3150 /***************************************************************************
3151 * section general
3152 ***************************************************************************/
3153 general_entry: GENERAL
3154 '{' general_items '}' ';';
3155
3156 general_items: general_items general_item | general_item;
3157 general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
3158 general_failed_oper_notice | general_anti_nick_flood |
3159 general_max_nick_time | general_max_nick_changes |
3160 general_max_accept | general_anti_spam_exit_message_time |
3161 general_ts_warn_delta | general_ts_max_delta |
3162 general_kill_chase_time_limit | general_kline_with_reason |
3163 general_kline_reason | general_invisible_on_connect |
3164 general_warn_no_nline | general_dots_in_ident |
3165 general_stats_o_oper_only | general_stats_k_oper_only |
3166 general_pace_wait | general_stats_i_oper_only |
3167 general_pace_wait_simple | general_stats_P_oper_only |
3168 general_short_motd | general_no_oper_flood |
3169 general_true_no_oper_flood | general_oper_pass_resv |
3170 general_idletime | general_message_locale |
3171 general_oper_only_umodes | general_max_targets |
3172 general_use_egd | general_egdpool_path |
3173 general_oper_umodes | general_caller_id_wait |
3174 general_opers_bypass_callerid | general_default_floodcount |
3175 general_min_nonwildcard | general_min_nonwildcard_simple |
3176 general_servlink_path | general_disable_remote_commands |
3177 general_default_cipher_preference |
3178 general_compression_level | general_client_flood |
3179 general_throttle_time | general_havent_read_conf |
3180 general_dot_in_ip6_addr | general_ping_cookie |
3181 general_disable_auth | general_burst_away |
3182 general_tkline_expire_notices | general_gline_min_cidr |
3183 general_gline_min_cidr6 | general_use_whois_actually |
3184 general_reject_hold_time | general_stats_e_disabled |
3185 general_max_watch |
3186 error;
3187
3188
3189 general_max_watch: MAX_WATCH '=' NUMBER ';'
3190 {
3191 ConfigFileEntry.max_watch = $3;
3192 };
3193
3194 general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
3195 {
3196 ConfigFileEntry.gline_min_cidr = $3;
3197 };
3198
3199 general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
3200 {
3201 ConfigFileEntry.gline_min_cidr6 = $3;
3202 };
3203
3204 general_burst_away: BURST_AWAY '=' TBOOL ';'
3205 {
3206 ConfigFileEntry.burst_away = yylval.number;
3207 };
3208
3209 general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';'
3210 {
3211 ConfigFileEntry.use_whois_actually = yylval.number;
3212 };
3213
3214 general_reject_hold_time: TREJECT_HOLD_TIME '=' timespec ';'
3215 {
3216 GlobalSetOptions.rejecttime = yylval.number;
3217 };
3218
3219 general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
3220 {
3221 ConfigFileEntry.tkline_expire_notices = yylval.number;
3222 };
3223
3224 general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' NUMBER ';'
3225 {
3226 ConfigFileEntry.kill_chase_time_limit = $3;
3227 };
3228
3229 general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
3230 {
3231 ConfigFileEntry.hide_spoof_ips = yylval.number;
3232 };
3233
3234 general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
3235 {
3236 ConfigFileEntry.ignore_bogus_ts = yylval.number;
3237 };
3238
3239 general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
3240 {
3241 ConfigFileEntry.disable_remote = yylval.number;
3242 };
3243
3244 general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
3245 {
3246 ConfigFileEntry.failed_oper_notice = yylval.number;
3247 };
3248
3249 general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
3250 {
3251 ConfigFileEntry.anti_nick_flood = yylval.number;
3252 };
3253
3254 general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
3255 {
3256 ConfigFileEntry.max_nick_time = $3;
3257 };
3258
3259 general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
3260 {
3261 ConfigFileEntry.max_nick_changes = $3;
3262 };
3263
3264 general_max_accept: MAX_ACCEPT '=' NUMBER ';'
3265 {
3266 ConfigFileEntry.max_accept = $3;
3267 };
3268
3269 general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
3270 {
3271 ConfigFileEntry.anti_spam_exit_message_time = $3;
3272 };
3273
3274 general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
3275 {
3276 ConfigFileEntry.ts_warn_delta = $3;
3277 };
3278
3279 general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
3280 {
3281 if (conf_parser_ctx.pass == 2)
3282 ConfigFileEntry.ts_max_delta = $3;
3283 };
3284
3285 general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
3286 {
3287 if (($3 > 0) && conf_parser_ctx.pass == 1)
3288 {
3289 ilog(L_CRIT, "You haven't read your config file properly.");
3290 ilog(L_CRIT, "There is a line in the example conf that will kill your server if not removed.");
3291 ilog(L_CRIT, "Consider actually reading/editing the conf file, and removing this line.");
3292 exit(0);
3293 }
3294 };
3295
3296 general_kline_with_reason: KLINE_WITH_REASON '=' TBOOL ';'
3297 {
3298 ConfigFileEntry.kline_with_reason = yylval.number;
3299 };
3300
3301 general_kline_reason: KLINE_REASON '=' QSTRING ';'
3302 {
3303 if (conf_parser_ctx.pass == 2)
3304 {
3305 MyFree(ConfigFileEntry.kline_reason);
3306 DupString(ConfigFileEntry.kline_reason, yylval.string);
3307 }
3308 };
3309
3310 general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
3311 {
3312 ConfigFileEntry.invisible_on_connect = yylval.number;
3313 };
3314
3315 general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
3316 {
3317 ConfigFileEntry.warn_no_nline = yylval.number;
3318 };
3319
3320 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
3321 {
3322 ConfigFileEntry.stats_e_disabled = yylval.number;
3323 };
3324
3325 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
3326 {
3327 ConfigFileEntry.stats_o_oper_only = yylval.number;
3328 };
3329
3330 general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
3331 {
3332 ConfigFileEntry.stats_P_oper_only = yylval.number;
3333 };
3334
3335 general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
3336 {
3337 ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
3338 } | STATS_K_OPER_ONLY '=' TMASKED ';'
3339 {
3340 ConfigFileEntry.stats_k_oper_only = 1;
3341 };
3342
3343 general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
3344 {
3345 ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
3346 } | STATS_I_OPER_ONLY '=' TMASKED ';'
3347 {
3348 ConfigFileEntry.stats_i_oper_only = 1;
3349 };
3350
3351 general_pace_wait: PACE_WAIT '=' timespec ';'
3352 {
3353 ConfigFileEntry.pace_wait = $3;
3354 };
3355
3356 general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
3357 {
3358 ConfigFileEntry.caller_id_wait = $3;
3359 };
3360
3361 general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
3362 {
3363 ConfigFileEntry.opers_bypass_callerid = yylval.number;
3364 };
3365
3366 general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
3367 {
3368 ConfigFileEntry.pace_wait_simple = $3;
3369 };
3370
3371 general_short_motd: SHORT_MOTD '=' TBOOL ';'
3372 {
3373 ConfigFileEntry.short_motd = yylval.number;
3374 };
3375
3376 general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
3377 {
3378 ConfigFileEntry.no_oper_flood = yylval.number;
3379 };
3380
3381 general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
3382 {
3383 ConfigFileEntry.true_no_oper_flood = yylval.number;
3384 };
3385
3386 general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
3387 {
3388 ConfigFileEntry.oper_pass_resv = yylval.number;
3389 };
3390
3391 general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
3392 {
3393 if (conf_parser_ctx.pass == 2)
3394 {
3395 if (strlen(yylval.string) > LOCALE_LENGTH-2)
3396 yylval.string[LOCALE_LENGTH-1] = '\0';
3397
3398 set_locale(yylval.string);
3399 }
3400 };
3401
3402 general_idletime: IDLETIME '=' timespec ';'
3403 {
3404 ConfigFileEntry.idletime = $3;
3405 };
3406
3407 general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
3408 {
3409 ConfigFileEntry.dots_in_ident = $3;
3410 };
3411
3412 general_max_targets: MAX_TARGETS '=' NUMBER ';'
3413 {
3414 ConfigFileEntry.max_targets = $3;
3415 };
3416
3417 general_servlink_path: SERVLINK_PATH '=' QSTRING ';'
3418 {
3419 if (conf_parser_ctx.pass == 2)
3420 {
3421 MyFree(ConfigFileEntry.servlink_path);
3422 DupString(ConfigFileEntry.servlink_path, yylval.string);
3423 }
3424 };
3425
3426 general_default_cipher_preference: DEFAULT_CIPHER_PREFERENCE '=' QSTRING ';'
3427 {
3428 #ifdef HAVE_LIBCRYPTO
3429 if (conf_parser_ctx.pass == 2)
3430 {
3431 struct EncCapability *ecap;
3432 const char *cipher_name;
3433 int found = 0;
3434
3435 ConfigFileEntry.default_cipher_preference = NULL;
3436 cipher_name = yylval.string;
3437
3438 for (ecap = CipherTable; ecap->name; ecap++)
3439 {
3440 if ((irccmp(ecap->name, cipher_name) == 0) &&
3441 (ecap->cap & CAP_ENC_MASK))
3442 {
3443 ConfigFileEntry.default_cipher_preference = ecap;
3444 found = 1;
3445 break;
3446 }
3447 }
3448
3449 if (!found)
3450 yyerror("Invalid cipher");
3451 }
3452 #else
3453 if (conf_parser_ctx.pass == 2)
3454 yyerror("Ignoring default_cipher_preference -- no OpenSSL support");
3455 #endif
3456 };
3457
3458 general_compression_level: COMPRESSION_LEVEL '=' NUMBER ';'
3459 {
3460 if (conf_parser_ctx.pass == 2)
3461 {
3462 ConfigFileEntry.compression_level = $3;
3463 #ifndef HAVE_LIBZ
3464 yyerror("Ignoring compression_level -- no zlib support");
3465 #else
3466 if ((ConfigFileEntry.compression_level < 1) ||
3467 (ConfigFileEntry.compression_level > 9))
3468 {
3469 yyerror("Ignoring invalid compression_level, using default");
3470 ConfigFileEntry.compression_level = 0;
3471 }
3472 #endif
3473 }
3474 };
3475
3476 general_use_egd: USE_EGD '=' TBOOL ';'
3477 {
3478 ConfigFileEntry.use_egd = yylval.number;
3479 };
3480
3481 general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
3482 {
3483 if (conf_parser_ctx.pass == 2)
3484 {
3485 MyFree(ConfigFileEntry.egdpool_path);
3486 DupString(ConfigFileEntry.egdpool_path, yylval.string);
3487 }
3488 };
3489
3490 general_ping_cookie: PING_COOKIE '=' TBOOL ';'
3491 {
3492 ConfigFileEntry.ping_cookie = yylval.number;
3493 };
3494
3495 general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
3496 {
3497 ConfigFileEntry.disable_auth = yylval.number;
3498 };
3499
3500 general_throttle_time: THROTTLE_TIME '=' timespec ';'
3501 {
3502 ConfigFileEntry.throttle_time = yylval.number;
3503 };
3504
3505 general_oper_umodes: OPER_UMODES
3506 {
3507 ConfigFileEntry.oper_umodes = 0;
3508 } '=' umode_oitems ';' ;
3509
3510 umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
3511 umode_oitem: T_BOTS
3512 {
3513 ConfigFileEntry.oper_umodes |= UMODE_BOTS;
3514 } | T_CCONN
3515 {
3516 ConfigFileEntry.oper_umodes |= UMODE_CCONN;
3517 } | T_CCONN_FULL
3518 {
3519 ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
3520 } | T_DEAF
3521 {
3522 ConfigFileEntry.oper_umodes |= UMODE_DEAF;
3523 } | T_DEBUG
3524 {
3525 ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
3526 } | T_FULL
3527 {
3528 ConfigFileEntry.oper_umodes |= UMODE_FULL;
3529 } | T_SKILL
3530 {
3531 ConfigFileEntry.oper_umodes |= UMODE_SKILL;
3532 } | T_NCHANGE
3533 {
3534 ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
3535 } | T_REJ
3536 {
3537 ConfigFileEntry.oper_umodes |= UMODE_REJ;
3538 } | T_UNAUTH
3539 {
3540 ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
3541 } | T_SPY
3542 {
3543 ConfigFileEntry.oper_umodes |= UMODE_SPY;
3544 } | T_EXTERNAL
3545 {
3546 ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
3547 } | T_OPERWALL
3548 {
3549 ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
3550 } | T_SERVNOTICE
3551 {
3552 ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
3553 } | T_INVISIBLE
3554 {
3555 ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
3556 } | T_WALLOP
3557 {
3558 ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
3559 } | T_SOFTCALLERID
3560 {
3561 ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
3562 } | T_CALLERID
3563 {
3564 ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
3565 } | T_LOCOPS
3566 {
3567 ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
3568 };
3569
3570 general_oper_only_umodes: OPER_ONLY_UMODES
3571 {
3572 ConfigFileEntry.oper_only_umodes = 0;
3573 } '=' umode_items ';' ;
3574
3575 umode_items: umode_items ',' umode_item | umode_item;
3576 umode_item: T_BOTS
3577 {
3578 ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
3579 } | T_CCONN
3580 {
3581 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
3582 } | T_CCONN_FULL
3583 {
3584 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
3585 } | T_DEAF
3586 {
3587 ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
3588 } | T_DEBUG
3589 {
3590 ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
3591 } | T_FULL
3592 {
3593 ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
3594 } | T_SKILL
3595 {
3596 ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
3597 } | T_NCHANGE
3598 {
3599 ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
3600 } | T_REJ
3601 {
3602 ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
3603 } | T_UNAUTH
3604 {
3605 ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
3606 } | T_SPY
3607 {
3608 ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
3609 } | T_EXTERNAL
3610 {
3611 ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
3612 } | T_OPERWALL
3613 {
3614 ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
3615 } | T_SERVNOTICE
3616 {
3617 ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
3618 } | T_INVISIBLE
3619 {
3620 ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
3621 } | T_WALLOP
3622 {
3623 ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
3624 } | T_SOFTCALLERID
3625 {
3626 ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
3627 } | T_CALLERID
3628 {
3629 ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
3630 } | T_LOCOPS
3631 {
3632 ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
3633 };
3634
3635 general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
3636 {
3637 ConfigFileEntry.min_nonwildcard = $3;
3638 };
3639
3640 general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
3641 {
3642 ConfigFileEntry.min_nonwildcard_simple = $3;
3643 };
3644
3645 general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
3646 {
3647 ConfigFileEntry.default_floodcount = $3;
3648 };
3649
3650 general_client_flood: T_CLIENT_FLOOD '=' sizespec ';'
3651 {
3652 ConfigFileEntry.client_flood = $3;
3653 };
3654
3655 general_dot_in_ip6_addr: DOT_IN_IP6_ADDR '=' TBOOL ';'
3656 {
3657 ConfigFileEntry.dot_in_ip6_addr = yylval.number;
3658 };
3659
3660 /***************************************************************************
3661 * section glines
3662 ***************************************************************************/
3663 gline_entry: GLINES
3664 {
3665 if (conf_parser_ctx.pass == 2)
3666 {
3667 yy_conf = make_conf_item(GDENY_TYPE);
3668 yy_aconf = map_to_conf(yy_conf);
3669 }
3670 } '{' gline_items '}' ';'
3671 {
3672 if (conf_parser_ctx.pass == 2)
3673 {
3674 /*
3675 * since we re-allocate yy_conf/yy_aconf after the end of action=, at the
3676 * end we will have one extra, so we should free it.
3677 */
3678 if (yy_conf->name == NULL || yy_aconf->user == NULL)
3679 {
3680 delete_conf_item(yy_conf);
3681 yy_conf = NULL;
3682 yy_aconf = NULL;
3683 }
3684 }
3685 };
3686
3687 gline_items: gline_items gline_item | gline_item;
3688 gline_item: gline_enable |
3689 gline_duration |
3690 gline_logging |
3691 gline_user |
3692 gline_server |
3693 gline_action |
3694 error;
3695
3696 gline_enable: ENABLE '=' TBOOL ';'
3697 {
3698 if (conf_parser_ctx.pass == 2)
3699 ConfigFileEntry.glines = yylval.number;
3700 };
3701
3702 gline_duration: DURATION '=' timespec ';'
3703 {
3704 if (conf_parser_ctx.pass == 2)
3705 ConfigFileEntry.gline_time = $3;
3706 };
3707
3708 gline_logging: LOGGING
3709 {
3710 if (conf_parser_ctx.pass == 2)
3711 ConfigFileEntry.gline_logging = 0;
3712 } '=' gline_logging_types ';';
3713 gline_logging_types: gline_logging_types ',' gline_logging_type_item | gline_logging_type_item;
3714 gline_logging_type_item: T_REJECT
3715 {
3716 if (conf_parser_ctx.pass == 2)
3717 ConfigFileEntry.gline_logging |= GDENY_REJECT;
3718 } | T_BLOCK
3719 {
3720 if (conf_parser_ctx.pass == 2)
3721 ConfigFileEntry.gline_logging |= GDENY_BLOCK;
3722 };
3723
3724 gline_user: USER '=' QSTRING ';'
3725 {
3726 if (conf_parser_ctx.pass == 2)
3727 {
3728 struct split_nuh_item nuh;
3729
3730 nuh.nuhmask = yylval.string;
3731 nuh.nickptr = NULL;
3732 nuh.userptr = userbuf;
3733 nuh.hostptr = hostbuf;
3734
3735 nuh.nicksize = 0;
3736 nuh.usersize = sizeof(userbuf);
3737 nuh.hostsize = sizeof(hostbuf);
3738
3739 split_nuh(&nuh);
3740
3741 if (yy_aconf->user == NULL)
3742 {
3743 DupString(yy_aconf->user, userbuf);
3744 DupString(yy_aconf->host, hostbuf);
3745 }
3746 else
3747 {
3748 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
3749
3750 DupString(yy_tmp->user, userbuf);
3751 DupString(yy_tmp->host, hostbuf);
3752
3753 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
3754 }
3755 }
3756 };
3757
3758 gline_server: NAME '=' QSTRING ';'
3759 {
3760 if (conf_parser_ctx.pass == 2)
3761 {
3762 MyFree(yy_conf->name);
3763 DupString(yy_conf->name, yylval.string);
3764 }
3765 };
3766
3767 gline_action: ACTION
3768 {
3769 if (conf_parser_ctx.pass == 2)
3770 yy_aconf->flags = 0;
3771 } '=' gdeny_types ';'
3772 {
3773 if (conf_parser_ctx.pass == 2)
3774 {
3775 struct CollectItem *yy_tmp = NULL;
3776 dlink_node *ptr, *next_ptr;
3777
3778 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
3779 {
3780 struct AccessItem *new_aconf;
3781 struct ConfItem *new_conf;
3782
3783 yy_tmp = ptr->data;
3784 new_conf = make_conf_item(GDENY_TYPE);
3785 new_aconf = map_to_conf(new_conf);
3786
3787 new_aconf->flags = yy_aconf->flags;
3788
3789 if (yy_conf->name != NULL)
3790 DupString(new_conf->name, yy_conf->name);
3791 else
3792 DupString(new_conf->name, "*");
3793 if (yy_aconf->user != NULL)
3794 DupString(new_aconf->user, yy_tmp->user);
3795 else
3796 DupString(new_aconf->user, "*");
3797 if (yy_aconf->host != NULL)
3798 DupString(new_aconf->host, yy_tmp->host);
3799 else
3800 DupString(new_aconf->host, "*");
3801
3802 dlinkDelete(&yy_tmp->node, &col_conf_list);
3803 }
3804
3805 /*
3806 * In case someone has fed us with more than one action= after user/name
3807 * which would leak memory -Michael
3808 */
3809 if (yy_conf->name == NULL || yy_aconf->user == NULL)
3810 delete_conf_item(yy_conf);
3811
3812 yy_conf = make_conf_item(GDENY_TYPE);
3813 yy_aconf = map_to_conf(yy_conf);
3814 }
3815 };
3816
3817 gdeny_types: gdeny_types ',' gdeny_type_item | gdeny_type_item;
3818 gdeny_type_item: T_REJECT
3819 {
3820 if (conf_parser_ctx.pass == 2)
3821 yy_aconf->flags |= GDENY_REJECT;
3822 } | T_BLOCK
3823 {
3824 if (conf_parser_ctx.pass == 2)
3825 yy_aconf->flags |= GDENY_BLOCK;
3826 };
3827
3828 /***************************************************************************
3829 * section channel
3830 ***************************************************************************/
3831 channel_entry: CHANNEL
3832 '{' channel_items '}' ';';
3833
3834 channel_items: channel_items channel_item | channel_item;
3835 channel_item: channel_disable_local_channels | channel_use_except |
3836 channel_use_invex | channel_use_knock |
3837 channel_max_bans | channel_knock_delay |
3838 channel_knock_delay_channel | channel_max_chans_per_user |
3839 channel_quiet_on_ban | channel_default_split_user_count |
3840 channel_default_split_server_count |
3841 channel_no_create_on_split | channel_restrict_channels |
3842 channel_no_join_on_split | channel_burst_topicwho |
3843 channel_jflood_count | channel_jflood_time |
3844 channel_disable_fake_channels | error;
3845
3846 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
3847 {
3848 ConfigChannel.disable_fake_channels = yylval.number;
3849 };
3850
3851 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
3852 {
3853 ConfigChannel.restrict_channels = yylval.number;
3854 };
3855
3856 channel_disable_local_channels: DISABLE_LOCAL_CHANNELS '=' TBOOL ';'
3857 {
3858 ConfigChannel.disable_local_channels = yylval.number;
3859 };
3860
3861 channel_use_except: USE_EXCEPT '=' TBOOL ';'
3862 {
3863 ConfigChannel.use_except = yylval.number;
3864 };
3865
3866 channel_use_invex: USE_INVEX '=' TBOOL ';'
3867 {
3868 ConfigChannel.use_invex = yylval.number;
3869 };
3870
3871 channel_use_knock: USE_KNOCK '=' TBOOL ';'
3872 {
3873 ConfigChannel.use_knock = yylval.number;
3874 };
3875
3876 channel_knock_delay: KNOCK_DELAY '=' timespec ';'
3877 {
3878 ConfigChannel.knock_delay = $3;
3879 };
3880
3881 channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
3882 {
3883 ConfigChannel.knock_delay_channel = $3;
3884 };
3885
3886 channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
3887 {
3888 ConfigChannel.max_chans_per_user = $3;
3889 };
3890
3891 channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
3892 {
3893 ConfigChannel.quiet_on_ban = yylval.number;
3894 };
3895
3896 channel_max_bans: MAX_BANS '=' NUMBER ';'
3897 {
3898 ConfigChannel.max_bans = $3;
3899 };
3900
3901 channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
3902 {
3903 ConfigChannel.default_split_user_count = $3;
3904 };
3905
3906 channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
3907 {
3908 ConfigChannel.default_split_server_count = $3;
3909 };
3910
3911 channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
3912 {
3913 ConfigChannel.no_create_on_split = yylval.number;
3914 };
3915
3916 channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
3917 {
3918 ConfigChannel.no_join_on_split = yylval.number;
3919 };
3920
3921 channel_burst_topicwho: BURST_TOPICWHO '=' TBOOL ';'
3922 {
3923 ConfigChannel.burst_topicwho = yylval.number;
3924 };
3925
3926 channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3927 {
3928 GlobalSetOptions.joinfloodcount = yylval.number;
3929 };
3930
3931 channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
3932 {
3933 GlobalSetOptions.joinfloodtime = yylval.number;
3934 };
3935
3936 /***************************************************************************
3937 * section serverhide
3938 ***************************************************************************/
3939 serverhide_entry: SERVERHIDE
3940 '{' serverhide_items '}' ';';
3941
3942 serverhide_items: serverhide_items serverhide_item | serverhide_item;
3943 serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
3944 serverhide_links_delay |
3945 serverhide_disable_hidden |
3946 serverhide_hidden | serverhide_hidden_name |
3947 serverhide_hide_server_ips |
3948 error;
3949
3950 serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
3951 {
3952 if (conf_parser_ctx.pass == 2)
3953 ConfigServerHide.flatten_links = yylval.number;
3954 };
3955
3956 serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
3957 {
3958 if (conf_parser_ctx.pass == 2)
3959 ConfigServerHide.hide_servers = yylval.number;
3960 };
3961
3962 serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
3963 {
3964 if (conf_parser_ctx.pass == 2)
3965 {
3966 MyFree(ConfigServerHide.hidden_name);
3967 DupString(ConfigServerHide.hidden_name, yylval.string);
3968 }
3969 };
3970
3971 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
3972 {
3973 if (conf_parser_ctx.pass == 2)
3974 {
3975 if (($3 > 0) && ConfigServerHide.links_disabled == 1)
3976 {
3977 eventAddIsh("write_links_file", write_links_file, NULL, $3);
3978 ConfigServerHide.links_disabled = 0;
3979 }
3980
3981 ConfigServerHide.links_delay = $3;
3982 }
3983 };
3984
3985 serverhide_hidden: HIDDEN '=' TBOOL ';'
3986 {
3987 if (conf_parser_ctx.pass == 2)
3988 ConfigServerHide.hidden = yylval.number;
3989 };
3990
3991 serverhide_disable_hidden: DISABLE_HIDDEN '=' TBOOL ';'
3992 {
3993 if (conf_parser_ctx.pass == 2)
3994 ConfigServerHide.disable_hidden = yylval.number;
3995 };
3996
3997 serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
3998 {
3999 if (conf_parser_ctx.pass == 2)
4000 ConfigServerHide.hide_server_ips = yylval.number;
4001 };

Properties

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