Example #1
0
        public ISMBFileStore TreeConnect(string shareName, out NTStatus status)
        {
            if (!m_isConnected || !m_isLoggedIn)
            {
                throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
            }

            IPAddress          serverIPAddress = ((IPEndPoint)m_clientSocket.RemoteEndPoint).Address;
            string             sharePath       = String.Format(@"\\{0}\{1}", serverIPAddress.ToString(), shareName);
            TreeConnectRequest request         = new TreeConnectRequest();

            request.Path = sharePath;
            TrySendCommand(request);
            SMB2Command response = WaitForCommand(SMB2CommandName.TreeConnect);

            if (response != null)
            {
                status = response.Header.Status;
                if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is TreeConnectResponse)
                {
                    return(new SMB2FileStore(this, response.Header.TreeID));
                }
            }
            else
            {
                status = NTStatus.STATUS_INVALID_SMB;
            }
            return(null);
        }
Example #2
0
        public ISMBFileStore TreeConnect(string shareName, out NTStatus status)
        {
            if (!m_isConnected || !m_isLoggedIn)
            {
                throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
            }

            string             sharePath = String.Format(@"\\{0}\{1}", m_serverName, shareName);
            TreeConnectRequest request   = new TreeConnectRequest();

            request.Path = sharePath;
            TrySendCommand(request);
            SMB2Command response = WaitForCommand(request.MessageID);

            if (response != null)
            {
                status = response.Header.Status;
                if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is TreeConnectResponse)
                {
                    bool encryptShareData = (((TreeConnectResponse)response).ShareFlags & ShareFlags.EncryptData) > 0;
                    return(new SMB2FileStore(this, response.Header.TreeID, m_encryptSessionData || encryptShareData));
                }
            }
            else
            {
                status = NTStatus.STATUS_INVALID_SMB;
            }
            return(null);
        }
Example #3
0
        public uint TreeConnect(string strShareName)
        {
            if (!IsBuildSession)
            {
                throw new Exception("no build session");
            }
            string      strPath     = @"\\" + IpAddress + @"\" + strShareName;
            ulong       mid         = (ulong)Interlocked.Increment(ref MessageId);
            SMB2Header  sMB2Header  = new SMB2Header(ESMB2Command.TREE_CONNECT, SMB2HeaderFlags.None, mid, 0, SessionId);
            SMB2Body    sMB2Body    = new TreeConnectRequest(strPath.GetUnicodeBytes());
            SMB2Message sMB2Message = new SMB2Message(sMB2Header, sMB2Body);

            SMBTransport.SendDatas(sMB2Message.DumpBinary());

            var sm = GetMessage(mid);

            if (sm.SMB2Header.Status == 0)
            {
                return(sm.SMB2Header.TreeId);
            }
            else
            {
                throw new Exception("TreeConnect Status error:" + sm.SMB2Header.Status);
            }
        }
Example #4
0
        public async Task <(NTStatus status, ISMBFileStore share)> TreeConnectAsync(string shareName, CancellationToken cancellationToken)
        {
            if (!m_isConnected || !m_isLoggedIn)
            {
                throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
            }

            IPAddress          serverIPAddress = ((IPEndPoint)m_clientSocket.RemoteEndPoint).Address;
            string             sharePath       = string.Format(@"\\{0}\{1}", serverIPAddress.ToString(), shareName);
            TreeConnectRequest request         = new TreeConnectRequest();

            request.Path = sharePath;
            await TrySendCommandAsync(request, cancellationToken);

            SMB2Command response = WaitForCommand(SMB2CommandName.TreeConnect);


            NTStatus status = NTStatus.STATUS_INVALID_SMB;

            if (response != null)
            {
                status = response.Header.Status;
                if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is TreeConnectResponse)
                {
                    var share = new SMB2FileStore(this, response.Header.TreeID);
                    return(status, share);
                }
            }
            return(status, null);
        }
        internal static SMB2Command GetTreeConnectResponse(TreeConnectRequest request, SMB2ConnectionState state, NamedPipeShare services, SMBShareCollection shares)
        {
            SMB2Session         session  = state.GetSession(request.Header.SessionID);
            TreeConnectResponse response = new TreeConnectResponse();
            string     shareName         = ServerPathUtils.GetShareName(request.Path);
            ISMBShare  share;
            ShareType  shareType;
            ShareFlags shareFlags;

            if (String.Equals(shareName, NamedPipeShare.NamedPipeShareName, StringComparison.OrdinalIgnoreCase))
            {
                share      = services;
                shareType  = ShareType.Pipe;
                shareFlags = ShareFlags.NoCaching;
            }
            else
            {
                share = shares.GetShareFromName(shareName);
                if (share == null)
                {
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_OBJECT_PATH_NOT_FOUND));
                }

                shareType  = ShareType.Disk;
                shareFlags = GetShareCachingFlags(((FileSystemShare)share).CachingPolicy);
                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
                {
                    state.LogToServer(Severity.Verbose, "Tree Connect to '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName);
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED));
                }
            }

            uint?treeID = session.AddConnectedTree(share);

            if (!treeID.HasValue)
            {
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_INSUFF_SERVER_RESOURCES));
            }
            state.LogToServer(Severity.Information, "Tree Connect: User '{0}' connected to '{1}' (SessionID: {2}, TreeID: {3})", session.UserName, share.Name, request.Header.SessionID, treeID.Value);
            response.Header.TreeID = treeID.Value;
            response.ShareType     = shareType;
            response.ShareFlags    = shareFlags;
            response.MaximalAccess = (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA | FileAccessMask.FILE_APPEND_DATA |
                                                  FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA |
                                                  FileAccessMask.FILE_EXECUTE |
                                                  FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES) |
                                     AccessMask.DELETE | AccessMask.READ_CONTROL | AccessMask.WRITE_DAC | AccessMask.WRITE_OWNER | AccessMask.SYNCHRONIZE;
            return(response);
        }
        /// <summary>
        /// Update SMB_COM_TREE_CONNECT_ANDX response.
        /// </summary>
        /// <param name="connection">It represents the SMB connection.</param>
        /// <param name="messageId">This is used to associate a response with a request.</param>
        /// <param name="treeId">This is used to indicate the share that the client is accessing.</param>
        /// <param name="shareType">The type of resource the client intends to access.</param>
        /// <param name="sessionId">
        /// Set this value to 0 to request a new session setup, or set this value to a previously established session
        /// identifier to request the re-authentication of an existing session.
        /// </param>
        public static void UpdateTreeConnectResponse(
            SmbConnection connection,
            int messageId,
            int sessionId,
            int treeId,
            ShareType shareType)
        {
            TreeConnectRequest request = (TreeConnectRequest)connection.sentRequest[messageId];

            connection.treeConnectList.Add(
                treeId,
                new SmbTree(treeId, new SmbShare(request.shareName, shareType), sessionId));

            switch (shareType)
            {
            case ShareType.Disk:
                Parameter.shareFileNames.Remove(request.shareName);
                break;

            case ShareType.NamedPipe:
                Parameter.sharePipeNames.Remove(request.shareName);
                break;

            case ShareType.Printer:
                Parameter.sharePrinterNames.Remove(request.shareName);
                break;

            case ShareType.CommunicationDevice:
                Parameter.shareDeviceNames.Remove(request.shareName);
                break;

            default:
                break;
            }

            connection.SutSendSequenceNumber.Remove(messageId);
            connection.SutSendSequenceNumber.Remove(messageId);
            connection.sentRequest.Remove(messageId);
            connection.SutNextReceiveSequenceNumber++;
            connection.treeId++;
        }