bool as_root;
uint16_t fileid_ofs;
bool allow_invalid_fileid;
- bool modify;
} smbd_smb2_table[] = {
#define _OP(o) .opcode = o, .name = #o
{
.need_session = true,
.need_tcon = true,
.fileid_ofs = 0x10,
- .modify = true;
},{
_OP(SMB2_OP_LOCK),
.need_session = true,
.need_tcon = true,
.fileid_ofs = 0x08,
.allow_invalid_fileid = true,
- .modify = true;
},{
_OP(SMB2_OP_CANCEL),
.as_root = true,
.need_session = true,
.need_tcon = true,
.fileid_ofs = 0x10,
- .modify = true;
},{
_OP(SMB2_OP_BREAK),
.need_session = true,
uint16_t opcode;
uint32_t flags;
uint64_t mid;
- uint16_t channel_sequence;
NTSTATUS status;
NTSTATUS session_status;
uint32_t allowed_flags;
struct smbXsrv_session *x = NULL;
bool signing_required = false;
bool encryption_required = false;
- struct smbXsrv_open *op = NULL;
inhdr = SMBD_SMB2_IN_HDR_PTR(req);
flags = IVAL(inhdr, SMB2_HDR_FLAGS);
opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
- channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
DEBUG(10,("smbd_smb2_request_dispatch: opcode[%s] mid = %llu\n",
smb2_opcode_name(opcode),
(unsigned long long)mid));
if (opcode == SMB2_OP_CANCEL) {
allowed_flags |= SMB2_HDR_FLAG_ASYNC;
}
- if (conn->protocol >= PROTOCOL_SMB2_22) {
- allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
- }
if ((flags & ~allowed_flags) != 0) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
file_id_volatile = BVAL(body, call->fileid_ofs + 8);
fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
- if (fsp != NULL) {
- op = fsp->op;
- } else {
+ if (fsp == NULL) {
if (!call->allow_invalid_fileid) {
return smbd_smb2_request_error(req,
NT_STATUS_FILE_CLOSED);
}
}
- if ((conn->protocol >= PROTOCOL_SMB2_22) && (op != NULL)) {
- int cmp = channel_sequence - op->global->channel_sequence;
- bool overflow = false;
-
- if (abs(cmp) > INT16_MAX) {
- /*
- * we like to handle an 16-bit overflow here.
- *
- * If the difference between the numbers
- * if more than 15-bit, it is likely to be an overflow.
- */
- overflow = true;
- cmp *= -1;
- }
-
- if (!(flags & SMB2_HDR_FLAG_REPLAY_OPERATION)) {
- if (cmp == 0) {
- op->request_count += 1;
- } else if (cmp > 0) {
- op->pre_request_count += op->request_count;
- op->request_count = 0;
- op->request_count += 1;
- op->global->channel_sequence = channel_sequence;
- update_open = true;
- } else if (call->modify) {
- return smbd_smb2_request_error(req,
- NT_STATUS_FILE_NOT_AVAILABLE);
- }
- } else {
- if (cmp == 0) {
- if (op->pre_request_count == 0) {
- op->request_count += 1;
- } else if (call->modify) {
- return smbd_smb2_request_error(req,
- NT_STATUS_FILE_NOT_AVAILABLE);
- }
- } else if (cmp > 0) {
- if (op->pre_request_count == 0) {
- op->request_count += 1;
- op->global->channel_sequence =
- channel_sequence;
- update_open = true;
- } else if (call->modify) {
- return smbd_smb2_request_error(req,
- NT_STATUS_FILE_NOT_AVAILABLE);
- }
- } else {
- if (call->modify) {
- return smbd_smb2_request_error(req,
- NT_STATUS_FILE_NOT_AVAILABLE);
- }
- }
- }
- }
-
if (call->as_root) {
SMB_ASSERT(call->fileid_ofs == 0);
/* This call needs to be run as root */