TreeConnectHelper.cs 5.0 KB

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