NTSTATUS status;
int ret;
- TALLOC_FREE(conn->fde);
+ TALLOC_FREE(conn->smb1.fde);
conn->smb2.event_ctx = smbd_event_context();
return NT_STATUS_NO_MEMORY;
}
+ conn->smb2.sessions.idtree = idr_init(conn);
+ if (conn->smb2.sessions.idtree == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ conn->smb2.sessions.limit = 0x0000FFFE;
+ conn->smb2.sessions.list = NULL;
+
ret = tstream_bsd_existing_socket(conn, smbd_server_fd(),
&conn->smb2.stream);
if (ret == -1) {
const uint8_t *inhdr;
int i = req->current_idx;
uint16_t opcode;
+ uint32_t flags;
+ NTSTATUS status;
+ NTSTATUS session_status;
inhdr = (const uint8_t *)req->in.vector[i].iov_base;
/* TODO: verify more things */
+ flags = IVAL(inhdr, SMB2_HDR_FLAGS);
opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode));
+
+#define TMP_SMB2_ALLOWED_FLAGS ( \
+ SMB2_HDR_FLAG_CHAINED | \
+ SMB2_HDR_FLAG_SIGNED | \
+ SMB2_HDR_FLAG_DFS)
+ if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+#undef TMP_SMB2_ALLOWED_FLAGS
+
+ session_status = smbd_smb2_request_check_session(req);
+
+ req->do_signing = false;
+ if (flags & SMB2_HDR_FLAG_SIGNED) {
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+
+ req->do_signing = true;
+ status = smb2_signing_check_pdu(req->session->session_key,
+ &req->in.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ } else if (req->session && req->session->do_signing) {
+ return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
+ }
+
switch (opcode) {
case SMB2_OP_NEGPROT:
return smbd_smb2_request_process_negprot(req);
case SMB2_OP_SESSSETUP:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ return smbd_smb2_request_process_sesssetup(req);
case SMB2_OP_LOGOFF:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ return smbd_smb2_request_process_logoff(req);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TCON:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_tcon(req);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TDIS:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_tdis(req);
case SMB2_OP_CREATE:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_create(req);
case SMB2_OP_CLOSE:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_close(req);
case SMB2_OP_FLUSH:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_flush(req);
case SMB2_OP_READ:
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ return smbd_smb2_request_process_read(req);
case SMB2_OP_WRITE:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_LOCK:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_IOCTL:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CANCEL:
return smbd_smb2_request_process_keepalive(req);
case SMB2_OP_FIND:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_NOTIFY:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_GETINFO:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_SETINFO:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_BREAK:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+ status = smbd_smb2_request_check_tcon(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
}
{
struct tevent_req *subreq;
- /* TODO: sign the response here */
-
smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
+ if (req->do_signing) {
+ int i = req->current_idx;
+ NTSTATUS status;
+ status = smb2_signing_sign_pdu(req->session->session_key,
+ &req->out.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
req->current_idx += 3;
if (req->current_idx > req->in.vector_count) {
/* the fallback dynamic buffer */
outdyn = outhdr + SMB2_HDR_BODY + 8;
- next_command_ofs = SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
+ next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
req->out.vector[i+1].iov_base = (void *)body.data;