ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1474
Committed: Sun Jul 22 14:44:07 2012 UTC (13 years, 1 month ago) by michael
Original Path: ircd-hybrid-8/src/conf_parser.y
File size: 74961 byte(s)
Log Message:
- removed &localchannels

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * conf_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 #include "stdinc.h"
33 #include "ircd.h"
34 #include "list.h"
35 #include "conf.h"
36 #include "event.h"
37 #include "log.h"
38 #include "client.h" /* for UMODE_ALL only */
39 #include "irc_string.h"
40 #include "sprintf_irc.h"
41 #include "memory.h"
42 #include "modules.h"
43 #include "s_serv.h"
44 #include "hostmask.h"
45 #include "send.h"
46 #include "listener.h"
47 #include "resv.h"
48 #include "numeric.h"
49 #include "s_user.h"
50
51 #ifdef HAVE_LIBCRYPTO
52 #include <openssl/rsa.h>
53 #include <openssl/bio.h>
54 #include <openssl/pem.h>
55 #include <openssl/dh.h>
56 #endif
57
58 int yylex(void);
59
60 static char *class_name = NULL;
61 static struct ConfItem *yy_conf = NULL;
62 static struct AccessItem *yy_aconf = NULL;
63 static struct MatchItem *yy_match_item = NULL;
64 static struct ClassItem *yy_class = NULL;
65 static char *yy_class_name = NULL;
66
67 static dlink_list col_conf_list = { NULL, NULL, 0 };
68 static unsigned int listener_flags = 0;
69 static unsigned int regex_ban = 0;
70 static char userbuf[IRCD_BUFSIZE];
71 static char hostbuf[IRCD_BUFSIZE];
72 static char reasonbuf[REASONLEN + 1];
73 static char gecos_name[REALLEN * 4];
74 static char lfile[IRCD_BUFSIZE];
75 static unsigned int ltype = 0;
76 static unsigned int lsize = 0;
77 static char *resv_reason = NULL;
78 static char *listener_address = NULL;
79
80 struct CollectItem
81 {
82 dlink_node node;
83 char *name;
84 char *user;
85 char *host;
86 char *passwd;
87 int port;
88 int flags;
89 #ifdef HAVE_LIBCRYPTO
90 char *rsa_public_key_file;
91 RSA *rsa_public_key;
92 #endif
93 };
94
95 static void
96 free_collect_item(struct CollectItem *item)
97 {
98 MyFree(item->name);
99 MyFree(item->user);
100 MyFree(item->host);
101 MyFree(item->passwd);
102 #ifdef HAVE_LIBCRYPTO
103 MyFree(item->rsa_public_key_file);
104 #endif
105 MyFree(item);
106 }
107
108 %}
109
110 %union {
111 int number;
112 char *string;
113 }
114
115 %token ACCEPT_PASSWORD
116 %token ACTION
117 %token ADMIN
118 %token AFTYPE
119 %token T_ALLOW
120 %token ANTI_NICK_FLOOD
121 %token ANTI_SPAM_EXIT_MESSAGE_TIME
122 %token AUTOCONN
123 %token T_BLOCK
124 %token BURST_AWAY
125 %token BYTES KBYTES MBYTES GBYTES TBYTES
126 %token CALLER_ID_WAIT
127 %token CAN_FLOOD
128 %token CHANNEL
129 %token CIDR_BITLEN_IPV4
130 %token CIDR_BITLEN_IPV6
131 %token CLASS
132 %token CONNECT
133 %token CONNECTFREQ
134 %token DEFAULT_FLOODCOUNT
135 %token DEFAULT_SPLIT_SERVER_COUNT
136 %token DEFAULT_SPLIT_USER_COUNT
137 %token DENY
138 %token DESCRIPTION
139 %token DIE
140 %token DISABLE_AUTH
141 %token DISABLE_FAKE_CHANNELS
142 %token DISABLE_HIDDEN
143 %token DISABLE_REMOTE_COMMANDS
144 %token DOTS_IN_IDENT
145 %token DURATION
146 %token EGDPOOL_PATH
147 %token EMAIL
148 %token ENABLE
149 %token ENCRYPTED
150 %token EXCEED_LIMIT
151 %token EXEMPT
152 %token FAILED_OPER_NOTICE
153 %token IRCD_FLAGS
154 %token FLATTEN_LINKS
155 %token GECOS
156 %token GENERAL
157 %token GLINE
158 %token GLINE_DURATION
159 %token GLINE_ENABLE
160 %token GLINE_EXEMPT
161 %token GLINE_TIME
162 %token GLINE_REQUEST_DURATION
163 %token GLINE_MIN_CIDR
164 %token GLINE_MIN_CIDR6
165 %token GLOBAL_KILL
166 %token IRCD_AUTH
167 %token NEED_IDENT
168 %token HAVENT_READ_CONF
169 %token HIDDEN
170 %token HIDDEN_NAME
171 %token HIDE_SERVER_IPS
172 %token HIDE_SERVERS
173 %token HIDE_SPOOF_IPS
174 %token HOST
175 %token HUB
176 %token HUB_MASK
177 %token IGNORE_BOGUS_TS
178 %token INVISIBLE_ON_CONNECT
179 %token IP
180 %token KILL
181 %token KILL_CHASE_TIME_LIMIT
182 %token KLINE
183 %token KLINE_EXEMPT
184 %token KLINE_REASON
185 %token KLINE_WITH_REASON
186 %token KNOCK_DELAY
187 %token KNOCK_DELAY_CHANNEL
188 %token LEAF_MASK
189 %token LINKS_DELAY
190 %token LISTEN
191 %token T_LOG
192 %token MAX_ACCEPT
193 %token MAX_BANS
194 %token MAX_CHANS_PER_OPER
195 %token MAX_CHANS_PER_USER
196 %token MAX_GLOBAL
197 %token MAX_IDENT
198 %token MAX_LOCAL
199 %token MAX_NICK_CHANGES
200 %token MAX_NICK_TIME
201 %token MAX_NUMBER
202 %token MAX_TARGETS
203 %token MAX_WATCH
204 %token MESSAGE_LOCALE
205 %token MIN_NONWILDCARD
206 %token MIN_NONWILDCARD_SIMPLE
207 %token MODULE
208 %token MODULES
209 %token NAME
210 %token NEED_PASSWORD
211 %token NETWORK_DESC
212 %token NETWORK_NAME
213 %token NICK
214 %token NICK_CHANGES
215 %token NO_CREATE_ON_SPLIT
216 %token NO_JOIN_ON_SPLIT
217 %token NO_OPER_FLOOD
218 %token NO_TILDE
219 %token NUMBER
220 %token NUMBER_PER_IDENT
221 %token NUMBER_PER_CIDR
222 %token NUMBER_PER_IP
223 %token NUMBER_PER_IP_GLOBAL
224 %token OPERATOR
225 %token OPERS_BYPASS_CALLERID
226 %token OPER_ONLY_UMODES
227 %token OPER_PASS_RESV
228 %token OPER_SPY_T
229 %token OPER_UMODES
230 %token JOIN_FLOOD_COUNT
231 %token JOIN_FLOOD_TIME
232 %token PACE_WAIT
233 %token PACE_WAIT_SIMPLE
234 %token PASSWORD
235 %token PATH
236 %token PING_COOKIE
237 %token PING_TIME
238 %token PING_WARNING
239 %token PORT
240 %token QSTRING
241 %token QUIET_ON_BAN
242 %token REASON
243 %token REDIRPORT
244 %token REDIRSERV
245 %token REGEX_T
246 %token REHASH
247 %token TREJECT_HOLD_TIME
248 %token REMOTE
249 %token REMOTEBAN
250 %token RESTRICT_CHANNELS
251 %token RESTRICTED
252 %token RSA_PRIVATE_KEY_FILE
253 %token RSA_PUBLIC_KEY_FILE
254 %token SSL_CERTIFICATE_FILE
255 %token SSL_DH_PARAM_FILE
256 %token T_SSL_CLIENT_METHOD
257 %token T_SSL_SERVER_METHOD
258 %token T_SSLV3
259 %token T_TLSV1
260 %token RESV
261 %token RESV_EXEMPT
262 %token SECONDS MINUTES HOURS DAYS WEEKS
263 %token SENDQ
264 %token SEND_PASSWORD
265 %token SERVERHIDE
266 %token SERVERINFO
267 %token IRCD_SID
268 %token TKLINE_EXPIRE_NOTICES
269 %token T_SHARED
270 %token T_CLUSTER
271 %token TYPE
272 %token SHORT_MOTD
273 %token SILENT
274 %token SPOOF
275 %token SPOOF_NOTICE
276 %token STATS_E_DISABLED
277 %token STATS_I_OPER_ONLY
278 %token STATS_K_OPER_ONLY
279 %token STATS_O_OPER_ONLY
280 %token STATS_P_OPER_ONLY
281 %token TBOOL
282 %token TMASKED
283 %token T_REJECT
284 %token TS_MAX_DELTA
285 %token TS_WARN_DELTA
286 %token TWODOTS
287 %token T_ALL
288 %token T_BOTS
289 %token T_SOFTCALLERID
290 %token T_CALLERID
291 %token T_CCONN
292 %token T_CCONN_FULL
293 %token T_SSL_CIPHER_LIST
294 %token T_CLIENT_FLOOD
295 %token T_DEAF
296 %token T_DEBUG
297 %token T_DLINE
298 %token T_DRONE
299 %token T_EXTERNAL
300 %token T_FULL
301 %token T_INVISIBLE
302 %token T_IPV4
303 %token T_IPV6
304 %token T_LOCOPS
305 %token T_MAX_CLIENTS
306 %token T_NCHANGE
307 %token T_OPERWALL
308 %token T_REJ
309 %token T_SERVER
310 %token T_SERVNOTICE
311 %token T_SET
312 %token T_SKILL
313 %token T_SPY
314 %token T_SSL
315 %token T_UMODES
316 %token T_UNAUTH
317 %token T_UNDLINE
318 %token T_UNLIMITED
319 %token T_UNRESV
320 %token T_UNXLINE
321 %token T_GLOBOPS
322 %token T_WALLOP
323 %token T_RESTART
324 %token T_SERVICE
325 %token T_SERVICES_NAME
326 %token THROTTLE_TIME
327 %token TOPICBURST
328 %token TRUE_NO_OPER_FLOOD
329 %token TKLINE
330 %token TXLINE
331 %token TRESV
332 %token UNKLINE
333 %token USER
334 %token USE_EGD
335 %token USE_EXCEPT
336 %token USE_INVEX
337 %token USE_KNOCK
338 %token USE_LOGGING
339 %token USE_WHOIS_ACTUALLY
340 %token VHOST
341 %token VHOST6
342 %token XLINE
343 %token WARN
344 %token WARN_NO_NLINE
345 %token T_SIZE
346 %token T_FILE
347
348 %type <string> QSTRING
349 %type <number> NUMBER
350 %type <number> timespec
351 %type <number> timespec_
352 %type <number> sizespec
353 %type <number> sizespec_
354
355 %%
356 conf:
357 | conf conf_item
358 ;
359
360 conf_item: admin_entry
361 | logging_entry
362 | oper_entry
363 | channel_entry
364 | class_entry
365 | listen_entry
366 | auth_entry
367 | serverinfo_entry
368 | serverhide_entry
369 | resv_entry
370 | service_entry
371 | shared_entry
372 | cluster_entry
373 | connect_entry
374 | kill_entry
375 | deny_entry
376 | exempt_entry
377 | general_entry
378 | gecos_entry
379 | modules_entry
380 | error ';'
381 | error '}'
382 ;
383
384
385 timespec_: { $$ = 0; } | timespec;
386 timespec: NUMBER timespec_
387 {
388 $$ = $1 + $2;
389 }
390 | NUMBER SECONDS timespec_
391 {
392 $$ = $1 + $3;
393 }
394 | NUMBER MINUTES timespec_
395 {
396 $$ = $1 * 60 + $3;
397 }
398 | NUMBER HOURS timespec_
399 {
400 $$ = $1 * 60 * 60 + $3;
401 }
402 | NUMBER DAYS timespec_
403 {
404 $$ = $1 * 60 * 60 * 24 + $3;
405 }
406 | NUMBER WEEKS timespec_
407 {
408 $$ = $1 * 60 * 60 * 24 * 7 + $3;
409 }
410 ;
411
412 sizespec_: { $$ = 0; } | sizespec;
413 sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
414 | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
415 | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
416 | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
417 ;
418
419
420 /***************************************************************************
421 * section modules
422 ***************************************************************************/
423 modules_entry: MODULES
424 '{' modules_items '}' ';';
425
426 modules_items: modules_items modules_item | modules_item;
427 modules_item: modules_module | modules_path | error ';' ;
428
429 modules_module: MODULE '=' QSTRING ';'
430 {
431 if (conf_parser_ctx.pass == 2)
432 add_conf_module(libio_basename(yylval.string));
433 };
434
435 modules_path: PATH '=' QSTRING ';'
436 {
437 if (conf_parser_ctx.pass == 2)
438 mod_add_path(yylval.string);
439 };
440
441
442 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
443
444 serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
445 serverinfo_item: serverinfo_name | serverinfo_vhost |
446 serverinfo_hub | serverinfo_description |
447 serverinfo_network_name | serverinfo_network_desc |
448 serverinfo_max_clients | serverinfo_ssl_dh_param_file |
449 serverinfo_rsa_private_key_file | serverinfo_vhost6 |
450 serverinfo_sid | serverinfo_ssl_certificate_file |
451 serverinfo_ssl_client_method | serverinfo_ssl_server_method |
452 serverinfo_ssl_cipher_list |
453 error ';' ;
454
455
456 serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
457 serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;
458
459 client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
460 client_method_type_item: T_SSLV3
461 {
462 #ifdef HAVE_LIBCRYPTO
463 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
464 SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
465 #endif
466 } | T_TLSV1
467 {
468 #ifdef HAVE_LIBCRYPTO
469 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
470 SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
471 #endif
472 };
473
474 server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
475 server_method_type_item: T_SSLV3
476 {
477 #ifdef HAVE_LIBCRYPTO
478 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
479 SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
480 #endif
481 } | T_TLSV1
482 {
483 #ifdef HAVE_LIBCRYPTO
484 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
485 SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
486 #endif
487 };
488
489 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
490 {
491 #ifdef HAVE_LIBCRYPTO
492 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
493 {
494 if (!ServerInfo.rsa_private_key_file)
495 {
496 yyerror("No rsa_private_key_file specified, SSL disabled");
497 break;
498 }
499
500 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
501 SSL_FILETYPE_PEM) <= 0 ||
502 SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string,
503 SSL_FILETYPE_PEM) <= 0)
504 {
505 yyerror(ERR_lib_error_string(ERR_get_error()));
506 break;
507 }
508
509 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
510 SSL_FILETYPE_PEM) <= 0 ||
511 SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file,
512 SSL_FILETYPE_PEM) <= 0)
513 {
514 yyerror(ERR_lib_error_string(ERR_get_error()));
515 break;
516 }
517
518 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) ||
519 !SSL_CTX_check_private_key(ServerInfo.client_ctx))
520 {
521 yyerror(ERR_lib_error_string(ERR_get_error()));
522 break;
523 }
524 }
525 #endif
526 };
527
528 serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
529 {
530 #ifdef HAVE_LIBCRYPTO
531 if (conf_parser_ctx.pass == 1)
532 {
533 BIO *file;
534
535 if (ServerInfo.rsa_private_key)
536 {
537 RSA_free(ServerInfo.rsa_private_key);
538 ServerInfo.rsa_private_key = NULL;
539 }
540
541 if (ServerInfo.rsa_private_key_file)
542 {
543 MyFree(ServerInfo.rsa_private_key_file);
544 ServerInfo.rsa_private_key_file = NULL;
545 }
546
547 DupString(ServerInfo.rsa_private_key_file, yylval.string);
548
549 if ((file = BIO_new_file(yylval.string, "r")) == NULL)
550 {
551 yyerror("File open failed, ignoring");
552 break;
553 }
554
555 ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
556
557 BIO_set_close(file, BIO_CLOSE);
558 BIO_free(file);
559
560 if (ServerInfo.rsa_private_key == NULL)
561 {
562 yyerror("Couldn't extract key, ignoring");
563 break;
564 }
565
566 if (!RSA_check_key(ServerInfo.rsa_private_key))
567 {
568 RSA_free(ServerInfo.rsa_private_key);
569 ServerInfo.rsa_private_key = NULL;
570
571 yyerror("Invalid key, ignoring");
572 break;
573 }
574
575 /* require 2048 bit (256 byte) key */
576 if (RSA_size(ServerInfo.rsa_private_key) != 256)
577 {
578 RSA_free(ServerInfo.rsa_private_key);
579 ServerInfo.rsa_private_key = NULL;
580
581 yyerror("Not a 2048 bit key, ignoring");
582 }
583 }
584 #endif
585 };
586
587 serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
588 {
589 /* TBD - XXX: error reporting */
590 #ifdef HAVE_LIBCRYPTO
591 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
592 {
593 BIO *file = BIO_new_file(yylval.string, "r");
594
595 if (file)
596 {
597 DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
598
599 BIO_free(file);
600
601 if (dh)
602 {
603 if (DH_size(dh) < 128)
604 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
605 else
606 SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh);
607
608 DH_free(dh);
609 }
610 }
611 }
612 #endif
613 };
614
615 serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
616 {
617 #ifdef HAVE_LIBCRYPTO
618 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
619 SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string);
620 #endif
621 };
622
623 serverinfo_name: NAME '=' QSTRING ';'
624 {
625 /* this isn't rehashable */
626 if (conf_parser_ctx.pass == 2 && !ServerInfo.name)
627 {
628 if (valid_servname(yylval.string))
629 DupString(ServerInfo.name, yylval.string);
630 else
631 {
632 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting.");
633 exit(0);
634 }
635 }
636 };
637
638 serverinfo_sid: IRCD_SID '=' QSTRING ';'
639 {
640 /* this isn't rehashable */
641 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
642 {
643 if (valid_sid(yylval.string))
644 DupString(ServerInfo.sid, yylval.string);
645 else
646 {
647 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting.");
648 exit(0);
649 }
650 }
651 };
652
653 serverinfo_description: DESCRIPTION '=' QSTRING ';'
654 {
655 if (conf_parser_ctx.pass == 2)
656 {
657 MyFree(ServerInfo.description);
658 DupString(ServerInfo.description,yylval.string);
659 }
660 };
661
662 serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
663 {
664 if (conf_parser_ctx.pass == 2)
665 {
666 char *p;
667
668 if ((p = strchr(yylval.string, ' ')) != NULL)
669 p = '\0';
670
671 MyFree(ServerInfo.network_name);
672 DupString(ServerInfo.network_name, yylval.string);
673 }
674 };
675
676 serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
677 {
678 if (conf_parser_ctx.pass == 2)
679 {
680 MyFree(ServerInfo.network_desc);
681 DupString(ServerInfo.network_desc, yylval.string);
682 }
683 };
684
685 serverinfo_vhost: VHOST '=' QSTRING ';'
686 {
687 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
688 {
689 struct addrinfo hints, *res;
690
691 memset(&hints, 0, sizeof(hints));
692
693 hints.ai_family = AF_UNSPEC;
694 hints.ai_socktype = SOCK_STREAM;
695 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
696
697 if (getaddrinfo(yylval.string, NULL, &hints, &res))
698 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
699 else
700 {
701 assert(res != NULL);
702
703 memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
704 ServerInfo.ip.ss.ss_family = res->ai_family;
705 ServerInfo.ip.ss_len = res->ai_addrlen;
706 freeaddrinfo(res);
707
708 ServerInfo.specific_ipv4_vhost = 1;
709 }
710 }
711 };
712
713 serverinfo_vhost6: VHOST6 '=' QSTRING ';'
714 {
715 #ifdef IPV6
716 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
717 {
718 struct addrinfo hints, *res;
719
720 memset(&hints, 0, sizeof(hints));
721
722 hints.ai_family = AF_UNSPEC;
723 hints.ai_socktype = SOCK_STREAM;
724 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
725
726 if (getaddrinfo(yylval.string, NULL, &hints, &res))
727 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
728 else
729 {
730 assert(res != NULL);
731
732 memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
733 ServerInfo.ip6.ss.ss_family = res->ai_family;
734 ServerInfo.ip6.ss_len = res->ai_addrlen;
735 freeaddrinfo(res);
736
737 ServerInfo.specific_ipv6_vhost = 1;
738 }
739 }
740 #endif
741 };
742
743 serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
744 {
745 if (conf_parser_ctx.pass == 2)
746 {
747 recalc_fdlimit(NULL);
748
749 if ($3 < MAXCLIENTS_MIN)
750 {
751 char buf[IRCD_BUFSIZE];
752 ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
753 yyerror(buf);
754 }
755 else if ($3 > MAXCLIENTS_MAX)
756 {
757 char buf[IRCD_BUFSIZE];
758 ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
759 yyerror(buf);
760 }
761 else
762 ServerInfo.max_clients = $3;
763 }
764 };
765
766 serverinfo_hub: HUB '=' TBOOL ';'
767 {
768 if (conf_parser_ctx.pass == 2)
769 ServerInfo.hub = yylval.number;
770 };
771
772 /***************************************************************************
773 * admin section
774 ***************************************************************************/
775 admin_entry: ADMIN '{' admin_items '}' ';' ;
776
777 admin_items: admin_items admin_item | admin_item;
778 admin_item: admin_name | admin_description |
779 admin_email | error ';' ;
780
781 admin_name: NAME '=' QSTRING ';'
782 {
783 if (conf_parser_ctx.pass == 2)
784 {
785 MyFree(AdminInfo.name);
786 DupString(AdminInfo.name, yylval.string);
787 }
788 };
789
790 admin_email: EMAIL '=' QSTRING ';'
791 {
792 if (conf_parser_ctx.pass == 2)
793 {
794 MyFree(AdminInfo.email);
795 DupString(AdminInfo.email, yylval.string);
796 }
797 };
798
799 admin_description: DESCRIPTION '=' QSTRING ';'
800 {
801 if (conf_parser_ctx.pass == 2)
802 {
803 MyFree(AdminInfo.description);
804 DupString(AdminInfo.description, yylval.string);
805 }
806 };
807
808 /***************************************************************************
809 * section logging
810 ***************************************************************************/
811 logging_entry: T_LOG '{' logging_items '}' ';' ;
812 logging_items: logging_items logging_item | logging_item ;
813
814 logging_item: logging_use_logging | logging_file_entry |
815 error ';' ;
816
817 logging_use_logging: USE_LOGGING '=' TBOOL ';'
818 {
819 if (conf_parser_ctx.pass == 2)
820 ConfigLoggingEntry.use_logging = yylval.number;
821 };
822
823 logging_file_entry:
824 {
825 lfile[0] = '\0';
826 ltype = 0;
827 lsize = 0;
828 } T_FILE '{' logging_file_items '}' ';'
829 {
830 if (conf_parser_ctx.pass == 2 && ltype > 0)
831 log_add_file(ltype, lsize, lfile);
832 };
833
834 logging_file_items: logging_file_items logging_file_item |
835 logging_file_item ;
836
837 logging_file_item: logging_file_name | logging_file_type |
838 logging_file_size | error ';' ;
839
840 logging_file_name: NAME '=' QSTRING ';'
841 {
842 strlcpy(lfile, yylval.string, sizeof(lfile));
843 }
844
845 logging_file_size: T_SIZE '=' sizespec ';'
846 {
847 lsize = $3;
848 } | T_SIZE '=' T_UNLIMITED ';'
849 {
850 lsize = 0;
851 };
852
853 logging_file_type: TYPE
854 {
855 if (conf_parser_ctx.pass == 2)
856 ltype = 0;
857 } '=' logging_file_type_items ';' ;
858
859 logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item;
860 logging_file_type_item: USER
861 {
862 if (conf_parser_ctx.pass == 2)
863 ltype = LOG_TYPE_USER;
864 } | OPERATOR
865 {
866 if (conf_parser_ctx.pass == 2)
867 ltype = LOG_TYPE_OPER;
868 } | GLINE
869 {
870 if (conf_parser_ctx.pass == 2)
871 ltype = LOG_TYPE_GLINE;
872 } | T_DLINE
873 {
874 if (conf_parser_ctx.pass == 2)
875 ltype = LOG_TYPE_DLINE;
876 } | KLINE
877 {
878 if (conf_parser_ctx.pass == 2)
879 ltype = LOG_TYPE_KLINE;
880 } | KILL
881 {
882 if (conf_parser_ctx.pass == 2)
883 ltype = LOG_TYPE_KILL;
884 } | T_DEBUG
885 {
886 if (conf_parser_ctx.pass == 2)
887 ltype = LOG_TYPE_DEBUG;
888 };
889
890
891 /***************************************************************************
892 * section oper
893 ***************************************************************************/
894 oper_entry: OPERATOR
895 {
896 if (conf_parser_ctx.pass == 2)
897 {
898 yy_conf = make_conf_item(OPER_TYPE);
899 yy_aconf = map_to_conf(yy_conf);
900 SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */
901 }
902 else
903 {
904 MyFree(class_name);
905 class_name = NULL;
906 }
907 } '{' oper_items '}' ';'
908 {
909 if (conf_parser_ctx.pass == 2)
910 {
911 struct CollectItem *yy_tmp;
912 dlink_node *ptr;
913 dlink_node *next_ptr;
914
915 conf_add_class_to_conf(yy_conf, class_name);
916
917 /* Now, make sure there is a copy of the "base" given oper
918 * block in each of the collected copies
919 */
920
921 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
922 {
923 struct AccessItem *new_aconf;
924 struct ConfItem *new_conf;
925 yy_tmp = ptr->data;
926
927 new_conf = make_conf_item(OPER_TYPE);
928 new_aconf = (struct AccessItem *)map_to_conf(new_conf);
929
930 new_aconf->flags = yy_aconf->flags;
931
932 if (yy_conf->name != NULL)
933 DupString(new_conf->name, yy_conf->name);
934 if (yy_tmp->user != NULL)
935 DupString(new_aconf->user, yy_tmp->user);
936 else
937 DupString(new_aconf->user, "*");
938 if (yy_tmp->host != NULL)
939 DupString(new_aconf->host, yy_tmp->host);
940 else
941 DupString(new_aconf->host, "*");
942
943 new_aconf->type = parse_netmask(new_aconf->host, &new_aconf->addr,
944 &new_aconf->bits);
945
946 conf_add_class_to_conf(new_conf, class_name);
947 if (yy_aconf->passwd != NULL)
948 DupString(new_aconf->passwd, yy_aconf->passwd);
949
950 new_aconf->port = yy_aconf->port;
951 #ifdef HAVE_LIBCRYPTO
952 if (yy_aconf->rsa_public_key_file != NULL)
953 {
954 BIO *file;
955
956 DupString(new_aconf->rsa_public_key_file,
957 yy_aconf->rsa_public_key_file);
958
959 file = BIO_new_file(yy_aconf->rsa_public_key_file, "r");
960 new_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file,
961 NULL, 0, NULL);
962 BIO_set_close(file, BIO_CLOSE);
963 BIO_free(file);
964 }
965 #endif
966
967 #ifdef HAVE_LIBCRYPTO
968 if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key)
969 && yy_tmp->host)
970 #else
971 if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host)
972 #endif
973 {
974 conf_add_class_to_conf(new_conf, class_name);
975 if (yy_tmp->name != NULL)
976 DupString(new_conf->name, yy_tmp->name);
977 }
978
979 dlinkDelete(&yy_tmp->node, &col_conf_list);
980 free_collect_item(yy_tmp);
981 }
982
983 yy_conf = NULL;
984 yy_aconf = NULL;
985
986
987 MyFree(class_name);
988 class_name = NULL;
989 }
990 };
991
992 oper_items: oper_items oper_item | oper_item;
993 oper_item: oper_name | oper_user | oper_password |
994 oper_umodes | oper_class | oper_encrypted |
995 oper_rsa_public_key_file | oper_flags | error ';' ;
996
997 oper_name: NAME '=' QSTRING ';'
998 {
999 if (conf_parser_ctx.pass == 2)
1000 {
1001 MyFree(yy_conf->name);
1002 DupString(yy_conf->name, yylval.string);
1003 }
1004 };
1005
1006 oper_user: USER '=' QSTRING ';'
1007 {
1008 if (conf_parser_ctx.pass == 2)
1009 {
1010 struct split_nuh_item nuh;
1011
1012 nuh.nuhmask = yylval.string;
1013 nuh.nickptr = NULL;
1014 nuh.userptr = userbuf;
1015 nuh.hostptr = hostbuf;
1016
1017 nuh.nicksize = 0;
1018 nuh.usersize = sizeof(userbuf);
1019 nuh.hostsize = sizeof(hostbuf);
1020
1021 split_nuh(&nuh);
1022
1023 if (yy_aconf->user == NULL)
1024 {
1025 DupString(yy_aconf->user, userbuf);
1026 DupString(yy_aconf->host, hostbuf);
1027
1028 yy_aconf->type = parse_netmask(yy_aconf->host, &yy_aconf->addr,
1029 &yy_aconf->bits);
1030 }
1031 else
1032 {
1033 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
1034
1035 DupString(yy_tmp->user, userbuf);
1036 DupString(yy_tmp->host, hostbuf);
1037
1038 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1039 }
1040 }
1041 };
1042
1043 oper_password: PASSWORD '=' QSTRING ';'
1044 {
1045 if (conf_parser_ctx.pass == 2)
1046 {
1047 if (yy_aconf->passwd != NULL)
1048 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1049
1050 MyFree(yy_aconf->passwd);
1051 DupString(yy_aconf->passwd, yylval.string);
1052 }
1053 };
1054
1055 oper_encrypted: ENCRYPTED '=' TBOOL ';'
1056 {
1057 if (conf_parser_ctx.pass == 2)
1058 {
1059 if (yylval.number)
1060 SetConfEncrypted(yy_aconf);
1061 else
1062 ClearConfEncrypted(yy_aconf);
1063 }
1064 };
1065
1066 oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1067 {
1068 #ifdef HAVE_LIBCRYPTO
1069 if (conf_parser_ctx.pass == 2)
1070 {
1071 BIO *file;
1072
1073 if (yy_aconf->rsa_public_key != NULL)
1074 {
1075 RSA_free(yy_aconf->rsa_public_key);
1076 yy_aconf->rsa_public_key = NULL;
1077 }
1078
1079 if (yy_aconf->rsa_public_key_file != NULL)
1080 {
1081 MyFree(yy_aconf->rsa_public_key_file);
1082 yy_aconf->rsa_public_key_file = NULL;
1083 }
1084
1085 DupString(yy_aconf->rsa_public_key_file, yylval.string);
1086 file = BIO_new_file(yylval.string, "r");
1087
1088 if (file == NULL)
1089 {
1090 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
1091 break;
1092 }
1093
1094 yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
1095
1096 if (yy_aconf->rsa_public_key == NULL)
1097 {
1098 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1099 break;
1100 }
1101
1102 BIO_set_close(file, BIO_CLOSE);
1103 BIO_free(file);
1104 }
1105 #endif /* HAVE_LIBCRYPTO */
1106 };
1107
1108 oper_class: CLASS '=' QSTRING ';'
1109 {
1110 if (conf_parser_ctx.pass == 2)
1111 {
1112 MyFree(class_name);
1113 DupString(class_name, yylval.string);
1114 }
1115 };
1116
1117 oper_umodes: T_UMODES
1118 {
1119 if (conf_parser_ctx.pass == 2)
1120 yy_aconf->modes = 0;
1121 } '=' oper_umodes_items ';' ;
1122
1123 oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1124 oper_umodes_item: T_BOTS
1125 {
1126 if (conf_parser_ctx.pass == 2)
1127 yy_aconf->modes |= UMODE_BOTS;
1128 } | T_CCONN
1129 {
1130 if (conf_parser_ctx.pass == 2)
1131 yy_aconf->modes |= UMODE_CCONN;
1132 } | T_CCONN_FULL
1133 {
1134 if (conf_parser_ctx.pass == 2)
1135 yy_aconf->modes |= UMODE_CCONN_FULL;
1136 } | T_DEAF
1137 {
1138 if (conf_parser_ctx.pass == 2)
1139 yy_aconf->modes |= UMODE_DEAF;
1140 } | T_DEBUG
1141 {
1142 if (conf_parser_ctx.pass == 2)
1143 yy_aconf->modes |= UMODE_DEBUG;
1144 } | T_FULL
1145 {
1146 if (conf_parser_ctx.pass == 2)
1147 yy_aconf->modes |= UMODE_FULL;
1148 } | HIDDEN
1149 {
1150 if (conf_parser_ctx.pass == 2)
1151 yy_aconf->modes |= UMODE_HIDDEN;
1152 } | T_SKILL
1153 {
1154 if (conf_parser_ctx.pass == 2)
1155 yy_aconf->modes |= UMODE_SKILL;
1156 } | T_NCHANGE
1157 {
1158 if (conf_parser_ctx.pass == 2)
1159 yy_aconf->modes |= UMODE_NCHANGE;
1160 } | T_REJ
1161 {
1162 if (conf_parser_ctx.pass == 2)
1163 yy_aconf->modes |= UMODE_REJ;
1164 } | T_UNAUTH
1165 {
1166 if (conf_parser_ctx.pass == 2)
1167 yy_aconf->modes |= UMODE_UNAUTH;
1168 } | T_SPY
1169 {
1170 if (conf_parser_ctx.pass == 2)
1171 yy_aconf->modes |= UMODE_SPY;
1172 } | T_EXTERNAL
1173 {
1174 if (conf_parser_ctx.pass == 2)
1175 yy_aconf->modes |= UMODE_EXTERNAL;
1176 } | T_OPERWALL
1177 {
1178 if (conf_parser_ctx.pass == 2)
1179 yy_aconf->modes |= UMODE_OPERWALL;
1180 } | T_SERVNOTICE
1181 {
1182 if (conf_parser_ctx.pass == 2)
1183 yy_aconf->modes |= UMODE_SERVNOTICE;
1184 } | T_INVISIBLE
1185 {
1186 if (conf_parser_ctx.pass == 2)
1187 yy_aconf->modes |= UMODE_INVISIBLE;
1188 } | T_WALLOP
1189 {
1190 if (conf_parser_ctx.pass == 2)
1191 yy_aconf->modes |= UMODE_WALLOP;
1192 } | T_SOFTCALLERID
1193 {
1194 if (conf_parser_ctx.pass == 2)
1195 yy_aconf->modes |= UMODE_SOFTCALLERID;
1196 } | T_CALLERID
1197 {
1198 if (conf_parser_ctx.pass == 2)
1199 yy_aconf->modes |= UMODE_CALLERID;
1200 } | T_LOCOPS
1201 {
1202 if (conf_parser_ctx.pass == 2)
1203 yy_aconf->modes |= UMODE_LOCOPS;
1204 };
1205
1206 oper_flags: IRCD_FLAGS
1207 {
1208 if (conf_parser_ctx.pass == 2)
1209 yy_aconf->port = 0;
1210 } '=' oper_flags_items ';';
1211
1212 oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1213 oper_flags_item: GLOBAL_KILL
1214 {
1215 if (conf_parser_ctx.pass == 2)
1216 yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1217 } | REMOTE
1218 {
1219 if (conf_parser_ctx.pass == 2)
1220 yy_aconf->port |= OPER_FLAG_REMOTE;
1221 } | KLINE
1222 {
1223 if (conf_parser_ctx.pass == 2)
1224 yy_aconf->port |= OPER_FLAG_K;
1225 } | UNKLINE
1226 {
1227 if (conf_parser_ctx.pass == 2)
1228 yy_aconf->port |= OPER_FLAG_UNKLINE;
1229 } | T_DLINE
1230 {
1231 if (conf_parser_ctx.pass == 2)
1232 yy_aconf->port |= OPER_FLAG_DLINE;
1233 } | T_UNDLINE
1234 {
1235 if (conf_parser_ctx.pass == 2)
1236 yy_aconf->port |= OPER_FLAG_UNDLINE;
1237 } | XLINE
1238 {
1239 if (conf_parser_ctx.pass == 2)
1240 yy_aconf->port |= OPER_FLAG_X;
1241 } | GLINE
1242 {
1243 if (conf_parser_ctx.pass == 2)
1244 yy_aconf->port |= OPER_FLAG_GLINE;
1245 } | DIE
1246 {
1247 if (conf_parser_ctx.pass == 2)
1248 yy_aconf->port |= OPER_FLAG_DIE;
1249 } | T_RESTART
1250 {
1251 if (conf_parser_ctx.pass == 2)
1252 yy_aconf->port |= OPER_FLAG_RESTART;
1253 } | REHASH
1254 {
1255 if (conf_parser_ctx.pass == 2)
1256 yy_aconf->port |= OPER_FLAG_REHASH;
1257 } | ADMIN
1258 {
1259 if (conf_parser_ctx.pass == 2)
1260 yy_aconf->port |= OPER_FLAG_ADMIN;
1261 } | NICK_CHANGES
1262 {
1263 if (conf_parser_ctx.pass == 2)
1264 yy_aconf->port |= OPER_FLAG_N;
1265 } | T_OPERWALL
1266 {
1267 if (conf_parser_ctx.pass == 2)
1268 yy_aconf->port |= OPER_FLAG_OPERWALL;
1269 } | T_GLOBOPS
1270 {
1271 if (conf_parser_ctx.pass == 2)
1272 yy_aconf->port |= OPER_FLAG_GLOBOPS;
1273 } | OPER_SPY_T
1274 {
1275 if (conf_parser_ctx.pass == 2)
1276 yy_aconf->port |= OPER_FLAG_OPER_SPY;
1277 } | REMOTEBAN
1278 {
1279 if (conf_parser_ctx.pass == 2)
1280 yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1281 } | T_SET
1282 {
1283 if (conf_parser_ctx.pass == 2)
1284 yy_aconf->port |= OPER_FLAG_SET;
1285 } | MODULE
1286 {
1287 if (conf_parser_ctx.pass == 2)
1288 yy_aconf->port |= OPER_FLAG_MODULE;
1289 };
1290
1291
1292 /***************************************************************************
1293 * section class
1294 ***************************************************************************/
1295 class_entry: CLASS
1296 {
1297 if (conf_parser_ctx.pass == 1)
1298 {
1299 yy_conf = make_conf_item(CLASS_TYPE);
1300 yy_class = map_to_conf(yy_conf);
1301 }
1302 } '{' class_items '}' ';'
1303 {
1304 if (conf_parser_ctx.pass == 1)
1305 {
1306 struct ConfItem *cconf = NULL;
1307 struct ClassItem *class = NULL;
1308
1309 if (yy_class_name == NULL)
1310 delete_conf_item(yy_conf);
1311 else
1312 {
1313 cconf = find_exact_name_conf(CLASS_TYPE, NULL, yy_class_name, NULL, NULL);
1314
1315 if (cconf != NULL) /* The class existed already */
1316 {
1317 int user_count = 0;
1318
1319 rebuild_cidr_class(cconf, yy_class);
1320
1321 class = map_to_conf(cconf);
1322
1323 user_count = class->curr_user_count;
1324 memcpy(class, yy_class, sizeof(*class));
1325 class->curr_user_count = user_count;
1326 class->active = 1;
1327
1328 delete_conf_item(yy_conf);
1329
1330 MyFree(cconf->name); /* Allows case change of class name */
1331 cconf->name = yy_class_name;
1332 }
1333 else /* Brand new class */
1334 {
1335 MyFree(yy_conf->name); /* just in case it was allocated */
1336 yy_conf->name = yy_class_name;
1337 yy_class->active = 1;
1338 }
1339 }
1340
1341 yy_class_name = NULL;
1342 }
1343 };
1344
1345 class_items: class_items class_item | class_item;
1346 class_item: class_name |
1347 class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1348 class_ping_time |
1349 class_ping_warning |
1350 class_number_per_cidr |
1351 class_number_per_ip |
1352 class_connectfreq |
1353 class_max_number |
1354 class_max_global |
1355 class_max_local |
1356 class_max_ident |
1357 class_sendq |
1358 error ';' ;
1359
1360 class_name: NAME '=' QSTRING ';'
1361 {
1362 if (conf_parser_ctx.pass == 1)
1363 {
1364 MyFree(yy_class_name);
1365 DupString(yy_class_name, yylval.string);
1366 }
1367 };
1368
1369 class_ping_time: PING_TIME '=' timespec ';'
1370 {
1371 if (conf_parser_ctx.pass == 1)
1372 yy_class->ping_freq = $3;
1373 };
1374
1375 class_ping_warning: PING_WARNING '=' timespec ';'
1376 {
1377 if (conf_parser_ctx.pass == 1)
1378 yy_class->ping_warning = $3;
1379 };
1380
1381 class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1382 {
1383 if (conf_parser_ctx.pass == 1)
1384 yy_class->max_perip = $3;
1385 };
1386
1387 class_connectfreq: CONNECTFREQ '=' timespec ';'
1388 {
1389 if (conf_parser_ctx.pass == 1)
1390 yy_class->con_freq = $3;
1391 };
1392
1393 class_max_number: MAX_NUMBER '=' NUMBER ';'
1394 {
1395 if (conf_parser_ctx.pass == 1)
1396 yy_class->max_total = $3;
1397 };
1398
1399 class_max_global: MAX_GLOBAL '=' NUMBER ';'
1400 {
1401 if (conf_parser_ctx.pass == 1)
1402 yy_class->max_global = $3;
1403 };
1404
1405 class_max_local: MAX_LOCAL '=' NUMBER ';'
1406 {
1407 if (conf_parser_ctx.pass == 1)
1408 yy_class->max_local = $3;
1409 };
1410
1411 class_max_ident: MAX_IDENT '=' NUMBER ';'
1412 {
1413 if (conf_parser_ctx.pass == 1)
1414 yy_class->max_ident = $3;
1415 };
1416
1417 class_sendq: SENDQ '=' sizespec ';'
1418 {
1419 if (conf_parser_ctx.pass == 1)
1420 yy_class->max_sendq = $3;
1421 };
1422
1423 class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1424 {
1425 if (conf_parser_ctx.pass == 1)
1426 yy_class->cidr_bitlen_ipv4 = $3 > 32 ? 32 : $3;
1427 };
1428
1429 class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1430 {
1431 if (conf_parser_ctx.pass == 1)
1432 yy_class->cidr_bitlen_ipv6 = $3 > 128 ? 128 : $3;
1433 };
1434
1435 class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1436 {
1437 if (conf_parser_ctx.pass == 1)
1438 yy_class->number_per_cidr = $3;
1439 };
1440
1441 /***************************************************************************
1442 * section listen
1443 ***************************************************************************/
1444 listen_entry: LISTEN
1445 {
1446 if (conf_parser_ctx.pass == 2)
1447 {
1448 listener_address = NULL;
1449 listener_flags = 0;
1450 }
1451 } '{' listen_items '}' ';'
1452 {
1453 if (conf_parser_ctx.pass == 2)
1454 {
1455 MyFree(listener_address);
1456 listener_address = NULL;
1457 }
1458 };
1459
1460 listen_flags: IRCD_FLAGS
1461 {
1462 listener_flags = 0;
1463 } '=' listen_flags_items ';';
1464
1465 listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1466 listen_flags_item: T_SSL
1467 {
1468 if (conf_parser_ctx.pass == 2)
1469 listener_flags |= LISTENER_SSL;
1470 } | HIDDEN
1471 {
1472 if (conf_parser_ctx.pass == 2)
1473 listener_flags |= LISTENER_HIDDEN;
1474 } | T_SERVER
1475 {
1476 if (conf_parser_ctx.pass == 2)
1477 listener_flags |= LISTENER_SERVER;
1478 };
1479
1480
1481
1482 listen_items: listen_items listen_item | listen_item;
1483 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1484
1485 listen_port: PORT '=' port_items { listener_flags = 0; } ';';
1486
1487 port_items: port_items ',' port_item | port_item;
1488
1489 port_item: NUMBER
1490 {
1491 if (conf_parser_ctx.pass == 2)
1492 {
1493 if ((listener_flags & LISTENER_SSL))
1494 #ifdef HAVE_LIBCRYPTO
1495 if (!ServerInfo.server_ctx)
1496 #endif
1497 {
1498 yyerror("SSL not available - port closed");
1499 break;
1500 }
1501 add_listener($1, listener_address, listener_flags);
1502 }
1503 } | NUMBER TWODOTS NUMBER
1504 {
1505 if (conf_parser_ctx.pass == 2)
1506 {
1507 int i;
1508
1509 if ((listener_flags & LISTENER_SSL))
1510 #ifdef HAVE_LIBCRYPTO
1511 if (!ServerInfo.server_ctx)
1512 #endif
1513 {
1514 yyerror("SSL not available - port closed");
1515 break;
1516 }
1517
1518 for (i = $1; i <= $3; ++i)
1519 add_listener(i, listener_address, listener_flags);
1520 }
1521 };
1522
1523 listen_address: IP '=' QSTRING ';'
1524 {
1525 if (conf_parser_ctx.pass == 2)
1526 {
1527 MyFree(listener_address);
1528 DupString(listener_address, yylval.string);
1529 }
1530 };
1531
1532 listen_host: HOST '=' QSTRING ';'
1533 {
1534 if (conf_parser_ctx.pass == 2)
1535 {
1536 MyFree(listener_address);
1537 DupString(listener_address, yylval.string);
1538 }
1539 };
1540
1541 /***************************************************************************
1542 * section auth
1543 ***************************************************************************/
1544 auth_entry: IRCD_AUTH
1545 {
1546 if (conf_parser_ctx.pass == 2)
1547 {
1548 yy_conf = make_conf_item(CLIENT_TYPE);
1549 yy_aconf = map_to_conf(yy_conf);
1550 }
1551 else
1552 {
1553 MyFree(class_name);
1554 class_name = NULL;
1555 }
1556 } '{' auth_items '}' ';'
1557 {
1558 if (conf_parser_ctx.pass == 2)
1559 {
1560 struct CollectItem *yy_tmp = NULL;
1561 dlink_node *ptr = NULL, *next_ptr = NULL;
1562
1563 if (yy_aconf->user && yy_aconf->host)
1564 {
1565 conf_add_class_to_conf(yy_conf, class_name);
1566 add_conf_by_address(CONF_CLIENT, yy_aconf);
1567 }
1568 else
1569 delete_conf_item(yy_conf);
1570
1571 /* copy over settings from first struct */
1572 DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
1573 {
1574 struct AccessItem *new_aconf;
1575 struct ConfItem *new_conf;
1576
1577 new_conf = make_conf_item(CLIENT_TYPE);
1578 new_aconf = map_to_conf(new_conf);
1579
1580 yy_tmp = ptr->data;
1581
1582 assert(yy_tmp->user && yy_tmp->host);
1583
1584 if (yy_aconf->passwd != NULL)
1585 DupString(new_aconf->passwd, yy_aconf->passwd);
1586 if (yy_conf->name != NULL)
1587 DupString(new_conf->name, yy_conf->name);
1588 if (yy_aconf->passwd != NULL)
1589 DupString(new_aconf->passwd, yy_aconf->passwd);
1590
1591 new_aconf->flags = yy_aconf->flags;
1592 new_aconf->port = yy_aconf->port;
1593
1594 DupString(new_aconf->user, yy_tmp->user);
1595 collapse(new_aconf->user);
1596
1597 DupString(new_aconf->host, yy_tmp->host);
1598 collapse(new_aconf->host);
1599
1600 conf_add_class_to_conf(new_conf, class_name);
1601 add_conf_by_address(CONF_CLIENT, new_aconf);
1602 dlinkDelete(&yy_tmp->node, &col_conf_list);
1603 free_collect_item(yy_tmp);
1604 }
1605
1606 MyFree(class_name);
1607 class_name = NULL;
1608 yy_conf = NULL;
1609 yy_aconf = NULL;
1610 }
1611 };
1612
1613 auth_items: auth_items auth_item | auth_item;
1614 auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1615 auth_spoof | auth_redir_serv | auth_redir_port |
1616 auth_encrypted | error ';' ;
1617
1618 auth_user: USER '=' QSTRING ';'
1619 {
1620 if (conf_parser_ctx.pass == 2)
1621 {
1622 struct CollectItem *yy_tmp = NULL;
1623 struct split_nuh_item nuh;
1624
1625 nuh.nuhmask = yylval.string;
1626 nuh.nickptr = NULL;
1627 nuh.userptr = userbuf;
1628 nuh.hostptr = hostbuf;
1629
1630 nuh.nicksize = 0;
1631 nuh.usersize = sizeof(userbuf);
1632 nuh.hostsize = sizeof(hostbuf);
1633
1634 split_nuh(&nuh);
1635
1636 if (yy_aconf->user == NULL)
1637 {
1638 DupString(yy_aconf->user, userbuf);
1639 DupString(yy_aconf->host, hostbuf);
1640 }
1641 else
1642 {
1643 yy_tmp = MyMalloc(sizeof(struct CollectItem));
1644
1645 DupString(yy_tmp->user, userbuf);
1646 DupString(yy_tmp->host, hostbuf);
1647
1648 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1649 }
1650 }
1651 };
1652
1653 auth_passwd: PASSWORD '=' QSTRING ';'
1654 {
1655 if (conf_parser_ctx.pass == 2)
1656 {
1657 /* be paranoid */
1658 if (yy_aconf->passwd != NULL)
1659 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1660
1661 MyFree(yy_aconf->passwd);
1662 DupString(yy_aconf->passwd, yylval.string);
1663 }
1664 };
1665
1666 auth_class: CLASS '=' QSTRING ';'
1667 {
1668 if (conf_parser_ctx.pass == 2)
1669 {
1670 MyFree(class_name);
1671 DupString(class_name, yylval.string);
1672 }
1673 };
1674
1675 auth_encrypted: ENCRYPTED '=' TBOOL ';'
1676 {
1677 if (conf_parser_ctx.pass == 2)
1678 {
1679 if (yylval.number)
1680 SetConfEncrypted(yy_aconf);
1681 else
1682 ClearConfEncrypted(yy_aconf);
1683 }
1684 };
1685
1686 auth_flags: IRCD_FLAGS
1687 {
1688 } '=' auth_flags_items ';';
1689
1690 auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1691 auth_flags_item: SPOOF_NOTICE
1692 {
1693 if (conf_parser_ctx.pass == 2)
1694 yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1695 } | EXCEED_LIMIT
1696 {
1697 if (conf_parser_ctx.pass == 2)
1698 yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1699 } | KLINE_EXEMPT
1700 {
1701 if (conf_parser_ctx.pass == 2)
1702 yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1703 } | NEED_IDENT
1704 {
1705 if (conf_parser_ctx.pass == 2)
1706 yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
1707 } | CAN_FLOOD
1708 {
1709 if (conf_parser_ctx.pass == 2)
1710 yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
1711 } | NO_TILDE
1712 {
1713 if (conf_parser_ctx.pass == 2)
1714 yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
1715 } | GLINE_EXEMPT
1716 {
1717 if (conf_parser_ctx.pass == 2)
1718 yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
1719 } | RESV_EXEMPT
1720 {
1721 if (conf_parser_ctx.pass == 2)
1722 yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
1723 } | NEED_PASSWORD
1724 {
1725 if (conf_parser_ctx.pass == 2)
1726 yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
1727 };
1728
1729 /* XXX - need check for illegal hostnames here */
1730 auth_spoof: SPOOF '=' QSTRING ';'
1731 {
1732 if (conf_parser_ctx.pass == 2)
1733 {
1734 MyFree(yy_conf->name);
1735
1736 if (strlen(yylval.string) < HOSTLEN)
1737 {
1738 DupString(yy_conf->name, yylval.string);
1739 yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
1740 }
1741 else
1742 {
1743 ilog(LOG_TYPE_IRCD, "Spoofs must be less than %d..ignoring it", HOSTLEN);
1744 yy_conf->name = NULL;
1745 }
1746 }
1747 };
1748
1749 auth_redir_serv: REDIRSERV '=' QSTRING ';'
1750 {
1751 if (conf_parser_ctx.pass == 2)
1752 {
1753 yy_aconf->flags |= CONF_FLAGS_REDIR;
1754 MyFree(yy_conf->name);
1755 DupString(yy_conf->name, yylval.string);
1756 }
1757 };
1758
1759 auth_redir_port: REDIRPORT '=' NUMBER ';'
1760 {
1761 if (conf_parser_ctx.pass == 2)
1762 {
1763 yy_aconf->flags |= CONF_FLAGS_REDIR;
1764 yy_aconf->port = $3;
1765 }
1766 };
1767
1768
1769 /***************************************************************************
1770 * section resv
1771 ***************************************************************************/
1772 resv_entry: RESV
1773 {
1774 if (conf_parser_ctx.pass == 2)
1775 {
1776 MyFree(resv_reason);
1777 resv_reason = NULL;
1778 }
1779 } '{' resv_items '}' ';'
1780 {
1781 if (conf_parser_ctx.pass == 2)
1782 {
1783 MyFree(resv_reason);
1784 resv_reason = NULL;
1785 }
1786 };
1787
1788 resv_items: resv_items resv_item | resv_item;
1789 resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
1790
1791 resv_creason: REASON '=' QSTRING ';'
1792 {
1793 if (conf_parser_ctx.pass == 2)
1794 {
1795 MyFree(resv_reason);
1796 DupString(resv_reason, yylval.string);
1797 }
1798 };
1799
1800 resv_channel: CHANNEL '=' QSTRING ';'
1801 {
1802 if (conf_parser_ctx.pass == 2)
1803 {
1804 if (IsChanPrefix(*yylval.string))
1805 {
1806 char def_reason[] = "No reason";
1807
1808 create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
1809 }
1810 }
1811 /* ignore it for now.. but we really should make a warning if
1812 * its an erroneous name --fl_ */
1813 };
1814
1815 resv_nick: NICK '=' QSTRING ';'
1816 {
1817 if (conf_parser_ctx.pass == 2)
1818 {
1819 char def_reason[] = "No reason";
1820
1821 create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
1822 }
1823 };
1824
1825 /***************************************************************************
1826 * section service
1827 ***************************************************************************/
1828 service_entry: T_SERVICE '{' service_items '}' ';';
1829
1830 service_items: service_items service_item | service_item;
1831 service_item: service_name | error;
1832
1833 service_name: NAME '=' QSTRING ';'
1834 {
1835 if (conf_parser_ctx.pass == 2)
1836 {
1837 if (valid_servname(yylval.string))
1838 {
1839 yy_conf = make_conf_item(SERVICE_TYPE);
1840 DupString(yy_conf->name, yylval.string);
1841 }
1842 }
1843 };
1844
1845 /***************************************************************************
1846 * section shared, for sharing remote klines etc.
1847 ***************************************************************************/
1848 shared_entry: T_SHARED
1849 {
1850 if (conf_parser_ctx.pass == 2)
1851 {
1852 yy_conf = make_conf_item(ULINE_TYPE);
1853 yy_match_item = map_to_conf(yy_conf);
1854 yy_match_item->action = SHARED_ALL;
1855 }
1856 } '{' shared_items '}' ';'
1857 {
1858 if (conf_parser_ctx.pass == 2)
1859 {
1860 yy_conf = NULL;
1861 }
1862 };
1863
1864 shared_items: shared_items shared_item | shared_item;
1865 shared_item: shared_name | shared_user | shared_type | error ';' ;
1866
1867 shared_name: NAME '=' QSTRING ';'
1868 {
1869 if (conf_parser_ctx.pass == 2)
1870 {
1871 MyFree(yy_conf->name);
1872 DupString(yy_conf->name, yylval.string);
1873 }
1874 };
1875
1876 shared_user: USER '=' QSTRING ';'
1877 {
1878 if (conf_parser_ctx.pass == 2)
1879 {
1880 struct split_nuh_item nuh;
1881
1882 nuh.nuhmask = yylval.string;
1883 nuh.nickptr = NULL;
1884 nuh.userptr = userbuf;
1885 nuh.hostptr = hostbuf;
1886
1887 nuh.nicksize = 0;
1888 nuh.usersize = sizeof(userbuf);
1889 nuh.hostsize = sizeof(hostbuf);
1890
1891 split_nuh(&nuh);
1892
1893 DupString(yy_match_item->user, userbuf);
1894 DupString(yy_match_item->host, hostbuf);
1895 }
1896 };
1897
1898 shared_type: TYPE
1899 {
1900 if (conf_parser_ctx.pass == 2)
1901 yy_match_item->action = 0;
1902 } '=' shared_types ';' ;
1903
1904 shared_types: shared_types ',' shared_type_item | shared_type_item;
1905 shared_type_item: KLINE
1906 {
1907 if (conf_parser_ctx.pass == 2)
1908 yy_match_item->action |= SHARED_KLINE;
1909 } | UNKLINE
1910 {
1911 if (conf_parser_ctx.pass == 2)
1912 yy_match_item->action |= SHARED_UNKLINE;
1913 } | T_DLINE
1914 {
1915 if (conf_parser_ctx.pass == 2)
1916 yy_match_item->action |= SHARED_DLINE;
1917 } | T_UNDLINE
1918 {
1919 if (conf_parser_ctx.pass == 2)
1920 yy_match_item->action |= SHARED_UNDLINE;
1921 } | XLINE
1922 {
1923 if (conf_parser_ctx.pass == 2)
1924 yy_match_item->action |= SHARED_XLINE;
1925 } | T_UNXLINE
1926 {
1927 if (conf_parser_ctx.pass == 2)
1928 yy_match_item->action |= SHARED_UNXLINE;
1929 } | RESV
1930 {
1931 if (conf_parser_ctx.pass == 2)
1932 yy_match_item->action |= SHARED_RESV;
1933 } | T_UNRESV
1934 {
1935 if (conf_parser_ctx.pass == 2)
1936 yy_match_item->action |= SHARED_UNRESV;
1937 } | T_LOCOPS
1938 {
1939 if (conf_parser_ctx.pass == 2)
1940 yy_match_item->action |= SHARED_LOCOPS;
1941 } | T_ALL
1942 {
1943 if (conf_parser_ctx.pass == 2)
1944 yy_match_item->action = SHARED_ALL;
1945 };
1946
1947 /***************************************************************************
1948 * section cluster
1949 ***************************************************************************/
1950 cluster_entry: T_CLUSTER
1951 {
1952 if (conf_parser_ctx.pass == 2)
1953 {
1954 yy_conf = make_conf_item(CLUSTER_TYPE);
1955 yy_conf->flags = SHARED_ALL;
1956 }
1957 } '{' cluster_items '}' ';'
1958 {
1959 if (conf_parser_ctx.pass == 2)
1960 {
1961 if (yy_conf->name == NULL)
1962 DupString(yy_conf->name, "*");
1963 yy_conf = NULL;
1964 }
1965 };
1966
1967 cluster_items: cluster_items cluster_item | cluster_item;
1968 cluster_item: cluster_name | cluster_type | error ';' ;
1969
1970 cluster_name: NAME '=' QSTRING ';'
1971 {
1972 if (conf_parser_ctx.pass == 2)
1973 DupString(yy_conf->name, yylval.string);
1974 };
1975
1976 cluster_type: TYPE
1977 {
1978 if (conf_parser_ctx.pass == 2)
1979 yy_conf->flags = 0;
1980 } '=' cluster_types ';' ;
1981
1982 cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
1983 cluster_type_item: KLINE
1984 {
1985 if (conf_parser_ctx.pass == 2)
1986 yy_conf->flags |= SHARED_KLINE;
1987 } | UNKLINE
1988 {
1989 if (conf_parser_ctx.pass == 2)
1990 yy_conf->flags |= SHARED_UNKLINE;
1991 } | T_DLINE
1992 {
1993 if (conf_parser_ctx.pass == 2)
1994 yy_conf->flags |= SHARED_DLINE;
1995 } | T_UNDLINE
1996 {
1997 if (conf_parser_ctx.pass == 2)
1998 yy_conf->flags |= SHARED_UNDLINE;
1999 } | XLINE
2000 {
2001 if (conf_parser_ctx.pass == 2)
2002 yy_conf->flags |= SHARED_XLINE;
2003 } | T_UNXLINE
2004 {
2005 if (conf_parser_ctx.pass == 2)
2006 yy_conf->flags |= SHARED_UNXLINE;
2007 } | RESV
2008 {
2009 if (conf_parser_ctx.pass == 2)
2010 yy_conf->flags |= SHARED_RESV;
2011 } | T_UNRESV
2012 {
2013 if (conf_parser_ctx.pass == 2)
2014 yy_conf->flags |= SHARED_UNRESV;
2015 } | T_LOCOPS
2016 {
2017 if (conf_parser_ctx.pass == 2)
2018 yy_conf->flags |= SHARED_LOCOPS;
2019 } | T_ALL
2020 {
2021 if (conf_parser_ctx.pass == 2)
2022 yy_conf->flags = SHARED_ALL;
2023 };
2024
2025 /***************************************************************************
2026 * section connect
2027 ***************************************************************************/
2028 connect_entry: CONNECT
2029 {
2030 if (conf_parser_ctx.pass == 2)
2031 {
2032 yy_conf = make_conf_item(SERVER_TYPE);
2033 yy_aconf = map_to_conf(yy_conf);
2034
2035 /* defaults */
2036 yy_aconf->port = PORTNUM;
2037 }
2038 else
2039 {
2040 MyFree(class_name);
2041 class_name = NULL;
2042 }
2043 } '{' connect_items '}' ';'
2044 {
2045 if (conf_parser_ctx.pass == 2)
2046 {
2047 if (yy_aconf->host && yy_aconf->passwd && yy_aconf->spasswd)
2048 {
2049 if (conf_add_server(yy_conf, class_name) == -1)
2050 delete_conf_item(yy_conf);
2051 }
2052 else
2053 {
2054 if (yy_conf->name != NULL)
2055 {
2056 if (yy_aconf->host == NULL)
2057 yyerror("Ignoring connect block -- missing host");
2058 else if (!yy_aconf->passwd || !yy_aconf->spasswd)
2059 yyerror("Ignoring connect block -- missing password");
2060 }
2061
2062 /* XXX
2063 * This fixes a try_connections() core (caused by invalid class_ptr
2064 * pointers) reported by metalrock. That's an ugly fix, but there
2065 * is currently no better way. The entire config subsystem needs an
2066 * rewrite ASAP. make_conf_item() shouldn't really add things onto
2067 * a doubly linked list immediately without any sanity checks! -Michael
2068 */
2069 delete_conf_item(yy_conf);
2070 }
2071
2072 MyFree(class_name);
2073 class_name = NULL;
2074 yy_conf = NULL;
2075 yy_aconf = NULL;
2076 }
2077 };
2078
2079 connect_items: connect_items connect_item | connect_item;
2080 connect_item: connect_name | connect_host | connect_vhost |
2081 connect_send_password | connect_accept_password |
2082 connect_aftype | connect_port | connect_ssl_cipher_list |
2083 connect_flags | connect_hub_mask | connect_leaf_mask |
2084 connect_class | connect_encrypted |
2085 error ';' ;
2086
2087 connect_name: NAME '=' QSTRING ';'
2088 {
2089 if (conf_parser_ctx.pass == 2)
2090 {
2091 MyFree(yy_conf->name);
2092 DupString(yy_conf->name, yylval.string);
2093 }
2094 };
2095
2096 connect_host: HOST '=' QSTRING ';'
2097 {
2098 if (conf_parser_ctx.pass == 2)
2099 {
2100 MyFree(yy_aconf->host);
2101 DupString(yy_aconf->host, yylval.string);
2102 }
2103 };
2104
2105 connect_vhost: VHOST '=' QSTRING ';'
2106 {
2107 if (conf_parser_ctx.pass == 2)
2108 {
2109 struct addrinfo hints, *res;
2110
2111 memset(&hints, 0, sizeof(hints));
2112
2113 hints.ai_family = AF_UNSPEC;
2114 hints.ai_socktype = SOCK_STREAM;
2115 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2116
2117 if (getaddrinfo(yylval.string, NULL, &hints, &res))
2118 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
2119 else
2120 {
2121 assert(res != NULL);
2122
2123 memcpy(&yy_aconf->bind, res->ai_addr, res->ai_addrlen);
2124 yy_aconf->bind.ss.ss_family = res->ai_family;
2125 yy_aconf->bind.ss_len = res->ai_addrlen;
2126 freeaddrinfo(res);
2127 }
2128 }
2129 };
2130
2131 connect_send_password: SEND_PASSWORD '=' QSTRING ';'
2132 {
2133 if (conf_parser_ctx.pass == 2)
2134 {
2135 if ($3[0] == ':')
2136 yyerror("Server passwords cannot begin with a colon");
2137 else if (strchr($3, ' ') != NULL)
2138 yyerror("Server passwords cannot contain spaces");
2139 else {
2140 if (yy_aconf->spasswd != NULL)
2141 memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd));
2142
2143 MyFree(yy_aconf->spasswd);
2144 DupString(yy_aconf->spasswd, yylval.string);
2145 }
2146 }
2147 };
2148
2149 connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
2150 {
2151 if (conf_parser_ctx.pass == 2)
2152 {
2153 if ($3[0] == ':')
2154 yyerror("Server passwords cannot begin with a colon");
2155 else if (strchr($3, ' ') != NULL)
2156 yyerror("Server passwords cannot contain spaces");
2157 else {
2158 if (yy_aconf->passwd != NULL)
2159 memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
2160
2161 MyFree(yy_aconf->passwd);
2162 DupString(yy_aconf->passwd, yylval.string);
2163 }
2164 }
2165 };
2166
2167 connect_port: PORT '=' NUMBER ';'
2168 {
2169 if (conf_parser_ctx.pass == 2)
2170 yy_aconf->port = $3;
2171 };
2172
2173 connect_aftype: AFTYPE '=' T_IPV4 ';'
2174 {
2175 if (conf_parser_ctx.pass == 2)
2176 yy_aconf->aftype = AF_INET;
2177 } | AFTYPE '=' T_IPV6 ';'
2178 {
2179 #ifdef IPV6
2180 if (conf_parser_ctx.pass == 2)
2181 yy_aconf->aftype = AF_INET6;
2182 #endif
2183 };
2184
2185 connect_flags: IRCD_FLAGS
2186 {
2187 } '=' connect_flags_items ';';
2188
2189 connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2190 connect_flags_item: AUTOCONN
2191 {
2192 if (conf_parser_ctx.pass == 2)
2193 SetConfAllowAutoConn(yy_aconf);
2194 } | BURST_AWAY
2195 {
2196 if (conf_parser_ctx.pass == 2)
2197 SetConfAwayBurst(yy_aconf);
2198 } | TOPICBURST
2199 {
2200 if (conf_parser_ctx.pass == 2)
2201 SetConfTopicBurst(yy_aconf);
2202 } | T_SSL
2203 {
2204 if (conf_parser_ctx.pass == 2)
2205 SetConfSSL(yy_aconf);
2206 };
2207
2208 connect_encrypted: ENCRYPTED '=' TBOOL ';'
2209 {
2210 if (conf_parser_ctx.pass == 2)
2211 {
2212 if (yylval.number)
2213 yy_aconf->flags |= CONF_FLAGS_ENCRYPTED;
2214 else
2215 yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED;
2216 }
2217 };
2218
2219 connect_hub_mask: HUB_MASK '=' QSTRING ';'
2220 {
2221 if (conf_parser_ctx.pass == 2)
2222 {
2223 char *mask;
2224
2225 DupString(mask, yylval.string);
2226 dlinkAdd(mask, make_dlink_node(), &yy_aconf->hub_list);
2227 }
2228 };
2229
2230 connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2231 {
2232 if (conf_parser_ctx.pass == 2)
2233 {
2234 char *mask;
2235
2236 DupString(mask, yylval.string);
2237 dlinkAdd(mask, make_dlink_node(), &yy_aconf->leaf_list);
2238 }
2239 };
2240
2241 connect_class: CLASS '=' QSTRING ';'
2242 {
2243 if (conf_parser_ctx.pass == 2)
2244 {
2245 MyFree(class_name);
2246 DupString(class_name, yylval.string);
2247 }
2248 };
2249
2250 connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2251 {
2252 #ifdef HAVE_LIBCRYPTO
2253 if (conf_parser_ctx.pass == 2)
2254 {
2255 MyFree(yy_aconf->cipher_list);
2256 DupString(yy_aconf->cipher_list, yylval.string);
2257 }
2258 #else
2259 if (conf_parser_ctx.pass == 2)
2260 yyerror("Ignoring connect::ciphers -- no OpenSSL support");
2261 #endif
2262 };
2263
2264
2265 /***************************************************************************
2266 * section kill
2267 ***************************************************************************/
2268 kill_entry: KILL
2269 {
2270 if (conf_parser_ctx.pass == 2)
2271 {
2272 userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0';
2273 regex_ban = 0;
2274 }
2275 } '{' kill_items '}' ';'
2276 {
2277 if (conf_parser_ctx.pass == 2)
2278 {
2279 if (userbuf[0] && hostbuf[0])
2280 {
2281 if (regex_ban)
2282 {
2283 #ifdef HAVE_LIBPCRE
2284 void *exp_user = NULL;
2285 void *exp_host = NULL;
2286 const char *errptr = NULL;
2287
2288 if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2289 !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2290 {
2291 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s",
2292 errptr);
2293 break;
2294 }
2295
2296 yy_aconf = map_to_conf(make_conf_item(RKLINE_TYPE));
2297 yy_aconf->regexuser = exp_user;
2298 yy_aconf->regexhost = exp_host;
2299
2300 DupString(yy_aconf->user, userbuf);
2301 DupString(yy_aconf->host, hostbuf);
2302
2303 if (reasonbuf[0])
2304 DupString(yy_aconf->reason, reasonbuf);
2305 else
2306 DupString(yy_aconf->reason, "No reason");
2307 #else
2308 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support");
2309 break;
2310 #endif
2311 }
2312 else
2313 {
2314 find_and_delete_temporary(userbuf, hostbuf, CONF_KLINE);
2315
2316 yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE));
2317
2318 DupString(yy_aconf->user, userbuf);
2319 DupString(yy_aconf->host, hostbuf);
2320
2321 if (reasonbuf[0])
2322 DupString(yy_aconf->reason, reasonbuf);
2323 else
2324 DupString(yy_aconf->reason, "No reason");
2325 add_conf_by_address(CONF_KLINE, yy_aconf);
2326 }
2327 }
2328
2329 yy_aconf = NULL;
2330 }
2331 };
2332
2333 kill_type: TYPE
2334 {
2335 } '=' kill_type_items ';';
2336
2337 kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2338 kill_type_item: REGEX_T
2339 {
2340 if (conf_parser_ctx.pass == 2)
2341 regex_ban = 1;
2342 };
2343
2344 kill_items: kill_items kill_item | kill_item;
2345 kill_item: kill_user | kill_reason | kill_type | error;
2346
2347 kill_user: USER '=' QSTRING ';'
2348 {
2349 if (conf_parser_ctx.pass == 2)
2350 {
2351 struct split_nuh_item nuh;
2352
2353 nuh.nuhmask = yylval.string;
2354 nuh.nickptr = NULL;
2355 nuh.userptr = userbuf;
2356 nuh.hostptr = hostbuf;
2357
2358 nuh.nicksize = 0;
2359 nuh.usersize = sizeof(userbuf);
2360 nuh.hostsize = sizeof(hostbuf);
2361
2362 split_nuh(&nuh);
2363 }
2364 };
2365
2366 kill_reason: REASON '=' QSTRING ';'
2367 {
2368 if (conf_parser_ctx.pass == 2)
2369 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
2370 };
2371
2372 /***************************************************************************
2373 * section deny
2374 ***************************************************************************/
2375 deny_entry: DENY
2376 {
2377 if (conf_parser_ctx.pass == 2)
2378 hostbuf[0] = reasonbuf[0] = '\0';
2379 } '{' deny_items '}' ';'
2380 {
2381 if (conf_parser_ctx.pass == 2)
2382 {
2383 if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST)
2384 {
2385 find_and_delete_temporary(NULL, hostbuf, CONF_DLINE);
2386
2387 yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE));
2388 DupString(yy_aconf->host, hostbuf);
2389
2390 if (reasonbuf[0])
2391 DupString(yy_aconf->reason, reasonbuf);
2392 else
2393 DupString(yy_aconf->reason, "No reason");
2394 add_conf_by_address(CONF_DLINE, yy_aconf);
2395 yy_aconf = NULL;
2396 }
2397 }
2398 };
2399
2400 deny_items: deny_items deny_item | deny_item;
2401 deny_item: deny_ip | deny_reason | error;
2402
2403 deny_ip: IP '=' QSTRING ';'
2404 {
2405 if (conf_parser_ctx.pass == 2)
2406 strlcpy(hostbuf, yylval.string, sizeof(hostbuf));
2407 };
2408
2409 deny_reason: REASON '=' QSTRING ';'
2410 {
2411 if (conf_parser_ctx.pass == 2)
2412 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
2413 };
2414
2415 /***************************************************************************
2416 * section exempt
2417 ***************************************************************************/
2418 exempt_entry: EXEMPT '{' exempt_items '}' ';';
2419
2420 exempt_items: exempt_items exempt_item | exempt_item;
2421 exempt_item: exempt_ip | error;
2422
2423 exempt_ip: IP '=' QSTRING ';'
2424 {
2425 if (conf_parser_ctx.pass == 2)
2426 {
2427 if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2428 {
2429 yy_aconf = map_to_conf(make_conf_item(EXEMPTDLINE_TYPE));
2430 DupString(yy_aconf->host, yylval.string);
2431
2432 add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf);
2433 yy_aconf = NULL;
2434 }
2435 }
2436 };
2437
2438 /***************************************************************************
2439 * section gecos
2440 ***************************************************************************/
2441 gecos_entry: GECOS
2442 {
2443 if (conf_parser_ctx.pass == 2)
2444 {
2445 regex_ban = 0;
2446 reasonbuf[0] = gecos_name[0] = '\0';
2447 }
2448 } '{' gecos_items '}' ';'
2449 {
2450 if (conf_parser_ctx.pass == 2)
2451 {
2452 if (gecos_name[0])
2453 {
2454 if (regex_ban)
2455 {
2456 #ifdef HAVE_LIBPCRE
2457 void *exp_p = NULL;
2458 const char *errptr = NULL;
2459
2460 if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr)))
2461 {
2462 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s",
2463 errptr);
2464 break;
2465 }
2466
2467 yy_conf = make_conf_item(RXLINE_TYPE);
2468 yy_conf->regexpname = exp_p;
2469 #else
2470 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support");
2471 break;
2472 #endif
2473 }
2474 else
2475 yy_conf = make_conf_item(XLINE_TYPE);
2476
2477 yy_match_item = map_to_conf(yy_conf);
2478 DupString(yy_conf->name, gecos_name);
2479
2480 if (reasonbuf[0])
2481 DupString(yy_match_item->reason, reasonbuf);
2482 else
2483 DupString(yy_match_item->reason, "No reason");
2484 }
2485 }
2486 };
2487
2488 gecos_flags: TYPE
2489 {
2490 } '=' gecos_flags_items ';';
2491
2492 gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
2493 gecos_flags_item: REGEX_T
2494 {
2495 if (conf_parser_ctx.pass == 2)
2496 regex_ban = 1;
2497 };
2498
2499 gecos_items: gecos_items gecos_item | gecos_item;
2500 gecos_item: gecos_name | gecos_reason | gecos_flags | error;
2501
2502 gecos_name: NAME '=' QSTRING ';'
2503 {
2504 if (conf_parser_ctx.pass == 2)
2505 strlcpy(gecos_name, yylval.string, sizeof(gecos_name));
2506 };
2507
2508 gecos_reason: REASON '=' QSTRING ';'
2509 {
2510 if (conf_parser_ctx.pass == 2)
2511 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
2512 };
2513
2514 /***************************************************************************
2515 * section general
2516 ***************************************************************************/
2517 general_entry: GENERAL
2518 '{' general_items '}' ';';
2519
2520 general_items: general_items general_item | general_item;
2521 general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
2522 general_failed_oper_notice | general_anti_nick_flood |
2523 general_max_nick_time | general_max_nick_changes |
2524 general_max_accept | general_anti_spam_exit_message_time |
2525 general_ts_warn_delta | general_ts_max_delta |
2526 general_kill_chase_time_limit | general_kline_with_reason |
2527 general_kline_reason | general_invisible_on_connect |
2528 general_warn_no_nline | general_dots_in_ident |
2529 general_stats_o_oper_only | general_stats_k_oper_only |
2530 general_pace_wait | general_stats_i_oper_only |
2531 general_pace_wait_simple | general_stats_P_oper_only |
2532 general_short_motd | general_no_oper_flood |
2533 general_true_no_oper_flood | general_oper_pass_resv |
2534 general_message_locale |
2535 general_oper_only_umodes | general_max_targets |
2536 general_use_egd | general_egdpool_path |
2537 general_oper_umodes | general_caller_id_wait |
2538 general_opers_bypass_callerid | general_default_floodcount |
2539 general_min_nonwildcard | general_min_nonwildcard_simple |
2540 general_disable_remote_commands |
2541 general_client_flood |
2542 general_throttle_time | general_havent_read_conf |
2543 general_ping_cookie |
2544 general_disable_auth |
2545 general_tkline_expire_notices | general_gline_enable |
2546 general_gline_duration | general_gline_request_duration |
2547 general_gline_min_cidr |
2548 general_gline_min_cidr6 | general_use_whois_actually |
2549 general_reject_hold_time | general_stats_e_disabled |
2550 general_max_watch | general_services_name |
2551 error;
2552
2553
2554 general_max_watch: MAX_WATCH '=' NUMBER ';'
2555 {
2556 ConfigFileEntry.max_watch = $3;
2557 };
2558
2559 general_gline_enable: GLINE_ENABLE '=' TBOOL ';'
2560 {
2561 if (conf_parser_ctx.pass == 2)
2562 ConfigFileEntry.glines = yylval.number;
2563 };
2564
2565 general_gline_duration: GLINE_DURATION '=' timespec ';'
2566 {
2567 if (conf_parser_ctx.pass == 2)
2568 ConfigFileEntry.gline_time = $3;
2569 };
2570
2571 general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';'
2572 {
2573 if (conf_parser_ctx.pass == 2)
2574 ConfigFileEntry.gline_request_time = $3;
2575 };
2576
2577 general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
2578 {
2579 ConfigFileEntry.gline_min_cidr = $3;
2580 };
2581
2582 general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
2583 {
2584 ConfigFileEntry.gline_min_cidr6 = $3;
2585 };
2586
2587 general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';'
2588 {
2589 ConfigFileEntry.use_whois_actually = yylval.number;
2590 };
2591
2592 general_reject_hold_time: TREJECT_HOLD_TIME '=' timespec ';'
2593 {
2594 GlobalSetOptions.rejecttime = yylval.number;
2595 };
2596
2597 general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
2598 {
2599 ConfigFileEntry.tkline_expire_notices = yylval.number;
2600 };
2601
2602 general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2603 {
2604 ConfigFileEntry.kill_chase_time_limit = $3;
2605 };
2606
2607 general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
2608 {
2609 ConfigFileEntry.hide_spoof_ips = yylval.number;
2610 };
2611
2612 general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2613 {
2614 ConfigFileEntry.ignore_bogus_ts = yylval.number;
2615 };
2616
2617 general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
2618 {
2619 ConfigFileEntry.disable_remote = yylval.number;
2620 };
2621
2622 general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
2623 {
2624 ConfigFileEntry.failed_oper_notice = yylval.number;
2625 };
2626
2627 general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
2628 {
2629 ConfigFileEntry.anti_nick_flood = yylval.number;
2630 };
2631
2632 general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
2633 {
2634 ConfigFileEntry.max_nick_time = $3;
2635 };
2636
2637 general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
2638 {
2639 ConfigFileEntry.max_nick_changes = $3;
2640 };
2641
2642 general_max_accept: MAX_ACCEPT '=' NUMBER ';'
2643 {
2644 ConfigFileEntry.max_accept = $3;
2645 };
2646
2647 general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
2648 {
2649 ConfigFileEntry.anti_spam_exit_message_time = $3;
2650 };
2651
2652 general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
2653 {
2654 ConfigFileEntry.ts_warn_delta = $3;
2655 };
2656
2657 general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
2658 {
2659 if (conf_parser_ctx.pass == 2)
2660 ConfigFileEntry.ts_max_delta = $3;
2661 };
2662
2663 general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
2664 {
2665 if (($3 > 0) && conf_parser_ctx.pass == 1)
2666 {
2667 ilog(LOG_TYPE_IRCD, "You haven't read your config file properly.");
2668 ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed.");
2669 ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line.");
2670 exit(0);
2671 }
2672 };
2673
2674 general_kline_with_reason: KLINE_WITH_REASON '=' TBOOL ';'
2675 {
2676 ConfigFileEntry.kline_with_reason = yylval.number;
2677 };
2678
2679 general_kline_reason: KLINE_REASON '=' QSTRING ';'
2680 {
2681 if (conf_parser_ctx.pass == 2)
2682 {
2683 MyFree(ConfigFileEntry.kline_reason);
2684 DupString(ConfigFileEntry.kline_reason, yylval.string);
2685 }
2686 };
2687
2688 general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
2689 {
2690 ConfigFileEntry.invisible_on_connect = yylval.number;
2691 };
2692
2693 general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
2694 {
2695 ConfigFileEntry.warn_no_nline = yylval.number;
2696 };
2697
2698 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
2699 {
2700 ConfigFileEntry.stats_e_disabled = yylval.number;
2701 };
2702
2703 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
2704 {
2705 ConfigFileEntry.stats_o_oper_only = yylval.number;
2706 };
2707
2708 general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
2709 {
2710 ConfigFileEntry.stats_P_oper_only = yylval.number;
2711 };
2712
2713 general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
2714 {
2715 ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
2716 } | STATS_K_OPER_ONLY '=' TMASKED ';'
2717 {
2718 ConfigFileEntry.stats_k_oper_only = 1;
2719 };
2720
2721 general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
2722 {
2723 ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
2724 } | STATS_I_OPER_ONLY '=' TMASKED ';'
2725 {
2726 ConfigFileEntry.stats_i_oper_only = 1;
2727 };
2728
2729 general_pace_wait: PACE_WAIT '=' timespec ';'
2730 {
2731 ConfigFileEntry.pace_wait = $3;
2732 };
2733
2734 general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
2735 {
2736 ConfigFileEntry.caller_id_wait = $3;
2737 };
2738
2739 general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
2740 {
2741 ConfigFileEntry.opers_bypass_callerid = yylval.number;
2742 };
2743
2744 general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
2745 {
2746 ConfigFileEntry.pace_wait_simple = $3;
2747 };
2748
2749 general_short_motd: SHORT_MOTD '=' TBOOL ';'
2750 {
2751 ConfigFileEntry.short_motd = yylval.number;
2752 };
2753
2754 general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
2755 {
2756 ConfigFileEntry.no_oper_flood = yylval.number;
2757 };
2758
2759 general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
2760 {
2761 ConfigFileEntry.true_no_oper_flood = yylval.number;
2762 };
2763
2764 general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
2765 {
2766 ConfigFileEntry.oper_pass_resv = yylval.number;
2767 };
2768
2769 general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
2770 {
2771 if (conf_parser_ctx.pass == 2)
2772 {
2773 if (strlen(yylval.string) > LOCALE_LENGTH-2)
2774 yylval.string[LOCALE_LENGTH-1] = '\0';
2775
2776 set_locale(yylval.string);
2777 }
2778 };
2779
2780 general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
2781 {
2782 ConfigFileEntry.dots_in_ident = $3;
2783 };
2784
2785 general_max_targets: MAX_TARGETS '=' NUMBER ';'
2786 {
2787 ConfigFileEntry.max_targets = $3;
2788 };
2789
2790 general_use_egd: USE_EGD '=' TBOOL ';'
2791 {
2792 ConfigFileEntry.use_egd = yylval.number;
2793 };
2794
2795 general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
2796 {
2797 if (conf_parser_ctx.pass == 2)
2798 {
2799 MyFree(ConfigFileEntry.egdpool_path);
2800 DupString(ConfigFileEntry.egdpool_path, yylval.string);
2801 }
2802 };
2803
2804 general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2805 {
2806 if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2807 {
2808 MyFree(ConfigFileEntry.service_name);
2809 DupString(ConfigFileEntry.service_name, yylval.string);
2810 }
2811 };
2812
2813 general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2814 {
2815 ConfigFileEntry.ping_cookie = yylval.number;
2816 };
2817
2818 general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
2819 {
2820 ConfigFileEntry.disable_auth = yylval.number;
2821 };
2822
2823 general_throttle_time: THROTTLE_TIME '=' timespec ';'
2824 {
2825 ConfigFileEntry.throttle_time = yylval.number;
2826 };
2827
2828 general_oper_umodes: OPER_UMODES
2829 {
2830 ConfigFileEntry.oper_umodes = 0;
2831 } '=' umode_oitems ';' ;
2832
2833 umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
2834 umode_oitem: T_BOTS
2835 {
2836 ConfigFileEntry.oper_umodes |= UMODE_BOTS;
2837 } | T_CCONN
2838 {
2839 ConfigFileEntry.oper_umodes |= UMODE_CCONN;
2840 } | T_CCONN_FULL
2841 {
2842 ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
2843 } | T_DEAF
2844 {
2845 ConfigFileEntry.oper_umodes |= UMODE_DEAF;
2846 } | T_DEBUG
2847 {
2848 ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
2849 } | T_FULL
2850 {
2851 ConfigFileEntry.oper_umodes |= UMODE_FULL;
2852 } | HIDDEN
2853 {
2854 ConfigFileEntry.oper_umodes |= UMODE_HIDDEN;
2855 } | T_SKILL
2856 {
2857 ConfigFileEntry.oper_umodes |= UMODE_SKILL;
2858 } | T_NCHANGE
2859 {
2860 ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
2861 } | T_REJ
2862 {
2863 ConfigFileEntry.oper_umodes |= UMODE_REJ;
2864 } | T_UNAUTH
2865 {
2866 ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
2867 } | T_SPY
2868 {
2869 ConfigFileEntry.oper_umodes |= UMODE_SPY;
2870 } | T_EXTERNAL
2871 {
2872 ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
2873 } | T_OPERWALL
2874 {
2875 ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
2876 } | T_SERVNOTICE
2877 {
2878 ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
2879 } | T_INVISIBLE
2880 {
2881 ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
2882 } | T_WALLOP
2883 {
2884 ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
2885 } | T_SOFTCALLERID
2886 {
2887 ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
2888 } | T_CALLERID
2889 {
2890 ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
2891 } | T_LOCOPS
2892 {
2893 ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
2894 };
2895
2896 general_oper_only_umodes: OPER_ONLY_UMODES
2897 {
2898 ConfigFileEntry.oper_only_umodes = 0;
2899 } '=' umode_items ';' ;
2900
2901 umode_items: umode_items ',' umode_item | umode_item;
2902 umode_item: T_BOTS
2903 {
2904 ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
2905 } | T_CCONN
2906 {
2907 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
2908 } | T_CCONN_FULL
2909 {
2910 ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
2911 } | T_DEAF
2912 {
2913 ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
2914 } | T_DEBUG
2915 {
2916 ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
2917 } | T_FULL
2918 {
2919 ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
2920 } | T_SKILL
2921 {
2922 ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
2923 } | HIDDEN
2924 {
2925 ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN;
2926 } | T_NCHANGE
2927 {
2928 ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
2929 } | T_REJ
2930 {
2931 ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
2932 } | T_UNAUTH
2933 {
2934 ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
2935 } | T_SPY
2936 {
2937 ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
2938 } | T_EXTERNAL
2939 {
2940 ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
2941 } | T_OPERWALL
2942 {
2943 ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
2944 } | T_SERVNOTICE
2945 {
2946 ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
2947 } | T_INVISIBLE
2948 {
2949 ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
2950 } | T_WALLOP
2951 {
2952 ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
2953 } | T_SOFTCALLERID
2954 {
2955 ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
2956 } | T_CALLERID
2957 {
2958 ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
2959 } | T_LOCOPS
2960 {
2961 ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
2962 };
2963
2964 general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
2965 {
2966 ConfigFileEntry.min_nonwildcard = $3;
2967 };
2968
2969 general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
2970 {
2971 ConfigFileEntry.min_nonwildcard_simple = $3;
2972 };
2973
2974 general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
2975 {
2976 ConfigFileEntry.default_floodcount = $3;
2977 };
2978
2979 general_client_flood: T_CLIENT_FLOOD '=' sizespec ';'
2980 {
2981 ConfigFileEntry.client_flood = $3;
2982 };
2983
2984
2985 /***************************************************************************
2986 * section channel
2987 ***************************************************************************/
2988 channel_entry: CHANNEL
2989 '{' channel_items '}' ';';
2990
2991 channel_items: channel_items channel_item | channel_item;
2992 channel_item: channel_use_except |
2993 channel_use_invex | channel_use_knock | channel_max_bans |
2994 channel_knock_delay | channel_knock_delay_channel |
2995 channel_max_chans_per_user | channel_max_chans_per_oper |
2996 channel_quiet_on_ban | channel_default_split_user_count |
2997 channel_default_split_server_count |
2998 channel_no_create_on_split | channel_restrict_channels |
2999 channel_no_join_on_split |
3000 channel_jflood_count | channel_jflood_time |
3001 channel_disable_fake_channels | error;
3002
3003 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
3004 {
3005 ConfigChannel.disable_fake_channels = yylval.number;
3006 };
3007
3008 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
3009 {
3010 ConfigChannel.restrict_channels = yylval.number;
3011 };
3012
3013 channel_use_except: USE_EXCEPT '=' TBOOL ';'
3014 {
3015 ConfigChannel.use_except = yylval.number;
3016 };
3017
3018 channel_use_invex: USE_INVEX '=' TBOOL ';'
3019 {
3020 ConfigChannel.use_invex = yylval.number;
3021 };
3022
3023 channel_use_knock: USE_KNOCK '=' TBOOL ';'
3024 {
3025 ConfigChannel.use_knock = yylval.number;
3026 };
3027
3028 channel_knock_delay: KNOCK_DELAY '=' timespec ';'
3029 {
3030 ConfigChannel.knock_delay = $3;
3031 };
3032
3033 channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
3034 {
3035 ConfigChannel.knock_delay_channel = $3;
3036 };
3037
3038 channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
3039 {
3040 ConfigChannel.max_chans_per_user = $3;
3041 };
3042
3043 channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
3044 {
3045 ConfigChannel.max_chans_per_oper = $3;
3046 };
3047
3048 channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
3049 {
3050 ConfigChannel.quiet_on_ban = yylval.number;
3051 };
3052
3053 channel_max_bans: MAX_BANS '=' NUMBER ';'
3054 {
3055 ConfigChannel.max_bans = $3;
3056 };
3057
3058 channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
3059 {
3060 ConfigChannel.default_split_user_count = $3;
3061 };
3062
3063 channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
3064 {
3065 ConfigChannel.default_split_server_count = $3;
3066 };
3067
3068 channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
3069 {
3070 ConfigChannel.no_create_on_split = yylval.number;
3071 };
3072
3073 channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
3074 {
3075 ConfigChannel.no_join_on_split = yylval.number;
3076 };
3077
3078 channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3079 {
3080 GlobalSetOptions.joinfloodcount = yylval.number;
3081 };
3082
3083 channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
3084 {
3085 GlobalSetOptions.joinfloodtime = yylval.number;
3086 };
3087
3088 /***************************************************************************
3089 * section serverhide
3090 ***************************************************************************/
3091 serverhide_entry: SERVERHIDE
3092 '{' serverhide_items '}' ';';
3093
3094 serverhide_items: serverhide_items serverhide_item | serverhide_item;
3095 serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
3096 serverhide_links_delay |
3097 serverhide_disable_hidden |
3098 serverhide_hidden | serverhide_hidden_name |
3099 serverhide_hide_server_ips |
3100 error;
3101
3102 serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
3103 {
3104 if (conf_parser_ctx.pass == 2)
3105 ConfigServerHide.flatten_links = yylval.number;
3106 };
3107
3108 serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
3109 {
3110 if (conf_parser_ctx.pass == 2)
3111 ConfigServerHide.hide_servers = yylval.number;
3112 };
3113
3114 serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
3115 {
3116 if (conf_parser_ctx.pass == 2)
3117 {
3118 MyFree(ConfigServerHide.hidden_name);
3119 DupString(ConfigServerHide.hidden_name, yylval.string);
3120 }
3121 };
3122
3123 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
3124 {
3125 if (conf_parser_ctx.pass == 2)
3126 {
3127 if (($3 > 0) && ConfigServerHide.links_disabled == 1)
3128 {
3129 eventAddIsh("write_links_file", write_links_file, NULL, $3);
3130 ConfigServerHide.links_disabled = 0;
3131 }
3132
3133 ConfigServerHide.links_delay = $3;
3134 }
3135 };
3136
3137 serverhide_hidden: HIDDEN '=' TBOOL ';'
3138 {
3139 if (conf_parser_ctx.pass == 2)
3140 ConfigServerHide.hidden = yylval.number;
3141 };
3142
3143 serverhide_disable_hidden: DISABLE_HIDDEN '=' TBOOL ';'
3144 {
3145 if (conf_parser_ctx.pass == 2)
3146 ConfigServerHide.disable_hidden = yylval.number;
3147 };
3148
3149 serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
3150 {
3151 if (conf_parser_ctx.pass == 2)
3152 ConfigServerHide.hide_server_ips = yylval.number;
3153 };

Properties

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