Exemplo n.º 1
0
/**
 * 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 */
Exemplo n.º 2
0
/**
 * 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 */