internal static SMB2Command GetCreateResponse(CreateRequest request, ISMBShare share, SMB2ConnectionState state)
        {
            SMB2Session session = state.GetSession(request.Header.SessionID);
            string      path    = request.Name;

            if (!path.StartsWith(@"\"))
            {
                path = @"\" + path;
            }

            FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                {
                    state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, path, session.UserName);
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED));
                }
            }

            object     handle;
            FileStatus fileStatus;
            // GetFileInformation/FileNetworkOpenInformation requires FILE_READ_ATTRIBUTES
            AccessMask desiredAccess = request.DesiredAccess | (AccessMask)FileAccessMask.FILE_READ_ATTRIBUTES;
            NTStatus   createStatus  = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, request.FileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);

            if (createStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus);
                return(new ErrorResponse(request.CommandName, createStatus));
            }

            FileAccess fileAccess = NTFileStoreHelper.ToFileAccess(desiredAccess);
            FileID?    fileID     = session.AddOpenFile(request.Header.TreeID, share.Name, path, handle, fileAccess);

            if (fileID == null)
            {
                share.FileStore.CloseFile(handle);
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path);
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_TOO_MANY_OPENED_FILES));
            }

            string fileAccessString  = fileAccess.ToString().Replace(", ", "|");
            string shareAccessString = request.ShareAccess.ToString().Replace(", ", "|");

            state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}', FileAccess: {2}, ShareAccess: {3}. (SessionID: {4}, TreeID: {5}, FileId: {6})", share.Name, path, fileAccessString, shareAccessString, request.Header.SessionID, request.Header.TreeID, fileID.Value.Volatile);
            if (share is NamedPipeShare)
            {
                return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
            }
            else
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle);
                CreateResponse             response = CreateResponseFromFileSystemEntry(fileInfo, fileID.Value, fileStatus);
                return(response);
            }
        }
        internal static SMB2Command GetCreateResponse(CreateRequest request, ISMBShare share, SMB2ConnectionState state)
        {
            SMB2Session session = state.GetSession(request.Header.SessionID);
            string      path    = request.Name;

            if (!path.StartsWith(@"\"))
            {
                path = @"\" + path;
            }

            FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                {
                    state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, path, session.UserName);
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED));
                }
            }

            object     handle;
            FileStatus fileStatus;
            NTStatus   createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);

            if (createStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: '{2}'.", share.Name, path, createStatus);
                return(new ErrorResponse(request.CommandName, createStatus));
            }

            state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}'.", share.Name, path);
            FileID?fileID = session.AddOpenFile(request.Header.TreeID, path, handle);

            if (fileID == null)
            {
                share.FileStore.CloseFile(handle);
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_TOO_MANY_OPENED_FILES));
            }

            if (share is NamedPipeShare)
            {
                return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
            }
            else
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle);
                CreateResponse             response = CreateResponseFromFileSystemEntry(fileInfo, fileID.Value, fileStatus);
                if (request.RequestedOplockLevel == OplockLevel.Batch)
                {
                    response.OplockLevel = OplockLevel.Batch;
                }
                return(response);
            }
        }
Exemple #3
0
        public static NTStatus SetInformation2(INTFileStore fileStore, object handle, DateTime?creationTime, DateTime?lastAccessTime, DateTime?lastWriteTime)
        {
            FileNetworkOpenInformation fileInfo  = NTFileStoreHelper.GetNetworkOpenInformation(fileStore, handle);
            FileBasicInformation       basicInfo = new FileBasicInformation();

            basicInfo.FileAttributes = fileInfo.FileAttributes;
            basicInfo.CreationTime   = creationTime;
            basicInfo.LastAccessTime = lastAccessTime;
            basicInfo.LastWriteTime  = lastWriteTime;
            return(fileStore.SetFileInformation(handle, basicInfo));
        }
Exemple #4
0
        public static NTStatus QueryInformation(out FileNetworkOpenInformation fileInfo, INTFileStore fileStore, string path, SecurityContext securityContext)
        {
            object     handle;
            FileStatus fileStatus;
            NTStatus   openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext);

            if (openStatus != NTStatus.STATUS_SUCCESS)
            {
                fileInfo = null;
                return(openStatus);
            }

            fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(fileStore, handle);
            return(NTStatus.STATUS_SUCCESS);
        }
Exemple #5
0
        internal static SMB2Command GetCloseResponse(CloseRequest 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, "Close 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));
            }

            NTStatus closeStatus = share.FileStore.CloseFile(openFile.Handle);

            if (closeStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Information, "Close: Closing '{0}{1}' failed. NTStatus: {2}. (SessionID: {3}, TreeID: {4}, FileId: {5})", share.Name, openFile.Path, closeStatus, request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
                return(new ErrorResponse(request.CommandName, closeStatus));
            }

            state.LogToServer(Severity.Information, "Close: Closed '{0}{1}'. (SessionID: {2}, TreeID: {3}, FileId: {4})", share.Name, openFile.Path, request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
            session.RemoveOpenFile(request.FileId);
            CloseResponse response = new CloseResponse();

            if (request.PostQueryAttributes)
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, openFile.Path, session.SecurityContext);
                if (fileInfo != null)
                {
                    response.CreationTime   = fileInfo.CreationTime;
                    response.LastAccessTime = fileInfo.LastAccessTime;
                    response.LastWriteTime  = fileInfo.LastWriteTime;
                    response.ChangeTime     = fileInfo.ChangeTime;
                    response.AllocationSize = fileInfo.AllocationSize;
                    response.EndofFile      = fileInfo.EndOfFile;
                    response.FileAttributes = fileInfo.FileAttributes;
                }
            }
            return(response);
        }
Exemple #6
0
        internal static SMB1Command GetOpenAndXResponse(SMB1Header header, OpenAndXRequest request, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session session    = state.GetSession(header.UID);
            bool        isExtended = (request.Flags & OpenFlags.SMB_OPEN_EXTENDED_RESPONSE) > 0;
            string      path       = request.FileName;

            if (!path.StartsWith(@"\"))
            {
                path = @"\" + path;
            }

            AccessMask        desiredAccess;
            ShareAccess       shareAccess;
            CreateDisposition createDisposition;

            try
            {
                desiredAccess     = ToAccessMask(request.AccessMode.AccessMode);
                shareAccess       = ToShareAccess(request.AccessMode.SharingMode);
                createDisposition = ToCreateDisposition(request.OpenMode);
            }
            catch (ArgumentException)
            {
                // Invalid input according to MS-CIFS
                header.Status = NTStatus.STATUS_OS2_INVALID_ACCESS;
                return(new ErrorResponse(request.CommandName));
            }
            CreateOptions createOptions = ToCreateOptions(request.AccessMode);

            FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(desiredAccess, createDisposition);

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                {
                    state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName);
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(new ErrorResponse(request.CommandName));
                }
            }

            object     handle;
            FileStatus fileStatus;

            header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, 0, shareAccess, createDisposition, createOptions, session.SecurityContext);
            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, header.Status);
                return(new ErrorResponse(request.CommandName));
            }

            FileAccess fileAccess = ToFileAccess(request.AccessMode.AccessMode);
            ushort?    fileID     = session.AddOpenFile(header.TID, share.Name, path, handle, fileAccess);

            if (!fileID.HasValue)
            {
                share.FileStore.CloseFile(handle);
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path);
                header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES;
                return(new ErrorResponse(request.CommandName));
            }

            state.LogToServer(Severity.Verbose, "OpenAndX: Opened '{0}{1}'. (UID: {2}, TID: {3}, FID: {4})", share.Name, path, header.UID, header.TID, fileID.Value);
            OpenResult openResult = ToOpenResult(fileStatus);

            if (share is NamedPipeShare)
            {
                if (isExtended)
                {
                    return(CreateResponseExtendedForNamedPipe(fileID.Value, openResult));
                }
                else
                {
                    return(CreateResponseForNamedPipe(fileID.Value, openResult));
                }
            }
            else // FileSystemShare
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle);
                if (isExtended)
                {
                    return(CreateResponseExtendedFromFileInfo(fileInfo, fileID.Value, openResult));
                }
                else
                {
                    return(CreateResponseFromFileInfo(fileInfo, fileID.Value, openResult));
                }
            }
        }
        internal static SMB1Command GetNTCreateResponse(SMB1Header header, NTCreateAndXRequest request, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session session      = state.GetSession(header.UID);
            bool        isExtended   = (request.Flags & NTCreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE) > 0;
            string      path         = request.FileName;
            FileAccess  createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                {
                    state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName);
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(new ErrorResponse(request.CommandName));
                }
            }

            object     handle;
            FileStatus fileStatus;
            NTStatus   createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);

            if (createStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: '{2}'.", share.Name, path, createStatus);
                header.Status = createStatus;
                return(new ErrorResponse(request.CommandName));
            }

            state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}'.", share.Name, path);
            ushort?fileID = session.AddOpenFile(header.TID, path, handle);

            if (!fileID.HasValue)
            {
                share.FileStore.CloseFile(handle);
                header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES;
                return(new ErrorResponse(request.CommandName));
            }

            if (share is NamedPipeShare)
            {
                if (isExtended)
                {
                    return(CreateResponseExtendedForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
                }
                else
                {
                    return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
                }
            }
            else // FileSystemShare
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle);
                if (isExtended)
                {
                    NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileInformation(fileInfo, fileID.Value, fileStatus);
                    if ((request.Flags & NTCreateFlags.NT_CREATE_REQUEST_OPBATCH) > 0)
                    {
                        response.OpLockLevel = OpLockLevel.BatchOpLockGranted;
                    }
                    return(response);
                }
                else
                {
                    NTCreateAndXResponse response = CreateResponseFromFileInformation(fileInfo, fileID.Value, fileStatus);
                    if ((request.Flags & NTCreateFlags.NT_CREATE_REQUEST_OPBATCH) > 0)
                    {
                        response.OpLockLevel = OpLockLevel.BatchOpLockGranted;
                    }
                    return(response);
                }
            }
        }
Exemple #8
0
        internal static SMB1Command GetNTCreateResponse(SMB1Header header, NTCreateAndXRequest request, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session session    = state.GetSession(header.UID);
            bool        isExtended = (request.Flags & NTCreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE) > 0;
            string      path       = request.FileName;

            if (!path.StartsWith(@"\"))
            {
                path = @"\" + path;
            }

            FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);

            if (share is FileSystemShare)
            {
                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                {
                    state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName);
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(new ErrorResponse(request.CommandName));
                }
            }

            object         handle;
            FileStatus     fileStatus;
            FileAttributes fileAttributes = ToFileAttributes(request.ExtFileAttributes);
            // GetFileInformation/FileNetworkOpenInformation requires FILE_READ_ATTRIBUTES
            AccessMask desiredAccess = request.DesiredAccess | (AccessMask)FileAccessMask.FILE_READ_ATTRIBUTES;
            NTStatus   createStatus  = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, fileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);

            if (createStatus != NTStatus.STATUS_SUCCESS)
            {
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus);
                header.Status = createStatus;
                return(new ErrorResponse(request.CommandName));
            }

            FileAccess fileAccess = NTFileStoreHelper.ToFileAccess(desiredAccess);
            ushort?    fileID     = session.AddOpenFile(header.TID, share.Name, path, handle, fileAccess);

            if (!fileID.HasValue)
            {
                share.FileStore.CloseFile(handle);
                state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path);
                header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES;
                return(new ErrorResponse(request.CommandName));
            }

            string fileAccessString  = fileAccess.ToString().Replace(", ", "|");
            string shareAccessString = request.ShareAccess.ToString().Replace(", ", "|");

            state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}', FileAccess: {2}, ShareAccess: {3}. (UID: {4}, TID: {5}, FID: {6})", share.Name, path, fileAccessString, shareAccessString, header.UID, header.TID, fileID.Value);
            if (share is NamedPipeShare)
            {
                if (isExtended)
                {
                    return(CreateResponseExtendedForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
                }
                else
                {
                    return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED));
                }
            }
            else // FileSystemShare
            {
                FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle);
                if (isExtended)
                {
                    NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileInformation(fileInfo, fileID.Value, fileStatus);
                    return(response);
                }
                else
                {
                    NTCreateAndXResponse response = CreateResponseFromFileInformation(fileInfo, fileID.Value, fileStatus);
                    return(response);
                }
            }
        }