ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1119
Committed: Fri Jan 7 22:01:47 2011 UTC (15 years, 6 months ago) by michael
Original Path: ircd-hybrid-7.3/src/ircd_parser.y
File size: 87869 byte(s)
Log Message:
- removed HUB capability, which was a LL leftover

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

Properties

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