Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
            }
        }