public void NegotiateRequest(ModelDialectRevision maxSmbVersionClientSupported, SigningFlagType signingFlagType, SigningEnabledType signingEnabledType, SigningRequiredType signingRequiredType) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); Packet_Header_Flags_Values headerFlags = (signingFlagType == SigningFlagType.SignedFlagSet) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE; SigningEnabledType resSigningEnabledType = SigningEnabledType.SigningEnabledNotSet; SigningRequiredType resSigningRequiredType = SigningRequiredType.SigningRequiredNotSet; uint status = testClient.Negotiate( headerFlags, dialects, GetNegotiateSecurityMode(signingEnabledType, signingRequiredType), checker: (header, response) => { resSigningEnabledType = response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED) ? SigningEnabledType.SigningEnabledSet : SigningEnabledType.SigningEnabledNotSet; resSigningRequiredType = response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED) ? SigningRequiredType.SigningRequiredSet : SigningRequiredType.SigningRequiredNotSet; }); NegotiateResponse((ModelSmb2Status)status, resSigningEnabledType, resSigningRequiredType, signingConfig); }
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> /// Initialize the two clients. And register Oplock/Lease break notification event. /// </summary> public void Preparation() { oplockClient = InitializeClient(testConfig.SutIPAddress, out treeIdOplock); oplockClient.Smb2Client.OplockBreakNotificationReceived += new Action<Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived); leaseClient = InitializeClient(testConfig.SutIPAddress, out treeIdLease); leaseClient.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived); fileName = "MixedOplockLeaseModel_" + Guid.NewGuid() + ".txt"; }
public override void Reset() { base.Reset(); if (testClient != null) { testClient.Disconnect(); testClient = null; } }
public override void Reset() { base.Reset(); if (testClient != null) { testClient.Disconnect(); testClient = null; } }
protected override void TestInitialize() { base.TestInitialize(); clientGuid = Guid.NewGuid(); mainChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); ReadIpAddressesFromTestConfig(out clientIps, out serverIps); }
protected override void TestInitialize() { base.TestInitialize(); fileName = "OpLock" + Guid.NewGuid() + ".txt"; sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); client2 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); OpLockNotificationReceived = new ManualResetEvent(false); }
protected bool TryReadFile(Smb2FunctionalClient client, AccountCredential user, string sharePath, string fileName) { bool accessSucceed = true; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message."); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false); uint treeId; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath); client.TreeConnect(sharePath, out treeId); FILEID fileId; Smb2CreateContextResponse[] createContexResponse; BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request."); uint status = client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContexResponse, accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_READ_ATTRIBUTES, createDisposition: CreateDisposition_Values.FILE_OPEN, checker: (header, response) => { if (header.Status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Successfully opened the file with Access Mask: FILE_READ_DATA | FILE_READ_ATTRIBUTES."); accessSucceed = true; } else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Fail to open the file with Access Mask: FILE_READ_DATA | FILE_READ_ATTRIBUTES."); accessSucceed = false; } else { BaseTestSite.Assert.Fail("Unexpected error code in CREATE response: {0}", Smb2Status.GetStatusCode(header.Status)); } }); if (status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF."); client.Close(treeId, fileId); } client.TreeDisconnect(treeId); client.LogOff(); return(accessSucceed); }
protected override void TestInitialize() { base.TestInitialize(); #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb30); TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_OFFLOAD_READ, CtlCode_Values.FSCTL_OFFLOAD_WRITE); #endregion client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); }
/// <summary> /// Attempt to trigger LeaseBreakNotification from a separate client /// </summary> /// <param name="client">Client to trigger LeaseBreakNotification</param> /// <param name="requestDialect">Negotiate dialects</param> /// <param name="isDirectory">True value indicating to open a directory, false for a file</param> /// <param name="requestedLeaseState">LeaseState when open the directory or file</param> /// <param name="accessMask">AccessMask when open the directory or file</param> private void TriggerBreakFromClient( Smb2FunctionalClient client, DialectRevision[] requestDialect, bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Trigger a lease break notification by accessing same file/directory from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask); #region Negotiate status = client.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 = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; status = client.Create( treeId, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState } }, accessMask: accessMask); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish triggering lease break notification"); }
protected override void TestInitialize() { base.TestInitialize(); sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = GetTestFileName(sharePath); clientBeforeDisconnection = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientAfterDisconnection = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientBeforeDisconnection.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); clientAfterDisconnection.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); }
public void ReEstablishResilientOpenRequest(ModelUser user) { reconnectClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); AccountCredential account = testConfig.AccountCredential; if (user == ModelUser.DefaultUser) { account = testConfig.AccountCredential; } else if (user == ModelUser.DiffUser) { account = testConfig.NonAdminAccountCredential; } // Connect to Share ConnectToShare( Site, testConfig, reconnectClient, new DialectRevision[] { dialect }, clientGuid, account, out dialect, out treeId); // Reconnect to the Open Smb2CreateContextResponse[] createContextResponse; testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT); uint status = reconnectClient.Create( treeId, fileName, CreateOptions_Values.NONE, out fileId, out createContextResponse, createContexts: new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleReconnect() { Data = fileId } }, checker: (header, response) => { // do nothing, skip the exception } ); ReEstablishResilientOpenResponse((ModelSmb2Status)status); }
public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType) { // Set checkEncrypt to false to not check if the response from the server is actually encrypted. testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site, checkEncrypt: false); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); testClient.Smb2Client.Disconnected += new Action(OnServerDisconnected); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); //Set capabilities according to isClientSupportsEncryption Capabilities_Values commonCapability = 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; Capabilities_Values encryptionCapability = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? (commonCapability | Capabilities_Values.GLOBAL_CAP_ENCRYPTION) : commonCapability; uint status; DialectRevision selectedDialect; NEGOTIATE_Response?negotiateResponse = null; status = testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, capabilityValue: encryptionCapability, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }, ifHandleRejectUnencryptedAccessSeparately: true, ifAddGLOBAL_CAP_ENCRYPTION: false, addDefaultEncryption: true ); selectedDialect = negotiateResponse.Value.DialectRevision; if ((selectedDialect == DialectRevision.Smb30 || selectedDialect == DialectRevision.Smb302) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) { /// TD section 3.3.5.4 /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect is "3.0" or "3.0.2", the server supports encryption, /// and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request Site.Assert.IsTrue( negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION), "SMB2_GLOBAL_CAP_ENCRYPTION should be set in the negotiate response."); } else { Site.Assert.IsFalse( negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION), "SMB2_GLOBAL_CAP_ENCRYPTION should not be set in the negotiate response."); } }
protected override void TestInitialize() { base.TestInitialize(); clientGuid = Guid.NewGuid(); mainChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); fileName = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid()); ReadIpAddressesFromTestConfig(out clientIps, out serverIps); }
private void ConnectToShare(Smb2FunctionalClient client, Guid clientGuid, string uncShareName, out uint treeId) { client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.FileServerNameContainingSharedVHD, TestConfig.FileServerIPContainingSharedVHD); client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid); client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false); client.TreeConnect(Smb2Utility.GetUncPath(TestConfig.FileServerNameContainingSharedVHD, TestConfig.ShareContainingSharedVHD), out treeId); }
protected override void TestInitialize() { base.TestInitialize(); smb2client = null; //The SMB2 server MUST reserve -1 for invalid FileId fileId = FILEID.Invalid; // The SMB2 server MUST reserve -1 for invalid TreeId. treeId = 0xFFFF; }
private void OpenFileAndResilientRequest( Smb2FunctionalClient client, Guid clientGuid, string fileName, uint timeoutInMilliSeconds, out FILEID fileId) { uint treeId; // connect to share ConnectToShare( client, clientGuid, out treeId); BaseTestSite.Log.Add( LogEntryKind.Debug, "Connect to share '{0}' on server '{1}'", testConfig.BasicFileShare, testConfig.SutComputerName); // open file Smb2CreateContextResponse[] createContextResponse; client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse ); BaseTestSite.Log.Add( LogEntryKind.Debug, "Create Open with file name '{0}'", fileName); // resiliency request Packet_Header ioCtlHeader; IOCTL_Response ioCtlResponse; byte[] inputInResponse; byte[] outputInResponse; client.ResiliencyRequest( treeId, fileId, timeoutInMilliSeconds, (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)), out ioCtlHeader, out ioCtlResponse, out inputInResponse, out outputInResponse ); BaseTestSite.Log.Add( LogEntryKind.Debug, "Resiliency request with timeout {0} milliseconds", timeoutInMilliSeconds); }
protected override void TestInitialize() { base.TestInitialize(); clientGuid = Guid.NewGuid(); clientBeforeFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientAfterFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); accessIpList = Dns.GetHostAddresses(TestConfig.ClusteredFileServerName); uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare); contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); fileName = GetTestFileName(uncSharePath); }
protected override void TestInitialize() { base.TestInitialize(); clientGuid = Guid.NewGuid(); clientBeforeFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientAfterFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); accessIpList = Dns.GetHostEntry(TestConfig.ClusteredFileServerName).AddressList; uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare); contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); fileName = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid()); }
protected override void TestInitialize() { base.TestInitialize(); clientForInitialOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientForReOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); appInstanceId = Guid.NewGuid(); contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); fileName = GetTestFileName(uncSharePath); }
private void Compound_RelatedRequests(string fileName, bool isEncrypted) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize the test client."); Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to the SMB2 basic share by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT."); ConnectToShare(client, out treeId); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Create packet."); Smb2CreateRequestPacket createPacket = ConstructCreatePacket(client.SessionId, treeId, fileName); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Write packet, flag FLAGS_RELATED_OPERATIONS is set."); Smb2WriteRequestPacket writePacket = ConstructRelatedWritePacket(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Close packet, flag FLAGS_RELATED_OPERATIONS is set."); Smb2CloseRequestPacket closePacket = ConstructRelatedClosePacket(); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send {0}compounded Create, Write and Close requests to SUT.", isEncrypted ? "encrypted " : ""); List <Smb2SinglePacket> requestPackets = new List <Smb2SinglePacket>(); requestPackets.Add(createPacket); requestPackets.Add(writePacket); requestPackets.Add(closePacket); if (isEncrypted) { // Enable encryption client.EnableSessionSigningAndEncryption(enableSigning: testConfig.SendSignedRequest, enableEncryption: true); } List <Smb2SinglePacket> responsePackets = client.SendAndReceiveCompoundPacket(requestPackets); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify responses to the compounded request."); foreach (var responsePacket in responsePackets) { if (TestConfig.Platform == Platform.WindowsServer2016 && responsePacket.Header.Status != Smb2Status.STATUS_SUCCESS) { } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, responsePacket.Header.Status, "{0} should succeed, actual status is {1}", responsePacket.Header.Command, Smb2Status.GetStatusCode(responsePacket.Header.Status)); } } client.TreeDisconnect(treeId); client.LogOff(); client.Disconnect(); }
private void OpenFile(Smb2FunctionalClient smbClient, Guid clientGuid, string fileName, out uint treeId, out FILEID fileId) { ConnectToShare(smbClient, clientGuid, out treeId); BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to share '{0}' on server '{1}'", TestConfig.ShareName, TestConfig.ShareServerName); Smb2CreateContextResponse[] createContextResponse; smbClient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out createContextResponse); BaseTestSite.Log.Add(LogEntryKind.Debug, "Create Open with file name '{0}'", fileName); }
private void ConnectToShare( Smb2FunctionalClient client, Guid clientGuid, out uint treeId) { client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.CAShareServerName, TestConfig.CAShareServerIP); // Negotiate client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid: clientGuid, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "Negotiate should be successfully"); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response); } ); // SMB2 SESSION SETUP client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.CAShareServerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); // SMB2 Tree Connect client.TreeConnect( Smb2Utility.GetUncPath(TestConfig.CAShareServerName, TestConfig.CAShareName), out treeId, checker: (header, response) => { BaseTestSite.Assert.AreEqual <NtStatus>( NtStatus.STATUS_SUCCESS, (NtStatus)header.Status, "TreeConnect should be successfully"); // Check IsCA BaseTestSite.Assert.IsTrue( response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY), "Share should support capabilities of SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY "); }); }
public void InvalidCreateRequestStructureSize() { uint status; client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, this.Site); 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 treeId; status = client1.TreeConnect(uncSharePath, out treeId); string fileName = "BVT_SMB2Basic_InvalidCreateRequestStructureSize" + Guid.NewGuid(); FILEID fileID; Smb2CreateContextResponse[] serverCreateContexts; // [MS-SMB2] Section 2.2.13 SMB2 CREATE Request // StructureSize (2 bytes): The client MUST set this field to 57, indicating the size of the request structure, not including the header. // The client MUST set it to this value regardless of how long Buffer[] actually is in the request being sent. // So set the StuctureSize to 58 here to make "the size of the SMB2 CREATE Request is less than specified in the StructureSize field". client1.BeforeSendingPacket(ReplacePacketByStructureSize); status = client1.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileID, out serverCreateContexts, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_INVALID_PARAMETER, status, "The size of the SMB2 CREATE Request (excluding the SMB2 header) is less than specified in the StructureSize field, then the request MUST be failed with STATUS_ INVALID_PARAMETER"); client1.TreeDisconnect(treeId); client1.LogOff(); }
/// <summary> /// Negotiate, SessionSetup and TreeConnect /// </summary> public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode) { #region Connect to server testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); #endregion // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0. Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid(); #region negotiate testClient.Negotiate( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), securityMode, (Capabilities_Values)capabilities, clientGuid, (header, response) => { Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); #endregion #region session setup testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken, (SESSION_SETUP_Request_SecurityMode_Values)securityMode); #endregion #region treeconnect testClient.TreeConnect( Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); #endregion Connection_Dialect = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision); Connection_ClientCapabilities = (Capabilities_Values)capabilities; if (dialect >= ModelDialectRevision.Smb30) // GLOBAL_CAP_ENCRYPTION will be added in Functional client when dialect >= SMB30 { Connection_ClientCapabilities |= Capabilities_Values.GLOBAL_CAP_ENCRYPTION; } Connection_ClientSecurityMode = securityMode; Connection_ClientGuid = clientGuid; }
public void ReadConfig(out ResilientHandleServerConfig config) { resilientHandleConfig = new ResilientHandleServerConfig { MaxSmbVersionSupported = ModelUtility.GetModelDialectRevision(testConfig.MaxSmbVersionSupported), IsIoCtlCodeResiliencySupported = testConfig.IsIoCtlCodeSupported(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY), Platform = testConfig.Platform >= Platform.WindowsServer2016 ? Platform.WindowsServer2016 : testConfig.Platform }; config = resilientHandleConfig; prepareOpenClient = null; Site.Log.Add(LogEntryKind.Debug, resilientHandleConfig.ToString()); // Resilient only applies only to servers that implement the SMB 2.1 or the SMB 3.x dialect family. testConfig.CheckDialect(DialectRevision.Smb21); }
/// <summary> /// The two client connects to the two IP addresses of scaleout file server /// Negotiate, SessionSetup, TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServerOverTCP(ip); client.Negotiate( Smb2Utility.GetDialects(DialectRevision.Smb21), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.ScaleOutFileServerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId); return client; }
private void OplockBreakAcknowledgment(Smb2FunctionalClient client) { OPLOCK_BREAK_Acknowledgment_OplockLevel_Values acknowledgementOplockLevel = default(OPLOCK_BREAK_Acknowledgment_OplockLevel_Values); //OpLockBreakNotifyReceived.OplockLevel can only be one of the next two values, otherwise AssertionError will be got in OnOpLockBreakNotificationReceived if (OpLockBreakNotifyReceived.OplockLevel == OPLOCK_BREAK_Notification_Packet_OplockLevel_Values.OPLOCK_LEVEL_II) { acknowledgementOplockLevel = OPLOCK_BREAK_Acknowledgment_OplockLevel_Values.OPLOCK_LEVEL_II; } else if (OpLockBreakNotifyReceived.OplockLevel == OPLOCK_BREAK_Notification_Packet_OplockLevel_Values.OPLOCK_LEVEL_NONE) { acknowledgementOplockLevel = OPLOCK_BREAK_Acknowledgment_OplockLevel_Values.OPLOCK_LEVEL_NONE; } client.OplockAcknowledgement(treeId, fileId, acknowledgementOplockLevel); }
public void Send_Multiple_Requests() { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize the test client."); Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); uint treeId; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to the SMB2 basic share by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT."); ConnectToShare(client, out treeId); List <Smb2SinglePacket> requestPackets = new List <Smb2SinglePacket>(); for (int i = 1; i <= 10; i++) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct the {0} Create packet.", i); string fileName = string.Format("FileNew_{0}_{1}.txt", i, Guid.NewGuid()); Task <Smb2CreateRequestPacket> t1 = Task <Smb2CreateRequestPacket> .Factory.StartNew(() => ConstructCreatePacket(client.SessionId, treeId, fileName)); requestPackets.Add(t1.Result); } client.EnableSessionSigningAndEncryption(enableSigning: testConfig.SendSignedRequest, enableEncryption: false); Task <List <ulong> > sendRequest = Task <List <ulong> > .Factory.StartNew(() => client.SendCompoundPacket(requestPackets)); List <Smb2SinglePacket> responsePackets = client.ReceiveCompoundPacket(sendRequest.Result); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify responses to the compounded request."); foreach (var responsePacket in responsePackets) { if (TestConfig.Platform == Platform.WindowsServer2016 && responsePacket.Header.Status != Smb2Status.STATUS_SUCCESS) { } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, responsePacket.Header.Status, "{0} should succeed, actual status is {1}", responsePacket.Header.Command, Smb2Status.GetStatusCode(responsePacket.Header.Status)); } } client.TreeDisconnect(treeId); client.LogOff(); client.Disconnect(); }
private void Initialize() { smb2ClientMainChannel = null; smb2ClientAlternativeChannel = null; prepared = false; setIntegrityInfo.ChecksumAlgorithm = FSCTL_SET_INTEGRITY_INFO_INPUT_CHECKSUMALGORITHM.CHECKSUM_TYPE_CRC64; setIntegrityInfo.Flags = FSCTL_SET_INTEGRITY_INFO_INPUT_FLAGS.FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF; setIntegrityInfo.Reserved = FSCTL_SET_INTEGRITY_INFO_INPUT_RESERVED.V1; endOfFileInformation.EndOfFile = 2048; fileNameMainChannel = Guid.NewGuid().ToString(); leaseKeyMainChannel = Guid.NewGuid(); clientGuidMainChannel = Guid.NewGuid(); createGuidMainChannel = Guid.NewGuid(); clientCapabilitiesMainChannel = Capabilities_Values.NONE; }
public override void Reset() { try { testClient.LogOff(); testClient.Disconnect(); } catch { } finally { testClient = null; } base.Reset(); }
protected override void TestInitialize() { base.TestInitialize(); testConfig = new SqosTestConfig(BaseTestSite); BaseTestSite.DefaultProtocolDocShortName = "MS-SQOS"; BaseTestSite.Log.Add(LogEntryKind.Debug, "SecurityPackage for authentication: " + TestConfig.DefaultSecurityPackage); client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); treeId = 0; fileId = FILEID.Zero; #region Check Applicability TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_STORAGE_QOS_CONTROL); #endregion }
/// <summary> /// Initialize the test client by /// ConnectToServer, Negotiate, SessionSetup and TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip); client.Negotiate( // Model cases only test Dialect lower than 3.11 Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); return(client); }
public override void Reset() { if (smb2ClientMainChannel != null) { smb2ClientMainChannel.Disconnect(); smb2ClientMainChannel = null; } if (smb2ClientAlternativeChannel != null) { smb2ClientAlternativeChannel.Disconnect(); smb2ClientAlternativeChannel = null; } Initialize(); base.Reset(); }
/// <summary> /// Negotiate, SessionSetup and TreeConnect /// </summary> public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode) { #region Connect to server testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); #endregion // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0. Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid(); #region negotiate testClient.Negotiate( Packet_Header_Flags_Values.NONE, Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)), securityMode, (Capabilities_Values)capabilities, clientGuid, (header, response) => { Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); #endregion #region session setup testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken, (SESSION_SETUP_Request_SecurityMode_Values)securityMode); #endregion #region treeconnect testClient.TreeConnect( Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); #endregion Connection_Dialect = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision); Connection_ClientCapabilities = (Capabilities_Values)capabilities; Connection_ClientSecurityMode = securityMode; Connection_ClientGuid = clientGuid; }
/// <summary> /// Acknowledge LeaseBreakNotification received from server /// </summary> /// <param name="client">Client to send the acknowledgement</param> /// <param name="treeId">TreeId associated to send the acknowledgement</param> /// <param name="leaseBreakNotify">LeaseBreakNotification received from server</param> protected virtual void AcknowledgeLeaseBreak(Smb2FunctionalClient client, uint treeId, LEASE_BREAK_Notification_Packet leaseBreakNotify) { 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"); // Will add verification for response after SDK change uint status = client.LeaseBreakAcknowledgment(treeId, leaseBreakNotify.LeaseKey, leaseBreakNotify.NewLeaseState); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "LeaseBreakAcknowledgement should succeed, actual status is {0}", Smb2Status.GetStatusCode(status)); } else { BaseTestSite.Log.Add( LogEntryKind.Debug, "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY"); } }
public void SetupConnection(ModelSessionSecurityContext securityContext) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); // SMB2 Negotiate // Model cases only test Dialect lower than 3.11 DialectRevision[] dialects = Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302); testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled); // SMB2 SESSION SETUP AccountCredential account = null; switch (securityContext) { case ModelSessionSecurityContext.Admin: account = testConfig.AccountCredential; break; case ModelSessionSecurityContext.NonAdmin: account = testConfig.NonAdminAccountCredential; break; default: throw new InvalidOperationException(securityContext + " is not supported."); } testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, account, testConfig.UseServerGssToken); // reset TreeId this.treeId = 0; }
private void ClientTearDown(Smb2FunctionalClient client, uint treeId, FILEID fileId) { status = client.Close(treeId, fileId); status = client.TreeDisconnect(treeId); status = client.LogOff(); }
public void DirectoryLeasing_BreakReadCachingByChildRenamed() { #region Prepare test directory and test file BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory and test file."); uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare); fileName = "DirectoryLeasing_BreakReadCachingByChildRenamed_" + Guid.NewGuid().ToString() + ".txt"; sutProtocolController.CreateFile(uncSharePath + "\\" + testDirectory, fileName, string.Empty); #endregion #region Initialize test clients BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients."); Guid clientGuidRequestingLease = Guid.NewGuid(); Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); Guid clientGuidTriggeringBreak = Guid.NewGuid(); Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived); clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #endregion #region CREATE an open to request lease uint treeIdClientRequestingLease; FILEID fileIdClientRequestingLease; LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING; // Add expected NewLeaseState expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_NONE; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory); status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, testDirectory, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status)); #endregion // Create a timer that signals the delegate to invoke CheckBreakNotification Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite); base.clientToAckLeaseBreak = clientRequestingLease; #region Attempt to trigger lease break by renaming child item uint treeIdClientTriggeringBreak; FILEID fileIdClientTriggeringBreak; AccessMask accessMaskTrigger = AccessMask.DELETE; string targeName = testDirectory + "\\" + fileName; BaseTestSite.Log.Add(LogEntryKind.TestStep, "A separate client attempts to access directory {0} to trigger lease break by renaming it", testDirectory); status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, targeName, false, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed, actual status is {1}", targeName, Smb2Status.GetStatusCode(status)); #region SetFileAttributes with FileRenameInformation to rename child item BaseTestSite.Log.Add(LogEntryKind.TestStep, "SetFileAttributes with FileRenameInformation to rename child item."); string newName = "Renamed_" + fileName; FileRenameInformation fileRenameInfo; fileRenameInfo.ReplaceIfExists = TypeMarshal.ToBytes(false)[0]; fileRenameInfo.Reserved = new byte[7]; fileRenameInfo.RootDirectory = FileRenameInformation_RootDirectory_Values.V1; fileRenameInfo.FileName = Encoding.Unicode.GetBytes(newName); fileRenameInfo.FileNameLength = (uint)fileRenameInfo.FileName.Length; byte[] inputBuffer; inputBuffer = TypeMarshal.ToBytes<FileRenameInformation>(fileRenameInfo); status = clientTriggeringBreak.SetFileAttributes( treeIdClientTriggeringBreak, (byte)FileInformationClasses.FileRenameInformation, fileIdClientTriggeringBreak, inputBuffer, (header, response) => { }); #endregion ClientTearDown(clientTriggeringBreak, treeIdClientTriggeringBreak, fileIdClientTriggeringBreak); #endregion }
/// <summary> /// Initialize the test client by /// ConnectToServer, Negotiate, SessionSetup and TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip); client.Negotiate( // Model cases only test Dialect lower than 3.11 Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId); return client; }
/// <summary> /// Reset all member variables before running next test case /// </summary> public override void Reset() { if (oplockClient != null) { oplockClient.Disconnect(); oplockClient = null; } if (leaseClient != null) { leaseClient.Disconnect(); leaseClient = null; } fileName = null; breakType = ModelBreakType.NoBreak; treeIdOplock = 0; treeIdLease = 0; alreadyRequested = false; grantedLeaseState = LeaseStateValues.SMB2_LEASE_NONE; grantedOplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE; base.Reset(); }
/// <summary> /// 1. Prepare the test file /// The two clients connects to the two Nodes of the scaleout file server, including: Negotiate, SessionSetup, TreeConnect /// </summary> public void Preparation() { PrepareTestFile(); firstClient = InitializeClient(testConfig.ScaleOutFileServerIP1, out treeId1); firstClient.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived); secondClient = InitializeClient(testConfig.ScaleOutFileServerIP2, out treeId2); }
protected override void TestInitialize() { base.TestInitialize(); testConfig = new SqosTestConfig(BaseTestSite); BaseTestSite.DefaultProtocolDocShortName = "MS-SQOS"; BaseTestSite.Log.Add(LogEntryKind.Debug, "SecurityPackage for authentication: " + TestConfig.DefaultSecurityPackage); client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); treeId = 0; fileId = FILEID.Zero; #region Check Applicability TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_STORAGE_QOS_CONTROL); #endregion }
/// <summary> /// Create operation for Open operation /// </summary> private uint OpenCreate( Smb2FunctionalClient client, uint treeIdAfterDisconnection, string fileName, out FILEID fileIdAfterDisconnection, out Smb2CreateContextResponse[] serverCreateContexts, RequestedOplockLevel_Values requestedOplocklevel, Smb2CreateContextRequest[] openContext) { return client.Create( treeIdAfterDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdAfterDisconnection, out serverCreateContexts, requestedOplocklevel, openContext, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { }); }
private void FileServerFailoverTest(string server, FileServerType fsType, bool reconnectWithoutFailover = false) { int ret = 0; uint callId = 0; IPAddress currentAccessIpAddr = null; WITNESS_INTERFACE_INFO registerInterface = new WITNESS_INTERFACE_INFO(); WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST(); currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server); BaseTestSite.Log.Add(LogEntryKind.Debug, "Get current file server IP: {0}.", currentAccessIpAddr); #region Register SWN witness if (witnessType == WitnessType.SwnWitness) { if (TestConfig.IsWindowsPlatform && fsType == FileServerType.ScaleOutFileServer) { // Windows Server: when stopping a non-owner node of ScaleOutFS, no notication will be sent by SMB witness. // So get one IP of the owner node of ScaleOutFS to access. string resourceOwnerNode = sutController.GetClusterResourceOwner(server); IPAddress[] ownerIpList = Dns.GetHostEntry(resourceOwnerNode).AddressList; foreach (var ip in ownerIpList) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Owner IP: {0}", ip); } if (!ownerIpList.Contains(currentAccessIpAddr)) { currentAccessIpAddr = null; IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList; foreach (var ip in accessIpList) { if (ownerIpList.Contains(ip)) { currentAccessIpAddr = ip; break; } } BaseTestSite.Assert.IsNotNull(currentAccessIpAddr, "IP should not be null."); BaseTestSite.Log.Add(LogEntryKind.Debug, "Get the owner IP {0} as file server IP.", currentAccessIpAddr); } DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr, TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage, TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, resourceOwnerNode), TestConfig.FailoverTimeout, "Retry BindServer until succeed within timeout span"); } else { DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr, TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage, TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout, "Retry BindServer until succeed within timeout span"); } DoUntilSucceed(() => { ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList); BaseTestSite.Assert.AreEqual<SwnErrorCode>( SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret); return SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform); }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span."); SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface); DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness, (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6), TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage, TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, registerInterface.InterfaceGroupName), TestConfig.FailoverTimeout, "Retry BindServer until succeed within timeout span"); string clientName = Guid.NewGuid().ToString(); BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:"); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server)); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIpAddr.ToString()); BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName); ret = swnClientForWitness.WitnessrRegister(SwnVersion.SWN_VERSION_1, SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server), currentAccessIpAddr.ToString(), clientName, out pContext); BaseTestSite.Assert.AreEqual<SwnErrorCode>( SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret); BaseTestSite.Assert.IsNotNull( pContext, "Expect pContext is not null."); callId = swnClientForWitness.WitnessrAsyncNotify(pContext); BaseTestSite.Assert.AreNotEqual<uint>( 0, callId, "WitnessrAsyncNotify returns callId = {0}", callId); } #endregion #region Create a file and write content string uncSharePath = Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare); string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); string testDirectory = CreateTestDirectory(uncSharePath); string file = Path.Combine(testDirectory, Guid.NewGuid().ToString()); Guid clientGuid = Guid.NewGuid(); Guid createGuid = Guid.NewGuid(); DoUntilSucceed(() => WriteContentBeforeFailover(fsType, server, currentAccessIpAddr, uncSharePath, file, content, clientGuid, createGuid), TestConfig.FailoverTimeout, "Before failover, retry Write content until succeed within timeout span."); #endregion #region Disable accessed node if (TestConfig.IsWindowsPlatform) { AssignCurrentAccessNode(server, fsType, currentAccessIpAddr); } if (!reconnectWithoutFailover) { BaseTestSite.Log.Add( LogEntryKind.TestStep, "Disable owner node for general file server or the node currently provides the access for scale-out file server."); FailoverServer(currentAccessIpAddr, server, fsType); } #endregion #region Wait for available server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Wait for available server."); if (witnessType == WitnessType.None) { if (fsType == FileServerType.GeneralFileServer) { currentAccessIpAddr = null; IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList; DoUntilSucceed(() => { foreach (IPAddress ipAddress in accessIpList) { Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite); try { pingClient.ConnectToServerOverTCP(ipAddress); pingClient.Disconnect(); pingClient = null; currentAccessIpAddr = ipAddress; return true; } catch { } } return false; }, TestConfig.FailoverTimeout, "Retry to ping to server until succeed within timeout span"); } else { currentAccessIpAddr = null; IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList; foreach (IPAddress ipAddress in accessIpList) { if (TestConfig.IsWindowsPlatform) { // When setting failover mode to StopNodeService for Windows, SMB2 servers on two nodes can still be accessed by the client. // So the client needs to get the new node to access it after failover by comparing host name. if (string.Compare(currentAccessNode, Dns.GetHostEntry(ipAddress).HostName, true) == 0) { continue; } } Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite); try { pingClient.ConnectToServerOverTCP(ipAddress); pingClient.Disconnect(); pingClient = null; currentAccessIpAddr = ipAddress; break; } catch { } } } } else if (witnessType == WitnessType.SwnWitness) { // Verifying for notification RESP_ASYNC_NOTIFY respNotify; do { // Wait the notification ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify); BaseTestSite.Assert.AreEqual<SwnErrorCode>( SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret); SWNTestUtility.PrintNotification(respNotify); RESOURCE_CHANGE[] resourceChangeList; SwnUtility.ParseResourceChange(respNotify, out resourceChangeList); BaseTestSite.Assert.AreEqual<uint>(0x00000001, respNotify.NumberOfMessages, "Expect NumberOfMessages is set to 1."); if (resourceChangeList[0].ChangeType == (uint)SwnResourceChangeType.RESOURCE_STATE_AVAILABLE) { // Verify RESP_ASYNC_NOTIFY, the resource is available SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_AVAILABLE); break; } // Verify RESP_ASYNC_NOTIFY, the resource is unavailable SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_UNAVAILABLE); callId = swnClientForWitness.WitnessrAsyncNotify(pContext); BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId); } while (true); ret = swnClientForWitness.WitnessrUnRegister(pContext); BaseTestSite.Assert.AreEqual<SwnErrorCode>( SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret); pContext = IntPtr.Zero; swnClientForWitness.SwnUnbind(TestConfig.Timeout); if (fsType == FileServerType.ScaleOutFileServer) { // For scale-out file server case, retrieve and use another access IP for connection currentAccessIpAddr = (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6); } } #endregion #region Read content and close the file DoUntilSucceed(() => ReadContentAfterFailover(server, currentAccessIpAddr, uncSharePath, file, content, clientGuid, createGuid), TestConfig.FailoverTimeout, "After failover, retry Read content until succeed within timeout span."); #endregion }
private void Logoff(Smb2FunctionalClient client) { client.LogOff(); client.Disconnect(); }
/// <summary> /// Verify if server grant lease state as expected /// </summary> /// <param name="requestedLeaseState">Requested lease state from client</param> /// <param name="expectedGrantedLeaseState">Expected lease state that server granted</param> private void VerifyGrantedLeaseState(LeaseStateValues requestedLeaseState, LeaseStateValues expectedGrantedLeaseState) { Guid clientGuid = Guid.NewGuid(); string testDirectory = "DirectoryLeasing_GrantedLeaseState_" + clientGuid.ToString(); #region Connect to share BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to share {0}.", uncSharePath); Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #region Negotiate Capabilities_Values clientCapabilities = 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; client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, clientCapabilities, clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "NEGOTIATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response); }); #endregion #region SessionSetup status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status)); #endregion #region TreeConnect uint treeId; status = client.TreeConnect(uncSharePath, out treeId); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "TreeConnect should succeed, actual status is {0}", Smb2Status.GetStatusCode(status)); #endregion #endregion #region CREATE open to directory with lease BaseTestSite.Log.Add(LogEntryKind.TestStep, "CREATE open to directory with lease."); Smb2CreateContextResponse[] serverCreateContexts; FILEID fileId; status = client.Create( treeId, testDirectory, CreateOptions_Values.FILE_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = clientGuid, LeaseState = requestedLeaseState } }, accessMask: AccessMask.GENERIC_ALL, shareAccess: ShareAccess_Values.FILE_SHARE_READ, checker: (header, response) => { }); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open on directory should succeed, actual status is {0}", Smb2Status.GetStatusCode(status)); #endregion #region Verify server granted lease state BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server granted lease state."); BaseTestSite.Assert.AreNotEqual( null, serverCreateContexts, "Server should return granted lease state"); foreach (Smb2CreateContextResponse serverCreateContext in serverCreateContexts) { Smb2CreateResponseLeaseV2 createResponseLeaseV2 = serverCreateContext as Smb2CreateResponseLeaseV2; if (createResponseLeaseV2 != null) { BaseTestSite.Assert.AreEqual( expectedGrantedLeaseState, createResponseLeaseV2.LeaseState, "Server granted lease state {0} should be the same as {1}", createResponseLeaseV2.LeaseState, expectedGrantedLeaseState); break; } } #endregion }
/// <summary> /// Reset all member variables before running next test case /// </summary> public override void Reset() { if (firstClient != null) { firstClient.Disconnect(); firstClient = null; } if (secondClient != null) { secondClient.Disconnect(); secondClient = null; } fileName = null; leaseBreakState = LeaseBreakState.NoLeaseBreak; treeId1 = 0; treeId2 = 0; fileId1 = FILEID.Zero; fileId2 = FILEID.Zero; base.Reset(); }
protected override void TestInitialize() { base.TestInitialize(); ReadIpAddressesFromTestConfig(out clientIps, out serverIps); BaseTestSite.Assert.IsTrue( clientIps.Count > 1, "Client should have more than one IP address"); BaseTestSite.Assert.IsTrue( serverIps.Count > 1, "Server should have more than one IP address"); mainChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientGuid = Guid.NewGuid(); uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); fileName = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid()); testDirectory = CreateTestDirectory(uncSharePath); contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); }
/// <summary> /// Create operation for PrepareOpen operation /// </summary> private void PrepareOpenCreate( Smb2FunctionalClient client, uint treeIdBeforeDisconnection, string fileName, out FILEID fileIdBeforDisconnection, out Smb2CreateContextResponse[] serverCreateContexts, RequestedOplockLevel_Values requestedOplocklevel, Smb2CreateContextRequest[] prepareContext) { client.Create( treeIdBeforeDisconnection, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforDisconnection, out serverCreateContexts, requestedOplocklevel, prepareContext, shareAccess: ShareAccess_Values.NONE, checker: (HASH_HEADER, response) => { }); }
public void DirectoryLeasing_BreakReadCachingByChildModified() { #region Prepare test directory and test file BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory and test file."); uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); fileName = "DirectoryLeasing_BreakReadCachingByChildModified_" + Guid.NewGuid().ToString() + ".txt"; testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare); sutProtocolController.CreateFile(uncSharePath + "\\" + testDirectory, fileName, string.Empty); #endregion #region Initialize test clients BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients."); Guid clientGuidRequestingLease = Guid.NewGuid(); Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); Guid clientGuidTriggeringBreak = Guid.NewGuid(); Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived); clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #endregion #region CREATE an open to request lease uint treeIdClientRequestingLease; FILEID fileIdClientRequestingLease; LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING; // Add expected NewLeaseState expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_NONE; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory); status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, testDirectory, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status)); #endregion // Create a timer that signals the delegate to invoke CheckBreakNotification Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite); base.clientToAckLeaseBreak = clientRequestingLease; #region Attempt to trigger lease break by modifying child item uint treeIdClientTriggeringBreak; FILEID fileIdClientTriggeringBreak; AccessMask accessMaskTrigger = AccessMask.GENERIC_WRITE; string targetName = testDirectory + "\\" + fileName; string contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); BaseTestSite.Log.Add( LogEntryKind.TestStep, "A separate client attempts to access directory {0} to trigger lease break by modifying inner file", testDirectory); status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, targetName, false, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status)); status = clientTriggeringBreak.Write(treeIdClientTriggeringBreak, fileIdClientTriggeringBreak, contentWrite); ClientTearDown(clientTriggeringBreak, treeIdClientTriggeringBreak, fileIdClientTriggeringBreak); #endregion }
/// <summary> /// Create an open from client, this include NEGOTIATE and SESSION_SETUP with server, TREE_CONNECT to the share and CREATE an open to file/directory /// </summary> /// <param name="client">Client used to take the operation</param> /// <param name="clientGuid">Client GUID for negotiation</param> /// <param name="targetName">File/directory name for the open</param> /// <param name="isDirectory">Set true if create open to a directory, set false if create open to a file</param> /// <param name="accessMask">Desired access when create the open</param> /// <param name="treeId">Out param for tree id used to connect to the share</param> /// <param name="fileId">Out param for file id that is associated with the open</param> /// <param name="shareAccess">Optional param for share access when create the open</param> /// <returns>Status value returned from CREATE request</returns> private uint CreateOpenFromClient(Smb2FunctionalClient client, Guid clientGuid, string targetName, bool isDirectory, LeaseStateValues requestLeaseState, AccessMask accessMask, out uint treeId, out FILEID fileId, ShareAccess_Values shareAccess = ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE) { #region Negotiate BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client {0} sends NEGOTIATE request with the following 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.", clientGuid.ToString()); 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, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation is expected success, actually server returns {0}", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response); }); #endregion #region SESSION_SETUP BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends SESSION_SETUP request.", clientGuid.ToString()); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends TREE_CONNECT request.", clientGuid.ToString()); status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE Smb2CreateContextResponse[] serverCreateContexts; CreateOptions_Values createOptions; if (isDirectory) { createOptions = CreateOptions_Values.FILE_DIRECTORY_FILE; } else { createOptions = CreateOptions_Values.FILE_NON_DIRECTORY_FILE; } // Include FILE_DELETE_ON_CLOSE if accessMask has DELETE if ((accessMask & AccessMask.DELETE) == AccessMask.DELETE) { createOptions = createOptions | CreateOptions_Values.FILE_DELETE_ON_CLOSE; } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client {0} sends CREATE request with the lease state in SMB2_CREATE_REQUEST_LEASE_V2 set to {1}.", clientGuid.ToString(), requestLeaseState); status = client.Create( treeId, targetName, createOptions, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = clientGuid, LeaseState = requestLeaseState } }, accessMask: accessMask, shareAccess: shareAccess, checker: (header, response) => { }); return status; #endregion }
/// <summary> /// Common method used to connect to target server, including the following message sequences: /// 1. Negotiate /// 2. Session Setup /// 3. Tree Connect /// </summary> /// <param name="smb2Dialect"></param> /// <param name="client"></param> /// <param name="clientGuid"></param> /// <param name="account"></param> /// <param name="connectShareType"></param> /// <param name="treeId"></param> /// <param name="clientBeforeDisconnection"></param> protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection) { DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect); Capabilities_Values clientCapabilities = 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_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress; string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName; client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid); client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid); if (null != clientBeforeDisconnection) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid); client.ReconnectSessionSetup( clientBeforeDisconnection, testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } else { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid); client.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid); client.TreeConnect( durableHandleUncSharePath, out treeId, checker: (header, response) => { BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities in TREE_CONNECT response: {0}", response.Capabilities); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful", header.Command); if (connectShareType == ConnectShareType.CAShare) { BaseTestSite.Assert.AreEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } if (connectShareType == ConnectShareType.BasicShare) { BaseTestSite.Assert.AreNotEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } }); }
/// <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)); } }
public void PrepareOpen( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { // Lease V2 cases only apply on the server implements SMB 3.x family. if (oplockLeaseType == OplockLeaseType.LeaseV2) testConfig.CheckDialect(DialectRevision.Smb30); // Lease V1 cases only apply on the server implements SMB 2.1 and 3.x family. if (oplockLeaseType == OplockLeaseType.LeaseV1) testConfig.CheckDialect(DialectRevision.Smb21); if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2) && !testConfig.IsLeasingSupported) Site.Assert.Inconclusive("Test case is applicable in servers that support leasing."); requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); clientCapabilities = 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; if (persistentBit == PersistentBitType.PersistentBitSet) { clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; } clientGuid = Guid.NewGuid(); requestedContext = oplockLeaseType; isCAShare = (connectToCAShare == CAShareType.CAShare); IPAddress targetIPAddress; string targetServer; #region Connect to Common Share or CA Share if (!isCAShare) { sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt"; targetIPAddress = testConfig.SutIPAddress; targetServer = testConfig.SutComputerName; } else { sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName); fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt"; targetIPAddress = testConfig.CAShareServerIP; targetServer = testConfig.CAShareServerName; } testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClientBeforeDisconnection.CreditGoal = 20; testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress); testClientBeforeDisconnection.Negotiate( requestDialect, testConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, clientGuid: clientGuid, checker: (header, response) => { if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) && handleConfig.IsPersistentHandleSupported && persistentBit == PersistentBitType.PersistentBitSet) { Site.Assert.IsTrue( response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " + "Actual capabilities are {0}", response.Capabilities); } }); testClientBeforeDisconnection.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, testConfig.AccountCredential, testConfig.UseServerGssToken); testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection); #endregion #region Create operation according to the handle type and context Smb2CreateContextRequest[] prepareRequestContext = null; Smb2CreateContextResponse[] serverCreateContexts = null; RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; switch (oplockLeaseType) { case OplockLeaseType.LeaseV1: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE); prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; case OplockLeaseType.LeaseV2: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2); prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; case OplockLeaseType.BatchOplock: { prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; } break; case OplockLeaseType.NoOplockOrLease: { prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType); requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; } break; } PrepareOpenCreate( testClientBeforeDisconnection, treeIdBeforeDisconnection, fileName, out fileIdBeforDisconnection, out serverCreateContexts, requestedOplockLevel, prepareRequestContext); #endregion }
/// <summary> /// The two client connects to the two IP addresses of scaleout file server /// Negotiate, SessionSetup, TreeConnect /// </summary> private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId) { Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); client.ConnectToServerOverTCP(ip); client.Negotiate( Smb2Utility.GetDialects(DialectRevision.Smb21), testConfig.IsSMB1NegotiateEnabled); client.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.ScaleOutFileServerName, testConfig.AccountCredential, testConfig.UseServerGssToken); client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId); return client; }
private void SendCreateRequestWithSpecificAppInstanceversion( Smb2FunctionalClient client, Guid appInstanceId, ulong? appInstanceVersionHigh, ulong? appInstanceVersionLow, DialectRevision dialect, uint expectedCreateResponseStatus, out uint treeId, out FILEID fileId ) { #region Client connects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress); client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); client.TreeConnect(uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion(); Smb2CreateContextRequest[] clientCreateContexts; if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue) { appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value; appInstanceVersion.AppInstanceVersionLow = appInstanceVersionLow.Value; clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId }, appInstanceVersion }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow); } else { clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId } }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion."); } client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, clientCreateContexts, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( expectedCreateResponseStatus, header.Status, (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ? "The open will be closed. Create should succeed. Actually server returns with {0}." : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."), Smb2Status.GetStatusCode(header.Status)); }); #endregion }
public void ReconnectOpenRequest( DurableV1ReconnectContext durableV1ReconnectContext, DurableV2ReconnectContext durableV2ReconnectContext, OplockLeaseType oplockLeaseType, LeaseKeyDifferentialType leaseKeyDifferentialType, ClientIdType clientIdType, CreateGuidType createGuidType) { if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2) && !testConfig.IsLeasingSupported) Site.Assert.Inconclusive("Test case is applicable in servers that support leasing."); bool isSameLeaseKey = (leaseKeyDifferentialType == LeaseKeyDifferentialType.SameLeaseKey); bool isSameClient = (clientIdType == ClientIdType.SameClient); bool isSameCreateGuid = (createGuidType == CreateGuidType.SameCreateGuid); FILEID fileIdAfterDisconnection; Smb2CreateContextResponse[] serverCreateContexts; IPAddress targetIPAddress; string targetServer; string targetShare; #region Construct Create Contexts Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext( DurableV1RequestContext.DurableV1RequestContextNotExist, DurableV2RequestContext.DurableV2RequestContextNotExist, durableV1ReconnectContext, durableV2ReconnectContext, oplockLeaseType, isSameLeaseKey, isSameCreateGuid); #endregion #region Client reconnect to server Site.Log.Add(LogEntryKind.Debug, "Client reconnect to server"); #region Reconnect to Common Share or CA Share if (!isCAShare) { targetIPAddress = testConfig.SutIPAddress; targetServer = testConfig.SutComputerName; targetShare = testConfig.BasicFileShare; } else { targetIPAddress = testConfig.CAShareServerIP; targetServer = testConfig.CAShareServerName; targetShare = testConfig.CAShareName; } // Connect to Server testClientAfterDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClientAfterDisconnection.CreditGoal = 10; testClientAfterDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress); // Negotiate testClientAfterDisconnection.Negotiate( requestDialect, testConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, // If the reconnect use the same client guid, then keep client guid the same value, otherwise use a new client guid. clientGuid: (isSameClient ? clientGuid : Guid.NewGuid())); uint status = testClientAfterDisconnection.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, testConfig.AccountCredential, testConfig.UseServerGssToken); Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Reconnect Session Setup should be successful, actual status is {0}", Smb2Status.GetStatusCode(status)); // TreeConnect testClientAfterDisconnection.TreeConnect(sharePath, out treeIdAfterDisconnection); #endregion #region Send Create request according to different context combination RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; switch (oplockLeaseType) { case OplockLeaseType.NoOplockOrLease: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; } break; case OplockLeaseType.BatchOplock: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; } break; case OplockLeaseType.LeaseV1: case OplockLeaseType.LeaseV2: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; } status = OpenCreate( testClientAfterDisconnection, treeIdAfterDisconnection, fileName, out fileIdAfterDisconnection, out serverCreateContexts, requestedOplockLevel, smb2CreateContextRequest); #endregion DurableHandleResponseContext durableHandleResponse; LeaseResponseContext leaseResponse; CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse); OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig); testClientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection); testClientAfterDisconnection.LogOff(); #endregion }
public void DirectoryLeasing_BreakHandleCachingByParentDeleted() { #region Prepare test directory BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory."); uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); string parentDirectory = "ParentDirectory_" + Guid.NewGuid().ToString(); sutProtocolController.CreateDirectory(uncSharePath, parentDirectory); testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare + "\\" + parentDirectory); #endregion #region Initialize test clients BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients."); Guid clientGuidRequestingLease = Guid.NewGuid(); Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); Guid clientGuidTriggeringBreak = Guid.NewGuid(); Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived); clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #endregion #region CREATE an open to request lease uint treeIdClientRequestingLease; FILEID fileIdClientRequestingLease; string targetName = parentDirectory + "\\" + testDirectory; LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING; // Add expected NewLeaseState expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory); status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, targetName, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status)); #endregion // Create a timer that signals the delegate to invoke CheckBreakNotification Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite); base.clientToAckLeaseBreak = clientRequestingLease; #region Attempt to trigger lease break by deleting parent directory uint treeIdClientTriggeringBreak; FILEID fileIdClientTriggeringBreak; AccessMask accessMaskTrigger = AccessMask.DELETE; BaseTestSite.Log.Add( LogEntryKind.TestStep, "A separate client attempts to trigger lease break by deleting its parent directory"); status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, parentDirectory, true, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, status, "Create an open to {0} should succeed", parentDirectory); #region set FileDispositionInformation for deletion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Set FileDispositionInformation for deletion."); FileDispositionInformation fileDispositionInfo; fileDispositionInfo.DeletePending = 1; // Set 1 to indicate directory SHOULD be delted when the open closed byte[] inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(fileDispositionInfo); status = clientTriggeringBreak.SetFileAttributes( treeIdClientTriggeringBreak, (byte)FileInformationClasses.FileDispositionInformation, fileIdClientTriggeringBreak, inputBuffer, (header, response) => { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Setting FileDispositionInformation to the parent directory for deletion when child is opened by others is not expected to SUCCESS. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_DIRECTORY_NOT_EMPTY, header.Status, RequirementCategory.STATUS_DIRECTORY_NOT_EMPTY.Id, RequirementCategory.STATUS_DIRECTORY_NOT_EMPTY.Description); }); status = clientTriggeringBreak.Close(treeIdClientTriggeringBreak, fileIdClientTriggeringBreak); #endregion #region CREATE an open to parent directory again BaseTestSite.Log.Add(LogEntryKind.TestStep, "CREATE an open to parent directory again."); // Currently we need an additional CREATE to open the parent directory to trigger the lease break // which is the same way when Windows attempt to delete the parent directory when child is opened by others Smb2CreateContextResponse[] serverCreateContexts; status = clientTriggeringBreak.Create( treeIdClientTriggeringBreak, targetName, CreateOptions_Values.FILE_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE, out fileIdClientTriggeringBreak, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = clientGuidTriggeringBreak, LeaseState = LeaseStateValues.SMB2_LEASE_NONE } }, accessMask: accessMaskTrigger); #endregion #endregion }
public void OpenRequest( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, OplockLeaseType oplockLeaseType, DurableV1RequestContext durableV1RequestContext, DurableV2RequestContext durableV2RequestContext, DurableV1ReconnectContext durableV1ReconnectContext, DurableV2ReconnectContext durableV2ReconnectContext) { requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); clientCapabilities = 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; if (persistentBit == PersistentBitType.PersistentBitSet) { clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; } clientGuid = Guid.NewGuid(); requestedContext = oplockLeaseType; isCAShare = (connectToCAShare == CAShareType.CAShare); IPAddress targetIPAddress; string targetServer; #region Connect to Common Share or CA Share if (!isCAShare) { sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare); fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt"; targetIPAddress = testConfig.SutIPAddress; targetServer = testConfig.SutComputerName; } else { sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName); fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt"; targetIPAddress = testConfig.CAShareServerIP; targetServer = testConfig.CAShareServerName; } testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClientBeforeDisconnection.CreditGoal = 20; testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress); testClientBeforeDisconnection.Negotiate( requestDialect, testConfig.IsSMB1NegotiateEnabled, capabilityValue: clientCapabilities, clientGuid: clientGuid, checker: (header, response) => { if (Smb2Utility.IsSmb3xFamily(response.DialectRevision) && handleConfig.IsPersistentHandleSupported && persistentBit == PersistentBitType.PersistentBitSet) { Site.Assert.IsTrue( response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES), "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " + "Actual capabilities are {0}", response.Capabilities); } }); testClientBeforeDisconnection.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, testConfig.AccountCredential, testConfig.UseServerGssToken); testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection); #endregion #region Construct Create Contexts Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext( durableV1RequestContext, durableV2RequestContext, durableV1ReconnectContext, durableV2ReconnectContext, oplockLeaseType, false, false); #endregion #region Send Create request according to different context combination RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; switch (oplockLeaseType) { case OplockLeaseType.NoOplockOrLease: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE; } break; case OplockLeaseType.BatchOplock: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH; } break; case OplockLeaseType.LeaseV1: case OplockLeaseType.LeaseV2: { requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE; } break; } FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; uint status = OpenCreate( testClientBeforeDisconnection, treeIdBeforeDisconnection, fileName, out fileId, out serverCreateContexts, requestedOplockLevel, smb2CreateContextRequest); #endregion DurableHandleResponseContext durableHandleResponse; LeaseResponseContext leaseResponse; CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse); OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig); testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { }); testClientBeforeDisconnection.LogOff(); }