*/
static void reply_smb20xx(struct smb_request *req, uint16_t dialect)
{
- uint8_t *smb2_inbuf;
+ uint8_t *smb2_inpdu;
uint8_t *smb2_hdr;
uint8_t *smb2_body;
uint8_t *smb2_dyn;
- size_t len = 4 + SMB2_HDR_BODY + 0x24 + 2;
+ size_t len = SMB2_HDR_BODY + 0x24 + 2;
- smb2_inbuf = talloc_zero_array(talloc_tos(), uint8_t, len);
- if (smb2_inbuf == NULL) {
+ smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
+ if (smb2_inpdu == NULL) {
DEBUG(0, ("Could not push spnego blob\n"));
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- smb2_hdr = smb2_inbuf + 4;
+ smb2_hdr = smb2_inpdu;
smb2_body = smb2_hdr + SMB2_HDR_BODY;
smb2_dyn = smb2_body + 0x24;
req->outbuf = NULL;
- smbd_smb2_first_negprot(req->xconn, smb2_inbuf, len);
+ smbd_smb2_first_negprot(req->xconn, smb2_inpdu, len);
return;
}
const int dialect_count,
uint16_t *dialect)
{
- size_t c = 0;
- enum protocol_types protocol = PROTOCOL_NONE;
-
- for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
- if (lp_server_max_protocol() < PROTOCOL_SMB3_00) {
- break;
- }
- if (lp_server_min_protocol() > PROTOCOL_SMB3_00) {
- break;
- }
-
- *dialect = SVAL(indyn, c*2);
- if (*dialect == SMB3_DIALECT_REVISION_300) {
- protocol = PROTOCOL_SMB3_00;
- break;
- }
- }
-
- for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
- if (lp_server_max_protocol() < PROTOCOL_SMB2_24) {
- break;
- }
- if (lp_server_min_protocol() > PROTOCOL_SMB2_24) {
- break;
- }
-
- *dialect = SVAL(indyn, c*2);
- if (*dialect == SMB2_DIALECT_REVISION_224) {
- protocol = PROTOCOL_SMB2_24;
- break;
- }
- }
-
- for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
- if (lp_server_max_protocol() < PROTOCOL_SMB2_22) {
- break;
- }
- if (lp_server_min_protocol() > PROTOCOL_SMB2_22) {
- break;
+ struct {
+ enum protocol_types proto;
+ uint16_t dialect;
+ } pd[] = {
+ { PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300 },
+ { PROTOCOL_SMB2_24, SMB2_DIALECT_REVISION_224 },
+ { PROTOCOL_SMB2_22, SMB2_DIALECT_REVISION_222 },
+ { PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210 },
+ { PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202 },
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(pd); i ++) {
+ size_t c = 0;
+
+ if (lp_server_max_protocol() < pd[i].proto) {
+ continue;
}
-
- *dialect = SVAL(indyn, c*2);
- if (*dialect == SMB2_DIALECT_REVISION_222) {
- protocol = PROTOCOL_SMB2_22;
- break;
- }
- }
-
- for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
- if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
- break;
- }
- if (lp_server_min_protocol() > PROTOCOL_SMB2_10) {
- break;
- }
-
- *dialect = SVAL(indyn, c*2);
- if (*dialect == SMB2_DIALECT_REVISION_210) {
- protocol = PROTOCOL_SMB2_10;
- break;
- }
- }
-
- for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
- if (lp_server_max_protocol() < PROTOCOL_SMB2_02) {
- break;
- }
- if (lp_server_min_protocol() > PROTOCOL_SMB2_02) {
- break;
+ if (lp_server_min_protocol() > pd[i].proto) {
+ continue;
}
- *dialect = SVAL(indyn, c*2);
- if (*dialect == SMB2_DIALECT_REVISION_202) {
- protocol = PROTOCOL_SMB2_02;
- break;
+ for (c = 0; c < dialect_count; c++) {
+ *dialect = SVAL(indyn, c*2);
+ if (*dialect == pd[i].dialect) {
+ return pd[i].proto;
+ }
}
}
- return protocol;
+ return PROTOCOL_NONE;
}
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
DEBUG(3,("Selected protocol %s\n", remote_proto));
/* negprot_spnego() returns a the server guid in the first 16 bytes */
- negprot_spnego_blob = negprot_spnego(req, req->sconn);
+ negprot_spnego_blob = negprot_spnego(req, xconn);
if (negprot_spnego_blob.data == NULL) {
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
}
capabilities |= SMB2_CAP_DFS;
}
+ if (protocol >= PROTOCOL_SMB2_10 &&
+ lp_smb2_leases() &&
+ lp_oplocks(GLOBAL_SECTION_SNUM) &&
+ !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
+ {
+ capabilities |= SMB2_CAP_LEASING;
+ }
+
if ((protocol >= PROTOCOL_SMB2_24) &&
(lp_smb_encrypt(-1) != SMB_SIGNING_OFF) &&
(in_capabilities & SMB2_CAP_ENCRYPTION)) {
capabilities |= SMB2_CAP_LARGE_MTU;
xconn->smb2.credits.multicredit = true;
- /* Windows 2012R2 allows up to 8 MB */
- max_limit = 0x800000; /* 8MB */
+ /*
+ * We allow up to allmost 16MB.
+ *
+ * The maximum PDU size is 0xFFFFFF (16776960)
+ * and we need some space for the header.
+ */
+ max_limit = 0xFFFF00;
}
}
max_read = MIN(max_limit, lp_smb2_max_read());
max_write = MIN(max_limit, lp_smb2_max_write());
+ if (capabilities & SMB2_CAP_ENCRYPTION) {
+ xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
+ }
+
security_offset = SMB2_HDR_BODY + 0x40;
#if 1