ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/src/conf_parser.y
Revision: 440
Committed: Sat Feb 11 23:11:38 2006 UTC (18 years, 1 month ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 88981 byte(s)
Log Message:
- Fixed bug where "listen { flags = ssl; port 1,2,3; }" would result
  in only port 1 being set ssl enabled.

File Contents

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

Properties

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