ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1119
Committed: Fri Jan 7 22:01:47 2011 UTC (14 years, 7 months ago) by michael
Original Path: ircd-hybrid-7.3/src/ircd_parser.y
File size: 87869 byte(s)
Log Message:
- removed HUB capability, which was a LL leftover

File Contents

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

Properties

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