summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_negprot.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-12-15 14:45:56 +0100
committerStefan Metzmacher <metze@samba.org>2012-05-12 01:01:34 +0200
commitb3235d483da924a41ca9cecf72e1c62bab7fedd5 (patch)
tree9d34739a9e01e7d9176613a71ce68727e1ecf79d /source3/smbd/smb2_negprot.c
parentc8a3c0e0f793c622e071953b25a70a3fd8a0da65 (diff)
downloadsamba-b3235d483da924a41ca9cecf72e1c62bab7fedd5.tar.gz
samba-b3235d483da924a41ca9cecf72e1c62bab7fedd5.tar.bz2
samba-b3235d483da924a41ca9cecf72e1c62bab7fedd5.zip
s3:smbd: introduce struct smbXsrv_connection
This will represent a transport connection for SMB 1 or 2 in the server. smbd_server_connection will slowly be moved to the SMB_VFS layer to satisfy the existing modules, but it will hopefully be protocol independend in future. metze
Diffstat (limited to 'source3/smbd/smb2_negprot.c')
-rw-r--r--source3/smbd/smb2_negprot.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 6d60117710..cfb5dcb777 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -23,6 +23,7 @@
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../lib/tsocket/tsocket.h"
+#include "../librpc/ndr/libndr.h"
/*
* this is the entry point if SMB2 is selected via
@@ -94,8 +95,15 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
size_t c;
uint16_t security_mode;
uint16_t dialect_count;
+ uint16_t in_security_mode;
+ uint32_t in_capabilities;
+ DATA_BLOB in_guid_blob;
+ struct GUID in_guid;
+ NTTIME in_start_time;
uint16_t dialect = 0;
uint32_t capabilities;
+ DATA_BLOB out_guid_blob;
+ struct GUID out_guid;
enum protocol_types protocol = PROTOCOL_NONE;
uint32_t max_limit;
uint32_t max_trans = lp_smb2_max_trans();
@@ -109,10 +117,21 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
inbody = (const uint8_t *)req->in.vector[i+1].iov_base;
dialect_count = SVAL(inbody, 0x02);
+
+ in_security_mode = SVAL(inbody, 0x04);
+ in_capabilities = IVAL(inbody, 0x08);
+ in_guid_blob = data_blob_const(inbody + 0x0C, 16);
+ in_start_time = BVAL(inbody, 0x1C);
+
if (dialect_count == 0) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
+ status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
expected_dyn_size = dialect_count * 2;
if (req->in.vector[i+2].iov_len < expected_dyn_size) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
@@ -280,6 +299,12 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
security_buffer = data_blob_const(NULL, 0);
#endif
+ out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
+ status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
if (outbody.data == NULL) {
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
@@ -291,7 +316,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
SSVAL(outbody.data, 0x04, dialect); /* dialect revision */
SSVAL(outbody.data, 0x06, 0); /* reserved */
memcpy(outbody.data + 0x08,
- negprot_spnego_blob.data, 16); /* server guid */
+ out_guid_blob.data, 16); /* server guid */
SIVAL(outbody.data, 0x18,
capabilities); /* capabilities */
SIVAL(outbody.data, 0x1C, max_trans); /* max transact size */
@@ -310,7 +335,34 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
req->sconn->using_smb2 = true;
if (dialect != SMB2_DIALECT_REVISION_2FF) {
- set_Protocol(protocol);
+ struct smbXsrv_connection *conn = req->sconn->conn;
+
+ status = smbXsrv_connection_init_tables(conn, protocol);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
+ conn->smb2.client.capabilities = in_capabilities;
+ conn->smb2.client.security_mode = in_security_mode;
+ conn->smb2.client.guid = in_guid;
+ conn->smb2.client.num_dialects = dialect_count;
+ conn->smb2.client.dialects = talloc_array(conn,
+ uint16_t,
+ dialect_count);
+ if (conn->smb2.client.dialects == NULL) {
+ return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+ }
+ for (c=0; c < dialect_count; c++) {
+ conn->smb2.client.dialects[c] = SVAL(indyn, c*2);
+ }
+
+ conn->smb2.server.capabilities = capabilities;
+ conn->smb2.server.security_mode = security_mode;
+ conn->smb2.server.guid = out_guid;
+ conn->smb2.server.dialect = dialect;
+ conn->smb2.server.max_trans = max_trans;
+ conn->smb2.server.max_read = max_read;
+ conn->smb2.server.max_write = max_write;
req->sconn->smb2.max_trans = max_trans;
req->sconn->smb2.max_read = max_read;