char *private_data,
size_t priv_len);
+struct smbXsrv_connection {
+ struct smbd_server_connection *sconn;
+
+ const struct tsocket_address *local_address;
+ const struct tsocket_address *remote_address;
+ const char *remote_hostname;
+
+ struct tevent_context *ev_ctx;
+ struct messaging_context *msg_ctx;
+
+ enum protocol_types protocol;
+
+ struct {
+ struct {
+ uint32_t capabilities;
+ struct GUID guid;
+ uint16_t security_mode;
+ uint16_t num_dialects;
+ uint16_t *dialects;
+ } client;
+ struct {
+ uint32_t capabilities;
+ struct GUID guid;
+ uint16_t security_mode;
+ uint16_t dialect;
+ uint32_t max_trans;
+ uint32_t max_read;
+ uint32_t max_write;
+ } server;
+ } smb2;
+};
+
+NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
+ enum protocol_types protocol);
+
struct smbd_smb2_request {
struct smbd_smb2_request *prev, *next;
struct bitmap *credits_bitmap;
bool compound_related_in_progress;
} smb2;
+
+ struct smbXsrv_connection *conn;
};
extern struct smbd_server_connection *smbd_server_conn;
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf, smb_vwv0, choice);
- set_Protocol(PROTOCOL_CORE);
+ smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_CORE);
}
/****************************************************************************
SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
* encrypt */
- set_Protocol(PROTOCOL_COREPLUS);
+
+ smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_COREPLUS);
}
/****************************************************************************
SSVAL(req->outbuf,smb_vwv11, 8);
}
- set_Protocol(PROTOCOL_LANMAN1);
+ smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_LANMAN1);
/* Reply, SMBlockread, SMBwritelock supported. */
SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
SSVAL(req->outbuf,smb_vwv11, 8);
}
- set_Protocol(PROTOCOL_LANMAN2);
+ smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_LANMAN2);
/* Reply, SMBlockread, SMBwritelock supported. */
SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
SSVAL(req->outbuf,smb_vwv0,choice);
SCVAL(req->outbuf,smb_vwv1,secword);
- set_Protocol(PROTOCOL_NT1);
+ smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_NT1);
SSVAL(req->outbuf,smb_vwv1+1, lp_maxmux()); /* maxmpx */
SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
id_cache_delete_from_cache(&id);
}
+NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
+ enum protocol_types protocol)
+{
+ NTSTATUS status;
+
+ set_Protocol(protocol);
+ conn->protocol = protocol;
+
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Process commands from the client
****************************************************************************/
char *rhost;
int ret;
+ sconn->conn = talloc_zero(sconn, struct smbXsrv_connection);
+ if (sconn->conn == NULL) {
+ DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
+ exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
+ }
+
if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
/*
* We're not making the decision here,
exit_server("failed to create smbd_server_connection fde");
}
+ sconn->conn->sconn = sconn;
+ sconn->conn->ev_ctx = sconn->ev_ctx;
+ sconn->conn->msg_ctx = sconn->msg_ctx;
+ sconn->conn->local_address = sconn->local_address;
+ sconn->conn->remote_address = sconn->remote_address;
+ sconn->conn->remote_hostname = sconn->remote_hostname;
+ sconn->conn->protocol = PROTOCOL_NONE;
+
TALLOC_FREE(frame);
while (True) {
#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
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();
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);
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);
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 */
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;