[PATCH 2/3] s3: Add async cli_session_request

Volker Lendecke vl at samba.org
Sun Dec 12 10:54:31 MST 2010


This does not do the redirects, but I think that might be obsolete anyway
---
 source3/include/async_smb.h |    7 +++
 source3/libsmb/async_smb.c  |  124 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h
index b73aed0..d2303cc 100644
--- a/source3/include/async_smb.h
+++ b/source3/include/async_smb.h
@@ -69,4 +69,11 @@ NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req,
 					  uint16_t *pfnum,
 					  uint8_t *plevel);
 
+struct tevent_req *cli_session_request_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    int sock,
+					    const struct nmb_name *called,
+					    const struct nmb_name *calling);
+bool cli_session_request_recv(struct tevent_req *req, int *err, uint8_t *resp);
+
 #endif
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index b04c274..af4740e 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -1095,3 +1095,127 @@ NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req,
 	*plevel = state->level;
 	return NT_STATUS_OK;
 }
+
+
+struct cli_session_request_state {
+	struct tevent_context *ev;
+	int sock;
+	uint32 len_hdr;
+	struct iovec iov[3];
+	uint8_t nb_session_response;
+};
+
+static void cli_session_request_sent(struct tevent_req *subreq);
+static void cli_session_request_recvd(struct tevent_req *subreq);
+
+struct tevent_req *cli_session_request_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    int sock,
+					    const struct nmb_name *called,
+					    const struct nmb_name *calling)
+{
+	struct tevent_req *req, *subreq;
+	struct cli_session_request_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_session_request_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->sock = sock;
+
+	state->iov[1].iov_base = name_mangle(
+		state, calling->name, calling->name_type);
+	if (tevent_req_nomem(state->iov[1].iov_base, req)) {
+		return tevent_req_post(req, ev);
+	}
+	state->iov[1].iov_len = name_len(
+		(unsigned char *)state->iov[1].iov_base,
+		talloc_get_size(state->iov[1].iov_base));
+
+	state->iov[2].iov_base = name_mangle(
+		state, called->name, called->name_type);
+	if (tevent_req_nomem(state->iov[2].iov_base, req)) {
+		return tevent_req_post(req, ev);
+	}
+	state->iov[2].iov_len = name_len(
+		(unsigned char *)state->iov[2].iov_base,
+		talloc_get_size(state->iov[2].iov_base));
+
+	_smb_setlen(((char *)&state->len_hdr),
+		    state->iov[1].iov_len + state->iov[2].iov_len);
+	SCVAL((char *)&state->len_hdr, 0, 0x81);
+
+	state->iov[0].iov_base = &state->len_hdr;
+	state->iov[0].iov_len = sizeof(state->len_hdr);
+
+	subreq = writev_send(state, ev, NULL, sock, true, state->iov, 3);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_session_request_sent, req);
+	return req;
+}
+
+static void cli_session_request_sent(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_session_request_state *state = tevent_req_data(
+		req, struct cli_session_request_state);
+	ssize_t ret;
+	int err;
+
+	ret = writev_recv(subreq, &err);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		tevent_req_error(req, err);
+		return;
+	}
+	subreq = read_smb_send(state, state->ev, state->sock);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, cli_session_request_recvd, req);
+}
+
+static void cli_session_request_recvd(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_session_request_state *state = tevent_req_data(
+		req, struct cli_session_request_state);
+	uint8_t *buf;
+	ssize_t ret;
+	int err;
+
+	ret = read_smb_recv(subreq, talloc_tos(), &buf, &err);
+	TALLOC_FREE(subreq);
+
+	if (ret != 4) {
+		/*
+		 * Here only the 4-byte response is valid
+		 */
+		ret = -1;
+		err = EIO;
+	}
+	if (ret == -1) {
+		tevent_req_error(req, err);
+		return;
+	}
+	state->nb_session_response = CVAL(buf, 0);
+	tevent_req_done(req);
+}
+
+bool cli_session_request_recv(struct tevent_req *req, int *err, uint8_t *resp)
+{
+	struct cli_session_request_state *state = tevent_req_data(
+		req, struct cli_session_request_state);
+
+	if (tevent_req_is_unix_error(req, err)) {
+		return false;
+	}
+	*resp = state->nb_session_response;
+	return true;
+}
-- 
1.7.0.4




More information about the samba-technical mailing list