/// <summary> /// Check server response. Return the abstracted context type of response. /// </summary> private void CheckResponseContexts( Smb2CreateContextResponse[] serverCreateContexts, out DurableHandleResponseContext durableHandleResponseContext, out LeaseResponseContext leaseResponseContext) { durableHandleResponseContext = DurableHandleResponseContext.NONE; leaseResponseContext = LeaseResponseContext.NONE; if (serverCreateContexts != null) { foreach (Smb2CreateContextResponse response in serverCreateContexts) { if (response is Smb2CreateDurableHandleResponse) { durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE; } else if (response is Smb2CreateDurableHandleResponseV2) { durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2; if ((response as Smb2CreateDurableHandleResponseV2).Flags.HasFlag(CREATE_DURABLE_HANDLE_RESPONSE_V2_Flags.DHANDLE_FLAG_PERSISTENT)) { durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2_WITH_PERSISTENT; } } else if (response is Smb2CreateResponseLease) { leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE; } else if (response is Smb2CreateResponseLeaseV2) { leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2; } } } }
/// <summary> /// Check server response. Return the abstracted context type of response. /// </summary> private void CheckResponseContexts( Smb2CreateContextResponse[] serverCreateContexts, out DurableHandleResponseContext durableHandleResponseContext, out LeaseResponseContext leaseResponseContext) { durableHandleResponseContext = DurableHandleResponseContext.NONE; leaseResponseContext = LeaseResponseContext.NONE; if (serverCreateContexts != null) { foreach (Smb2CreateContextResponse response in serverCreateContexts) { if (response is Smb2CreateDurableHandleResponse) { durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE; } else if (response is Smb2CreateDurableHandleResponseV2) { durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2; if ((response as Smb2CreateDurableHandleResponseV2).Flags.HasFlag(CREATE_DURABLE_HANDLE_RESPONSE_V2_Flags.DHANDLE_FLAG_PERSISTENT)) durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2_WITH_PERSISTENT; } else if (response is Smb2CreateResponseLease) { leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE; } else if (response is Smb2CreateResponseLeaseV2) { leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2; } } } }
/// <summary> /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context /// The client is requesting a reconnect to an existing durable open /// Cover TD section: 3.3.5.9.7 /// Return true means the message is handled by this function. /// Return false means the message needs further processing. /// </summary> private static bool Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_CreateContext( ModelSmb2Status status, ModelOpenFileRequest modelOpenFileRequest, LeaseResponseContext leaseResponseContext, HandleConfig c) { Condition.IsTrue(Config.Platform == c.Platform); ModelHelper.Log(LogType.Requirement, "3.3.5.9.7: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context"); if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist || modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { ModelHelper.Log(LogType.Requirement, "If the create request also contains an SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context, " + "the server SHOULD<267> fail the request with STATUS_INVALID_PARAMETER."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 is included."); } if (modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is included."); } if (Config.Platform == Platform.WindowsServer2008 || Config.Platform == Platform.WindowsServer2008R2) { ModelHelper.Log(LogType.Requirement, "<267> Section 3.3.5.9.7: Windows Vista SP1, Windows Server 2008, Windows 7 and Windows Server 2008 R2 ignore undefined create contexts."); ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", Config.Platform); Condition.IsTrue(leaseResponseContext == LeaseResponseContext.NONE); return false; } else if (Config.Platform == Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is NonWindows, so the server could return other error code."); Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } else { ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}", Config.Platform); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); } return true; } ModelHelper.Log(LogType.Requirement, "The server MUST look up an existing open in the GlobalOpenTable by doing a lookup with the FileId.Persistent portion of the create context. "); if (Open == null) { ModelHelper.Log(LogType.Requirement, "If the lookup fails, the server SHOULD<268> fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "The open does not exist and the SUT platform is {0}.", Config.Platform); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); if (Config.Platform == Platform.NonWindows) Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); else Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (Open.IsLeaseExisted && !modelOpenFileRequest.isSameClient) { ModelHelper.Log(LogType.Requirement, "If Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection that received this request, " + "the server MUST fail the create request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (NegotiateDialect != DialectRevision.Smb2002 && !Open.IsLeaseExisted && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2)) { ModelHelper.Log(LogType.Requirement, "If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is present, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.Lease is NULL and {0} is present.", modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 ? "SMB2_CREATE_REQUEST_LEASE" : "SMB2_CREATE_REQUEST_LEASE_V2"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (!Open.IsDurable) { ModelHelper.Log(LogType.Requirement, "If Open.IsDurable is FALSE and Open.IsResilient is FALSE or unimplemented, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9"); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is FALSE and Open.IsResilient is FALSE."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (Open.IsSessionExisted) { ModelHelper.Log(LogType.Requirement, "If Open.Session is not NULL, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.Session is not NULL."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } // workaround for SE bug Condition.IsTrue(Config.IsLeasingSupported == c.IsLeasingSupported); Condition.IsTrue(Config.IsDirectoryLeasingSupported == c.IsDirectoryLeasingSupported); if (Open.IsLeaseExisted && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV1 && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV2) { ModelHelper.Log(LogType.Requirement, "3. If Open.Lease is not NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is not present, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (!Open.IsLeaseExisted && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2)) { ModelHelper.Log(LogType.Requirement, "4. If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is present, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.Lease is NULL and {0} is present.", modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 ? "SMB2_CREATE_REQUEST_LEASE" : "SMB2_CREATE_REQUEST_LEASE_V2"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2 && ModelUtility.IsSmb3xFamily(NegotiateDialect) && Config.IsDirectoryLeasingSupported && Open.IsLeaseExisted && !modelOpenFileRequest.isSameLeaseKey) { ModelHelper.Log(LogType.Requirement, "7. If an SMB2_CREATE_REQUEST_LEASE_V2 create context is also present in the request, Connection.Dialect belongs to the SMB 3.x dialect family, " + "the server supports directory leasing, Open.Lease is not NULL, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE_V2 create context, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 && (NegotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(NegotiateDialect)) && Config.IsLeasingSupported && Open.IsLeaseExisted && !modelOpenFileRequest.isSameLeaseKey) { ModelHelper.Log(LogType.Requirement, "8. If an SMB2_CREATE_REQUEST_LEASE create context is also present in the request, Connection.Dialect is \"2.100\" or belongs to the SMB 3.x dialect family, " + "the server supports leasing, Open.Lease is not NULL, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE create context, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && Config.IsDirectoryLeasingSupported && Open.IsLeaseExisted && Open.LeaseVersion == 2) { ModelHelper.Log(LogType.Requirement, "If Connection.Dialect belongs to the SMB 3.x dialect family, the server supports directory leasing, Open.Lease is not NULL, " + "and Lease.Version is 2, then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 create context"); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE_V2 create context."); Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2); } if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && Config.IsLeasingSupported && Open.IsLeaseExisted && Open.LeaseVersion == 1) { ModelHelper.Log(LogType.Requirement, "If Connection.Dialect belongs to the SMB 3.x dialect family, the server supports leasing, Open.Lease is not NULL, and Lease.Version is 1, " + "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE Create Context"); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE create context."); Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE); } if (NegotiateDialect == DialectRevision.Smb21 && Config.IsLeasingSupported && Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "If Connection.Dialect is \"2.100\", the server supports leasing, and Open.Lease is not NULL, " + "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE create context"); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE create context."); if (Open.LeaseVersion == 1) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE); else if (Open.LeaseVersion == 2) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2); } return false; }
/// <summary> /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context /// Cover TD section 3.3.5.9.12 /// Return true means the message is handled by this function. /// Return false means the message needs further processing. /// </summary> private static bool Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2_CreateContext( ModelSmb2Status status, ModelOpenFileRequest modelOpenFileRequest, LeaseResponseContext leaseResponseContext, HandleConfig c) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.12: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context"); if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist || modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist || modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist) { ModelHelper.Log(LogType.Requirement, "If the create request also contains SMB2_CREATE_DURABLE_HANDLE_REQUEST context or SMB2_CREATE_DURABLE_HANDLE_RECONNECT context or " + "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 context, the server MUST fail the request with STATUS_INVALID_PARAMETER."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext); if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST is included."); } if (modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT is included."); } if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 is included."); } Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return true; } ModelHelper.Log(LogType.Requirement, "The server MUST look up an existing open in the GlobalOpenTable by doing a lookup with the FileId.Persistent portion of the create context."); ModelHelper.Log(LogType.TestInfo, "Open {0}.", Open != null ? "exists" : "does not exist"); Condition.IsTrue(Config.Platform == c.Platform); if (Open == null) { ModelHelper.Log(LogType.Requirement, "If the lookup fails, the server SHOULD<276> fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); if (Config.Platform == Platform.NonWindows) { ModelHelper.Log(LogType.TestInfo, "The SUT platform is NonWindows, so the server could fail the request with other error code."); Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } else if (Config.Platform == Platform.WindowsServer2012 && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithPersistent) { // Windows 2012 fails the request, but the error code is not a fixed one. Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } else { ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", Config.Platform); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); } return true; } else { // Workaround to resolve SE bug Condition.IsTrue(Config.IsLeasingSupported == c.IsLeasingSupported); Condition.IsTrue(Config.IsDirectoryLeasingSupported == c.IsDirectoryLeasingSupported); if (Open.IsLeaseExisted && !modelOpenFileRequest.isSameClient) { ModelHelper.Log(LogType.Requirement, "If Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection that received this request, " + "the server MUST fail the create request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } // TDI 72308 if (Open.IsPersistent && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithoutPersistent) { ModelHelper.Log(LogType.Requirement, "If Open.IsPersistent is TRUE and the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (!modelOpenFileRequest.isSameCreateGuid) { if (Config.Platform == Platform.WindowsServer2012 && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithPersistent) { // Windows 2012 fails the request, but the error code is not a fixed one. Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS); } else { ModelHelper.Log(LogType.Requirement, "If Open.CreateGuid is not equal to the CreateGuid in the request, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.CreateGuid is not equal to the CreateGuid in the request."); ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); } return true; } if (!Open.IsDurable) { ModelHelper.Log(LogType.Requirement, "If Open.IsDurable is FALSE and Open.IsResilient is FALSE or unimplemented, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is FALSE and Open.IsResilient is FALSE."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } // TDI, if Open.IsPersistent is true, then when reconnecting, if Open.Session is not NULL, the reconnect can still succeed. if (!Open.IsPersistent && Open.IsSessionExisted) { ModelHelper.Log(LogType.Requirement, "If Open.Session is not NULL, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND. "); ModelHelper.Log(LogType.TestInfo, "Open.Session is not NULL."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if ((!Open.IsLeaseExisted && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2)) || (Open.IsLeaseExisted && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV1 && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV2)) { ModelHelper.Log(LogType.Requirement, "If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is present, " + "or if Open.Lease is NOT NULL and the SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is not present, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND."); ModelHelper.Log(LogType.TestInfo, "Open.Lease is{0} NULL.", Open.IsLeaseExisted ? " not" : ""); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE is present."); } else if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2) { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE_V2 is present."); } else { ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is not present."); } Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2 && Config.IsDirectoryLeasingSupported && Open.IsLeaseExisted && !modelOpenFileRequest.isSameLeaseKey) { ModelHelper.Log(LogType.Requirement, "If an SMB2_CREATE_REQUEST_LEASE_V2 create context is also present in the request, " + "the server supports directory leasing, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE_V2 create context, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 && Config.IsLeasingSupported && Open.IsLeaseExisted && !modelOpenFileRequest.isSameLeaseKey) { ModelHelper.Log(LogType.Requirement, "If an SMB2_CREATE_REQUEST_LEASE create context is also present in the request, the server supports leasing, " + "and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE create context, " + "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND); return true; } ModelHelper.Log(LogType.Requirement, "In the \"Response Construction\" phase:"); // TDI 71165 if (Config.IsDirectoryLeasingSupported && modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2) { ModelHelper.Log(LogType.Requirement, "If the server supports directory leasing, and the request contains SMB2_CREATE_REQUEST_LEASE_V2 Create Context, " + "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 Create Context"); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So create response should contain an SMB2_CREATE_RESPONSE_LEASE_V2 Create Context."); if (Open.LeaseVersion == 1) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE); else if (Open.LeaseVersion == 2) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2); } // TDI 71165 if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 && Config.IsLeasingSupported && Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "If the request contains an SMB2_CREATE_REQUEST_LEASE Create Context, " + "the server supports leasing and Open.Lease is not NULL, then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE create context"); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So create response should contain an SMB2_CREATE_RESPONSE_LEASE Create Context."); if (Open.LeaseVersion == 1) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE); else if (Open.LeaseVersion == 2) Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2); } } return false; }
public static void OpenResponse( ModelSmb2Status status, DurableHandleResponseContext durableHandleResponseContext, LeaseResponseContext leaseResponseContext, HandleConfig c) { Condition.IsNotNull(Request); ModelOpenFileRequest modelOpenFileRequest = ModelHelper.RetrieveOutstandingRequest<ModelOpenFileRequest>(ref Request); if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextNotExist && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { ModelHelper.Log(LogType.Requirement, "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family and " + "the request does not contain SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context, " + "the server MUST look up an existing open in the GlobalOpenTable where Open.FileName matches the file name in the Buffer field of the request. "); ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0} and the request does not contain SMB2_CREATE_DURABLE_HANDLE_RECONNECT or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context.", NegotiateDialect); if (Open != null && !modelOpenFileRequest.isSameClient && Open.IsPersistent && !Open.IsConnectionExisted && !Open.IsBatchOplockExisted && !Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "If an Open entry is found, and if all the following conditions are satisfied, " + "the server MUST fail the request with STATUS_FILE_NOT_AVAILABLE."); ModelHelper.Log(LogType.Requirement, "\tOpen.IsPersistent is TRUE"); ModelHelper.Log(LogType.Requirement, "\tOpen.Connection is NULL"); ModelHelper.Log(LogType.Requirement, "\tOpen.OplockLevel is not equal to SMB2_OPLOCK_LEVEL_BATCH"); ModelHelper.Log(LogType.Requirement, "\tOpen.OplockLevel is not equal to SMB2_OPLOCK_LEVEL_LEASE or Open.Lease.LeaseState does not include SMB2_LEASE_HANDLE_CACHING"); ModelHelper.Log(LogType.TestInfo, "The Open is found, and all the conditions are satisfied."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_NOT_AVAILABLE); return; } } // TD section 3.3.5.9.6: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST Create Context if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist) { if (Handling_SMB2_CREATE_DURABLE_HANDLE_REQUEST_CreateContext(status, modelOpenFileRequest, durableHandleResponseContext, c)) return; } // TD section 3.3.5.9.7: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context if (modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist) { if (Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_CreateContext(status, modelOpenFileRequest, leaseResponseContext, c)) return; } // TD section 3.3.5.9.10: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 Create Context if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist) { if (Handling_SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2_CreateContext(status, modelOpenFileRequest, durableHandleResponseContext)) return; } // TD section 3.3.5.9.12: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context if (modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { if (Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2_CreateContext(status, modelOpenFileRequest, leaseResponseContext, c)) return; } Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS); }