ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1294
Committed: Wed Feb 22 20:48:30 2012 UTC (12 years, 1 month ago) by michael
Original Path: ircd-hybrid-8/src/ircd_parser.y
File size: 84166 byte(s)
Log Message:
- Add user mode +H which simply hides operator status to other users.
  This solution replaces current method of hidding operator status where the
  admin mode is not sent to other servers unless hidden_administrator is disabled.
- m_who() now takes care whether an operator is hidden or not

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