ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1309
Committed: Sun Mar 25 11:24:18 2012 UTC (12 years ago) by michael
Original Path: ircd-hybrid-8/src/conf_parser.y
File size: 81769 byte(s)
Log Message:
- renaming files:

  ircd_parser.y -> conf_parser.y
  ircd_lexer.l  -> conf_lexer.l
  s_conf.c      -> conf.c
  s_conf.h      -> conf.h
  s_log.c       -> log.c
  s_log.h       -> log.h

File Contents

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

Properties

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