TreeConnectHelper.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* Copyright (C) 2014 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 System.Text;
  10. using SMBLibrary.SMB1;
  11. using Utilities;
  12. namespace SMBLibrary.Server
  13. {
  14. public class TreeConnectHelper
  15. {
  16. internal static SMBCommand GetTreeConnectResponse(SMBHeader header, TreeConnectAndXRequest request, StateObject state, ShareCollection shares)
  17. {
  18. bool isExtended = (request.Flags & TreeConnectFlags.ExtendedResponse) > 0;
  19. string relativePath = ServerPathUtils.GetRelativeServerPath(request.Path);
  20. if (String.Equals(relativePath, "\\IPC$", StringComparison.InvariantCultureIgnoreCase))
  21. {
  22. header.TID = state.AddConnectedTree(relativePath);
  23. if (isExtended)
  24. {
  25. return CreateTreeConnectResponseExtended(ServiceName.NamedPipe);
  26. }
  27. else
  28. {
  29. return CreateTreeConnectResponse(ServiceName.NamedPipe);
  30. }
  31. }
  32. else
  33. {
  34. FileSystemShare share = shares.GetShareFromRelativePath(relativePath);
  35. if (share == null)
  36. {
  37. header.Status = NTStatus.STATUS_OBJECT_PATH_NOT_FOUND;
  38. return new ErrorResponse(CommandName.SMB_COM_TREE_CONNECT_ANDX);
  39. }
  40. else
  41. {
  42. string userName = state.GetConnectedUserName(header.UID);
  43. if (!share.HasReadAccess(userName))
  44. {
  45. header.Status = NTStatus.STATUS_ACCESS_DENIED;
  46. return new ErrorResponse(CommandName.SMB_COM_TREE_CONNECT_ANDX);
  47. }
  48. else
  49. {
  50. header.TID = state.AddConnectedTree(relativePath);
  51. if (isExtended)
  52. {
  53. return CreateTreeConnectResponseExtended(ServiceName.DiskShare);
  54. }
  55. else
  56. {
  57. return CreateTreeConnectResponse(ServiceName.DiskShare);
  58. }
  59. }
  60. }
  61. }
  62. }
  63. private static TreeConnectAndXResponse CreateTreeConnectResponse(ServiceName serviceName)
  64. {
  65. TreeConnectAndXResponse response = new TreeConnectAndXResponse();
  66. response.OptionalSupport = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS;
  67. response.NativeFileSystem = String.Empty;
  68. response.Service = serviceName;
  69. return response;
  70. }
  71. private static TreeConnectAndXResponseExtended CreateTreeConnectResponseExtended(ServiceName serviceName)
  72. {
  73. TreeConnectAndXResponseExtended response = new TreeConnectAndXResponseExtended();
  74. response.OptionalSupport = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS;
  75. response.MaximalShareAccessRights.File = FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA | FileAccessMask.FILE_APPEND_DATA |
  76. FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA |
  77. FileAccessMask.FILE_EXECUTE |
  78. FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES |
  79. FileAccessMask.DELETE | FileAccessMask.READ_CONTROL | FileAccessMask.WRITE_DAC | FileAccessMask.WRITE_OWNER | FileAccessMask.SYNCHRONIZE;
  80. response.GuestMaximalShareAccessRights.File = FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA |
  81. FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA |
  82. FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES |
  83. FileAccessMask.READ_CONTROL | FileAccessMask.SYNCHRONIZE;
  84. response.NativeFileSystem = String.Empty;
  85. response.Service = serviceName;
  86. return response;
  87. }
  88. internal static SMBCommand GetTreeDisconnectResponse(SMBHeader header, TreeDisconnectRequest request, StateObject state)
  89. {
  90. if (!state.IsTreeConnected(header.TID))
  91. {
  92. header.Status = NTStatus.STATUS_SMB_BAD_TID;
  93. return new ErrorResponse(CommandName.SMB_COM_TREE_DISCONNECT);
  94. }
  95. state.RemoveConnectedTree(header.TID);
  96. return new TreeDisconnectResponse();
  97. }
  98. }
  99. }