/// <summary> /// Check the status code of create response /// </summary> /// <param name="isNonAdmin">true for non admin credential</param> /// <param name="createOption">The create option set in create request</param> /// <param name="accessMask">The access mark set in create request</param> /// <param name="header">Header of create response</param> /// <param name="response">create response</param> /// <param name="fileNameType">file name type</param> private void CheckCreateResponse(bool isNonAdmin, CreateOptions_Values createOption, AccessMask accessMask, Packet_Header header, CREATE_Response response, FileNameType fileNameType) { switch (fileNameType) { case FileNameType.SymbolicLinkInMiddle: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If any intermediate component of the path specified in the create request is a symbolic link, " + "the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.SymbolicLinkAtLast: { if (!createOption.HasFlag(CreateOptions_Values.FILE_OPEN_REPARSE_POINT)) { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the final component of the path is a symbolic link, the server behavior depends on whether the flag FILE_OPEN_REPARSE_POINT was specified in the CreateOptions field of the request. " + "If FILE_OPEN_REPARSE_POINT was specified, the server MUST open the underlying file or directory and return a handle to it. " + "Otherwise, the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.InvalidSymbolicLink: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the underlying object store returns a failure indicating that the attempted open operation failed due to the presence of a symbolic link in the target path name, " + "the server MUST fail the create operation with the error code STATUS_STOPPED_ON_SYMLINK. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.NotExistedValidFileName: { if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && !(accessMask.HasFlag(AccessMask.DELETE) || accessMask.HasFlag(AccessMask.GENERIC_ALL))) { if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and Treeconnect.MaximalAccess does not include DELETE or GENERIC, the server SHOULD<283> fail the request with STATUS_ACCESS_DENIED. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify the behavior of windows 2008 and 2008R2, not check here } else if (testConfig.Platform == Platform.WindowsServer2012) { //For platform windows 2012 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_INVALID_PARAMETER, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and Treeconnect.MaximalAccess does not include DELETE or GENERIC, the server SHOULD<283> fail the request with STATUS_ACCESS_DENIED. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else { //For platform windows 2012R2 and above BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and Treeconnect.MaximalAccess does not include DELETE or GENERIC, the server SHOULD<283> fail the request with STATUS_ACCESS_DENIED. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && isNonAdmin) { //NonAdminAccountCredential does not include DELETE or GENERIC_ALL in MaximalAccess if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and Treeconnect.MaximalAccess does not include DELETE or GENERIC, the server SHOULD<283> fail the request with STATUS_ACCESS_DENIED. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify te behavior of windows 2008 and 2008R2, not check here } else { //For platform win2012 and 2012R2 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and Treeconnect.MaximalAccess does not include DELETE or GENERIC, the server SHOULD<283> fail the request with STATUS_ACCESS_DENIED. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.ExistedValidFileName: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; case FileNameType.NotExistedValidFileNameWithDotDirectoryName: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; case FileNameType.NotExistedValidFileNameWithDoubleDotDirectoryName: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_INVALID_PARAMETER, header.Status, "3.3.5.9: Windows-based servers accept the path names containing Dot Directory Names specified in [MS-FSCC] section 2.1.5.1 and attempt to normalize the path name by removing the pathname components of \".\" and \"..\"." + "Windows-based servers fail the CREATE request with STATUS_INVALID_PARAMETER if the file name in the Buffer field of the request begins in the form \"subfolder\\..\\\", for example \"x\\..\\y.txt\". " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } break; default: throw new ArgumentException("fileNameType"); } }
/// <summary> /// Check the status code of create response /// </summary> /// <param name="isNonAdmin">true for non admin credential</param> /// <param name="createOption">The create option set in create request</param> /// <param name="accessMask">The access mark set in create request</param> /// <param name="header">Header of create response</param> /// <param name="response">create response</param> /// <param name="fileNameType">file name type</param> private void CheckCreateResponse(bool isNonAdmin, CreateOptions_Values createOption, AccessMask accessMask, Packet_Header header, CREATE_Response response, FileNameType fileNameType) { switch (fileNameType) { case FileNameType.SymbolicLinkInMiddle: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If any intermediate component of the path specified in the create request is a symbolic link, " + "the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.SymbolicLinkAtLast: { if (!createOption.HasFlag(CreateOptions_Values.FILE_OPEN_REPARSE_POINT)) { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the final component of the path is a symbolic link, the server behavior depends on whether the flag FILE_OPEN_REPARSE_POINT was specified in the CreateOptions field of the request. " + "If FILE_OPEN_REPARSE_POINT was specified, the server MUST open the underlying file or directory and return a handle to it. " + "Otherwise, the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.InvalidSymbolicLink: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the underlying object store returns a failure indicating that the attempted open operation failed due to the presence of a symbolic link in the target path name, " + "the server MUST fail the create operation with the error code STATUS_STOPPED_ON_SYMLINK. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.NotExistedValidFileName: { if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && !(accessMask.HasFlag(AccessMask.DELETE) || accessMask.HasFlag(AccessMask.GENERIC_ALL))) { if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify the behavior of windows 2008 and 2008R2, not check here } else if(testConfig.Platform == Platform.WindowsServer2012) { //For platform windows 2012 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_INVALID_PARAMETER, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else { //For platform windows 2012R2 and above BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && isNonAdmin) { //NonAdminAccountCredential does not include DELETE or GENERIC_ALL in MaximalAccess if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify te behavior of windows 2008 and 2008R2, not check here } else { //For platform win2012 and 2012R2 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.ExistedValidFileName: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; default: throw new ArgumentException("fileNameType"); } }