/** * Reload the server configuration file. */ static void Rehash(void) { char old_name[CLIENT_ID_LEN]; unsigned old_nicklen; Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" ); /* Remember old server name and nickname length */ strlcpy( old_name, Conf_ServerName, sizeof old_name ); old_nicklen = Conf_MaxNickLength; /* Re-read configuration ... */ if (!Conf_Rehash( )) return; /* Close down all listening sockets */ Conn_ExitListeners( ); /* Recover old server name and nickname length: these values can't * be changed during run-time */ if (strcmp(old_name, Conf_ServerName) != 0 ) { strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName); Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name."); } if (old_nicklen != Conf_MaxNickLength) { Conf_MaxNickLength = old_nicklen; Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value."); } /* Create new pre-defined channels */ Channel_InitPredefined( ); if (!ConnSSL_InitLibrary()) Log(LOG_WARNING, "Re-Initializing of SSL failed, using old keys!"); /* Start listening on sockets */ Conn_InitListeners( ); /* Sync configuration with established connections */ Conn_SyncServerStruct( ); Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." ); } /* Rehash */
/** * Initialize ngIRCd daemon. * * @param NGIRCd_NoDaemon Set to true if ngIRCd should run in the * foreground (and not as a daemon). * @return true on success. */ static bool NGIRCd_Init(bool NGIRCd_NoDaemon) { static bool initialized; bool chrooted = false; struct passwd *pwd; struct group *grp; int real_errno, fd = -1; pid_t pid; if (initialized) return true; if (!NGIRCd_NoDaemon) { /* open /dev/null before chroot() */ fd = open( "/dev/null", O_RDWR); if (fd < 0) Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno)); } /* SSL initialization */ if (!ConnSSL_InitLibrary()) Log(LOG_WARNING, "Warning: Error during SSL initialization, continuing ..."); /* Change root */ if (Conf_Chroot[0]) { if (chdir(Conf_Chroot) != 0) { Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror(errno)); goto out; } if (chroot(Conf_Chroot) != 0) { Log(LOG_ERR, "Can't change root directory to \"%s\": %s", Conf_Chroot, strerror(errno)); goto out; } else { chrooted = true; Log(LOG_INFO, "Changed root and working directory to \"%s\".", Conf_Chroot); } } /* Check user ID */ if (Conf_UID == 0) { pwd = getpwuid(0); Log(LOG_INFO, "ServerUID must not be %s(0), using \"nobody\" instead.", pwd ? pwd->pw_name : "?"); if (!NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) { Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s", errno ? strerror(errno) : "not found" ); goto out; } } /* Change group ID */ if (getgid() != Conf_GID) { if (setgid(Conf_GID) != 0) { real_errno = errno; grp = getgrgid(Conf_GID); Log(LOG_ERR, "Can't change group ID to %s(%u): %s", grp ? grp->gr_name : "?", Conf_GID, strerror(errno)); if (real_errno != EPERM) goto out; } } /* Change user ID */ if (getuid() != Conf_UID) { if (setuid(Conf_UID) != 0) { real_errno = errno; pwd = getpwuid(Conf_UID); Log(LOG_ERR, "Can't change user ID to %s(%u): %s", pwd ? pwd->pw_name : "?", Conf_UID, strerror(errno)); if (real_errno != EPERM) goto out; } } initialized = true; /* Normally a child process is forked which isn't any longer * connected to ther controlling terminal. Use "--nodaemon" * to disable this "daemon mode" (useful for debugging). */ if (!NGIRCd_NoDaemon) { pid = fork(); if (pid > 0) { /* "Old" process: exit. */ exit(0); } if (pid < 0) { /* Error!? */ fprintf(stderr, "%s: Can't fork: %s!\nFatal error, exiting now ...\n", PACKAGE_NAME, strerror(errno)); exit(1); } /* New child process */ #ifndef NeXT (void)setsid(); #else setpgrp(0, getpid()); #endif if (chdir("/") != 0) Log(LOG_ERR, "Can't change directory to '/': %s", strerror(errno)); /* Detach stdin, stdout and stderr */ Setup_FDStreams(fd); if (fd > 2) close(fd); } pid = getpid(); Pidfile_Create(pid); /* Check UID/GID we are running as, can be different from values * configured (e. g. if we were already started with a UID>0. */ Conf_UID = getuid(); Conf_GID = getgid(); pwd = getpwuid(Conf_UID); grp = getgrgid(Conf_GID); Log(LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.", pwd ? pwd->pw_name : "unknown", (long)Conf_UID, grp ? grp->gr_name : "unknown", (long)Conf_GID, (long)pid); if (chrooted) { Log(LOG_INFO, "Running with root directory \"%s\".", Conf_Chroot ); return true; } else Log(LOG_INFO, "Not running with changed root directory."); /* Change working directory to home directory of the user we are * running as (only when running in daemon mode and not in chroot) */ if (NGIRCd_NoDaemon) return true; if (pwd) { if (chdir(pwd->pw_dir) == 0) Log(LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir); else Log(LOG_INFO, "Notice: Can't change working directory to \"%s\": %s", pwd->pw_dir, strerror(errno)); } else Log(LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID); return true; out: if (fd > 2) close(fd); return false; } /* NGIRCd_Init */