Example #1
0
        public NTStatus GetFileInformation(out QueryInformation result, object handle, QueryInformationLevel informationLevel)
        {
            result = null;
            int maxOutputLength = 4096;
            Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest();

            subcommand.FID = (ushort)handle;
            subcommand.QueryInformationLevel = informationLevel;

            Transaction2Request request = new Transaction2Request();

            request.Setup               = subcommand.GetSetup();
            request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
            request.TransData           = subcommand.GetData(m_client.Unicode);
            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

            TrySendMessage(request);
            SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);

            if (reply != null)
            {
                if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                {
                    Transaction2Response response = (Transaction2Response)reply.Commands[0];
                    Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                    result = subcommandResponse.GetQueryInformation(informationLevel);
                }
                return(reply.Header.Status);
            }
            return(NTStatus.STATUS_INVALID_SMB);
        }
Example #2
0
        public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
        {
            result = null;
            if (m_client.InfoLevelPassthrough)
            {
                int maxOutputLength = 4096;
                Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest();
                subcommand.FID = (ushort)handle;
                subcommand.FileInformationClass = informationClass;

                Transaction2Request request = new Transaction2Request();
                request.Setup               = subcommand.GetSetup();
                request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
                request.TransData           = subcommand.GetData(m_client.Unicode);
                request.TotalDataCount      = (ushort)request.TransData.Length;
                request.TotalParameterCount = (ushort)request.TransParameters.Length;
                request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
                request.MaxDataCount        = (ushort)maxOutputLength;

                TrySendMessage(request);
                SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);
                if (reply != null)
                {
                    if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                    {
                        Transaction2Response response = (Transaction2Response)reply.Commands[0];
                        Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                        if (informationClass == FileInformationClass.FileAllInformation)
                        {
                            // Windows implementations return SMB_QUERY_FILE_ALL_INFO when a client specifies native NT passthrough level "FileAllInformation".
                            QueryInformation queryFileAllInfo = subcommandResponse.GetQueryInformation(QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO);
                            result = QueryInformationHelper.ToFileInformation(queryFileAllInfo);
                        }
                        else
                        {
                            result = subcommandResponse.GetFileInformation(informationClass);
                        }
                    }
                    return(reply.Header.Status);
                }
                return(NTStatus.STATUS_INVALID_SMB);
            }
            else
            {
                QueryInformationLevel informationLevel = QueryInformationHelper.ToFileInformationLevel(informationClass);
                QueryInformation      queryInformation;
                NTStatus status = GetFileInformation(out queryInformation, handle, informationLevel);
                if (status == NTStatus.STATUS_SUCCESS)
                {
                    result = QueryInformationHelper.ToFileInformation(queryInformation);
                }
                return(status);
            }
        }
Example #3
0
        public void GetFileInformation(out FileInformation result, NtHandle handle, FileInformationClass informationClass)
        {
            if (m_client.InfoLevelPassthrough)
            {
                int maxOutputLength = 4096;
                Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest
                {
                    FID = ((Smb1Handle)handle).FID,
                    FileInformationClass = informationClass
                };

                Transaction2Request request = new Transaction2Request
                {
                    Setup           = subcommand.GetSetup(),
                    TransParameters = subcommand.GetParameters(m_client.Unicode),
                    TransData       = subcommand.GetData(m_client.Unicode)
                };
                request.TotalDataCount      = (ushort)request.TransData.Length;
                request.TotalParameterCount = (ushort)request.TransParameters.Length;
                request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
                request.MaxDataCount        = (ushort)maxOutputLength;

                TrySendMessage(request);
                SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);
                reply.IsSuccessElseThrow();
                if (!(reply.Commands[0] is Transaction2Response transaction2Response))
                {
                    throw new NtStatusException(reply.Header.Status);
                }

                Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(transaction2Response.TransParameters, transaction2Response.TransData);
                if (informationClass == FileInformationClass.FileAllInformation)
                {
                    // Windows implementations return SMB_QUERY_FILE_ALL_INFO when a client specifies native NT passthrough level "FileAllInformation".
                    QueryInformation queryFileAllInfo = subcommandResponse.GetQueryInformation(QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO);
                    result = QueryInformationHelper.ToFileInformation(queryFileAllInfo);
                }
                else
                {
                    result = subcommandResponse.GetFileInformation(informationClass);
                }
                reply.IsSuccessElseThrow();
                return;
            }

            QueryInformationLevel informationLevel = QueryInformationHelper.ToFileInformationLevel(informationClass);

            GetFileInformation(out QueryInformation? queryInformation, handle, informationLevel);
            result = QueryInformationHelper.ToFileInformation(queryInformation);
        }
Example #4
0
        public void GetFileInformation(out QueryInformation result, NtHandle handle, QueryInformationLevel informationLevel)
        {
            int maxOutputLength = 4096;
            Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest
            {
                FID = ((Smb1Handle)handle).FID,
                QueryInformationLevel = informationLevel
            };

            Transaction2Request request = new Transaction2Request
            {
                Setup           = subcommand.GetSetup(),
                TransParameters = subcommand.GetParameters(m_client.Unicode),
                TransData       = subcommand.GetData(m_client.Unicode)
            };

            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

            TrySendMessage(request);
            SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);

            reply.IsSuccessElseThrow();
            if (!(reply.Commands[0] is Transaction2Response))
            {
                throw new NtStatusException(reply.Header.Status);
            }

            Transaction2Response response = (Transaction2Response)reply.Commands[0];
            Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(response.TransParameters, response.TransData);

            result = subcommandResponse.GetQueryInformation(informationLevel);
            reply.IsSuccessElseThrow();
        }
        internal static Transaction2QueryFileInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2QueryFileInformationRequest subcommand, FileSystemShare share, StateObject state)
        {
            IFileSystem fileSystem     = share.FileSystem;
            string      openedFilePath = state.GetOpenedFilePath(subcommand.FID);

            if (openedFilePath == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            FileSystemEntry entry = fileSystem.GetEntry(openedFilePath);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(null);
            }
            Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse();

            response.QueryInfo = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel);

            return(response);
        }
Example #6
0
        internal static Transaction2QueryFileInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryFileInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session    session  = state.GetSession(header.UID);
            OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);

            if (openFile == null)
            {
                state.LogToServer(Severity.Verbose, "QueryFileInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID);
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                {
                    state.LogToServer(Severity.Verbose, "QueryFileInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(null);
                }
            }

            Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse();

            if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass != FileInformationClass.FileAllInformation)
            {
                FileInformation fileInfo;
                NTStatus        status = share.FileStore.GetFileInformation(out fileInfo, openFile.Handle, subcommand.FileInformationClass);
                if (status != NTStatus.STATUS_SUCCESS)
                {
                    state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.FileInformationClass, status, subcommand.FID);
                    header.Status = status;
                    return(null);
                }
                state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information class: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.FileInformationClass, subcommand.FID);
                response.SetFileInformation(fileInfo);
            }
            else
            {
                // The FILE_ALL_INFORMATION structure described in [MS-FSCC], is NOT used by [MS-SMB]
                if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass == FileInformationClass.FileAllInformation)
                {
                    subcommand.QueryInformationLevel = QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO;
                }
                QueryInformation queryInformation;
                NTStatus         status = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, openFile.Handle, subcommand.QueryInformationLevel);
                if (status != NTStatus.STATUS_SUCCESS)
                {
                    state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.QueryInformationLevel, status, subcommand.FID);
                    header.Status = status;
                    return(null);
                }
                state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.QueryInformationLevel, subcommand.FID);
                response.SetQueryInformation(queryInformation);
            }
            return(response);
        }
Example #7
0
        internal static Transaction2QueryFileInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryFileInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session    session  = state.GetSession(header.UID);
            OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);

            if (openFile == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                {
                    state.LogToServer(Severity.Verbose, "QueryFileInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(null);
                }
            }

            Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse();
            QueryInformation queryInformation;
            NTStatus         queryStatus = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, openFile.Handle, subcommand.InformationLevel);

            if (queryStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}", share.Name, openFile.Path, subcommand.InformationLevel, queryStatus);
                header.Status = queryStatus;
                return(null);
            }
            state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}", share.Name, openFile.Path, subcommand.InformationLevel);
            response.SetQueryInformation(queryInformation);
            return(response);
        }