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