ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 912
Committed: Wed Nov 7 22:47:44 2007 UTC (16 years, 5 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 89883 byte(s)
Log Message:
- Implemented libtool-ltdl. Only shared modules are supported currently
- Several build fixes and cleanups. ircd now builds and runs without any problems
- Added back all files to SVN that are needed to built the daemon
  I really don't want to force other people that want to test the snapshots
  or svn versions to install yyacc, lex, automake, autoconf and libtool...
  No problem having required files in svn
- Removed some automake maintainer stuff which is kinda useless for us

File Contents

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

Properties

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