1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * ircd.c: Starts up and runs the ircd.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 *
24 * $Id: ircd.c 26304 2008-12-16 03:08:43Z androsyn $
25 */
26
27 #include "ratbox_lib.h"
28 #include "setup.h"
29 #include "config.h"
30 #include "stdinc.h"
31 #include "struct.h"
32 #include "ircd.h"
33 #include "channel.h"
34 #include "class.h"
35 #include "client.h"
36 #include "hash.h"
37 #include "match.h"
38 #include "ircd_signal.h"
39 #include "hostmask.h"
40 #include "numeric.h"
41 #include "parse.h"
42 #include "restart.h"
43 #include "s_auth.h"
44 #include "s_conf.h"
45 #include "s_log.h"
46 #include "s_serv.h" /* try_connections */
47 #include "s_stats.h"
48 #include "scache.h"
49 #include "send.h"
50 #include "whowas.h"
51 #include "hook.h"
52 #include "modules.h"
53 #include "ircd_getopt.h"
54 #include "newconf.h"
55 #include "reject.h"
56 #include "s_conf.h"
57 #include "s_newconf.h"
58 #include "cache.h"
59 #include "monitor.h"
60 #include "dns.h"
61 #include "bandbi.h"
62 #include "sslproc.h"
63 #include "supported.h"
64 /*
65 * Try and find the correct name to use with getrlimit() for setting the max.
66 * number of files allowed to be open by this process.
67 */
68
69 /* /quote set variables */
70 struct SetOptions GlobalSetOptions;
71
72 /* configuration set from ircd.conf */
73 struct config_file_entry ConfigFileEntry;
74 /* server info set from ircd.conf */
75 struct server_info ServerInfo;
76 /* admin info set from ircd.conf */
77 struct admin_info AdminInfo;
78
79 struct Counter Count;
80 struct ServerStatistics ServerStats;
81
82 int maxconnections;
83 struct Client me; /* That's me */
84 struct LocalUser meLocalUser; /* That's also part of me */
85
86 rb_dlink_list global_client_list;
87
88 /* unknown/client pointer lists */
89 rb_dlink_list unknown_list; /* unknown clients ON this server only */
90 rb_dlink_list lclient_list; /* local clients only ON this server */
91 rb_dlink_list serv_list; /* local servers to this server ONLY */
92 rb_dlink_list global_serv_list; /* global servers on the network */
93 rb_dlink_list oper_list; /* our opers, duplicated in lclient_list */
94
95 static unsigned long initialVMTop = 0; /* top of virtual memory at init */
96 const char *logFileName = LPATH;
97 const char *pidFileName = PPATH;
98
99 char **myargv;
100 int dorehash = 0;
101 int dorehashbans = 0;
102 int doremotd = 0;
103 int kline_queued = 0;
104 int server_state_foreground = 0;
105 int printVersion = 0;
106 int ircd_ssl_ok = 0;
107 int zlib_ok = 1;
108
109 int testing_conf = 0;
110 int conf_parse_failure = 0;
111 time_t startup_time;
112
113 /* Set to zero because it should be initialized later using
114 * initialize_server_capabs
115 */
116 int default_server_capabs = CAP_MASK;
117
118 int splitmode;
119 int splitchecking;
120 int split_users;
121 int split_servers;
122 int eob_count;
123
124 void
ircd_shutdown(const char * reason)125 ircd_shutdown(const char *reason)
126 {
127 struct Client *target_p;
128 rb_dlink_node *ptr;
129
130 RB_DLINK_FOREACH(ptr, lclient_list.head)
131 {
132 target_p = ptr->data;
133
134 sendto_one(target_p, ":%s NOTICE %s :Server Terminating. %s",
135 me.name, target_p->name, reason);
136 }
137
138 RB_DLINK_FOREACH(ptr, serv_list.head)
139 {
140 target_p = ptr->data;
141
142 sendto_one(target_p, ":%s ERROR :Terminated by %s", me.name, reason);
143 }
144
145 ilog(L_MAIN, "Server Terminating. %s", reason);
146 close_logfiles();
147
148 unlink(pidFileName);
149 exit(0);
150 }
151
152 /*
153 * get_vm_top - get the operating systems notion of the resident set size
154 */
155 static unsigned long
get_vm_top(void)156 get_vm_top(void)
157 {
158 /*
159 * NOTE: sbrk is not part of the ANSI C library or the POSIX.1 standard
160 * however it seems that everyone defines it. Calling sbrk with a 0
161 * argument will return a pointer to the top of the process virtual
162 * memory without changing the process size, so this call should be
163 * reasonably safe (sbrk returns the new value for the top of memory).
164 * This code relies on the notion that the address returned will be an
165 * offset from 0 (NULL), so the result of sbrk is cast to a size_t and
166 * returned. We really shouldn't be using it here but...
167 */
168 #ifndef _WIN32
169 void *vptr = sbrk(0);
170 return (unsigned long)vptr;
171 #else
172 return -1;
173 #endif
174 }
175
176 /*
177 * get_maxrss - get the operating systems notion of the resident set size
178 */
179 unsigned long
get_maxrss(void)180 get_maxrss(void)
181 {
182 return get_vm_top() - initialVMTop;
183 }
184
185 /*
186 * print_startup - print startup information
187 */
188 static void
print_startup(int pid)189 print_startup(int pid)
190 {
191 printf("ircd: version %s\n", ircd_version);
192 printf("ircd: %s\n", rb_lib_version());
193 printf("ircd: pid %d\n", pid);
194 #ifndef RATBOX_PROFILE
195 printf("ircd: running in %s mode from %s\n",
196 !server_state_foreground ? "background" : "foreground", ConfigFileEntry.dpath);
197 #else
198 printf("ircd: running in foreground mode from %s for profiling\n", ConfigFileEntry.dpath);
199 #endif
200 }
201
202 /*
203 * init_sys
204 *
205 * inputs - boot_daemon flag
206 * output - none
207 * side effects - if boot_daemon flag is not set, don't daemonize
208 */
209 static void
init_sys(void)210 init_sys(void)
211 {
212 #if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
213 struct rlimit limit;
214
215 if(!getrlimit(RLIMIT_NOFILE, &limit))
216 {
217 maxconnections = limit.rlim_cur;
218 if(maxconnections <= MAX_BUFFER)
219 {
220 fprintf(stderr, "ERROR: Shell FD limits are too low.\n");
221 fprintf(stderr,
222 "ERROR: ircd-ratbox reserves %d FDs, shell limits must be above this\n",
223 MAX_BUFFER);
224 exit(EXIT_FAILURE);
225 }
226 return;
227 }
228 #endif /* RLIMIT_FD_MAX */
229 maxconnections = MAXCONNECTIONS;
230 }
231
232 static int
make_daemon(void)233 make_daemon(void)
234 {
235 #ifndef _WIN32
236 int pid, fd;
237
238 if((pid = fork()) < 0)
239 {
240 perror("fork");
241 exit(EXIT_FAILURE);
242 }
243 else if(pid > 0)
244 {
245 print_startup(pid);
246 exit(EXIT_SUCCESS);
247 }
248
249 setsid();
250
251 fd = open("/dev/null", O_RDWR);
252 /* dup2 should close the target fd if its open */
253 dup2(fd, 0);
254 dup2(fd, 1);
255 dup2(fd, 2);
256 close(fd);
257 #endif
258 return 0;
259 }
260
261 static const char *basedir = DPATH;
262 static const char *configfile = CPATH;
263
264 struct lgetopt myopts[] = {
265 {"basedir", &basedir,
266 ISTRING, "Base directory to run ircd from"},
267 {"configfile", &configfile,
268 ISTRING, "File to use for ircd.conf"},
269 {"logfile", &logFileName,
270 ISTRING, "File to use for ircd.log"},
271 {"pidfile", &pidFileName,
272 ISTRING, "File to use for process ID"},
273 {"foreground", &server_state_foreground,
274 YESNO, "Run in foreground (don't detach)"},
275 {"version", &printVersion,
276 YESNO, "Print version and exit"},
277 {"conftest", &testing_conf,
278 YESNO, "Test the configuration files and exit"},
279 {"help", NULL, USAGE, "Print this text"},
280 {NULL, NULL, ISTRING, NULL},
281 };
282
283 static void
check_rehash(void * unusued)284 check_rehash(void *unusued)
285 {
286 /*
287 * Check to see whether we have to rehash the configuration ..
288 */
289 if(dorehash)
290 {
291 rehash(1);
292 dorehash = 0;
293 }
294
295 if(dorehashbans)
296 {
297 rehash_bans(1);
298 dorehashbans = 0;
299 }
300
301 if(doremotd)
302 {
303 sendto_realops_flags(UMODE_ALL, L_ALL,
304 "Got signal SIGUSR1, reloading ircd motd file");
305 cache_user_motd();
306 doremotd = 0;
307 }
308 }
309
310 /*
311 * initalialize_global_set_options
312 *
313 * inputs - none
314 * output - none
315 * side effects - This sets all global set options needed
316 */
317 static void
initialize_global_set_options(void)318 initialize_global_set_options(void)
319 {
320 memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
321 /* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
322
323 GlobalSetOptions.maxclients = ServerInfo.default_max_clients;
324
325 if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER)
326 || (GlobalSetOptions.maxclients <= 0))
327 GlobalSetOptions.maxclients = maxconnections - MAX_BUFFER;
328
329 GlobalSetOptions.autoconn = 1;
330
331 GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
332 GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
333
334 if(ConfigFileEntry.default_floodcount)
335 GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount;
336 else
337 GlobalSetOptions.floodcount = 10;
338
339 split_servers = ConfigChannel.default_split_server_count;
340 split_users = ConfigChannel.default_split_user_count;
341
342 if(split_users && split_servers
343 && (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
344 {
345 splitmode = 1;
346 splitchecking = 1;
347 }
348
349 GlobalSetOptions.ident_timeout = IDENT_TIMEOUT;
350
351 rb_strlcpy(GlobalSetOptions.operstring,
352 ConfigFileEntry.default_operstring, sizeof(GlobalSetOptions.operstring));
353 rb_strlcpy(GlobalSetOptions.adminstring,
354 ConfigFileEntry.default_adminstring, sizeof(GlobalSetOptions.adminstring));
355
356 /* memset( &ConfigChannel, 0, sizeof(ConfigChannel)); */
357
358 /* End of global set options */
359
360 }
361
362 /*
363 * initialize_server_capabs
364 *
365 * inputs - none
366 * output - none
367 */
368 static void
initialize_server_capabs(void)369 initialize_server_capabs(void)
370 {
371 default_server_capabs &= ~CAP_ZIP;
372 }
373
374
375 /*
376 * write_pidfile
377 *
378 * inputs - filename+path of pid file
379 * output - none
380 * side effects - write the pid of the ircd to filename
381 */
382 static void
write_pidfile(const char * filename)383 write_pidfile(const char *filename)
384 {
385 FILE *fb;
386 char buff[32];
387 if((fb = fopen(filename, "w")))
388 {
389 unsigned int pid = (unsigned int)getpid();
390
391 rb_snprintf(buff, sizeof(buff), "%u\n", pid);
392 if((fputs(buff, fb) == -1))
393 {
394 ilog(L_MAIN, "Error writing %u to pid file %s (%s)",
395 pid, filename, strerror(errno));
396 }
397 fclose(fb);
398 return;
399 }
400 else
401 {
402 ilog(L_MAIN, "Error opening pid file %s", filename);
403 }
404 }
405
406 /*
407 * check_pidfile
408 *
409 * inputs - filename+path of pid file
410 * output - none
411 * side effects - reads pid from pidfile and checks if ircd is in process
412 * list. if it is, gracefully exits
413 * -kre
414 */
415 static void
check_pidfile(const char * filename)416 check_pidfile(const char *filename)
417 {
418 FILE *fb;
419 char buff[32];
420 pid_t pidfromfile;
421
422 /* Don't do logging here, since we don't have log() initialised */
423 if((fb = fopen(filename, "r")))
424 {
425 if(fgets(buff, 20, fb) != NULL)
426 {
427 pidfromfile = atoi(buff);
428 if(!rb_kill(pidfromfile, 0))
429 {
430 printf("ircd: daemon is already running\n");
431 exit(-1);
432 }
433 }
434 fclose(fb);
435 }
436 }
437
438 /*
439 * setup_corefile
440 *
441 * inputs - nothing
442 * output - nothing
443 * side effects - setups corefile to system limits.
444 * -kre
445 */
446 static void
setup_corefile(void)447 setup_corefile(void)
448 {
449 #ifdef HAVE_SYS_RESOURCE_H
450 struct rlimit rlim; /* resource limits */
451
452 /* Set corefilesize to maximum */
453 if(!getrlimit(RLIMIT_CORE, &rlim))
454 {
455 rlim.rlim_cur = rlim.rlim_max;
456 setrlimit(RLIMIT_CORE, &rlim);
457 }
458 #endif
459 }
460
461 static void
ilogcb(const char * buf)462 ilogcb(const char *buf)
463 {
464 ilog(L_MAIN, "libratbox reports: %s", buf);
465 }
466
467 static void
restartcb(const char * buf)468 restartcb(const char *buf)
469 {
470 ilog(L_MAIN, "libratbox has called the restart callback: %s", buf);
471 restart(buf);
472 }
473
474 static void
diecb(const char * buf)475 diecb(const char *buf)
476 {
477 if(buf != NULL)
478 ilog(L_MAIN, "libratbox has called the die callback..aborting: %s", buf);
479 else
480 ilog(L_MAIN, "libratbox has called the die callback..aborting");
481 abort();
482 }
483
484 #ifndef _WIN32
485 static int
seed_with_urandom(void)486 seed_with_urandom(void)
487 {
488 unsigned int seed;
489 int fd;
490
491 fd = open("/dev/urandom", O_RDONLY);
492 if(fd >= 0)
493 {
494 if(read(fd, &seed, sizeof(seed)) == sizeof(seed))
495 {
496 close(fd);
497 srand(seed);
498 return 1;
499 }
500 }
501 return 0;
502 }
503 #endif
504
505 static void
seed_with_clock(void)506 seed_with_clock(void)
507 {
508 const struct timeval *tv;
509 rb_set_time();
510 tv = rb_current_time_tv();
511 srand(tv->tv_sec ^ (tv->tv_usec | (getpid() << 20)));
512 }
513
514 static void
seed_random(void * unused)515 seed_random(void *unused)
516 {
517 unsigned int seed;
518 if(rb_get_random(&seed, sizeof(seed)) == -1)
519 {
520 #ifndef _WIN32
521 if(!seed_with_urandom())
522 #endif
523 seed_with_clock();
524 return;
525 }
526 srand(seed);
527 }
528
529 int
ratbox_main(int argc,char * argv[])530 ratbox_main(int argc, char *argv[])
531 {
532 char emptyname[] = "";
533 int r;
534 /* Check to see if the user is running us as root, which is a nono */
535 #ifndef _WIN32
536 if(geteuid() == 0)
537 {
538 fprintf(stderr, "Don't run ircd as root!!!\n");
539 exit(EXIT_FAILURE);
540 }
541 #endif
542 init_sys();
543
544
545
546 myargv = argv;
547 parseargs(&argc, &argv, myopts);
548
549 if(printVersion)
550 {
551 printf("ircd: version %s\n", ircd_version);
552 printf("ircd: %s\n", rb_lib_version());
553 printf("ircd: configure options\n");
554 puts(RATBOX_CONFIGURE_OPTS);
555 exit(EXIT_SUCCESS);
556 }
557
558 if(chdir(basedir))
559 {
560 fprintf(stderr, "Unable to chdir to %s: %s\n", basedir, strerror(errno));
561 exit(EXIT_FAILURE);
562 }
563
564 add_all_conf_settings();
565
566 r = read_config_file(configfile);
567 if(r > 0)
568 {
569 fprintf(stderr,
570 "ERROR: Unable to start ircd: found %d syntax error(s) whlist loading config file. Try running with -conftest\n",
571 r);
572 return 1;
573 }
574
575 if(testing_conf)
576 fprintf(stderr, "Syntax OK, doing second pass...\n");
577
578
579 r = check_valid_entries();
580 if(r > 0)
581 {
582 fprintf(stderr,
583 "ERROR: Unable to start ircd: found %d error(s) whilst loading config file. Try running with -conftest\n",
584 r);
585 return 1;
586 }
587
588 if(testing_conf)
589 fprintf(stderr, "Second pass reports OK\n");
590
591 ConfigFileEntry.dpath = basedir;
592 ConfigFileEntry.configfile = configfile; /* Server configuration file */
593
594 /* Check if there is pidfile and daemon already running */
595 if(!testing_conf)
596 {
597 check_pidfile(pidFileName);
598
599 if(!server_state_foreground)
600 make_daemon();
601 else
602 print_startup(getpid());
603 }
604
605 /* This must be after we daemonize.. */
606 rb_lib_init(ilogcb, restartcb, diecb, 1, maxconnections, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
607 rb_linebuf_init(LINEBUF_HEAP_SIZE);
608
609 set_default_conf();
610 rb_set_time();
611 setup_corefile();
612 initialVMTop = get_vm_top();
613
614 memset(&me, 0, sizeof(me));
615 me.name = emptyname;
616 memset(&meLocalUser, 0, sizeof(meLocalUser));
617 me.localClient = &meLocalUser;
618
619 /* Make sure all lists are zeroed */
620 memset(&unknown_list, 0, sizeof(unknown_list));
621 memset(&lclient_list, 0, sizeof(lclient_list));
622 memset(&serv_list, 0, sizeof(serv_list));
623 memset(&global_serv_list, 0, sizeof(global_serv_list));
624 memset(&oper_list, 0, sizeof(oper_list));
625
626 rb_dlinkAddTail(&me, &me.node, &global_client_list);
627
628 memset(&Count, 0, sizeof(Count));
629 memset(&ServerInfo, 0, sizeof(ServerInfo));
630 memset(&AdminInfo, 0, sizeof(AdminInfo));
631 memset(&ServerStats, 0, sizeof(struct ServerStatistics));
632
633
634 /* Initialise the channel capability usage counts... */
635 init_chcap_usage_counts();
636
637 ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
638
639 umask(077); /* better safe than sorry --SRB */
640
641
642 setup_signals();
643 init_s_conf();
644 init_s_newconf();
645
646
647
648 #if defined(__CYGWIN__) || defined(_WIN32) || defined(RATBOX_PROFILE)
649 server_state_foreground = 1;
650 #endif
651
652 if(ConfigServerHide.links_delay > 0)
653 rb_event_add("cache_links", cache_links, NULL, ConfigServerHide.links_delay);
654 else
655 ConfigServerHide.links_disabled = 1;
656
657 if(ConfigFileEntry.use_egd && (ConfigFileEntry.egdpool_path != NULL))
658 {
659 rb_init_prng(ConfigFileEntry.egdpool_path, RB_PRNG_EGD);
660 }
661 else
662 rb_init_prng(NULL, RB_PRNG_DEFAULT);
663 seed_random(NULL);
664
665 init_main_logfile(logFileName);
666 init_hash();
667 init_host_hash();
668 clear_hash_parse();
669 init_client();
670 init_channels();
671 initclass();
672 initwhowas();
673 init_hook();
674 init_reject();
675 init_cache();
676 init_monitor();
677 init_isupport();
678 #ifdef STATIC_MODULES
679 load_static_modules();
680 #else
681 load_all_modules(1);
682 load_core_modules(1);
683 #endif
684 init_resolver(); /* Needs to be setup before the io loop */
685 init_ssld();
686
687 load_conf_settings();
688 if(ServerInfo.bandb_path == NULL)
689 ServerInfo.bandb_path = rb_strdup(DBPATH);
690
691 init_bandb();
692 rehash_bans(0);
693
694 #ifndef STATIC_MODULES
695 mod_add_path(MODULE_DIR);
696 mod_add_path(MODULE_DIR "/autoload");
697 #endif
698
699 initialize_server_capabs(); /* Set up default_server_capabs */
700 initialize_global_set_options();
701
702 init_auth(); /* Initialise the auth code - depends on global set options */
703 rehash_dns_vhost(); /* load any vhost dns binds now */
704
705 if(ServerInfo.name == NULL)
706 {
707 fprintf(stderr, "ERROR: No server name specified in serverinfo block.\n");
708 ilog(L_MAIN, "No server name specified in serverinfo block.");
709 exit(EXIT_FAILURE);
710 }
711 me.name = ServerInfo.name;
712
713 if(ServerInfo.sid[0] == '\0')
714 {
715 fprintf(stderr, "ERROR: No server sid specified in serverinfo block.\n");
716 ilog(L_MAIN, "No server sid specified in serverinfo block.");
717 exit(EXIT_FAILURE);
718 }
719 strcpy(me.id, ServerInfo.sid);
720 init_uid();
721
722 /* serverinfo{} description must exist. If not, error out. */
723 if(ServerInfo.description == NULL)
724 {
725 fprintf(stderr, "ERROR: No server description specified in serverinfo block.\n");
726 ilog(L_MAIN, "ERROR: No server description specified in serverinfo block.");
727 exit(EXIT_FAILURE);
728 }
729 rb_strlcpy(me.info, ServerInfo.description, sizeof(me.info));
730
731 if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
732 {
733 /* just do the rb_setup_ssl_server to validate the config */
734 if(!rb_setup_ssl_server
735 (ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params))
736 {
737 ilog(L_MAIN, "WARNING: Unable to setup SSL.");
738 ircd_ssl_ok = 0;
739 }
740 else
741 ircd_ssl_ok = 1;
742 }
743
744 if(testing_conf)
745 {
746 exit(conf_parse_failure ? 1 : 0);
747 }
748
749 me.from = &me;
750 me.servptr = &me;
751 SetMe(&me);
752 make_server(&me);
753 startup_time = rb_current_time();
754 add_to_hash(HASH_CLIENT, me.name, &me);
755 add_to_hash(HASH_ID, me.id, &me);
756
757 rb_dlinkAddAlloc(&me, &global_serv_list);
758
759 check_class();
760 write_pidfile(pidFileName);
761 load_help();
762 open_logfiles(logFileName);
763
764 ilog(L_MAIN, "Server Ready");
765
766 /* We want try_connections to be called as soon as possible now! -- adrian */
767 /* No, 'cause after a restart it would cause all sorts of nick collides */
768 /* um. by waiting even longer, that just means we have even *more*
769 * nick collisions. what a stupid idea. set an event for the IO loop --fl
770 */
771 rb_event_addish("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
772 rb_event_addonce("try_connections_startup", try_connections, NULL, 2);
773 rb_event_add("check_rehash", check_rehash, NULL, 3);
774 rb_event_addish("reseed_srand", seed_random, NULL, 300); /* reseed every 10 minutes */
775
776 if(splitmode)
777 rb_event_add("check_splitmode", check_splitmode, NULL, 5);
778
779 rb_lib_loop(0); /* we'll never return from here */
780 return 0;
781 }
782