Example #1
0
/**
 * Read bytes from a pipe of a forked child process.
 * In addition, this function makes sure that the child process is ignored
 * after all data has been read or a fatal error occurred.
 */
GLOBAL size_t
Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
{
	ssize_t bytes_read = 0;

	assert(buffer != NULL);
	assert(buflen > 0);

	bytes_read = read(proc->pipe_fd, buffer, buflen);
	if (bytes_read < 0) {
		if (errno == EAGAIN)
			return 0;
		Log(LOG_CRIT, "Can't read from child process %ld: %s",
		    proc->pid, strerror(errno));
		Proc_Close(proc);
		bytes_read = 0;
	} else if (bytes_read == 0) {
		/* EOF: clean up */
		LogDebug("Child process %ld: EOF reached, closing pipe.",
		         proc->pid);
		Proc_Close(proc);
	}
	return (size_t)bytes_read;
}
Example #2
0
/**
 * Read result of the authenticator sub-process from pipe
 *
 * @param r_fd		File descriptor of the pipe.
 * @param events	(ignored IO specification)
 */
static void
cb_Read_Auth_Result(int r_fd, UNUSED short events)
{
	char user[CLIENT_USER_LEN], *ptr;
	CONN_ID conn;
	CLIENT *client;
	int result;
	size_t len;
	PROC_STAT *proc;

	LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
	conn = Conn_GetFromProc(r_fd);
	if (conn == NONE) {
		/* Ops, none found? Probably the connection has already
		 * been closed!? We'll ignore that ... */
		io_close(r_fd);
		LogDebug("Auth: Got callback for unknown connection!?");
		return;
	}
	proc = Conn_GetProcStat(conn);
	client = Conn_GetClient(conn);

	/* Read result from pipe */
	len = Proc_Read(proc, &result, sizeof(result));
	Proc_Close(proc);
	if (len == 0)
		return;

	if (len != sizeof(result)) {
		Log(LOG_CRIT, "Auth: Got malformed result!");
		Client_Reject(client, "Internal error", false);
		return;
	}

	if (result == true) {
		/* Authentication succeeded, now set the correct user name
		 * supplied by the client (without prepended '~' for exmaple),
		 * but cut it at the first '@' character: */
		strlcpy(user, Client_OrigUser(client), sizeof(user));
		ptr = strchr(user, '@');
		if (ptr)
			*ptr = '\0';
		Client_SetUser(client, user, true);
		(void)Login_User_PostAuth(client);
	} else
		Client_Reject(client, "Bad password", false);
}