ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/src/conf_parser.y
Revision: 900
Committed: Sun Nov 4 13:49:52 2007 UTC (17 years, 9 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 89863 byte(s)
Log Message:
- Added new 'server' option to listener::flags

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

Properties

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