ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/ircd_parser.y
Revision: 109
Committed: Wed Oct 12 09:42:59 2005 UTC (20 years, 10 months ago) by michael
File size: 88266 byte(s)
Log Message:
- Forward-ported GDENY core fix

File Contents

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

Properties

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