/// <summary> /// Get create context for PrepareOpen /// </summary> private Smb2CreateContextRequest[] GetPrepareOpenCreateContext( ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { Smb2CreateContextRequest[] contexts = new Smb2CreateContextRequest[] { }; contexts = GetPrepareOpenHandleContext(modelHandleType); contexts = ConcatContexts(contexts, GetPrepareOpenLeaseContext(oplockLeaseType)); return(contexts); }
/// <summary> /// Get handle context for PrepareOpen /// </summary> private Smb2CreateContextRequest[] GetPrepareOpenHandleContext( ModelHandleType modelHandleType) { Smb2CreateContextRequest[] handleContext = new Smb2CreateContextRequest[] { }; switch (modelHandleType) { case ModelHandleType.DurableHandleV1: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST); createGuid = Guid.Empty; handleContext = handleContext.Append(new Smb2CreateDurableHandleRequest { DurableRequest = createGuid }); return(handleContext); } case ModelHandleType.DurableHandleV2: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); createGuid = Guid.NewGuid(); handleContext = handleContext.Append(new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid }); return(handleContext); } case ModelHandleType.PersistentHandle: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); createGuid = Guid.NewGuid(); handleContext = handleContext.Append( new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT, }); return(handleContext); } default: throw new InvalidOperationException("Unsupported handle type"); } }
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> /// Get handle context for PrepareOpen /// </summary> private Smb2CreateContextRequest[] GetPrepareOpenHandleContext( ModelHandleType modelHandleType) { Smb2CreateContextRequest[] handleContext = new Smb2CreateContextRequest[] { }; switch (modelHandleType) { case ModelHandleType.DurableHandleV1: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST); createGuid = Guid.Empty; handleContext = handleContext.Append(new Smb2CreateDurableHandleRequest { DurableRequest = createGuid }); return handleContext; } case ModelHandleType.DurableHandleV2: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); createGuid = Guid.NewGuid(); handleContext = handleContext.Append(new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid }); return handleContext; } case ModelHandleType.PersistentHandle: { testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2); createGuid = Guid.NewGuid(); handleContext = handleContext.Append( new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT, }); return handleContext; } default: throw new InvalidOperationException("Unsupported handle type"); } }
/// <summary> /// Get create context for PrepareOpen /// </summary> private Smb2CreateContextRequest[] GetPrepareOpenCreateContext( ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { Smb2CreateContextRequest[] contexts = new Smb2CreateContextRequest[] { }; contexts = GetPrepareOpenHandleContext(modelHandleType); contexts = ConcatContexts(contexts, GetPrepareOpenLeaseContext(oplockLeaseType)); return contexts; }
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 }
public static void PrepareOpen( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { Condition.IsNull(Request); Condition.IsNull(Open); // CAShare, Persistent Handle , Durable Handle v2 and Lease V2 are only applied for SMB 3.x family. Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), connectToCAShare == CAShareType.NonCAShare); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), persistentBit == PersistentBitType.PersistentBitNotSet); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), modelHandleType == ModelHandleType.DurableHandleV1); // Case will go to non-accpeting state if clientMaxDialect > Config.MaxSmbVersionSupported. NegotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported); // Restrict the params combination Combination.Pairwise(clientMaxDialect, persistentBit, connectToCAShare, modelHandleType, oplockLeaseType); Share_IsCA = (connectToCAShare == CAShareType.CAShare); Open = new HandleModelOpen(); Open.IsConnectionExisted = true; Open.IsSessionExisted = true; if (oplockLeaseType == OplockLeaseType.LeaseV1) { Open.IsLeaseExisted = true; Open.LeaseVersion = 1; } else if (oplockLeaseType == OplockLeaseType.LeaseV2) { Open.IsLeaseExisted = true; Open.LeaseVersion = 2; } else if (oplockLeaseType == OplockLeaseType.BatchOplock) { Open.IsBatchOplockExisted = true; } if (modelHandleType == ModelHandleType.DurableHandleV1) { if (!Open.IsBatchOplockExisted && !Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: If the RequestedOplockLevel field in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH and " + "the create request does not include an SMB2_CREATE_REQUEST_LEASE create context with a LeaseState field that " + "includes the SMB2_LEASE_HANDLE_CACHING bit value, " + "the server MUST ignore this create context and skip this section."); ModelHelper.Log(LogType.TestInfo, "This section is skipped."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. "); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE."); Open.IsDurable = true; } else if (modelHandleType == ModelHandleType.DurableHandleV2 || modelHandleType == ModelHandleType.PersistentHandle) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: This section applies only to servers that implement the SMB 3.x dialect family. "); if (!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported)) { ModelHelper.Log(LogType.TestInfo, "The server implements the dialect {0}.", Config.MaxSmbVersionSupported); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } if (modelHandleType != ModelHandleType.PersistentHandle && !Open.IsBatchOplockExisted && !Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "If the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of this create context, " + "if RequestedOplockLevel in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH, " + "and if the create request does not include a SMB2_CREATE_REQUEST_LEASE or " + "SMB2_CREATE_REQUEST_LEASE_V2 create context with a LeaseState field that includes SMB2_LEASE_HANDLE_CACHING, " + "the server MUST ignore this create context and skip this section."); ModelHelper.Log(LogType.TestInfo, "This section is skipped."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && persistentBit == PersistentBitType.PersistentBitSet && Config.IsPersistentHandleSupported) { ModelHelper.Log(LogType.Requirement, "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:"); ModelHelper.Log(LogType.Requirement, "\tSMB2_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."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So SMB2_DHANDLE_FLAG_PERSISTENT bit is set in Connection.ServerCapabilities."); ServerCapabilities_PersistentBitSet = true; } if (modelHandleType == ModelHandleType.PersistentHandle && !(Share_IsCA && ServerCapabilities_PersistentBitSet)) { // TDI: if client asks for a persistent handle to a non CA share or // Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES // The persistent handle is not granted. ModelHelper.Log( LogType.TestInfo, "Share is not a CA share or Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } ModelHelper.Log(LogType.Requirement, "In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. "); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE."); Open.IsDurable = true; if (modelHandleType == ModelHandleType.PersistentHandle && Share_IsCA && ServerCapabilities_PersistentBitSet) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: If the SMB2_DHANDLE_FLAG_PERSISTENT bit is set in the Flags field of the request, " + "TreeConnect.Share.IsCA is TRUE, " + "and Connection.ServerCapabilities includes SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, " + "the server MUST set Open.IsPersistent to TRUE."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So Open.IsPersistent is set to TRUE."); Open.IsPersistent = true; } } }