Esempio n. 1
0
    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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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;
            }
        }