ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/ircd_parser.y
Revision: 126
Committed: Fri Oct 14 02:41:46 2005 UTC (20 years, 10 months ago) by db
File size: 88266 byte(s)
Log Message:
- attach/conf cleanup take 2
- Each client has now one AccessItem for its connect
  stored in localClient->iline
- The corresponding class is now stored in localClient->class

The ramifications of this move are, there is no conf list to traverse
to find the AccessItem, the class is instantly available from the localClient
struct without having to traverse the confs list and indirectly through the
aconf. This speeds up get_sendq etc. functions. As a bonus, at least
4 fewer bytes are used in the Client struct, since a dlink list is 4 words.
It does mean there is no longer a separate conf oper, which leads to the
kludge of patching the clients iline into an oper conf when
a client opers up. I don't think the oper flags are used after the client
is opered, so the patching operation may not be necessary.

- Server confs are stored in ->serv->sconf as before but attaching
  happens much earlier.
- server hub/leaf masks continues to be a dlink list but linked from
  the ->serv which is only allocated for servers.

- cleaned up some comments, added a comment, notably to check_server()
  which badly needed it.
- Pass ClassItem or AccessItem etc. in when it makes more sense than passing
  in struct ConfItem. This simplified and clarified rebuild_cidr_class()

And lo, there was a great rejoicing.


File Contents

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

Properties

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