ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.1.0beta2/src/conf_parser.y
Revision: 1285
Committed: Sun Feb 5 15:12:59 2012 UTC (14 years, 5 months ago) by michael
Original Path: ircd-hybrid-8/src/ircd_parser.y
File size: 84193 byte(s)
Log Message:
- added CIDR support for operator{} blocks
- operator "name"{} is no longer supported

File Contents

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

Properties

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