ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1285
Committed: Sun Feb 5 15:12:59 2012 UTC (12 years, 1 month ago) by michael
Original Path: ircd-hybrid-8/src/ircd_parser.y
File size: 84193 byte(s)
Log Message:
- added CIDR support for operator{} blocks
- operator "name"{} is no longer supported

File Contents

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

Properties

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