ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1123
Committed: Sun Feb 6 21:57:50 2011 UTC (13 years, 1 month ago) by michael
Original Path: ircd-hybrid-7.3/src/ircd_parser.y
File size: 87726 byte(s)
Log Message:
- Got rid of irc_addrinfo.c and irc_getnameinfo.c
- Fixed broken ipv6 detection due to incorrect use of AC_CHECK_TYPES

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

Properties

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