s3: Refactor smbd_smb2_request_process_negprot
authorIra Cooper <ira@samba.org>
Sat, 21 Jun 2014 04:29:26 +0000 (21:29 -0700)
committerStefan Metzmacher <metze@samba.org>
Mon, 23 Jun 2014 09:59:10 +0000 (11:59 +0200)
Breakout smb2_protocol_dialect_match to support future work in
fsctl_validate_neg_info.

Signed-off-by: Ira Cooper <ira@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/smbd/globals.h
source3/smbd/smb2_negprot.c

index 28e4f94430373e8d8ad39167a266baed465dba0c..d9ca5e31b04ff49c6b7cf5217c1444069ff3cdd3 100644 (file)
@@ -260,6 +260,9 @@ NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
                                        size_t expected_body_size);
 
+enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
+                                                    const int dialect_count,
+                                                    uint16_t *dialect);
 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_logoff(struct smbd_smb2_request *req);
index 66434643782e9f5ddf7696618c538c0b9b73ab56..5fa1fbbe008bdbf90e5f746e97925ea246e7e9ca 100644 (file)
@@ -82,61 +82,12 @@ void reply_smb20ff(struct smb_request *req, uint16_t choice)
        reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
 }
 
-NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
+enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
+                               const int dialect_count,
+                               uint16_t *dialect)
 {
-       NTSTATUS status;
-       const uint8_t *inbody;
-       const uint8_t *indyn = NULL;
-       DATA_BLOB outbody;
-       DATA_BLOB outdyn;
-       DATA_BLOB negprot_spnego_blob;
-       uint16_t security_offset;
-       DATA_BLOB security_buffer;
-       size_t expected_dyn_size = 0;
-       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;
-       uint16_t dialect = 0;
-       uint32_t capabilities;
-       DATA_BLOB out_guid_blob;
-       struct GUID out_guid;
+       size_t c = 0;
        enum protocol_types protocol = PROTOCOL_NONE;
-       uint32_t max_limit;
-       uint32_t max_trans = lp_smb2_max_trans();
-       uint32_t max_read = lp_smb2_max_read();
-       uint32_t max_write = lp_smb2_max_write();
-       NTTIME now = timeval_to_nttime(&req->request_time);
-
-       status = smbd_smb2_request_verify_sizes(req, 0x24);
-       if (!NT_STATUS_IS_OK(status)) {
-               return smbd_smb2_request_error(req, status);
-       }
-       inbody = SMBD_SMB2_IN_BODY_PTR(req);
-
-       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);
-
-       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 (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
-               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
-       }
-       indyn = SMBD_SMB2_IN_DYN_PTR(req);
 
        for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
                if (lp_server_max_protocol() < PROTOCOL_SMB3_00) {
@@ -146,8 +97,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
                        break;
                }
 
-               dialect = SVAL(indyn, c*2);
-               if (dialect == SMB3_DIALECT_REVISION_300) {
+               *dialect = SVAL(indyn, c*2);
+               if (*dialect == SMB3_DIALECT_REVISION_300) {
                        protocol = PROTOCOL_SMB3_00;
                        break;
                }
@@ -161,8 +112,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
                        break;
                }
 
-               dialect = SVAL(indyn, c*2);
-               if (dialect == SMB2_DIALECT_REVISION_224) {
+               *dialect = SVAL(indyn, c*2);
+               if (*dialect == SMB2_DIALECT_REVISION_224) {
                        protocol = PROTOCOL_SMB2_24;
                        break;
                }
@@ -176,8 +127,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
                        break;
                }
 
-               dialect = SVAL(indyn, c*2);
-               if (dialect == SMB2_DIALECT_REVISION_222) {
+               *dialect = SVAL(indyn, c*2);
+               if (*dialect == SMB2_DIALECT_REVISION_222) {
                        protocol = PROTOCOL_SMB2_22;
                        break;
                }
@@ -191,8 +142,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
                        break;
                }
 
-               dialect = SVAL(indyn, c*2);
-               if (dialect == SMB2_DIALECT_REVISION_210) {
+               *dialect = SVAL(indyn, c*2);
+               if (*dialect == SMB2_DIALECT_REVISION_210) {
                        protocol = PROTOCOL_SMB2_10;
                        break;
                }
@@ -206,13 +157,76 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
                        break;
                }
 
-               dialect = SVAL(indyn, c*2);
-               if (dialect == SMB2_DIALECT_REVISION_202) {
+               *dialect = SVAL(indyn, c*2);
+               if (*dialect == SMB2_DIALECT_REVISION_202) {
                        protocol = PROTOCOL_SMB2_02;
                        break;
                }
        }
 
+       return protocol;
+}
+
+NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
+{
+       NTSTATUS status;
+       const uint8_t *inbody;
+       const uint8_t *indyn = NULL;
+       DATA_BLOB outbody;
+       DATA_BLOB outdyn;
+       DATA_BLOB negprot_spnego_blob;
+       uint16_t security_offset;
+       DATA_BLOB security_buffer;
+       size_t expected_dyn_size = 0;
+       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;
+       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();
+       uint32_t max_read = lp_smb2_max_read();
+       uint32_t max_write = lp_smb2_max_write();
+       NTTIME now = timeval_to_nttime(&req->request_time);
+
+       status = smbd_smb2_request_verify_sizes(req, 0x24);
+       if (!NT_STATUS_IS_OK(status)) {
+               return smbd_smb2_request_error(req, status);
+       }
+       inbody = SMBD_SMB2_IN_BODY_PTR(req);
+
+       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);
+
+       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 (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
+               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+       }
+       indyn = SMBD_SMB2_IN_DYN_PTR(req);
+
+       protocol = smbd_smb2_protocol_dialect_match(indyn,
+                                       dialect_count,
+                                       &dialect);
+
        for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
                if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
                        break;