[SCM] Samba Shared Repository - branch master updated -
release-4-0-0alpha7-1730-g5d3d51e
Stefan Metzmacher
metze at samba.org
Wed May 20 18:54:49 GMT 2009
The branch, master has been updated
via 5d3d51e9ad1e4db8d9580ce7f2ba4e86e658bb13 (commit)
via 1ecdc8588da2eddfe673f736f519d37eac4be911 (commit)
via dafc1e0c8d16e4dcc3929d9e5f78ce60d3371fe8 (commit)
via f9da4fb71a4d93278025e009b8987a4ba0965fa1 (commit)
via eac12355196cbf15d8bc51109a12c65efc34ffde (commit)
via c4b41c56498bea40baf152e2ee23f9850710891d (commit)
from d649a46078e6af5bacafd74107aedea5d4f31312 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 5d3d51e9ad1e4db8d9580ce7f2ba4e86e658bb13
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 20 20:51:10 2009 +0200
s3:smbd: check the incoming session id for SMB2 requests
metze
commit 1ecdc8588da2eddfe673f736f519d37eac4be911
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 15 11:20:34 2009 +0200
s3:smbd: implement SMB2 Session Setup with raw NTLMSSP
metze
commit dafc1e0c8d16e4dcc3929d9e5f78ce60d3371fe8
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 20 19:45:28 2009 +0200
s3:smbd: for now indicate raw NTLMSSP in the SMB2 Negotiate response
metze
commit f9da4fb71a4d93278025e009b8987a4ba0965fa1
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 20 19:48:47 2009 +0200
s3:smbd: move the callback functions of smbd_smb2_request_reply() closer itself
metze
commit eac12355196cbf15d8bc51109a12c65efc34ffde
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 20 19:35:39 2009 +0200
s3:smbd: add smbd_smb2_request_done_ex()
Some times we have to return a non-error response
with status != NT_STATUS_OK.
metze
commit c4b41c56498bea40baf152e2ee23f9850710891d
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed May 20 19:32:55 2009 +0200
s3:smbd: fix initialized memory in SMB2 responses
MESSAGE_ID and SESSION_ID are both 64bit.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/Makefile.in | 1 +
source3/smbd/globals.h | 31 ++++++
source3/smbd/smb2_negprot.c | 3 +
source3/smbd/smb2_server.c | 176 +++++++++++++++++++++++----------
source3/smbd/smb2_sesssetup.c | 221 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 381 insertions(+), 51 deletions(-)
create mode 100644 source3/smbd/smb2_sesssetup.c
Changeset truncated at 500 lines:
diff --git a/source3/Makefile.in b/source3/Makefile.in
index f5074e3..fdcd86a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -749,6 +749,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/file_access.o \
smbd/dnsregister.o smbd/globals.o \
smbd/smb2_server.o smbd/smb2_negprot.o \
+ smbd/smb2_sesssetup.o \
smbd/smb2_keepalive.o \
$(MANGLE_OBJ) @VFS_STATIC@
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index c5dd97c..345f748 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -201,6 +201,7 @@ extern int num_children;
struct tstream_context;
struct smbd_smb2_request;
+struct smbd_smb2_session;
DATA_BLOB negprot_spnego(void);
@@ -214,10 +215,16 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
NTSTATUS status, DATA_BLOB *info);
NTSTATUS smbd_smb2_request_error(struct smbd_smb2_request *req,
NTSTATUS status);
+NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
+ NTSTATUS status,
+ DATA_BLOB body, DATA_BLOB *dyn);
NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
DATA_BLOB body, DATA_BLOB *dyn);
+NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
+
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req);
struct smbd_smb2_request {
@@ -225,6 +232,9 @@ struct smbd_smb2_request {
struct smbd_server_connection *conn;
+ /* the session the request operates on, maybe NULL */
+ struct smbd_smb2_session *session;
+
int current_idx;
struct {
@@ -273,6 +283,16 @@ struct smbd_smb2_request {
} out;
};
+struct smbd_server_connection;
+
+struct smbd_smb2_session {
+ struct smbd_smb2_session *prev, *next;
+ struct smbd_server_connection *conn;
+ NTSTATUS status;
+ uint64_t vuid;
+ AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
+};
+
struct smbd_server_connection {
struct fd_event *fde;
uint64_t num_requests;
@@ -283,6 +303,17 @@ struct smbd_server_connection {
struct tevent_queue *recv_queue;
struct tevent_queue *send_queue;
struct tstream_context *stream;
+ struct {
+ /* an id tree used to allocate vuids */
+ /* this holds info on session vuids that are already
+ * validated for this VC */
+ struct idr_context *idtree;
+
+ /* this is the limit of vuid values for this connection */
+ uint64_t limit;
+
+ struct smbd_smb2_session *list;
+ } sessions;
} smb2;
};
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 38dfe6d..b976ea2 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -133,6 +133,9 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
negprot_spnego_blob.length - 16);
+ /* for now we want raw NTLMSSP */
+ security_buffer = data_blob_const(NULL, 0);
+
outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
if (outbody.data == NULL) {
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 9be6a73..36f4c10 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -55,6 +55,13 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn)
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 = 0x0000FFFF;
+ conn->smb2.sessions.list = NULL;
+
ret = tstream_bsd_existing_socket(conn, smbd_server_fd(),
&conn->smb2.stream);
if (ret == -1) {
@@ -241,14 +248,14 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
SIVAL(outhdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
- SIVAL(outhdr, SMB2_HDR_MESSAGE_ID,
- IVAL(inhdr, SMB2_HDR_MESSAGE_ID));
+ SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
+ BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
SIVAL(outhdr, SMB2_HDR_PID,
IVAL(inhdr, SMB2_HDR_PID));
SIVAL(outhdr, SMB2_HDR_TID,
IVAL(inhdr, SMB2_HDR_TID));
- SIVAL(outhdr, SMB2_HDR_SESSION_ID,
- IVAL(inhdr, SMB2_HDR_SESSION_ID));
+ SBVAL(outhdr, SMB2_HDR_SESSION_ID,
+ BVAL(inhdr, SMB2_HDR_SESSION_ID));
memset(outhdr + SMB2_HDR_SIGNATURE, 0, 16);
/* setup error body header */
@@ -281,6 +288,7 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
const uint8_t *inhdr;
int i = req->current_idx;
uint16_t opcode;
+ NTSTATUS status;
inhdr = (const uint8_t *)req->in.vector[i].iov_base;
@@ -293,38 +301,76 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
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:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TCON:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
- return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_TDIS:
+ status = smbd_smb2_request_check_session(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_CREATE:
+ status = smbd_smb2_request_check_session(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_CLOSE:
+ status = smbd_smb2_request_check_session(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_FLUSH:
+ status = smbd_smb2_request_check_session(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_READ:
+ status = smbd_smb2_request_check_session(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_WRITE:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(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:
@@ -334,18 +380,38 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_keepalive(req);
case SMB2_OP_FIND:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(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:
+ status = smbd_smb2_request_check_session(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
}
@@ -394,6 +460,48 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
return NT_STATUS_OK;
}
+static void smbd_smb2_request_dispatch_compound(struct tevent_req *subreq)
+{
+ struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
+ struct smbd_smb2_request);
+ struct smbd_server_connection *conn = req->conn;
+ NTSTATUS status;
+
+ tevent_wakeup_recv(subreq);
+ TALLOC_FREE(subreq);
+
+ DEBUG(10,("smbd_smb2_request_dispatch_compound: idx[%d] of %d vectors\n",
+ req->current_idx, req->in.vector_count));
+
+ status = smbd_smb2_request_dispatch(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbd_server_connection_terminate(conn, nt_errstr(status));
+ return;
+ }
+}
+
+static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
+{
+ struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
+ struct smbd_smb2_request);
+ struct smbd_server_connection *conn = req->conn;
+ int ret;
+ int sys_errno;
+ TALLOC_CTX *mem_pool;
+
+ 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(conn, nt_errstr(status));
+ return;
+ }
+
+ mem_pool = req->mem_pool;
+ req = NULL;
+ talloc_free(mem_pool);
+}
+
NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
NTSTATUS status,
DATA_BLOB *info)
@@ -436,16 +544,18 @@ NTSTATUS smbd_smb2_request_error(struct smbd_smb2_request *req,
return smbd_smb2_request_error_ex(req, status, NULL);
}
-NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
- DATA_BLOB body, DATA_BLOB *dyn)
+NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
+ NTSTATUS status,
+ DATA_BLOB body, DATA_BLOB *dyn)
{
uint8_t *outhdr;
uint8_t *outdyn;
int i = req->current_idx;
uint32_t next_command_ofs;
- DEBUG(10,("smbd_smb2_request_done: idx[%d] body[%u] dyn[%s:%u]\n",
- i, (unsigned int)body.length,
+ DEBUG(10,("smbd_smb2_request_done_ex: "
+ "idx[%d] status[%s] body[%u] dyn[%s:%u]\n",
+ i, nt_errstr(status), (unsigned int)body.length,
dyn ? "yes": "no",
(unsigned int)(dyn ? dyn->length : 0)));
@@ -462,7 +572,7 @@ NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
outdyn = outhdr + SMB2_HDR_BODY + 8;
next_command_ofs = SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
- SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_OK));
+ SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
req->out.vector[i+1].iov_base = (void *)body.data;
req->out.vector[i+1].iov_len = body.length;
@@ -498,46 +608,10 @@ NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
return smbd_smb2_request_reply(req);
}
-static void smbd_smb2_request_dispatch_compound(struct tevent_req *subreq)
-{
- struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
- struct smbd_smb2_request);
- struct smbd_server_connection *conn = req->conn;
- NTSTATUS status;
-
- tevent_wakeup_recv(subreq);
- TALLOC_FREE(subreq);
-
- DEBUG(10,("smbd_smb2_request_dispatch_compound: idx[%d] of %d vectors\n",
- req->current_idx, req->in.vector_count));
-
- status = smbd_smb2_request_dispatch(req);
- if (!NT_STATUS_IS_OK(status)) {
- smbd_server_connection_terminate(conn, nt_errstr(status));
- return;
- }
-}
-
-static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
+NTSTATUS smbd_smb2_request_done(struct smbd_smb2_request *req,
+ DATA_BLOB body, DATA_BLOB *dyn)
{
- struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
- struct smbd_smb2_request);
- struct smbd_server_connection *conn = req->conn;
- int ret;
- int sys_errno;
- TALLOC_CTX *mem_pool;
-
- 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(conn, nt_errstr(status));
- return;
- }
-
- mem_pool = req->mem_pool;
- req = NULL;
- talloc_free(mem_pool);
+ return smbd_smb2_request_done_ex(req, NT_STATUS_OK, body, dyn);
}
struct smbd_smb2_request_read_state {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
new file mode 100644
index 0000000..d322223
--- /dev/null
+++ b/source3/smbd/smb2_sesssetup.c
@@ -0,0 +1,221 @@
+/*
+ Unix SMB/CIFS implementation.
+ Core SMB2 server
+
+ Copyright (C) Stefan Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "../source4/libcli/smb2/smb2_constants.h"
+
+static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
+ uint64_t in_session_id,
+ DATA_BLOB in_security_buffer,
+ DATA_BLOB *out_security_buffer,
+ uint64_t *out_session_id);
+
+NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
+{
+ const uint8_t *inhdr;
+ const uint8_t *inbody;
+ int i = req->current_idx;
+ uint8_t *outhdr;
+ DATA_BLOB outbody;
+ DATA_BLOB outdyn;
+ size_t expected_body_size = 0x19;
+ size_t body_size;
+ uint64_t in_session_id;
+ uint16_t in_security_offset;
+ uint16_t in_security_length;
+ DATA_BLOB in_security_buffer;
+ uint64_t out_session_id;
+ uint16_t out_security_offset;
+ DATA_BLOB out_security_buffer;
+ NTSTATUS status;
+
+ inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+
+ if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
+ inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
+
+ body_size = SVAL(inbody, 0x00);
+ if (body_size != expected_body_size) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
+ in_security_offset = SVAL(inbody, 0x0C);
+ in_security_length = SVAL(inbody, 0x0E);
+
+ if (in_security_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (in_security_length > req->in.vector[i+2].iov_len) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
+ in_session_id = SVAL(inhdr, SMB2_HDR_SESSION_ID);
+ in_security_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
+ in_security_buffer.length = in_security_length;
+
+ status = smbd_smb2_session_setup(req,
+ in_session_id,
+ in_security_buffer,
+ &out_security_buffer,
+ &out_session_id);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ status = nt_status_squash(status);
+ return smbd_smb2_request_error(req, status);
+ }
+
+ out_security_offset = SMB2_HDR_BODY + 0x08;
+
+ outhdr = (uint8_t *)req->out.vector[i].iov_base;
+
+ outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
+ if (outbody.data == NULL) {
+ return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+ }
+
+ SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
+
--
Samba Shared Repository
More information about the samba-cvs
mailing list