ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/ircd_parser.y
Revision: 200
Committed: Tue Nov 1 11:38:41 2005 UTC (20 years, 9 months ago) by adx
File size: 88142 byte(s)
Log Message:
+ removed invite_ops_only, controlled by +p now
+ sorted ircd.conf:channel{} a bit
+ added newconf framework for channel{}
+ added missing 7.2 RELNOTES


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

Properties

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