public void ToString_FormatsNumberAsDecimalOrName() { NTStatus status = 0x80000000; Assert.Equal("2147483648", status.ToString()); status = NTStatus.Code.DBG_CONTINUE; Assert.Equal("DBG_CONTINUE", status.ToString()); }
internal static SMB2Command GetQueryDirectoryResponse(QueryDirectoryRequest request, ISMBShare share, SMB2ConnectionState state) { SMB2Session session = state.GetSession(request.Header.SessionID); OpenFileObject openFile = session.GetOpenFileObject(request.FileId); if (openFile == null) { state.LogToServer(Severity.Verbose, "Query Directory failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED)); } if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "Query Directory on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED)); } FileSystemShare fileSystemShare = (FileSystemShare)share; FileID fileID = request.FileId; OpenSearch openSearch = session.GetOpenSearch(fileID); if (openSearch == null || request.Reopen) { if (request.Reopen) { session.RemoveOpenSearch(fileID); } List <QueryDirectoryFileInformation> entries; NTStatus searchStatus = share.FileStore.QueryDirectory(out entries, openFile.Handle, request.FileName, request.FileInformationClass); if (searchStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Query Directory on '{0}{1}', Searched for '{2}', NTStatus: {3}", share.Name, openFile.Path, request.FileName, searchStatus.ToString()); return(new ErrorResponse(request.CommandName, searchStatus)); } state.LogToServer(Severity.Information, "Query Directory on '{0}{1}', Searched for '{2}', found {3} matching entries", share.Name, openFile.Path, request.FileName, entries.Count); openSearch = session.AddOpenSearch(fileID, entries, 0); } if (request.Restart || request.Reopen) { openSearch.EnumerationLocation = 0; } if (openSearch.Entries.Count == 0) { // [MS-SMB2] If there are no entries to return [..] the server MUST fail the request with STATUS_NO_SUCH_FILE. session.RemoveOpenSearch(fileID); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NO_SUCH_FILE)); } if (openSearch.EnumerationLocation == openSearch.Entries.Count) { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NO_MORE_FILES)); } List <QueryDirectoryFileInformation> page = new List <QueryDirectoryFileInformation>(); int pageLength = 0; for (int index = openSearch.EnumerationLocation; index < openSearch.Entries.Count; index++) { QueryDirectoryFileInformation fileInformation = openSearch.Entries[index]; if (fileInformation.FileInformationClass != request.FileInformationClass) { // We do not support changing FileInformationClass during a search (unless SMB2_REOPEN is set). return(new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER)); } int entryLength = fileInformation.Length; if (pageLength + entryLength <= request.OutputBufferLength) { page.Add(fileInformation); int paddedLength = (int)Math.Ceiling((double)entryLength / 8) * 8; pageLength += paddedLength; openSearch.EnumerationLocation = index + 1; } else { break; } if (request.ReturnSingleEntry) { break; } } QueryDirectoryResponse response = new QueryDirectoryResponse(); response.SetFileInformationList(page); return(response); }
internal static Transaction2FindFirst2Response GetSubcommandResponse(SMB1Header header, uint maxDataCount, Transaction2FindFirst2Request subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); string fileNamePattern = subcommand.FileName; if (!fileNamePattern.StartsWith(@"\")) { fileNamePattern = @"\" + fileNamePattern; } List <QueryDirectoryFileInformation> entries; FileInformationClass informationClass; try { informationClass = FindInformationHelper.ToFileInformationClass(subcommand.InformationLevel); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "FindFirst2: Unsupported information level: {0}.", subcommand.InformationLevel); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } NTStatus searchStatus = SMB1FileStoreHelper.QueryDirectory(out entries, share.FileStore, fileNamePattern, informationClass, session.SecurityContext); if (searchStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "FindFirst2: Searched for '{0}{1}', NTStatus: {2}", share.Name, fileNamePattern, searchStatus.ToString()); header.Status = searchStatus; return(null); } // We ignore SearchAttributes state.LogToServer(Severity.Information, "FindFirst2: Searched for '{0}{1}', found {2} matching entries", share.Name, fileNamePattern, entries.Count); // [MS-CIFS] If no matching entries are found, the server SHOULD fail the request with STATUS_NO_SUCH_FILE. if (entries.Count == 0) { header.Status = NTStatus.STATUS_NO_SUCH_FILE; return(null); } bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0; int entriesToReturn = Math.Min(subcommand.SearchCount, entries.Count); List <QueryDirectoryFileInformation> segment = entries.GetRange(0, entriesToReturn); int maxLength = (int)maxDataCount; FindInformationList findInformationList; try { findInformationList = FindInformationHelper.ToFindInformationList(segment, header.UnicodeFlag, maxLength); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "FindFirst2: Unsupported information level: {0}.", subcommand.InformationLevel); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } int returnCount = findInformationList.Count; Transaction2FindFirst2Response response = new Transaction2FindFirst2Response(); response.SetFindInformationList(findInformationList, header.UnicodeFlag); response.EndOfSearch = (returnCount == entries.Count); // If [..] the search fit within a single response and SMB_FIND_CLOSE_AT_EOS is set in the Flags field, // or if SMB_FIND_CLOSE_AFTER_REQUEST is set in the request, // the server SHOULD return a SID field value of zero. // This indicates that the search has been closed and is no longer active on the server. if ((response.EndOfSearch && subcommand.CloseAtEndOfSearch) || subcommand.CloseAfterRequest) { response.SID = 0; } else { ushort?searchHandle = session.AddOpenSearch(entries, returnCount); if (!searchHandle.HasValue) { header.Status = NTStatus.STATUS_OS2_NO_MORE_SIDS; return(null); } response.SID = searchHandle.Value; } return(response); }
public static void HandleStatus(this NTStatus status) { switch (status) { //ERRDOS Class 0x01 case (NTStatus.STATUS_NOT_IMPLEMENTED): throw new NotImplementedException($"{status.ToString()}: {ERRBadFunc}"); case (NTStatus.STATUS_INVALID_DEVICE_REQUEST): throw new InvalidOperationException($"{status.ToString()}: {ERRBadFunc}"); case (NTStatus.STATUS_NO_SUCH_FILE): case (NTStatus.STATUS_NO_SUCH_DEVICE): case (NTStatus.STATUS_OBJECT_NAME_NOT_FOUND): throw new FileNotFoundException($"{status.ToString()}: {ERRBadFile}"); case (NTStatus.STATUS_OBJECT_PATH_INVALID): case (NTStatus.STATUS_OBJECT_PATH_NOT_FOUND): case (NTStatus.STATUS_OBJECT_PATH_SYNTAX_BAD): throw new DirectoryNotFoundException($"{status.ToString()}: {ERRBadPath}"); case (NTStatus.STATUS_TOO_MANY_OPENED_FILES): throw new FileNotFoundException($"{status.ToString()}: {ERRNoFids}"); case (NTStatus.STATUS_ACCESS_DENIED): case (NTStatus.STATUS_DELETE_PENDING): case (NTStatus.STATUS_PRIVILEGE_NOT_HELD): case (NTStatus.STATUS_LOGON_FAILURE): case (NTStatus.STATUS_FILE_IS_A_DIRECTORY): case (NTStatus.STATUS_CANNOT_DELETE): throw new UnauthorizedAccessException($"{status.ToString()}: {ERRNoAccess}"); case (NTStatus.STATUS_SMB_BAD_FID): case (NTStatus.STATUS_INVALID_HANDLE): case (NTStatus.STATUS_FILE_CLOSED): throw new ArgumentException($"{status.ToString()}: {ERRBadFid}"); case (NTStatus.STATUS_INSUFF_SERVER_RESOURCES): throw new OutOfMemoryException($"{status.ToString()}:{ERRNoMem}"); case (NTStatus.STATUS_OS2_INVALID_ACCESS): throw new UnauthorizedAccessException($"{status.ToString()}: {ERRBadAccess}"); case (NTStatus.STATUS_DATA_ERROR): throw new InvalidDataException($"{status.ToString()}: {ERRBadData}"); case (NTStatus.STATUS_DIRECTORY_NOT_EMPTY): throw new IOException($"{status.ToString()}: {ERRRemCd}"); case (NTStatus.STATUS_NO_MORE_FILES): throw new IOException($"{status.ToString()}: {ERRNoFiles}"); case (NTStatus.STATUS_END_OF_FILE): throw new IOException($"{status.ToString()}: {ERREof}"); case (NTStatus.STATUS_NOT_SUPPORTED): throw new NotSupportedException($"{status.ToString()}: {ERRUnsup}"); case (NTStatus.STATUS_OBJECT_NAME_COLLISION): throw new IOException($"{status.ToString()}: {ERRFileExists}"); case (NTStatus.STATUS_INVALID_PARAMETER): throw new ArgumentException($"{status.ToString()}: {ERRInvalidParam}"); case (NTStatus.STATUS_OS2_INVALID_LEVEL): throw new UnsupportedInformationLevelException($"{status.ToString()}: {ERRUnknownLevel}"); case (NTStatus.STATUS_RANGE_NOT_LOCKED): throw new AccessViolationException($"{status.ToString()}: {ERROR_NOT_LOCKED}"); case (NTStatus.STATUS_OS2_NO_MORE_SIDS): throw new InvalidOperationException($"{status.ToString()}: {ERROR_NO_MORE_SEARCH_HANDLES}"); case (NTStatus.STATUS_INVALID_INFO_CLASS): throw new UnsupportedInformationLevelException($"{status.ToString()}: {ERRBadPipe}"); case (NTStatus.STATUS_BUFFER_OVERFLOW): case (NTStatus.STATUS_MORE_PROCESSING_REQUIRED): throw new InvalidOperationException($"{status.ToString()}: {ERRMoreData}"); case (NTStatus.STATUS_NOTIFY_ENUM_DIR): throw new AccessViolationException($"{status.ToString()}: {ERR_NOTIFY_ENUM_DIR}"); //ERRSRV Class 0x02 case (NTStatus.STATUS_INVALID_SMB): throw new ArgumentException($"{status.ToString()}: {ERRInvSmb}"); //Is there a better exception for this? case (NTStatus.STATUS_NETWORK_NAME_DELETED): case (NTStatus.STATUS_SMB_BAD_TID): throw new ArgumentException($"{status.ToString()}: {ERRInvTid}"); case (NTStatus.STATUS_BAD_NETWORK_NAME): throw new ArgumentException($"{status.ToString()}: {ERRInvNetName}"); case (NTStatus.STATUS_SMB_BAD_COMMAND): throw new NotImplementedException($"{status.ToString()}: {ERRBadCmd}"); case (NTStatus.STATUS_TOO_MANY_SESSIONS): throw new ApplicationException($"{status.ToString()}: {ERRTooManyUids}"); case (NTStatus.STATUS_ACCOUNT_DISABLED): case (NTStatus.STATUS_ACCOUNT_EXPIRED): throw new AuthenticationException($"{status.ToString()}: {ERRAccountExpired}"); case (NTStatus.STATUS_INVALID_WORKSTATION): throw new UnauthorizedAccessException($"{status.ToString()}: {ERRBadClient}"); case (NTStatus.STATUS_INVALID_LOGON_HOURS): throw new UnauthorizedAccessException($"{status.ToString()}: {ERRBadLogonTime}"); case (NTStatus.STATUS_PASSWORD_EXPIRED): case (NTStatus.STATUS_PASSWORD_MUST_CHANGE): throw new InvalidCredentialException($"{status.ToString()}: {ERRPasswordExpired}"); //ERRHRD Class 0x03 case (NTStatus.STATUS_MEDIA_WRITE_PROTECTED): throw new AccessViolationException($"{status.ToString()}: {ERRNoWrite}"); case (NTStatus.STATUS_SHARING_VIOLATION): throw new InvalidOperationException($"{status.ToString()}: {ERRBadShare}"); case (NTStatus.STATUS_FILE_LOCK_CONFLICT): throw new InvalidOperationException($"{status.ToString()}: {ERRLock}"); //Others case (NTStatus.STATUS_DISK_FULL): throw new IOException($"{ status.ToString() }: Disk is full."); case (NTStatus.STATUS_LOGON_TYPE_NOT_GRANTED): throw new UnauthorizedAccessException($"{status.ToString()}: {NTStatus_STATUS_LOGON_TYPE_NOT_GRANTED}"); case (NTStatus.STATUS_ACCOUNT_LOCKED_OUT): throw new UnauthorizedAccessException($"{status.ToString()}: {NTStatus_STATUS_ACCOUNT_LOCKED_OUT}"); case (NTStatus.STATUS_ACCOUNT_RESTRICTION): throw new UnauthorizedAccessException($"{status.ToString()}: {NTStatus_STATUS_ACCOUNT_RESTRICTION}"); case (NTStatus.SEC_E_INVALID_TOKEN): throw new UnauthorizedAccessException($"{status.ToString()}"); case (NTStatus.SEC_E_SECPKG_NOT_FOUND): throw new InvalidCredentialException($"{status.ToString()}"); case (NTStatus.STATUS_OBJECT_NAME_INVALID): throw new MemberAccessException($"{status.ToString()}: {NTStatus_STATUS_OBJECT_NAME_INVALID}"); case (NTStatus.STATUS_OBJECT_NAME_EXISTS): throw new InvalidOperationException($"{status.ToString()}: {NTStatus_STATUS_OBJECT_NAME_EXISTS}"); case (NTStatus.STATUS_LOCK_NOT_GRANTED): throw new IOException($"{status.ToString()}: {NTStatus_STATUS_LOCK_NOT_GRANTED}"); case (NTStatus.STATUS_BUFFER_TOO_SMALL): throw new ArgumentException($"{status.ToString()}: {NTStatus_STATUS_BUFFER_TOO_SMALL}"); case (NTStatus.STATUS_BAD_DEVICE_TYPE): throw new InvalidOperationException($"{status.ToString()}: {NTStatus_STATUS_BAD_DEVICE_TYPE}"); case (NTStatus.STATUS_FS_DRIVER_REQUIRED): throw new FileLoadException($"{status.ToString()}: {NTStatus_STATUS_FS_DRIVER_REQUIRED}"); case (NTStatus.STATUS_USER_SESSION_DELETED): throw new UnauthorizedAccessException($"{status.ToString()}: {NTStatus_STATUS_USER_SESSION_DELETED}"); case (NTStatus.SEC_I_CONTINUE_NEEDED): throw new InvalidOperationException($"{status.ToString()}"); case (NTStatus.STATUS_CANCELLED): throw new IOException($"{status.ToString()}: {NTStatus_STATUS_CANCELLED}"); case (NTStatus.STATUS_PENDING): throw new InvalidOperationException($"{status.ToString()}: {NTStatus_STATUS_PENDING}"); case (SMBLibrary.NTStatus) 3221225566: throw new UnauthorizedAccessException("No logon servers are currently available to service the logon request."); case (NTStatus.STATUS_NOTIFY_CLEANUP): //Indicates that a notify change request has been completed due to closing the handle that made the notify change request. case (NTStatus.STATUS_SUCCESS): break; default: break; } }