Esempio n. 1
0
/*
  called when we can write to a connection
*/
static void wbsrv_send(struct stream_connection *conn, uint16_t flags)
{
	struct wbsrv_connection *wbsrv_conn = talloc_get_type(conn->private_data,
							struct wbsrv_connection);
	/* this should never be triggered! */
	wbsrv_terminate_connection(wbsrv_conn, "wbsrv_send: called");
}
Esempio n. 2
0
static void wbsrv_accept(struct stream_connection *conn)
{
	struct wbsrv_listen_socket *listen_socket = talloc_get_type(conn->private_data,
								    struct wbsrv_listen_socket);
	struct wbsrv_connection *wbconn;

	wbconn = talloc_zero(conn, struct wbsrv_connection);
	if (!wbconn) {
		stream_terminate_connection(conn, "wbsrv_accept: out of memory");
		return;
	}
	wbconn->conn	      = conn;
	wbconn->listen_socket = listen_socket;
	wbconn->lp_ctx        = listen_socket->service->task->lp_ctx;
	conn->private_data    = wbconn;

	wbconn->packet = packet_init(wbconn);
	if (wbconn->packet == NULL) {
		wbsrv_terminate_connection(wbconn, "wbsrv_accept: out of memory");
		return;
	}
	packet_set_private(wbconn->packet, wbconn);
	packet_set_socket(wbconn->packet, conn->socket);
	packet_set_callback(wbconn->packet, wbsrv_samba3_process);
	packet_set_full_request(wbconn->packet, wbsrv_samba3_packet_full_request);
	packet_set_error_handler(wbconn->packet, wbsrv_recv_error);
	packet_set_event_context(wbconn->packet, conn->event.ctx);
	packet_set_fde(wbconn->packet, conn->event.fde);
	packet_set_serialise(wbconn->packet);
}
Esempio n. 3
0
static void wbsrv_samba3_send_reply_done(struct tevent_req *subreq)
{
	struct wbsrv_samba3_call *call = tevent_req_callback_data(subreq,
			struct wbsrv_samba3_call);
	int sys_errno;
	int rc;

	rc = tstream_writev_queue_recv(subreq, &sys_errno);
	TALLOC_FREE(subreq);
	if (rc == -1) {
		const char *reason;

		reason = talloc_asprintf(call, "wbsrv_samba3_send_reply_done: "
					 "tstream_writev_queue_recv() - %d:%s",
					 sys_errno, strerror(sys_errno));
		if (reason == NULL) {
			reason = "wbsrv_samba3_send_reply_done: "
				 "tstream_writev_queue_recv() failed";
		}

		wbsrv_terminate_connection(call->wbconn, reason);
		return;
	}

	talloc_free(call);
}
Esempio n. 4
0
/*
 * queue a wbsrv_call reply on a wbsrv_connection
 * NOTE: that this implies talloc_free(call),
 *       use talloc_reference(call) if you need it after
 *       calling wbsrv_queue_reply
 */
NTSTATUS wbsrv_samba3_send_reply(struct wbsrv_samba3_call *call)
{
	struct wbsrv_connection *wbsrv_conn = call->wbconn;
	struct tevent_req *subreq;
	NTSTATUS status;

	status = wbsrv_samba3_push_reply(call);
	NT_STATUS_NOT_OK_RETURN(status);

	call->out_iov[0].iov_base = (char *) call->out.data;
	call->out_iov[0].iov_len = call->out.length;

	subreq = tstream_writev_queue_send(call,
					   wbsrv_conn->conn->event.ctx,
					   wbsrv_conn->tstream,
					   wbsrv_conn->send_queue,
					   call->out_iov, 1);
	if (subreq == NULL) {
		wbsrv_terminate_connection(wbsrv_conn, "wbsrv_call_loop: "
				"no memory for tstream_writev_queue_send");
		return NT_STATUS_NO_MEMORY;
	}
	tevent_req_set_callback(subreq, wbsrv_samba3_send_reply_done, call);

	return status;
}
Esempio n. 5
0
static void wbsrv_accept(struct stream_connection *conn)
{
	struct wbsrv_listen_socket *wbsrv_socket = talloc_get_type(conn->private_data,
								   struct wbsrv_listen_socket);
	struct wbsrv_connection *wbsrv_conn;
	struct tevent_req *subreq;
	int rc;

	wbsrv_conn = talloc_zero(conn, struct wbsrv_connection);
	if (wbsrv_conn == NULL) {
		stream_terminate_connection(conn, "wbsrv_accept: out of memory");
		return;
	}

	wbsrv_conn->send_queue = tevent_queue_create(conn, "wbsrv_accept");
	if (wbsrv_conn->send_queue == NULL) {
		stream_terminate_connection(conn,
				"wbsrv_accept: out of memory");
		return;
	}

	TALLOC_FREE(conn->event.fde);

	rc = tstream_bsd_existing_socket(wbsrv_conn,
			socket_get_fd(conn->socket),
			&wbsrv_conn->tstream);
	if (rc < 0) {
		stream_terminate_connection(conn,
				"wbsrv_accept: out of memory");
		return;
	}

	wbsrv_conn->conn = conn;
	wbsrv_conn->listen_socket = wbsrv_socket;
	wbsrv_conn->lp_ctx = wbsrv_socket->service->task->lp_ctx;
	conn->private_data = wbsrv_conn;

	/*
	 * The winbind pdu's has the length as 4 byte (initial_read_size),
	 * wbsrv_samba3_packet_full_request provides the pdu length then.
	 */
	subreq = tstream_read_pdu_blob_send(wbsrv_conn,
					    wbsrv_conn->conn->event.ctx,
					    wbsrv_conn->tstream,
					    4, /* initial_read_size */
					    wbsrv_samba3_packet_full_request,
					    wbsrv_conn);
	if (subreq == NULL) {
		wbsrv_terminate_connection(wbsrv_conn, "wbsrv_accept: "
				"no memory for tstream_read_pdu_blob_send");
		return;
	}
	tevent_req_set_callback(subreq, wbsrv_call_loop, wbsrv_conn);
}
Esempio n. 6
0
/*
 * queue a wbsrv_call reply on a wbsrv_connection
 * NOTE: that this implies talloc_free(call),
 *       use talloc_reference(call) if you need it after
 *       calling wbsrv_queue_reply
 */
NTSTATUS wbsrv_samba3_send_reply(struct wbsrv_samba3_call *call)
{
	struct wbsrv_connection *wbconn = call->wbconn;
	DATA_BLOB rep;
	NTSTATUS status;

	status = wbsrv_samba3_push_reply(call, call, &rep);
	NT_STATUS_NOT_OK_RETURN(status);

	status = packet_send(call->wbconn->packet, rep);
	
	talloc_free(call);

	if (!NT_STATUS_IS_OK(status)) {
		wbsrv_terminate_connection(wbconn,
					   "failed to packet_send winbindd reply");
		return status;
	}
	/* the call isn't needed any more */
	return status;
}
Esempio n. 7
0
static void wbsrv_call_loop(struct tevent_req *subreq)
{
	struct wbsrv_connection *wbsrv_conn = tevent_req_callback_data(subreq,
				      struct wbsrv_connection);
	struct wbsrv_samba3_call *call;
	NTSTATUS status;

	call = talloc_zero(wbsrv_conn, struct wbsrv_samba3_call);
	if (call == NULL) {
		wbsrv_terminate_connection(wbsrv_conn, "wbsrv_call_loop: "
				"no memory for wbsrv_samba3_call");
		return;
	}
	call->wbconn = wbsrv_conn;

	status = tstream_read_pdu_blob_recv(subreq,
					    call,
					    &call->in);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		const char *reason;

		reason = talloc_asprintf(wbsrv_conn, "wbsrv_call_loop: "
					 "tstream_read_pdu_blob_recv() - %s",
					 nt_errstr(status));
		if (!reason) {
			reason = nt_errstr(status);
		}

		wbsrv_terminate_connection(wbsrv_conn, reason);
		return;
	}

	DEBUG(10,("Received winbind TCP packet of length %lu from %s\n",
		 (long) call->in.length,
		 tsocket_address_string(wbsrv_conn->conn->remote_address, call)));

	status = wbsrv_samba3_process(call);
	if (!NT_STATUS_IS_OK(status)) {
		const char *reason;

		reason = talloc_asprintf(wbsrv_conn, "wbsrv_call_loop: "
					 "tstream_read_pdu_blob_recv() - %s",
					 nt_errstr(status));
		if (!reason) {
			reason = nt_errstr(status);
		}

		wbsrv_terminate_connection(wbsrv_conn, reason);
		return;
	}

	/*
	 * The winbind pdu's has the length as 4 byte (initial_read_size),
	 * wbsrv_samba3_packet_full_request provides the pdu length then.
	 */
	subreq = tstream_read_pdu_blob_send(wbsrv_conn,
					    wbsrv_conn->conn->event.ctx,
					    wbsrv_conn->tstream,
					    4, /* initial_read_size */
					    wbsrv_samba3_packet_full_request,
					    wbsrv_conn);
	if (subreq == NULL) {
		wbsrv_terminate_connection(wbsrv_conn, "wbsrv_call_loop: "
				"no memory for tstream_read_pdu_blob_send");
		return;
	}
	tevent_req_set_callback(subreq, wbsrv_call_loop, wbsrv_conn);
}
Esempio n. 8
0
/*
  called on a tcp recv
*/
static void wbsrv_recv(struct stream_connection *conn, uint16_t flags)
{
	struct wbsrv_connection *wbsrv_conn = talloc_get_type(conn->private_data,
							struct wbsrv_connection);
	wbsrv_terminate_connection(wbsrv_conn, "wbsrv_recv: called");
}
Esempio n. 9
0
/*
  called on a tcp recv error
*/
static void wbsrv_recv_error(void *private_data, NTSTATUS status)
{
	struct wbsrv_connection *wbconn = talloc_get_type(private_data, struct wbsrv_connection);
	wbsrv_terminate_connection(wbconn, nt_errstr(status));
}