ReadWriteResponseHelper.cs 5.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using SMBLibrary.Authentication;
  10. using SMBLibrary.SMB2;
  11. using Utilities;
  12. namespace SMBLibrary.Server.SMB2
  13. {
  14. internal class ReadWriteResponseHelper
  15. {
  16. internal static SMB2Command GetReadResponse(ReadRequest request, ISMBShare share, SMB2ConnectionState state)
  17. {
  18. SMB2Session session = state.GetSession(request.Header.SessionID);
  19. OpenFileObject openFile = session.GetOpenFileObject(request.FileId);
  20. if (openFile == null)
  21. {
  22. state.LogToServer(Severity.Verbose, "Read failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
  23. return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
  24. }
  25. if (share is FileSystemShare)
  26. {
  27. if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
  28. {
  29. state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
  30. return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
  31. }
  32. }
  33. byte[] data;
  34. NTStatus readStatus = share.FileStore.ReadFile(out data, openFile.Handle, (long)request.Offset, (int)request.ReadLength);
  35. if (readStatus != NTStatus.STATUS_SUCCESS)
  36. {
  37. state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. NTStatus: {2}. (FileId: {3})", share.Name, openFile.Path, readStatus, request.FileId.Volatile);
  38. return new ErrorResponse(request.CommandName, readStatus);
  39. }
  40. ReadResponse response = new ReadResponse();
  41. response.Data = data;
  42. return response;
  43. }
  44. internal static SMB2Command GetWriteResponse(WriteRequest request, ISMBShare share, SMB2ConnectionState state)
  45. {
  46. SMB2Session session = state.GetSession(request.Header.SessionID);
  47. OpenFileObject openFile = session.GetOpenFileObject(request.FileId);
  48. if (openFile == null)
  49. {
  50. state.LogToServer(Severity.Verbose, "Write failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
  51. return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
  52. }
  53. if (share is FileSystemShare)
  54. {
  55. if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
  56. {
  57. state.LogToServer(Severity.Verbose, "Write to '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
  58. return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
  59. }
  60. }
  61. int numberOfBytesWritten;
  62. NTStatus writeStatus = share.FileStore.WriteFile(out numberOfBytesWritten, openFile.Handle, (long)request.Offset, request.Data);
  63. if (writeStatus != NTStatus.STATUS_SUCCESS)
  64. {
  65. state.LogToServer(Severity.Verbose, "Write to '{0}{1}' failed. NTStatus: {2}. (FileId: {3})", share.Name, openFile.Path, writeStatus, request.FileId.Volatile);
  66. return new ErrorResponse(request.CommandName, writeStatus);
  67. }
  68. WriteResponse response = new WriteResponse();
  69. response.Count = (uint)numberOfBytesWritten;
  70. return response;
  71. }
  72. internal static SMB2Command GetFlushResponse(FlushRequest request, ISMBShare share, SMB2ConnectionState state)
  73. {
  74. SMB2Session session = state.GetSession(request.Header.SessionID);
  75. OpenFileObject openFile = session.GetOpenFileObject(request.FileId);
  76. if (openFile == null)
  77. {
  78. state.LogToServer(Severity.Verbose, "Flush failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
  79. return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
  80. }
  81. NTStatus status = share.FileStore.FlushFileBuffers(openFile.Handle);
  82. if (status != NTStatus.STATUS_SUCCESS)
  83. {
  84. state.LogToServer(Severity.Verbose, "Flush '{0}{1}' failed. NTStatus: {2}. (FileId: {3})", share.Name, openFile.Path, status, request.FileId.Volatile);
  85. return new ErrorResponse(request.CommandName, status);
  86. }
  87. return new FlushResponse();
  88. }
  89. }
  90. }