ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1072
Committed: Wed Feb 17 22:58:23 2010 UTC (15 years, 6 months ago) by michael
Original Path: ircd-hybrid-7.3/src/ircd_parser.y
File size: 94343 byte(s)
Log Message:
- remove old dot_in_ip6_addr configuration option. this is now obsolete.

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

Properties

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