ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1024
Committed: Sun Nov 1 23:14:25 2009 UTC (14 years, 4 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94504 byte(s)
Log Message:
- Fixed compile with --disable-openssl

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

Properties

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