mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
s3: Add async cli_session_request
This does not do the redirects, but I think that might be obsolete anyway
This commit is contained in:
parent
444dcc59c2
commit
02a74fd36d
@ -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
|
||||
|
@ -1095,3 +1095,130 @@ 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, called->name, called->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, calling->name, calling->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) {
|
||||
ret = -1;
|
||||
err = EIO;
|
||||
}
|
||||
if (ret == -1) {
|
||||
tevent_req_error(req, err);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* In case of an error there is more information in the data
|
||||
* portion according to RFC1002. We're not subtle enough to
|
||||
* respond to the different error conditions, so drop the
|
||||
* error info here.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user