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); } }