/// <summary> /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_REQUEST Create Context /// The client is requesting that the open be marked for durable operation /// Cover TD section: 3.3.5.9.6 /// 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_REQUEST_CreateContext( ModelSmb2Status status, ModelOpenFileRequest modelOpenFileRequest, DurableHandleResponseContext durableHandleResponseContext, HandleConfig c) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST Create Context"); if (modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist) { ModelHelper.Log(LogType.Requirement, "If the create request also includes an SMB2_CREATE_DURABLE_HANDLE_RECONNECT create context, " + "the server MUST process the create context as specified in section 3.3.5.9.7 and skip this section."); ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT is included."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return false; } if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist || modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { // Workaround to force SE explorers the platform field. Condition.IsTrue(Config.Platform == c.Platform); ModelHelper.Log(LogType.Requirement, "If the create request also includes an SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context, " + "the server SHOULD<266> fail the create 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, "<266> Section 3.3.5.9.6: Windows Vista SP1, Windows 7, Windows Server 2008, and Windows Server 2008 R2 ignore undefined create contexts."); ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}", Config.Platform); Condition.IsFalse(durableHandleResponseContext == DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE); 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; } if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.NoOplockOrLease) { ModelHelper.Log(LogType.Requirement, "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, "The create response should not contain SMB2_CREATE_DURABLE_HANDLE_RESPONSE."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsFalse(durableHandleResponseContext == DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE); return false; } ModelHelper.Log(LogType.Requirement, "In the \"Response Construction\" phase, the server MUST construct an SMB2_CREATE_DURABLE_HANDLE_RESPONSE response create context"); ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RESPONSE should be contained in create response"); Condition.IsTrue(durableHandleResponseContext == DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE); return false; }
/// <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; }
/// <summary> /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 Create Context /// Cover TD section: 3.3.5.9.10 /// 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_REQUEST_V2_CreateContext( ModelSmb2Status status, ModelOpenFileRequest modelOpenFileRequest, DurableHandleResponseContext durableHandleResponseContext) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 Create Context"); if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist || modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist || modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) { ModelHelper.Log(LogType.Requirement, "If the create request also includes an SMB2_CREATE_DURABLE_HANDLE_REQUEST create context, " + "or an SMB2_CREATE_DURABLE_HANDLE_RECONNECT or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context, " + "the server MUST fail the create 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.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist) ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is included."); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return true; } if (modelOpenFileRequest.durableV2RequestContext == DurableV2RequestContext.DurableV2RequestContextExistWithoutPersistent && modelOpenFileRequest.oplockLeaseType == OplockLeaseType.NoOplockOrLease) { 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, "All the above conditions are met. "); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); Condition.IsTrue(durableHandleResponseContext == DurableHandleResponseContext.NONE); return false; } if (Open != null && modelOpenFileRequest.isSameClient && modelOpenFileRequest.isSameCreateGuid) { ModelHelper.Log(LogType.Requirement, "The server MUST locate the Open in GlobalOpenTable where Open.CreateGuid matches the CreateGuid in the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 create context, " + "and Open.ClientGuid matches the ClientGuid of the connection that received this request."); ModelHelper.Log(LogType.TestInfo, "The Open is found."); ModelHelper.Log(LogType.Requirement, "If an Open is found and the SMB2_FLAGS_REPLAY_OPERATION bit is not set in the SMB2 header, the server MUST fail the request with STATUS_DUPLICATE_OBJECTID."); ModelHelper.Log(LogType.TestInfo, "SMB2_FLAGS_REPLAY_OPERATION is not set."); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_DUPLICATE_OBJECTID); return true; } if (Open == null) { ModelHelper.Log(LogType.Requirement, "If an Open is not found, the server MUST continue the create process specified in the \"Open Execution\" Phase, and perform the following additional steps:"); Open = new HandleModelOpen(); ModelHelper.Log(LogType.Requirement, "In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. "); Open.IsDurable = true; if (modelOpenFileRequest.durableV2RequestContext == DurableV2RequestContext.DurableV2RequestContextExistWithPersistent && Share_IsCA && ServerCapabilities_PersistentBitSet) { ModelHelper.Log(LogType.Requirement, "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. Open.IsPersistent is set to TRUE."); Open.IsPersistent = true; } } if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextExistWithPersistent && modelOpenFileRequest.oplockLeaseType == OplockLeaseType.NoOplockOrLease) { ModelHelper.Log(LogType.Requirement, "The server MUST skip the construction of the SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2 create context " + "if the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of the request and if neither of the following conditions are met:" + "\tOpen.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH. " + "\tOpen.Lease.LeaseState has SMB2_LEASE_HANDLE_CACHING bit set."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. " + "So the server skips the construction of the SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2 create context."); Condition.IsTrue(durableHandleResponseContext == DurableHandleResponseContext.NONE); } else { ModelHelper.Log(LogType.Requirement, "If Open.IsPersistent is TRUE, the server MUST set the SMB2_DHANDLE_FLAG_PERSISTENT bit in the Flags field. "); ModelHelper.Log(LogType.TestInfo, "Open.IsPersistent is {0}", Open.IsPersistent); if (Open.IsPersistent) { Condition.IsTrue(durableHandleResponseContext == DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2_WITH_PERSISTENT); } } return false; }