mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
s3:smbd: add smbd_smb2_send_oplock_break()
metze
This commit is contained in:
parent
cf7c41b841
commit
bea384b277
@ -195,6 +195,11 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
|
||||
#define smbd_smb2_request_done(req, body, dyn) \
|
||||
smbd_smb2_request_done_ex(req, NT_STATUS_OK, body, dyn, __location__)
|
||||
|
||||
NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
|
||||
uint64_t file_id_persistent,
|
||||
uint64_t file_id_volatile,
|
||||
uint8_t oplock_level);
|
||||
|
||||
NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
|
||||
NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
|
||||
|
||||
|
@ -821,6 +821,94 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
|
||||
return smbd_smb2_request_reply(req);
|
||||
}
|
||||
|
||||
struct smbd_smb2_send_oplock_break_state {
|
||||
struct smbd_server_connection *sconn;
|
||||
uint8_t buf[4 + SMB2_HDR_BODY + 0x18];
|
||||
struct iovec vector;
|
||||
};
|
||||
|
||||
static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
|
||||
|
||||
NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
|
||||
uint64_t file_id_persistent,
|
||||
uint64_t file_id_volatile,
|
||||
uint8_t oplock_level)
|
||||
{
|
||||
struct smbd_smb2_send_oplock_break_state *state;
|
||||
struct tevent_req *subreq;
|
||||
uint8_t *hdr;
|
||||
uint8_t *body;
|
||||
|
||||
state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
|
||||
if (state == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
state->sconn = sconn;
|
||||
|
||||
state->vector.iov_base = (void *)state->buf;
|
||||
state->vector.iov_len = sizeof(state->buf);
|
||||
|
||||
_smb2_setlen(state->buf, sizeof(state->buf) - 4);
|
||||
hdr = state->buf + 4;
|
||||
body = hdr + SMB2_HDR_BODY;
|
||||
|
||||
SIVAL(hdr, 0, SMB2_MAGIC);
|
||||
SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
||||
SSVAL(hdr, SMB2_HDR_EPOCH, 0);
|
||||
SIVAL(hdr, SMB2_HDR_STATUS, 0);
|
||||
SSVAL(hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK);
|
||||
SSVAL(hdr, SMB2_HDR_CREDIT, 0);
|
||||
SIVAL(hdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
|
||||
SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
|
||||
SBVAL(hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
|
||||
SIVAL(hdr, SMB2_HDR_PID, 0);
|
||||
SIVAL(hdr, SMB2_HDR_TID, 0);
|
||||
SBVAL(hdr, SMB2_HDR_SESSION_ID, 0);
|
||||
memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
|
||||
|
||||
SSVAL(body, 0x00, 0x18);
|
||||
|
||||
SCVAL(body, 0x02, oplock_level);
|
||||
SCVAL(body, 0x03, 0); /* reserved */
|
||||
SIVAL(body, 0x04, 0); /* reserved */
|
||||
SBVAL(body, 0x08, file_id_persistent);
|
||||
SBVAL(body, 0x10, file_id_volatile);
|
||||
|
||||
subreq = tstream_writev_queue_send(state,
|
||||
sconn->smb2.event_ctx,
|
||||
sconn->smb2.stream,
|
||||
sconn->smb2.send_queue,
|
||||
&state->vector, 1);
|
||||
if (subreq == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
tevent_req_set_callback(subreq,
|
||||
smbd_smb2_oplock_break_writev_done,
|
||||
state);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct smbd_smb2_send_oplock_break_state *state =
|
||||
tevent_req_callback_data(subreq,
|
||||
struct smbd_smb2_send_oplock_break_state);
|
||||
struct smbd_server_connection *sconn = state->sconn;
|
||||
int ret;
|
||||
int sys_errno;
|
||||
|
||||
ret = tstream_writev_queue_recv(subreq, &sys_errno);
|
||||
TALLOC_FREE(subreq);
|
||||
if (ret == -1) {
|
||||
NTSTATUS status = map_nt_error_from_unix(sys_errno);
|
||||
smbd_server_connection_terminate(sconn, nt_errstr(status));
|
||||
return;
|
||||
}
|
||||
|
||||
TALLOC_FREE(state);
|
||||
}
|
||||
|
||||
struct smbd_smb2_request_read_state {
|
||||
size_t missing;
|
||||
bool asked_for_header;
|
||||
|
Loading…
x
Reference in New Issue
Block a user