/// <summary> /// find the nt transaction packets /// </summary> /// <param name="command">the command of nt transaction</param> /// <param name="setup">the setup contains the sub command</param> /// <returns>the target nt transaction packet</returns> private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup) { SmbPacket smbPacket = null; switch (command) { case NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>(setup); switch ((NtTransFunctionCode)subCommand.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); break; default: smbPacket = new SmbNtTransactIoctlRequestPacket(); break; } break; default: switch ((SmbNtTransSubCommand)command) { case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaRequestPacket(); break; case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaRequestPacket(); break; } break; } return(smbPacket); }
/// <summary> /// Create NTTransSetQuota request for client to set quota on server. /// </summary> /// <param name = "messageId">the id of message, used to identity the request and the server response. </param> /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param> /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param> /// <param name = "flags"> /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. /// </param> /// <param name = "flags2"> /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate /// various client and server capabilities. /// </param> /// <param name = "fileId">the valid file id to operation on, response by server. </param> /// <param name = "nextEntryOffset"> /// An offset to the start of the subsequent entry from the start of this entry, or 0 for the final entry. /// </param> /// <param name = "changeTime">This value MUST be the time the quota was last changed, in TIME format. </param> /// <param name = "quotaUsed"> /// The amount of quota, in bytes, used by this user. This field is formatted as a LARGE_INTEGER, as specified /// in [CIFS] section 2.4.2. /// </param> /// <param name = "quotaThreshold"> /// The quota warning limit, in bytes, for this user. This field is formatted as a LARGE_INTEGER, as specified /// in [CIFS] section 2.4.2. /// </param> /// <param name = "quotaLimit"> /// The quota limit, in bytes, for this user. This field is formatted as a LARGE_INTEGER, as specified in /// [CIFS] section 2.4.2. /// </param> /// <param name = "sid"> /// The security identifier of this user. For details, see [MS-DTYP] section 2.4.2. Note that [CIFS] sections /// 4.3.4, 4.3.4.7, 4.3.5, and 4.3.5.6 use Sid as the field name for a search handle. In [XOPEN-SMB], the /// search handle field is called a findfirst_dirhandle or findnext_dirhandle. These are better field names /// for a search handle. this param can not be null. /// </param> /// <returns>a nt transaction set quota request packet </returns> /// <exception cref="ArgumentNullException">sid can not be null.</exception> private SmbNtTransSetQuotaRequestPacket CreateNTTransSetQuotaRequest( ushort messageId, ushort sessionUid, ushort treeId, SmbHeader_Flags_Values flags, SmbHeader_Flags2_Values flags2, ushort fileId, uint nextEntryOffset, ulong changeTime, ulong quotaUsed, ulong quotaThreshold, ulong quotaLimit, byte[] sid) { if (sid == null) { throw new ArgumentNullException("sid"); } SmbNtTransSetQuotaRequestPacket packet = new SmbNtTransSetQuotaRequestPacket(); packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NT_TRANSACT, messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2); // Set Smb_Parameters SMB_COM_NT_TRANSACT_Request_SMB_Parameters smbParameters = new SMB_COM_NT_TRANSACT_Request_SMB_Parameters(); smbParameters.MaxSetupCount = this.capability.MaxSetupCount; smbParameters.MaxParameterCount = this.capability.MaxParameterCount; smbParameters.MaxDataCount = this.capability.MaxDataCount; smbParameters.SetupCount = 0; // the correct count in word of the Setup is always 0. smbParameters.Function = (NtTransSubCommand)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA; smbParameters.Setup = new ushort[0]; smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>( smbParameters) / SmbCapability.NUM_BYTES_OF_WORD); // Set Smb_Data SMB_COM_NT_TRANSACT_Request_SMB_Data smbData = new SMB_COM_NT_TRANSACT_Request_SMB_Data(); // Set Nt Transaction Parameters NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Parameters ntTransParameters = new NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Parameters(); ntTransParameters.Fid = fileId; // Set Nt Transaction Data NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data ntTransData = new NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data(); ntTransData.NextEntryOffset = nextEntryOffset; ntTransData.SidLength = (uint)sid.Length; ntTransData.ChangeTime = changeTime; ntTransData.QuotaUsed = quotaUsed; ntTransData.QuotaThreshold = quotaThreshold; ntTransData.QuotaLimit = quotaLimit; ntTransData.Sid = sid; packet.SmbParameters = smbParameters; packet.SmbData = smbData; packet.NtTransParameters = ntTransParameters; packet.NtTransData = ntTransData; packet.UpdateCountAndOffset(); return packet; }
/// <summary> /// NTTrans set quota request additional. /// </summary> /// <param name="messageId">Message ID used to identify the message.</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 reauthenticate to an existing session. /// </param> /// <param name="treeId"> /// This field identifies the subdirectory (or tree) (also referred as a share in this document) on the /// server that the client is accessing. /// </param> /// <param name="fid">The file identifier.</param> /// <param name="isSigned"> /// Indicate whether the SUT has message signing enabled or required. /// </param> /// <param name="requestPara">NTTrans set quota request parameter.</param> public void NtTransSetQuotaRequestAdditional( int messageId, int sessionId, int treeId, int fid, bool isSigned, NtTransSetQuotaRequestParameter requestPara) { #region Create Packet SmbNtTransSetQuotaRequestPacket smbPacket = new SmbNtTransSetQuotaRequestPacket(); ushort uid = (ushort)this.uId[(uint)sessionId]; ushort fileId = (ushort)this.fId[(uint)fid]; string sid = Site.Properties["SutLoginAdminUserFullPathName"]; byte[] sidByte = this.GetSid(sid); uint nextEntryOffset = uint.MinValue; ulong quotaUsed = ulong.MinValue; ulong changeTime = ulong.MinValue; quotaUsed++; smbPacket = this.smbClientStack.CreateNTTransSetQuotaRequest( fileId, nextEntryOffset, changeTime, (ulong)quotaUsed, this.quotaThreshold, this.quotalimit, sidByte); if (isSigned) { NamespaceCifs.CifsClientPerConnection connection = this.smbClientStack.Context.GetConnection(ConnectionId); NamespaceCifs.CifsClientPerSession session = this.smbClientStack.Context.GetSession(ConnectionId, uid); smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey); } bool isVaildFileId = true; if (requestPara == NtTransSetQuotaRequestParameter.FileIdErrror) { isVaildFileId = false; } if (!isVaildFileId) { NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Parameters setQuotaParameters = smbPacket.NtTransParameters; setQuotaParameters.Fid = ushort.MaxValue; smbPacket.NtTransParameters = setQuotaParameters; } if ((requestPara == NtTransSetQuotaRequestParameter.AccessDenied)) { NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data setQuotaData = smbPacket.NtTransData; setQuotaData.QuotaLimit = ulong.MaxValue; smbPacket.NtTransData = setQuotaData; } bool isVaildQuotaInfo = true; if (requestPara == NtTransSetQuotaRequestParameter.QuotaInfoError) { isVaildQuotaInfo = false; } if (!isVaildQuotaInfo) { NT_TRANSACT_SET_QUOTA_Request_NT_Trans_Data setQuotaData = smbPacket.NtTransData; setQuotaData.QuotaLimit = ulong.MaxValue; setQuotaData.QuotaThreshold = ulong.MaxValue; setQuotaData.QuotaUsed = ulong.MaxValue; setQuotaData.NextEntryOffset = uint.MaxValue; setQuotaData.ChangeTime = ulong.MaxValue; smbPacket.NtTransData = setQuotaData; } #endregion #region Send and Receive ExpectPacket this.smbClientStack.SendPacket(smbPacket); StackPacket response = this.smbClientStack.ExpectPacket(this.timeout); NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response; this.QueryUidTable(smbPacketResponse); this.QueryTidTable(smbPacketResponse); VerifyTransport(smbPacketResponse); VerifyCommonMessageSyntax(smbPacketResponse); if (response.GetType() == typeof(SmbErrorResponsePacket)) { SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket; NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader; //f temp code (How To Trigger InvalidParameter TDQ) if (!isVaildQuotaInfo && !bool.Parse(Site.Properties["IsTDQ33005Fixed"])) { this.ErrorNtTransSetQuotaResponseAdditional( smbErrorHeader.Mid + this.addMidMark, MessageStatus.InvalidParameter); } //Workaround temp code (FILEID ERROR TDI) else if ((requestPara == NtTransSetQuotaRequestParameter.FileIdErrror) && !bool.Parse(Site.Properties["IsTDI33008Fixed"])) { this.ErrorNtTransSetQuotaResponseAdditional( smbErrorHeader.Mid + this.addMidMark, MessageStatus.StatusInvalidHandle); } else { this.ErrorNtTransSetQuotaResponseAdditional( smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status); } } else { SmbNtTransSetQuotaResponsePacket smbNtTransSetQuotaPacket = response as SmbNtTransSetQuotaResponsePacket; NamespaceCifs.SmbHeader ntTransSetQuotaResponseHeader = smbNtTransSetQuotaPacket.SmbHeader; VerifyMessageSyntaxNtTransactSetQuotaRequest( smbNtTransSetQuotaPacket, ntTransSetQuotaResponseHeader.Status); //Workaround temp code (Expected AccessDenied, actually Success) if ((requestPara == NtTransSetQuotaRequestParameter.AccessDenied) && !bool.Parse(Site.Properties["IsTDI50461Fixed"])) { this.ErrorNtTransSetQuotaResponseAdditional( ntTransSetQuotaResponseHeader.Mid + this.addMidMark, MessageStatus.AccessDenied); } else { this.NtTransSetQuotaResponseAdditional( ntTransSetQuotaResponseHeader.Mid + this.addMidMark, this.QueryUidTable(smbPacketResponse), this.QueryTidTable(smbPacketResponse), (smbPacketResponse).IsSignRequired, (MessageStatus)ntTransSetQuotaResponseHeader.Status); } } #endregion }
/// <summary> /// NT_TRANSACT_SET_QUOTA Client Request. /// </summary> /// <param name="messageId">This is used to associate a response with a request.</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 reauthenticate to an existing session. /// </param> /// <param name="treeId"> /// This field identifies the subdirectory (or tree) (also referred as a share in this document) on the /// server that the client is accessing. /// </param> /// <param name="fid">The file identifier.</param> /// <param name="isSigned"> /// Indicate whether the SUT has message signing enabled or required. /// </param> /// <param name="quotaInfo">The amount of quota, in bytes, used by this user.</param> public void NtTransSetQuotaRequest( int messageId, int sessionId, int treeId, int fid, bool isSigned, int quotaUsed) { #region Create Packet SmbNtTransSetQuotaRequestPacket smbPacket = new SmbNtTransSetQuotaRequestPacket(); ushort uid = (ushort)this.uId[(uint)sessionId]; ushort fileId = (ushort)this.fId[(uint)fid]; string sid = Site.Properties["SutLoginAdminUserFullPathName"]; byte[] sidByte = this.GetSid(sid); uint nextEntryOffset = uint.MinValue; ulong changeTime = uint.MinValue; smbPacket = this.smbClientStack.CreateNTTransSetQuotaRequest( fileId, nextEntryOffset, changeTime, (ulong)quotaUsed, this.quotaThreshold, this.quotalimit, sidByte); if (isSigned) { NamespaceCifs.CifsClientPerConnection connection = this.smbClientStack.Context.GetConnection(ConnectionId); NamespaceCifs.CifsClientPerSession session = this.smbClientStack.Context.GetSession(ConnectionId, uid); smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey); } #endregion #region Send and Receive ExpectPacket this.smbClientStack.SendPacket(smbPacket); StackPacket response = this.smbClientStack.ExpectPacket(this.timeout); NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response; this.QueryUidTable(smbPacketResponse); this.QueryTidTable(smbPacketResponse); VerifyTransport(smbPacketResponse); VerifyCommonMessageSyntax(smbPacketResponse); if (response.GetType() == typeof(SmbErrorResponsePacket)) { SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket; NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader; this.ErrorResponse(smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status); } else { SmbNtTransSetQuotaResponsePacket smbNtTransSetQuotaPacket = response as SmbNtTransSetQuotaResponsePacket; NamespaceCifs.SmbHeader ntTransSetQuotaResponseHeader = smbNtTransSetQuotaPacket.SmbHeader; VerifyMessageSyntaxNtTransactSetQuotaRequest( smbNtTransSetQuotaPacket, ntTransSetQuotaResponseHeader.Status); this.NtTransSetQuotaResponse( ntTransSetQuotaResponseHeader.Mid + this.addMidMark, this.QueryUidTable(smbPacketResponse), this.QueryTidTable(smbPacketResponse), (smbPacketResponse).IsSignRequired, (MessageStatus)ntTransSetQuotaResponseHeader.Status); } #endregion }
/// <summary> /// find the nt transaction packets /// </summary> /// <param name="command">the command of nt transaction</param> /// <param name="setup">the setup contains the sub command</param> /// <returns>the target nt transaction packet</returns> private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup) { SmbPacket smbPacket = null; switch (command) { case NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(setup); switch ((NtTransFunctionCode)subCommand.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); break; default: smbPacket = new SmbNtTransactIoctlRequestPacket(); break; } break; default: switch ((SmbNtTransSubCommand)command) { case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaRequestPacket(); break; case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaRequestPacket(); break; } break; } return smbPacket; }
/// <summary> /// Deep copy constructor. /// </summary> public SmbNtTransSetQuotaRequestPacket(SmbNtTransSetQuotaRequestPacket packet) : base(packet) { }