Ejemplo n.º 1
0
static int winbind_read_sock(void *buffer, int count)
{
	int fd;
	int nread = 0;
	int total_time = 0;

	fd = winbind_open_pipe_sock(false, false);
	if (fd == -1) {
		return -1;
	}

	/* Read data from socket */
	while(nread < count) {
		struct pollfd pfd;
		int ret;

		/* Catch pipe close on other end by checking if a read()
		   call would not block by calling poll(). */

		pfd.fd = fd;
		pfd.events = POLLIN|POLLHUP;

		/* Wait for 5 seconds for a reply. May need to parameterise this... */

		ret = poll(&pfd, 1, 5000);
		if (ret == -1) {
			winbind_close_sock();
			return -1;                   /* poll error */
		}

		if (ret == 0) {
			/* Not ready for read yet... */
			if (total_time >= 30) {
				/* Timeout */
				winbind_close_sock();
				return -1;
			}
			total_time += 5;
			continue;
		}

		if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {

			/* Do the Read */

			int result = read(fd, (char *)buffer + nread,
			      count - nread);

			if ((result == -1) || (result == 0)) {

				/* Read failed.  I think the only useful thing we
				   can do here is just return -1 and fail since the
				   transaction has failed half way through. */

				winbind_close_sock();
				return -1;
			}

			nread += result;

		}
	}

	return nread;
}
Ejemplo n.º 2
0
static int winbind_open_pipe_sock(int recursing, int need_priv)
{
#ifdef HAVE_UNIXSOCKET
	static pid_t our_pid;
	struct winbindd_request request;
	struct winbindd_response response;
	ZERO_STRUCT(request);
	ZERO_STRUCT(response);

	if (our_pid != getpid()) {
		winbind_close_sock();
		our_pid = getpid();
	}

	if ((need_priv != 0) && (is_privileged == 0)) {
		winbind_close_sock();
	}

	if (winbindd_fd != -1) {
		return winbindd_fd;
	}

	if (recursing) {
		return -1;
	}

	if ((winbindd_fd = winbind_named_pipe_sock(winbindd_socket_dir())) == -1) {
		return -1;
	}

	is_privileged = 0;

	/* version-check the socket */

	request.wb_flags = WBFLAG_RECURSE;
	if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) {
		winbind_close_sock();
		return -1;
	}

	/* try and get priv pipe */

	request.wb_flags = WBFLAG_RECURSE;

	/* Note that response needs to be initialized to avoid
	 * crashing on clean up after WINBINDD_PRIV_PIPE_DIR call failed
	 * as interface version (from the first request) returned as a fstring,
	 * thus response.extra_data.data will not be NULL even though
	 * winbindd response did not write over it due to a failure */
	ZERO_STRUCT(response);
	if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) {
		int fd;
		if ((fd = winbind_named_pipe_sock((char *)response.extra_data.data)) != -1) {
			close(winbindd_fd);
			winbindd_fd = fd;
			is_privileged = 1;
		}
	}

	if ((need_priv != 0) && (is_privileged == 0)) {
		return -1;
	}

	SAFE_FREE(response.extra_data.data);

	return winbindd_fd;
#else
	return -1;
#endif /* HAVE_UNIXSOCKET */
}
Ejemplo n.º 3
0
static int winbind_write_sock(void *buffer, int count, int recursing,
			      int need_priv)
{
	int fd, result, nwritten;

	/* Open connection to winbind daemon */

 restart:

	fd = winbind_open_pipe_sock(recursing, need_priv);
	if (fd == -1) {
		errno = ENOENT;
		return -1;
	}

	/* Write data to socket */

	nwritten = 0;

	while(nwritten < count) {
		struct pollfd pfd;
		int ret;

		/* Catch pipe close on other end by checking if a read()
		   call would not block by calling poll(). */

		pfd.fd = fd;
		pfd.events = POLLIN|POLLOUT|POLLHUP;

		ret = poll(&pfd, 1, -1);
		if (ret == -1) {
			winbind_close_sock();
			return -1;                   /* poll error */
		}

		/* Write should be OK if fd not available for reading */

		if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {

			/* Pipe has closed on remote end */

			winbind_close_sock();
			goto restart;
		}

		/* Do the write */

		result = write(fd, (char *)buffer + nwritten,
			       count - nwritten);

		if ((result == -1) || (result == 0)) {

			/* Write failed */

			winbind_close_sock();
			return -1;
		}

		nwritten += result;
	}

	return nwritten;
}
Ejemplo n.º 4
0
static int winbind_open_pipe_sock(int recursing, int need_priv)
{
#ifdef HAVE_UNIXSOCKET
	static pid_t our_pid;
	struct winbindd_request request;
	struct winbindd_response response;
	ZERO_STRUCT(request);
	ZERO_STRUCT(response);

	if (our_pid != getpid()) {
		winbind_close_sock();
		our_pid = getpid();
	}

	if ((need_priv != 0) && (is_privileged == 0)) {
		winbind_close_sock();
	}

	if (winbindd_fd != -1) {
		return winbindd_fd;
	}

	if (recursing) {
		return -1;
	}

	if ((winbindd_fd = winbind_named_pipe_sock(winbindd_socket_dir())) == -1) {
		return -1;
	}

	is_privileged = 0;

	/* version-check the socket */

	request.wb_flags = WBFLAG_RECURSE;
	if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) {
		winbind_close_sock();
		return -1;
	}

	/* try and get priv pipe */

	request.wb_flags = WBFLAG_RECURSE;
	if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) {
		int fd;
		if ((fd = winbind_named_pipe_sock((char *)response.extra_data.data)) != -1) {
			close(winbindd_fd);
			winbindd_fd = fd;
			is_privileged = 1;
		}
	}

	if ((need_priv != 0) && (is_privileged == 0)) {
		return -1;
	}

	SAFE_FREE(response.extra_data.data);

	return winbindd_fd;
#else
	return -1;
#endif /* HAVE_UNIXSOCKET */
}