Exemplo n.º 1
0
        /// <summary>
        /// Read and write the file within the locking byte range when lock or unlock is taken
        /// </summary>
        /// <param name="isLocked">Set true to indicate that access the file when lock operation is taken</param>
        private void ValidateByteLockRangeFromAnotherClient(bool isLocked)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint treeId;

            status = client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;

            status = client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            string data;
            Random random = new Random();
            uint   offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint   length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));

            status = client.Read(treeId, fileId, offset, length, out data);

            status = client.Write(treeId, fileId, contentWrite, checker: (header, response) => { });
            if (isLocked)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content to locked range of file from different client is not expected to success");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content in file failed with error code=" + Smb2Status.GetStatusCode(status));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Read and write file within byte lock range when the file is locked or unlocked
        /// </summary>
        /// <param name="isLocked">Set true to indicate that byte lock range is taken on the file</param>
        /// <param name="serverName">Name of file server to access</param>
        /// <param name="targetFileName">Target file name to read and write</param>
        private void ValidateByteLockRangeFromAnotherClient(bool isLocked, string serverName, string targetFileName)
        {
            uint status = 0;

            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, serverName, currentAccessIp);

            status = client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                serverName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint treeId;

            status = client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;

            status = client.Create(
                treeId,
                targetFileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            string data;
            Random random = new Random();
            uint   offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint   length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));

            status = client.Read(treeId, fileId, offset, length, out data);

            status = client.Write(treeId, fileId, contentWrite, checker: (header, response) => { });
            if (isLocked)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content to locked range of file from different client is not expected to success");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content in file should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            }
        }
Exemplo n.º 3
0
        public void ContentServer_SmbServer_OffsetInvalid()
        {
            CheckApplicability();

            contentInformationUtility.RetrieveContentData();

            using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(testConfig.Timeout))
            {
                smb2Client.OpenFile(
                    testConfig.ContentServerComputerName,
                    testConfig.SharedFolderName,
                    testConfig.NameOfFileWithMultipleBlocks,
                    testConfig.SecurityPackageType,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword,
                    AccessMask.GENERIC_READ);

                HASH_HEADER hashHeader;
                byte[]      hashData;

                uint smb2Status = 0;
                TestUtility.DoUntilSucceed(
                    () => (smb2Status = smb2Client.ReadHash(
                               SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                               SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1,
                               SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED,
                               uint.MaxValue,
                               uint.MaxValue,
                               out hashHeader,
                               out hashData)) != Smb2Status.STATUS_HASH_NOT_PRESENT,
                    testConfig.Timeout,
                    testConfig.RetryInterval);

                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    smb2Status,
                    "The content server should return error for invalid offset");

                /// If the HashRetrievalType is SRV_HASH_RETRIEVE_FILE_BASED and Offset field of the SRV_READ_HASH request is equal to or beyond the end of the file
                /// represented by Open.LocalOpen, the server MUST fail the SRV_READ_HASH request with error code STATUS_END_OF_FILE.
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_END_OF_FILE,
                    smb2Status,
                    RequirementCategory.EndOfFile,
                    RequirementCategory.EndOfFileMessage);

                smb2Client.CloseFile();
            }
        }
Exemplo n.º 4
0
        public void ContentServer_SmbServer_HashV2HashBased_Smb21()
        {
            CheckApplicability();

            contentInformationUtility.RetrieveContentData();

            using (Smb2ClientSupportDialect smb2Client = new Smb2ClientSupportDialect(testConfig.Timeout, DialectRevision.Smb21))
            {
                smb2Client.OpenFile(
                    testConfig.ContentServerComputerName,
                    testConfig.SharedFolderName,
                    testConfig.NameOfFileWithMultipleBlocks,
                    testConfig.SecurityPackageType,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword,
                    AccessMask.GENERIC_READ);

                HASH_HEADER hashHeader;
                byte[]      hashData;

                uint smb2Status = 0;
                TestUtility.DoUntilSucceed(
                    () => (smb2Status = smb2Client.ReadHash(
                               SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                               SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2,
                               SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED,
                               0,
                               uint.MaxValue,
                               out hashHeader,
                               out hashData)) != Smb2Status.STATUS_HASH_NOT_PRESENT,
                    testConfig.Timeout,
                    testConfig.RetryInterval);

                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    smb2Status,
                    "The content server should return error for invalid hash type");

                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_INVALID_PARAMETER,
                    smb2Status,
                    RequirementCategory.InvalidParameter,
                    RequirementCategory.InvalidParameterMessage);

                smb2Client.CloseFile();
            }
        }
Exemplo n.º 5
0
        public void ContentServer_SmbServer_HashTypeInvalid()
        {
            CheckApplicability();

            contentInformationUtility.RetrieveContentData();

            using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(testConfig.Timeout))
            {
                smb2Client.OpenFile(
                    testConfig.ContentServerComputerName,
                    testConfig.SharedFolderName,
                    testConfig.NameOfFileWithMultipleBlocks,
                    testConfig.SecurityPackageType,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword,
                    AccessMask.GENERIC_READ);

                HASH_HEADER hashHeader;
                byte[]      hashData;
                uint        smb2Status = smb2Client.ReadHash(
                    (SRV_READ_HASH_Request_HashType_Values)0xFEFEFEFE,
                    SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1,
                    SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED,
                    0,
                    uint.MaxValue,
                    out hashHeader,
                    out hashData);

                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    smb2Status,
                    "The content server should return error for invalid hash type");

                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_INVALID_PARAMETER,
                    smb2Status,
                    RequirementCategory.InvalidParameter,
                    RequirementCategory.InvalidParameterMessage);

                smb2Client.CloseFile();
            }
        }
Exemplo n.º 6
0
        public void BVT_SMB2Basic_LockAndUnLock()
        {
            uint   status;
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            #region From client1 lock a byte range and try to write content to the file within the range
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "From client1 locks a byte range and try to write content to the file within the range.");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start client1 to create a file with sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE.");
            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;
            status = client1.TreeConnect(uncSharePath, out treeId1);
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId1;
            string fileName = Guid.NewGuid().ToString() + ".txt";
            status = client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 writes content to the file created.");
            status = client1.Write(treeId1, fileId1, content);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client1 by sending CLOSE request.");
            client1.Close(treeId1, fileId1);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 sends CREATE request.");
            status = client1.Create(
                treeId1,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            //Construct LOCK_ELEMENT
            LOCK_ELEMENT[] locks        = new LOCK_ELEMENT[1];
            uint           lockSequence = 0;
            locks[0].Offset = 0;
            locks[0].Length = (ulong)TestConfig.WriteBufferLengthInKb * 1024;
            locks[0].Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 starts to lock a byte range for file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3})",
                fileName, locks[0].Offset, locks[0].Length, locks[0].Flags.ToString());
            status = client1.Lock(treeId1, lockSequence++, fileId1, locks);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 sends WRITE request to write content to the locking range");
            status = client1.Write(
                treeId1,
                fileId1,
                content,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    header.Status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            });
            #endregion

            #region From client2 to read and write the locking range of the same file after lock
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "From client2 to read and take shared lock on the locking range of the same file after lock");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start client2 to create a file with sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE.");
            client2 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client2.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client2.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId2;
            status = client2.TreeConnect(uncSharePath, out treeId2);
            FILEID fileId2;
            status = client2.Create(
                treeId2,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId2,
                out serverCreateContexts);

            string data;
            Random random = new Random();
            uint   offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint   length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends READ request to read a random area in the locking range of file \"{0}\" with offset: {1}, length: {2}",
                fileName, offset, length);
            status = client2.Read(treeId2, fileId2, offset, length, out data);

            //Construct LOCK_ELEMENT
            LOCK_ELEMENT[] locksFromOtherOpen = new LOCK_ELEMENT[1];
            locksFromOtherOpen[0].Offset = offset;
            locksFromOtherOpen[0].Length = (ulong)length;
            locksFromOtherOpen[0].Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 attempts to take a shared lock on random range of file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3})",
                fileName, locksFromOtherOpen[0].Offset, locksFromOtherOpen[0].Length, locksFromOtherOpen[0].Flags.ToString());
            status = client2.Lock(treeId2, lockSequence++, fileId2, locksFromOtherOpen);

            locksFromOtherOpen[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 attempts to unlock the range");
            status = client2.Lock(treeId2, lockSequence++, fileId2, locksFromOtherOpen);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends WRITE request to write a random area in the locking range of file \"{0}\" after lock", fileName);
            status = client2.Write(
                treeId2,
                fileId2,
                content,
                offset,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    header.Status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            });
            #endregion

            #region From client1 unlock the range
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 unlocks the range");
            locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Client1 attempts to unlock the range");
            status = client1.Lock(treeId1, lockSequence++, fileId1, locks);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client1 by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
            #endregion

            #region From client2 write content to the previous locking range after unlock
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client2 sends WRITE request to write content to the previous locking range after unlock");
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Client2 attempts to write a random area in the locking range of file \"{0}\" after unlock", fileName);
            status = client2.Write(treeId2, fileId2, content, offset);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down client2 by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client2.Close(treeId2, fileId2);
            client2.TreeDisconnect(treeId2);
            client2.LogOff();
            #endregion
        }
        /// <summary>
        /// Test server failover with encryption
        /// </summary>
        /// <param name="encryptionBeforeFailover">Set true if encryption is enabled before server failover, otherwise set false</param>
        /// <param name="encryptionAfterFailover">Set true if encryption is enabled after server failover, otherwise set false</param>
        private void FileServerFailoverWithEncryption(bool encryptionBeforeFailover, bool encryptionAfterFailover)
        {
            RestoreCluster();

            uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredEncryptedFileShare);

            FILEID fileIdBeforeFailover;
            uint   treeIdBeforeFailover;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: Connect to general file server {0}.", TestConfig.ClusteredFileServerName);
            ConnectGeneralFileServerBeforeFailover(TestConfig.ClusteredFileServerName, out treeIdBeforeFailover, encryptionBeforeFailover);

            #region CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT.");
            Smb2CreateContextResponse[] serverCreateContexts;
            createGuid = Guid.NewGuid();

            // Skip the verification of signature when sending a non-encrypted CREATE request to an encrypted share
            if (!encryptionBeforeFailover)
            {
                clientBeforeFailover.Smb2Client.DisableVerifySignature = true;
            }
            status = clientBeforeFailover.Create(
                treeIdBeforeFailover,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdBeforeFailover,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT,
                    Timeout    = 3600000,
                },
            },
                checker: (header, response) => { });
            #endregion

            if (!encryptionBeforeFailover)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "CreateDurableHandleRequestV2 to encrypted share without encryption should not SUCCESS ");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            }
            else if (encryptionBeforeFailover)
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "CreateDurableHandleRequestV2 for file {0} should succeed, actual status is {1}", fileName, Smb2Status.GetStatusCode(status));

                status = clientBeforeFailover.Write(treeIdBeforeFailover, fileIdBeforeFailover, contentWrite);
            }

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Do failover of the file server.");
            FailoverServer(currentAccessIp, TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer);

            FILEID fileIdAfterFailover = FILEID.Zero;
            uint   treeIdAfterFailover;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Connect to the same general file server {0}.", TestConfig.ClusteredFileServerName);
            ReconnectServerAfterFailover(TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer, out treeIdAfterFailover, encryptionAfterFailover);

            // Skip the verification of signature when sending a non-encrypted CREATE request to an encrypted share
            if (!encryptionAfterFailover)
            {
                clientAfterFailover.Smb2Client.DisableVerifySignature = true;
            }
            if (encryptionBeforeFailover && !encryptionAfterFailover)
            {
                #region CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT.");
                status = clientAfterFailover.Create(
                    treeIdAfterFailover,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileIdAfterFailover,
                    out serverCreateContexts,
                    RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                    new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleReconnectV2
                    {
                        FileId = new FILEID {
                            Persistent = fileIdBeforeFailover.Persistent
                        },
                        CreateGuid = createGuid,
                        Flags      = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                    },
                },
                    checker: (header, response) => { });
                #endregion

                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "CreatDurableHandleReconnectV2 to encrypted share without encryption should not SUCCESS ");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);

                status = clientAfterFailover.TreeDisconnect(treeIdAfterFailover, (header, response) => { });
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "TreeDisconnect should not SUCCESS");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            }
            else if (!encryptionBeforeFailover && encryptionAfterFailover)
            {
                #region CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT.");
                status = clientAfterFailover.Create(
                    treeIdAfterFailover,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileIdAfterFailover,
                    out serverCreateContexts,
                    RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                    new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleReconnectV2
                    {
                        FileId = new FILEID {
                            Persistent = fileIdBeforeFailover.Persistent
                        },
                        CreateGuid = createGuid,
                        Flags      = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                    },
                },
                    checker: (header, response) => { });
                #endregion

                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "CreatDurableHandleReconnectV2 should not SUCCESS ");

                if (TestConfig.Platform == Platform.WindowsServer2012)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug,
                                         @"[MS-SMB2] Section 3.3.5.9.12: Windows Server 2012 with [KB2770917] and Windows 8 with [KB2770917] fail the CREATE request with STATUS_INVALID_PARAMETER 
                        if the request includes the SMB2_DHANDLE_FLAG_PERSISTENT bit in the Flags field of the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context.");

                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_INVALID_PARAMETER,
                        status,
                        RequirementCategory.STATUS_INVALID_PARAMETER.Id,
                        RequirementCategory.STATUS_INVALID_PARAMETER.Description);
                }
                else
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug,
                                         @"[MS-SMB2] 3.3.5.9.12   Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context.
                        The server MUST look up an existing Open in the GlobalOpenTable by doing a lookup with the FileId.Persistent portion of the create context.
                        If the lookup fails, the server SHOULD (285) fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in Failed Open Handling in section 3.3.5.9.");

                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                        status,
                        RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                        RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                }
                status = clientAfterFailover.TreeDisconnect(treeIdAfterFailover);
            }
            else if (encryptionBeforeFailover && encryptionAfterFailover)
            {
                #region CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT.");
                status = DoUntilSucceed(
                    () => clientAfterFailover.Create(
                        treeIdAfterFailover,
                        fileName,
                        CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        out fileIdAfterFailover,
                        out serverCreateContexts,
                        RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                        new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleReconnectV2
                    {
                        FileId = new FILEID {
                            Persistent = fileIdBeforeFailover.Persistent
                        },
                        CreateGuid = createGuid,
                        Flags      = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                    },
                },
                        checker: (header, response) => { }),
                    TestConfig.FailoverTimeout,
                    "Retry Create until succeed within timeout span");
                #endregion
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "CreatDurableHandleReconnectV2 should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));

                BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Read contents written before failover.");
                status = clientAfterFailover.Read(treeIdAfterFailover, fileIdAfterFailover, 0, (uint)contentWrite.Length, out contentRead);

                BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Verify the contents are the same as the one written before failover.");
                BaseTestSite.Assert.IsTrue(
                    contentWrite.Equals(contentRead),
                    "Content read after failover should be identical to that written before failover");

                status = clientAfterFailover.Close(treeIdAfterFailover, fileIdAfterFailover);

                status = clientAfterFailover.TreeDisconnect(treeIdAfterFailover);
            }

            status = clientAfterFailover.LogOff();
        }
 public void CaptureRequirementAreEqualFailed()
 {
     BaseTestSite.CaptureRequirementIfAreEqual(1, 2, 2, "The two values should be equal.");
 }
 public void CaptureRequirementSameRequirementIdDifferentDescription()
 {
     BaseTestSite.CaptureRequirementIfAreEqual(1, 1, 28, "The two values should be equal.");
     BaseTestSite.CaptureRequirementIfIsTrue(true, 28, "The value should be true.");
 }
 public void CaptureRequirementSkipExceptionalRequirements()
 {
     BaseTestSite.CaptureRequirementIfAreEqual(2, 1, 26, "The two values should be equal.");
     BaseTestSite.CaptureRequirementIfIsTrue(false, 27, "The value should be true.");
 }
Exemplo n.º 11
0
        public void FileServerFailover_Lock()
        {
            FILEID fileIdBeforeFailover;
            uint   treeIdBeforeFailover;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: Connect to general file server {0}.", TestConfig.ClusteredFileServerName);
            ConnectGeneralFileServerBeforeFailover(TestConfig.ClusteredFileServerName, out treeIdBeforeFailover);

            #region CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT.");
            Smb2CreateContextResponse[] serverCreateContexts;
            createGuid = Guid.NewGuid();

            status = clientBeforeFailover.Create(
                treeIdBeforeFailover,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdBeforeFailover,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT,
                    Timeout    = 3600000,
                },
                new Smb2CreateQueryOnDiskId
                {
                },
            });
            #endregion

            #region WRITE content to file
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: WRITE content to file.");
            status = clientBeforeFailover.Write(treeIdBeforeFailover, fileIdBeforeFailover, contentWrite);
            #endregion

            #region Request byte range lock
            LOCK_ELEMENT[] locks        = new LOCK_ELEMENT[1];
            uint           lockSequence = 0;
            locks[0].Offset = 0;
            locks[0].Length = (ulong)TestConfig.WriteBufferLengthInKb * 1024;
            locks[0].Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client1 start to lock a byte range for file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3}",
                fileName, locks[0].Offset, locks[0].Length, locks[0].Flags.ToString());
            status = clientBeforeFailover.Lock(treeIdBeforeFailover, lockSequence++, fileIdBeforeFailover, locks);

            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Do failover of the file server.");
            FailoverServer(currentAccessIp, TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer);

            FILEID fileIdAfterFailover = FILEID.Zero;
            uint   treeIdAfterFailover;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Reconnect to the same general file server {0}.", TestConfig.ClusteredFileServerName);
            ReconnectServerAfterFailover(TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer, out treeIdAfterFailover);

            #region CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT.");
            status = DoUntilSucceed(
                () => clientAfterFailover.Create(
                    treeIdAfterFailover,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileIdAfterFailover,
                    out serverCreateContexts,
                    RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                    new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleReconnectV2
                {
                    FileId = new FILEID {
                        Persistent = fileIdBeforeFailover.Persistent
                    },
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT
                },
            },
                    checker: (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry Create until succeed within timeout span");
            #endregion

            #region READ and WRITE
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Read the contents written before failover.");
            status = clientAfterFailover.Read(
                treeIdAfterFailover,
                fileIdAfterFailover,
                0,
                (uint)contentWrite.Length,
                out contentRead);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Verify the contents are the same as the one written before failover.");
            BaseTestSite.Assert.IsTrue(
                contentWrite.Equals(contentRead),
                "Content read after failover should be identical to that written before failover.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Write contents to the locking range, it MUST NOT be allowed.");
            status = clientAfterFailover.Write(
                treeIdAfterFailover,
                fileIdAfterFailover,
                contentWrite,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    header.Status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            });
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "From client3: Read and write the locking range when the file is locked, it should fail.");
            ValidateByteLockRangeFromAnotherClient(true, TestConfig.ClusteredFileServerName, fileName);

            #region Unlock byte range
            locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "AfterFailover: Client2 attempts to unlock the range");
            status = clientAfterFailover.Lock(treeIdAfterFailover, lockSequence++, fileIdAfterFailover, locks);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "From client3: Read and write the locking range from a separate client when the file is unlocked, it should succeed.");
            ValidateByteLockRangeFromAnotherClient(false, TestConfig.ClusteredFileServerName, fileName);

            status = clientAfterFailover.Close(treeIdAfterFailover, fileIdAfterFailover);

            status = clientAfterFailover.TreeDisconnect(treeIdAfterFailover);

            status = clientAfterFailover.LogOff();
        }
        private void DirecotryLeasing(
            DialectRevision[] requestDialect,
            DialectRevision expectedDialect,
            LeaseStateValues leaseState,
            LeaseBreakAckType leaseBreakAckType = LeaseBreakAckType.None)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Start to create a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);

            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Negotiate
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            Capabilities_Values capabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            status = client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: capabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(expectedDialect, response);
                if (expectedDialect >= DialectRevision.Smb30)
                {
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                }
            });
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            uint   treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends CREATE request for the directory with the LeaseState set to {0} in SMB2_CREATE_REQUEST_LEASE_V2.", leaseState);
            status = client.Create(
                treeId,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
            {
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = Guid.NewGuid(),
                    LeaseState = leaseState
                }
            },
                checker: (Packet_Header header, CREATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21)
                {
                    BaseTestSite.Assert.AreEqual(
                        OplockLevel_Values.OPLOCK_LEVEL_NONE,
                        response.OplockLevel,
                        "The expected oplock level is OPLOCK_LEVEL_NONE.");
                }
            });

            #endregion

            if (expectedDialect >= DialectRevision.Smb30)
            {
                // Break the lease with creating another file in the directory
                sutProtocolController.CreateFile(Path.Combine(Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare), testDirectory), CurrentTestCaseName, string.Empty);

                // Wait until LEASE_BREAK_Notification is received
                BaseTestSite.Assert.IsTrue(
                    // Wait 5 seconds for notification arrival
                    notificationReceived.WaitOne(SMB2TestConfig.WAIT_TIMEOUT_IN_MILLISECONDS),
                    "LeaseBreakNotification should be raised.");

                if (receivedLeaseBreakNotify.Flags == LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED)
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server requires an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");

                    #region LEASE_BREAK_ACK
                    switch (leaseBreakAckType)
                    {
                    case LeaseBreakAckType.None:
                        status = client.LeaseBreakAcknowledgment(treeId, receivedLeaseBreakNotify.LeaseKey, receivedLeaseBreakNotify.NewLeaseState);
                        break;

                    case LeaseBreakAckType.InvalidLeaseState:
                        LeaseStateValues newLeaseState = LeaseStateValues.SMB2_LEASE_WRITE_CACHING;
                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseState {0} on this LEASE_BREAK_NOTIFY", newLeaseState);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            newLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseState is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_REQUEST_NOT_ACCEPTED,
                                header.Status,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Id,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidLeaseKey:
                        Guid invalidLeaseKey = Guid.NewGuid();
                        BaseTestSite.Log.Add(
                            LogEntryKind.Debug,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseKey {0} on this LEASE_BREAK_NOTIFY", invalidLeaseKey);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            invalidLeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseKey is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidClientGuid:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        Smb2FunctionalClient newClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

                        newClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

                        #region Negotiate
                        status = newClient.Negotiate(
                            requestDialect,
                            TestConfig.IsSMB1NegotiateEnabled,
                            capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);
                        #endregion

                        #region SESSION_SETUP
                        status = newClient.SessionSetup(
                            TestConfig.DefaultSecurityPackage,
                            TestConfig.SutComputerName,
                            TestConfig.AccountCredential,
                            TestConfig.UseServerGssToken);
                        #endregion

                        #region TREE_CONNECT to share
                        uint newTreeId;
                        status = newClient.TreeConnect(uncSharePath, out newTreeId);
                        #endregion

                        status = newClient.LeaseBreakAcknowledgment(
                            newTreeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK is not expected to SUCCESS when the open is closed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });

                        status = newClient.TreeDisconnect(newTreeId);

                        status = newClient.LogOff();

                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        break;

                    default:
                        throw new InvalidOperationException("Unexpected LeaseBreakAckType " + leaseBreakAckType);
                    }

                    #endregion
                }
                else
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");
                }
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF");
            #region TREE_DISCONNECT
            status = client.TreeDisconnect(treeId);
            #endregion

            #region LOGOFF
            status = client.LogOff();
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Complete creating a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);
        }
        private void DurableHandleV1_Reconnect_WithoutLogoff(bool isPreviousSessionIdSet)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb2002);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT);
            #endregion

            string content = Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb);
            durableHandleUncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
            fileName = "DurableHandleV1_Reconnect_WithoutLogoff" + Guid.NewGuid() + ".txt";

            #region client connect to server
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client connects to server and opens file with a durable handle");

            uint treeIdBeforeDisconnection;
            Connect(DialectRevision.Smb21, clientBeforeDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdBeforeDisconnection, null);

            FILEID fileIdBeforeDisconnection;
            Smb2CreateContextResponse[] serverCreateContexts = null;
            clientBeforeDisconnection.Create(
                treeIdBeforeDisconnection,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdBeforeDisconnection,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequest
                {
                    DurableRequest = Guid.Empty
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                CheckCreateContextResponses(serverCreateContexts, new DefaultDurableHandleResponseChecker(BaseTestSite));
            });

            clientBeforeDisconnection.Write(treeIdBeforeDisconnection, fileIdBeforeDisconnection, content);
            #endregion

            #region client reconnect to server
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client opens the same file and reconnects the durable handle");

            uint treeIdAfterDisconnection;
            Connect(DialectRevision.Smb21, clientAfterDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert,
                    out treeIdAfterDisconnection, isPreviousSessionIdSet ? clientBeforeDisconnection : null);

            FILEID fileIdAfterDisconnection;

            ResponseChecker <CREATE_Response> createResponseChecker = null;
            if (isPreviousSessionIdSet)
            {
                if (testConfig.Platform == Platform.WindowsServer2012R2)
                {
                    // 6   Appendix A: Product Behavior
                    // <265> Section 3.3.5.9.7: If the Session was established by specifying PreviousSessionId in the SMB2 SESSION_SETUP request,
                    // therefore invalidating the previous session, Windows 8.1 and Windows Server 2012 R2 close the durable opens established on the previous session.
                    createResponseChecker = (header, response) =>
                    {
                        BaseTestSite.Assert.AreNotEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "{0} should not be successful if Server is Windows Server 2012R2 and the Session was established by specifying PreviousSessionId in the SMB2 SESSION_SETUP request. " +
                            "Actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));

                        BaseTestSite.CaptureRequirementIfAreEqual(
                            Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                            header.Status,
                            RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                            RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                    };
                }
                else
                {
                    createResponseChecker = (header, response) =>
                    {
                        BaseTestSite.Assert.AreEqual(
                            Smb2Status.STATUS_SUCCESS,
                            header.Status,
                            "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                    };
                }
            }
            else
            {
                createResponseChecker = (header, response) =>
                {
                    BaseTestSite.Assert.AreNotEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should not be successful if Open.Session is not NULL, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));

                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                        header.Status,
                        RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                        RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                };
            }

            clientAfterDisconnection.Create(
                treeIdAfterDisconnection,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdAfterDisconnection,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleReconnect
                {
                    Data = new FILEID {
                        Persistent = fileIdBeforeDisconnection.Persistent
                    }
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: createResponseChecker);
            #endregion

            clientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection);

            clientAfterDisconnection.LogOff();

            clientAfterDisconnection.Disconnect();
        }
        public void MultipleChannel_Negative_EncryptionOnMainChannel()
        {
            #region Check Applicability
            TestConfig.CheckServerEncrypt();
            #endregion
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.EncryptedFileShare);

            uint   treeId;
            FILEID fileId;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Establish main channel with client {0} and server {1}, encryption is enabled.", clientIps[0].ToString(), serverIps[0].ToString());
            EstablishMainChannel(
                TestConfig.RequestDialects,
                serverIps[0],
                clientIps[0],
                out treeId,
                true);

            #region CREATE
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Main channel: Create file {0}.", fileName);
            Smb2CreateContextResponse[] serverCreateContexts;
            status = mainChannelClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                out fileId,
                out serverCreateContexts);
            #endregion

            #region WRITE
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Main channel: Write content to file.");
            status = mainChannelClient.Write(treeId, fileId, contentWrite);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Establish alternative channel with client {0} and server {1}, encryption is NOT enabled.", clientIps[1].ToString(), serverIps[1].ToString());
            EstablishAlternativeChannel(
                TestConfig.RequestDialects,
                serverIps[1],
                clientIps[1],
                treeId,
                false);

            #region READ
            // Skip the verification of signature when sending a non-encrypted CREATE request to an encrypted share
            alternativeChannelClient.Smb2Client.DisableVerifySignature = true;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Alternative channel: Read content from file.");
            status = alternativeChannelClient.Read(
                treeId,
                fileId,
                0,
                (uint)contentWrite.Length,
                out contentRead,
                checker: (header, response) =>
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify Server response indicates that read content failed.");
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Read data from file should not success");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    header.Status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            });
            #endregion
        }
Exemplo n.º 15
0
        /// <summary>
        /// Establish alternative channel and lock/unlock byte range of a file from same or different channel client
        /// </summary>
        /// <param name="lockUnlockOnSameChannel">Set this parameter to true if the unlock operation is taken from the same channel client</param>
        private void MultipleChannelTestWithLock(bool lockUnlockOnSameChannel)
        {
            uint   treeId;
            FILEID fileId;

            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Establish main channel with client {0} and server {1}.", clientIps[0].ToString(), serverIps[0].ToString());
            EstablishMainChannel(
                TestConfig.RequestDialects,
                serverIps[0],
                clientIps[0],
                out treeId);

            #region CREATE to open file for WRITE and LOCK
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Main channel: CREATE file.");
            Smb2CreateContextResponse[] serverCreateContexts;
            status = mainChannelClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
            #endregion

            #region WRITE content to file
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Main channel: WRITE content to file.");
            status = mainChannelClient.Write(treeId, fileId, contentWrite);
            #endregion

            #region Request byte lock range
            //Construct LOCK_ELEMENT
            LOCK_ELEMENT[] locks        = new LOCK_ELEMENT[1];
            uint           lockSequence = 0;
            locks[0].Offset = 0;
            locks[0].Length = (ulong)TestConfig.WriteBufferLengthInKb * 1024;
            locks[0].Flags  = LOCK_ELEMENT_Flags_Values.LOCKFLAG_SHARED_LOCK;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Main channel client starts to lock a byte range for file \"{0}\" with parameters offset:{1}, length:{2}, flags: {3})",
                fileName, locks[0].Offset, locks[0].Length, locks[0].Flags.ToString());
            status = mainChannelClient.Lock(treeId, lockSequence++, fileId, locks);
            #endregion

            #region WRITE content within the locking range
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Main channel: attempts to write content within the locking range.");
            status = mainChannelClient.Write(
                treeId,
                fileId,
                contentWrite,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Write should not success when shared lock is taken");

                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    header.Status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            });
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Establish alternative channel with client {0} and server {1}.", clientIps[1].ToString(), serverIps[1].ToString());
            EstablishAlternativeChannel(
                TestConfig.RequestDialects,
                serverIps[1],
                clientIps[1],
                treeId);

            #region READ/WRITE from alternative channel within the locking range
            Random random = new Random();
            uint   offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint   length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Alternative channel: attempts to randomly read the locking range with offset: {0} and length: {1}", offset, length);
            status = alternativeChannelClient.Read(treeId, fileId, offset, length, out contentRead);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Alternative channel: attempts to write content to the locking range");
            status = alternativeChannelClient.Write(
                treeId,
                fileId,
                contentWrite,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "All opens MUST NOT be allowed to write within the range when SMB2_LOCKFLAG_SHARED_LOCK set");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    header.Status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            });
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Read and write the locking range from Client3 when the file is locked");
            ValidateByteLockRangeFromAnotherClient(true);

            locks[0].Flags = LOCK_ELEMENT_Flags_Values.LOCKFLAG_UNLOCK;
            if (lockUnlockOnSameChannel)
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "From main channel client unlock the range");
                status = mainChannelClient.Lock(treeId, lockSequence++, fileId, locks);
            }
            else
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "From alternative channel client unlock the range");
                status = alternativeChannelClient.Lock(treeId, lockSequence++, fileId, locks);
            }

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Read and write the locking range from Client3 when the file is unlocked");
            ValidateByteLockRangeFromAnotherClient(false);

            ClientTearDown(mainChannelClient, treeId, fileId);
        }
Exemplo n.º 16
0
        public void BVT_SMB2Basic_CancelRegisteredChangeNotify()
        {
            uint   status;
            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Test directory \"{0}\" was created on share \"{1}\"", testDirectory, TestConfig.BasicFileShare);

            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.Smb2Client.ChangeNotifyResponseReceived += new Action <FILE_NOTIFY_INFORMATION[], Packet_Header, CHANGE_NOTIFY_Response>(OnChangeNotifyResponseReceived);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client to create a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE");
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;

            status = client1.TreeConnect(uncSharePath, out treeId1);
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId1;

            status = client1.Create(
                treeId1,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to register CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.ChangeNotify(treeId1, fileId1, CompletionFilter_Values.FILE_NOTIFY_CHANGE_LAST_ACCESS);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to cancel the registered CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.Cancel();

            BaseTestSite.Assert.IsTrue(
                changeNotificationReceived.WaitOne(TestConfig.WaitTimeoutInMilliseconds),
                "Change notification should be received within {0} milliseconds", TestConfig.WaitTimeoutInMilliseconds);

            BaseTestSite.Assert.AreNotEqual(
                Smb2Status.STATUS_SUCCESS,
                receivedChangeNotifyHeader.Status, "CHANGE_NOTIFY is not expected to success after cancel, actually server returns {0}.",
                Smb2Status.GetStatusCode(receivedChangeNotifyHeader.Status));
            BaseTestSite.CaptureRequirementIfAreEqual(
                Smb2Status.STATUS_CANCELLED,
                receivedChangeNotifyHeader.Status,
                RequirementCategory.STATUS_CANCELLED.Id,
                RequirementCategory.STATUS_CANCELLED.Description);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
        }
        /// <summary>
        /// Test AppInstanceId with encryption
        /// </summary>
        /// <param name="encryptionInInitialOpen">Set true if encryption is enabled in initial open, otherwise set false</param>
        /// <param name="encryptionInReOpen">Set true if encryption is enabled in re-open, otherwise set false</param>
        private void AppInstanceIdTestWithEncryption(bool encryptionInInitialOpen, bool encryptionInReOpen)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION
                                         | NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING
                                         | NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_APP_INSTANCE_ID, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE);
            #endregion

            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.EncryptedFileShare);

            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "InitialOpen: Connect to share via Nic1.");
            FILEID fileIdForInitialOpen;
            uint   treeIdForInitialOpen;
            ConnectShare(TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress, clientForInitialOpen, out treeIdForInitialOpen, encryptionInInitialOpen);

            // Skip the verification of signature when sending a non-encrypted CREATE request to an encrypted share
            if (!encryptionInInitialOpen)
            {
                clientForInitialOpen.Smb2Client.DisableVerifySignature = true;
            }

            #region CREATE an open with AppInstanceId
            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "InitialOpen: CREATE an open with AppInstanceId.");

            Smb2CreateContextResponse[] serverCreateContexts;
            status = clientForInitialOpen.Create(
                treeIdForInitialOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForInitialOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = Guid.NewGuid(),
                },
                new Smb2CreateAppInstanceId
                {
                    AppInstanceId = appInstanceId
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) => { });
            #endregion

            if (!encryptionInInitialOpen)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Create durable handle request to encrypted share without encryption should not SUCCESS ");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Create durable handle request V2 should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "InitialOpen: Write contents to file.");
                status = clientForInitialOpen.Write(treeIdForInitialOpen, fileIdForInitialOpen, contentWrite);
            }

            FILEID fileIdForReOpen;
            uint   treeIdForReOpen;
            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Connect to same share via Nic2.");
            ConnectShare(TestConfig.SutIPAddress, TestConfig.ClientNic2IPAddress, clientForReOpen, out treeIdForReOpen, encryptionInReOpen);

            // Skip the verification of signature when sending a non-encrypted CREATE request to an encrypted share
            if (!encryptionInReOpen)
            {
                clientForReOpen.Smb2Client.DisableVerifySignature = true;
            }
            #region CREATE an open with same AppInstanceId for reopen
            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: CREATE an open with same AppInstanceId for reopen.");
            status = clientForReOpen.Create(
                treeIdForReOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForReOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = Guid.NewGuid(),
                },
                new Smb2CreateAppInstanceId
                {
                    // Use the same application instance id to force the server close all files
                    AppInstanceId = appInstanceId
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) => { });
            #endregion

            if (encryptionInInitialOpen && encryptionInReOpen)
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Create durable handle request should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Read the contents written by InitialOpen.");
                status = clientForReOpen.Read(treeIdForReOpen, fileIdForReOpen, 0, (uint)contentWrite.Length, out contentRead);

                BaseTestSite.Assert.IsTrue(
                    contentRead.Equals(contentWrite),
                    "The written content should equal to read content.");

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Close file.");
                status = clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen);

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Disconnect the share.");
                status = clientForReOpen.TreeDisconnect(treeIdForReOpen);
            }
            else if (encryptionInInitialOpen && !encryptionInReOpen)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Create durable handle request to encrypted share without encryption should not SUCCESS ");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Disconnect the share.");
                status = clientForReOpen.TreeDisconnect(treeIdForReOpen, (header, response) => { });
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "TreeDisconnect should not SUCCESS");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            }
            else if (!encryptionInInitialOpen && encryptionInReOpen)
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Create durable handle request should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Close file.");
                status = clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen);

                BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Disconnect from the share.");
                status = clientForReOpen.TreeDisconnect(treeIdForReOpen);
            }

            BaseTestSite.Log.Add(TestTools.LogEntryKind.TestStep, "ReOpen: Log off.");
            status = clientForReOpen.LogOff();
        }
        private void AppInstanceIdTest(bool sameAppInstanceId, bool containCreateDurableContext)
        {
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            #region Client 1 Connect to Server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the first client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            clientForInitialOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientForInitialOpen.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress);
            clientForInitialOpen.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            clientForInitialOpen.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeIdForInitialOpen;
            clientForInitialOpen.TreeConnect(sharePath, out treeIdForInitialOpen);

            Guid   appInstanceId = Guid.NewGuid();
            FILEID fileIdForInitialOpen;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The first client sends CREATE request for exclusive open with SMB2_CREATE_APP_INSTANCE_ID create context.");
            Smb2CreateContextResponse[] serverCreateContexts;
            Smb2CreateContextRequest[]  createContextsRequestForInitialOpen = null;
            if (containCreateDurableContext)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is also included in the CREATE request.");
                createContextsRequestForInitialOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleRequestV2
                    {
                        CreateGuid = Guid.NewGuid()
                    },
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is not included in the CREATE request.");
                createContextsRequestForInitialOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
            }

            clientForInitialOpen.Create(
                treeIdForInitialOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForInitialOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                createContextsRequestForInitialOpen,
                shareAccess: ShareAccess_Values.NONE);
            #endregion

            #region Client 2 Connect to Server

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the second client by sending the following requests: NEGOTIATE; SESSION-SETUP; TREE_CONNECT");
            clientForReOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientForReOpen.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic2IPAddress);
            clientForReOpen.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            clientForReOpen.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeIdForReOpen;
            clientForReOpen.TreeConnect(sharePath, out treeIdForReOpen);

            FILEID fileIdForReOpen;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "The second client sends CREATE request for exclusive open with the {0} SMB2_CREATE_APP_INSTANCE_ID of the first client.", sameAppInstanceId ? "same" : "different");
            Smb2CreateContextRequest[] createContextsRequestForReOpen = null;
            if (containCreateDurableContext)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is also included in the CREATE request.");
                createContextsRequestForReOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateDurableHandleRequestV2
                    {
                        CreateGuid = Guid.NewGuid()
                    },
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = sameAppInstanceId ? appInstanceId : Guid.NewGuid()
                    }
                };
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context is not included in the CREATE request.");
                createContextsRequestForReOpen = new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = sameAppInstanceId ? appInstanceId : Guid.NewGuid()
                    }
                };
            }

            clientForReOpen.Create(
                treeIdForReOpen,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdForReOpen,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                createContextsRequestForReOpen,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                if (sameAppInstanceId)
                {
                    BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "The second client should create the open successfully.");
                }
                else
                {
                    BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, header.Status, "The second client should not create the open successfully.");
                }
            });

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The first client sends another WRITE request.");

            if (sameAppInstanceId)
            {
                clientForInitialOpen.Write(treeIdForInitialOpen, fileIdForInitialOpen, content,
                                           checker: (header, response) =>
                {
                    BaseTestSite.Assert.AreNotEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "The initial open is closed. Write should not succeed. Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status));
                    BaseTestSite.CaptureRequirementIfAreEqual(
                        Smb2Status.STATUS_FILE_CLOSED,
                        header.Status,
                        RequirementCategory.STATUS_FILE_CLOSED.Id,
                        RequirementCategory.STATUS_FILE_CLOSED.Description);
                });

                // The first open is closed, no need to do clean up job.
                // Clean up the second client.
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF; DISCONNECT");
                clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen);
                clientForReOpen.TreeDisconnect(treeIdForReOpen);
                clientForReOpen.LogOff();
                clientForReOpen.Disconnect();
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The initial open is not closed. Write should succeed.");
                clientForInitialOpen.Write(treeIdForInitialOpen, fileIdForInitialOpen, content);

                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the first client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
                clientForInitialOpen.Close(treeIdForInitialOpen, fileIdForInitialOpen);
                clientForInitialOpen.TreeDisconnect(treeIdForInitialOpen);
                clientForInitialOpen.LogOff();

                // The second client doesn't create the open succesfully, so no need to close the open.
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the second client by sending the following requests: TREE_DISCONNECT; LOG_OFF; DISCONNECT");
                clientForReOpen.TreeDisconnect(treeIdForReOpen);
                clientForReOpen.LogOff();
                clientForReOpen.Disconnect();
            }

            #endregion
        }
        public void DurableHandleV2_Reconnect_WithDifferentDurableOwner()
        {
            /// 1. Client requests a durable handle V2 with LeaseV1 context
            /// 2. Client disconnects
            /// 3. Client reconnects the durable handle V2 with a different durable owner, and expects that server will return STATUS_ACCESS_DENIED.

            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2, CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE);
            #endregion

            string content    = Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb);
            Guid   clientGuid = Guid.NewGuid();
            durableHandleUncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
            fileName = "DurableHandleV2_Reconnect_WithDifferentDurableOwner" + Guid.NewGuid() + ".txt";

            #region client connect to server
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client connects to server and opens file with a durable handle");

            uint treeIdBeforeDisconnection;
            Connect(DialectRevision.Smb30, clientBeforeDisconnection, clientGuid, testConfig.AccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdBeforeDisconnection, null);

            Guid                        createGuid = Guid.NewGuid();
            Guid                        leaseKey   = Guid.NewGuid();
            LeaseStateValues            leaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING | LeaseStateValues.SMB2_LEASE_WRITE_CACHING;
            FILEID                      fileIdBeforeDisconnection;
            Smb2CreateContextResponse[] serverCreateContexts = null;
            status = clientBeforeDisconnection.Create(
                treeIdBeforeDisconnection,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdBeforeDisconnection,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = createGuid,
                },
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = leaseKey,
                    LeaseState = leaseState,
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should be successful, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                CheckCreateContextResponses(serverCreateContexts, new DefaultDurableHandleV2ResponseChecker(BaseTestSite, 0, uint.MaxValue));
            });

            status = clientBeforeDisconnection.Write(treeIdBeforeDisconnection, fileIdBeforeDisconnection, content);
            #endregion

            clientBeforeDisconnection.Disconnect();

            #region client reconnect to server
            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client opens the same file and reconnects the durable handle");

            uint treeIdAfterDisconnection;
            Connect(DialectRevision.Smb30, clientAfterDisconnection, clientGuid, testConfig.NonAdminAccountCredential, ConnectShareType.BasicShareWithoutAssert, out treeIdAfterDisconnection, clientBeforeDisconnection);

            FILEID fileIdAfterDisconnection;
            clientAfterDisconnection.Create(
                treeIdAfterDisconnection,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdAfterDisconnection,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleReconnectV2
                {
                    CreateGuid = createGuid,
                    FileId     = new FILEID {
                        Persistent = fileIdBeforeDisconnection.Persistent
                    }
                },
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = leaseKey,
                    LeaseState = leaseState,
                }
            },
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should not be successful if the DurableOwner is different, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_ACCESS_DENIED,
                    header.Status,
                    RequirementCategory.STATUS_ACCESS_DENIED.Id,
                    RequirementCategory.STATUS_ACCESS_DENIED.Description);
            });

            #endregion

            clientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection);
            clientAfterDisconnection.LogOff();
            clientAfterDisconnection.Disconnect();
        }
 public void CaptureRequirementExpectedValueReclaimed()
 {
     BaseTestSite.CaptureRequirementIfAreEqual(2, 1, 25, "The two values should be equal.");
 }