static void check_registration(hook_user_register_check_t *hdata)
{
	char buf[1024];
	const char *user;
	const char *domain;
	int count;
	pid_t pid;
	struct procdata *pd;

	if (hdata->approved)
		return;

	if (proccount >= MAX_CHILDPROCS)
	{
		command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later.");
		hdata->approved = 1;
		return;
	}
	switch (pid = fork())
	{
		case 0: /* child */
			connection_close_all_fds();
			mowgli_strlcpy(buf, hdata->email, sizeof buf);
			user = strtok(buf, "@");
			domain = strtok(NULL, "@");
			count = count_mx(domain);

			if (count <= 0)
			{
				/* no MX records or error */
				struct hostent *host;

				/* attempt to resolve host (fallback to A) */
				if((host = gethostbyname(domain)) == NULL)
					_exit(1);
			}
			_exit(0);
			break;
		case -1: /* error */
			slog(LG_ERROR, "fork() failed for check_registration(): %s",
					strerror(errno));
			command_fail(hdata->si, fault_toomany, "Sorry, too many registrations in progress. Try again later.");
			hdata->approved = 1;
			return;
		default: /* parent */
			pd = &procdata[proccount++];
			mowgli_strlcpy(pd->name, hdata->account, sizeof pd->name);
			mowgli_strlcpy(pd->email, hdata->email, sizeof pd->email);
			childproc_add(pid, "ns_mxcheck_async", childproc_cb, pd);
			return;
	}
}
Ejemplo n.º 2
0
static void on_db_save(void *unused)
{
	int stdout_pipes[2], stderr_pipes[2];
	pid_t pid;
	int errno1;

	if (!command)
		return;

	if (update_command_proc.running)
	{
		slog(LG_ERROR, "ERROR: database update command is still running");
		return;
	}

	if (pipe(stdout_pipes) == -1)
	{
		int err = errno;
		slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err));
		return;
	}

	if (pipe(stderr_pipes) == -1)
	{
		int err = errno;
		slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err));
		close(stdout_pipes[0]);
		close(stdout_pipes[1]);
		return;
	}

	pid = fork();

	switch (pid)
	{
		case -1:
			errno1 = errno;
			slog(LG_ERROR, "Failed to fork for database update command: %s", strerror(errno1));
			return;
		case 0:
			connection_close_all_fds();
			close(stdout_pipes[0]);
			close(stderr_pipes[0]);
			dup2(stdout_pipes[1], 1);
			dup2(stderr_pipes[1], 2);
			close(stdout_pipes[1]);
			close(stderr_pipes[1]);
			execl("/bin/sh", "sh",  "-c", command, NULL);
			write(2, "Failed to exec /bin/sh\n", 23);
			_exit(255);
			return;
		default:
			close(stdout_pipes[1]);
			close(stderr_pipes[1]);
			update_command_proc.out = connection_add("update_command_stdout", stdout_pipes[0], 0, recvq_put, NULL);
			update_command_proc.err = connection_add("update_command_stderr", stderr_pipes[0], 0, recvq_put, NULL);
			update_command_proc.out->recvq_handler = update_command_stdout_handler;
			update_command_proc.err->recvq_handler = update_command_stderr_handler;
			update_command_proc.pid = pid;
			update_command_proc.running = 1;
			childproc_add(pid, "db_update", update_command_finished, NULL);
			break;
	}
}