/// <summary> /// Creates a SearchResultReference. For LDAP v3 only. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="referenceUrls">The referenced URL.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultReferencePacket CreateSearchResultReference( AdtsLdapContext context, string[] referenceUrls) { int length = (referenceUrls != null) ? referenceUrls.Length : 0; LDAPURL[] ldapUrlArray = new LDAPURL[length]; for (int i = 0; i < length; i++) { ldapUrlArray[i] = new LDAPURL(referenceUrls[i]); } SearchResultReference reference = new SearchResultReference(ldapUrlArray); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResRef, reference); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultReferencePacket packet = new AdtsSearchResultReferencePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates an ExtendedRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="requestName">The request name of the extended operation.</param> /// <param name="requestValue">The request value of the extended operation.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsExtendedRequestPacket CreateExtendedRequest( AdtsLdapContext context, string requestName, byte[] requestValue) { ExtendedRequest extendedRequest = new ExtendedRequest( new LDAPOID(requestName ?? string.Empty), new Asn1OctetString(requestValue)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, extendedRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsExtendedRequestPacket packet = new AdtsExtendedRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// create sasl bind response packet. /// </summary> /// <param name="context"> /// an AdtsLdapContext object that indicates the context of LDAP. /// </param> /// <param name="securityContext"> /// a ServerSecurityContext object that specifies the security provider. /// </param> /// <param name="enableMessageSecurity"> /// a bool value that indicates whether enable message security. /// </param> /// <returns> /// a BindResponsePacket object that responses the SASL bind request. /// </returns> /// <exception cref="ArgumentNullException"> /// thrown when context is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when securityContext is null. /// </exception> public AdtsBindResponsePacket CreateSaslBindResponse( AdtsLdapContext context, ServerSecurityContext securityContext, bool enableMessageSecurity) { if (context == null) { throw new ArgumentNullException("context"); } if (securityContext == null) { throw new ArgumentNullException("securityContext"); } if (context.Security == null) { context.Security = new AdtsLdapSaslSecurityLayer(securityContext); context.UsingMessageSecurity = enableMessageSecurity; } ResultCode resultCode = ResultCode.Success; if (securityContext.NeedContinueProcessing) { resultCode = ResultCode.SaslBindInProgress; } return(this.CreateBindResponse( context, resultCode, string.Empty, string.Empty, null, securityContext.Token)); }
/// <summary> /// create sasl bind response packet. /// </summary> /// <param name="context"> /// an AdtsLdapContext object that indicates the context of LDAP. /// </param> /// <param name="securityContext"> /// a ServerSecurityContext object that specifies the security provider. /// </param> /// <param name="enableMessageSecurity"> /// a bool value that indicates whether enable message security. /// </param> /// <returns> /// a BindResponsePacket object that responses the SASL bind request. /// </returns> /// <exception cref="ArgumentNullException"> /// thrown when context is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when securityContext is null. /// </exception> public AdtsBindResponsePacket CreateSaslBindResponse( AdtsLdapContext context, ServerSecurityContext securityContext, bool enableMessageSecurity) { if (context == null) { throw new ArgumentNullException("context"); } if (securityContext == null) { throw new ArgumentNullException("securityContext"); } if (context.Security == null) { context.Security = new AdtsLdapSaslSecurityLayer(securityContext); context.UsingMessageSecurity = enableMessageSecurity; } ResultCode resultCode = ResultCode.Success; if (securityContext.NeedContinueProcessing) { resultCode = ResultCode.SaslBindInProgress; } return this.CreateBindResponse( context, resultCode, string.Empty, string.Empty, null, securityContext.Token); }
/// <summary> /// Creates a BindResponse for normal bindings and SASL bindings. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN. Required, but can be an empty string.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional and for LDAP v3 only.</param> /// <param name="serverCredentials">Server credentials, optional for normal bind.</param> /// <returns>The packet that contains the response.</returns> internal abstract AdtsBindResponsePacket CreateBindResponse( AdtsLdapContext context, ResultCode resultCode, string matchedDn, string errorMessage, string[] referral, byte[] serverCredentials);
/// <summary> /// Creates an AddRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be added.</param> /// <param name="attributes">Attributes to be set.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAddRequestPacket CreateAddRequest( AdtsLdapContext context, string objectDn, params KeyValuePair <string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; AttributeList_element[] attributeArray = new AttributeList_element[length]; for (int i = 0; i < length; i++) { AttributeValue[] attributeValues = new AttributeValue[attributes[i].Value.Length]; for (int j = 0; j < attributes[i].Value.Length; i++) { attributeValues[j] = new AttributeValue(attributes[i].Value[j]); } attributeArray[i] = new AttributeList_element(new AttributeDescription(attributes[i].Key), new Asn1SetOf <AttributeValue>(attributeValues)); } AddRequest addRequest = new AddRequest( new LDAPDN(objectDn ?? string.Empty), new AttributeList(attributeArray)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, addRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsAddRequestPacket packet = new AdtsAddRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a BindResponse for normal bindings and SASL bindings. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN. Required, but can be an empty string.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional and for LDAP v3 only.</param> /// <param name="serverCredentials">Server credentials, optional for normal bind.</param> /// <returns>The packet that contains the response.</returns> internal abstract AdtsBindResponsePacket CreateBindResponse( AdtsLdapContext context, ResultCode resultCode, string matchedDn, string errorMessage, string[] referral, byte[] serverCredentials);
/// <summary> /// Creates an AddRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be added.</param> /// <param name="attributes">Attributes to be set.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAddRequestPacket CreateAddRequest( AdtsLdapContext context, string objectDn, params KeyValuePair<string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; AddRequest_attrs_element[] addrequestAttrsArray = new AddRequest_attrs_element[length]; for (int i = 0; i < length; i++) { addrequestAttrsArray[i] = new AddRequest_attrs_element( new AttributeType(attributes[i].Key), CreateAttributeValueSet(attributes[i].Value)); } Asn1SequenceOf<AddRequest_attrs_element> attributeList = new Asn1SequenceOf<AddRequest_attrs_element>(addrequestAttrsArray); AddRequest addRequest = new AddRequest( new LDAPDN(objectDn ?? string.Empty), attributeList); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.addRequest, addRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsAddRequestPacket packet = new AdtsAddRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a SearchResultEntry packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="attributes">The attributes and values that are contained in the entry.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultEntryPacket CreateSearchedResultEntry( AdtsLdapContext context, string matchedDn, params KeyValuePair <string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; SearchResponse_entry_attributes_element[] attributesElementArray = new SearchResponse_entry_attributes_element[length]; for (int i = 0; i < length; i++) { attributesElementArray[i] = new SearchResponse_entry_attributes_element( new AttributeType(attributes[i].Key), CreateAttributeValueSet(attributes[i].Value)); } Asn1SequenceOf <SearchResponse_entry_attributes_element> attributesElements = new Asn1SequenceOf <SearchResponse_entry_attributes_element>(attributesElementArray); SearchResponse_entry entry = new SearchResponse_entry( new LDAPDN(matchedDn ?? string.Empty), attributesElements); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResponse, new SearchResponse(SearchResponse.entry, entry)); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsSearchResultEntryPacket packet = new AdtsSearchResultEntryPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a SearchResultReference. For LDAP v3 only. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="referenceUrls">The referenced URL.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultReferencePacket CreateSearchResultReference( AdtsLdapContext context, string[] referenceUrls) { int length = (referenceUrls != null) ? referenceUrls.Length : 0; LDAPURL[] ldapUrlArray = new LDAPURL[length]; for (int i = 0; i < length; i++) { ldapUrlArray[i] = new LDAPURL(referenceUrls[i]); } SearchResultReference reference = new SearchResultReference(ldapUrlArray); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResRef, reference); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultReferencePacket packet = new AdtsSearchResultReferencePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a SearchResultDone packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultDonePacket CreateSearchResultDone( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral) { SearchResultDone searchResultDone = new SearchResultDone( new LDAPResult_resultCode((long)resultCode), new LDAPDN(matchedDn ?? string.Empty), new LDAPString(errorMessage ?? string.Empty), CreateReferral(referral)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResDone, searchResultDone); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultDonePacket packet = new AdtsSearchResultDonePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates an AddRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be added.</param> /// <param name="attributes">Attributes to be set.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAddRequestPacket CreateAddRequest( AdtsLdapContext context, string objectDn, params KeyValuePair <string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; AddRequest_attrs_element[] addrequestAttrsArray = new AddRequest_attrs_element[length]; for (int i = 0; i < length; i++) { addrequestAttrsArray[i] = new AddRequest_attrs_element( new AttributeType(attributes[i].Key), CreateAttributeValueSet(attributes[i].Value)); } Asn1SequenceOf <AddRequest_attrs_element> attributeList = new Asn1SequenceOf <AddRequest_attrs_element>(addrequestAttrsArray); AddRequest addRequest = new AddRequest( new LDAPDN(objectDn ?? string.Empty), attributeList); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.addRequest, addRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsAddRequestPacket packet = new AdtsAddRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a ModifyDNRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="oldDn">The original DN to be modified.</param> /// <param name="newRdn">The new relative DN.</param> /// <param name="newParentDn"> /// The new parent DN. For LDAP v3 only. Ignored when creating LDAP v2 requests. /// </param> /// <param name="delOldRdn"> /// Whether to delete old RDN. For LDAP v3 only. Ignored when creating LDAP v2 requests. /// </param> /// <returns>The packet that contains the request.</returns> internal override AdtsModifyDnRequestPacket CreateModifyDnRequest( AdtsLdapContext context, string oldDn, string newRdn, string newParentDn, bool delOldRdn) { ModifyDNRequest modifyDnRequest = new ModifyDNRequest( new LDAPDN(oldDn ?? string.Empty), new RelativeLDAPDN(newRdn ?? string.Empty), new Asn1Boolean(delOldRdn), new LDAPDN(newParentDn)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.modifyDNRequest, modifyDnRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsModifyDnRequestPacket packet = new AdtsModifyDnRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a BindRequest with SASL bind. This method is for LDAP v3 only. /// Note that for GSS-SPNEGO with NTLM, two rounds of bind requests is required. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="mechanism">Authentication mechanism used, e.g., GSS-SPNEGO, etc.</param> /// <param name="credential">The credential to be sent, it can be calculated with SSPI.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSaslBindRequest( AdtsLdapContext context, string mechanism, byte[] credential) { throw new NotSupportedException(); }
/// <summary> /// Creates an ExtendedRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="requestName">The request name of the extended operation.</param> /// <param name="requestValue">The request value of the extended operation.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsExtendedRequestPacket CreateExtendedRequest( AdtsLdapContext context, string requestName, byte[] requestValue) { throw new NotSupportedException(); }
/// <summary> /// Creates a BindResponse for normal bindings, SASL bindings and sicily bindings. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN. Required, but can be an empty string.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional and for LDAP v3 only.</param> /// <param name="serverCredentials">Server credentials, optional for normal bind.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsBindResponsePacket CreateBindResponse( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral, byte[] serverCredentials) { BindResponse bindResponse = new BindResponse( new LDAPResult_resultCode((long)resultCode), new LDAPDN(matchedDn ?? string.Empty), new LDAPString(errorMessage ?? string.Empty)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.bindResponse, bindResponse); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsBindResponsePacket packet = new AdtsBindResponsePacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a ModifyRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of object to be modified.</param> /// <param name="modificationList">Modification list of attributes.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsModifyRequestPacket CreateModifyRequest( AdtsLdapContext context, string objectDn, params MsLdap.DirectoryAttributeModification[] modificationList) { int length = (modificationList != null) ? modificationList.Length : 0; ModifyRequest_modifications_element[] modifyRequestArray = new ModifyRequest_modifications_element[length]; for (int i = 0; i < length; i++) { modifyRequestArray[i] = new ModifyRequest_modifications_element( new ModifyRequest_modifications_element_operation((long)modificationList[i].Operation), new ModifyRequest_modifications_element_modification( new AttributeType(modificationList[i].Name), CreateAttributeValueSet((string[])modificationList[i].GetValues(typeof(string))))); } Asn1SequenceOf <ModifyRequest_modifications_element> modificationSequence = new Asn1SequenceOf <ModifyRequest_modifications_element>(modifyRequestArray); ModifyRequest modifyRequest = new ModifyRequest( new LDAPDN(objectDn ?? string.Empty), modificationSequence); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.modifyRequest, modifyRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsModifyRequestPacket packet = new AdtsModifyRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a ModifyDnResponse packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional. Used for LDAP v3 only.</param> /// <returns>The packet that contains the response.</returns> public AdtsModifyDnResponsePacket CreateModifyDnResponse( AdtsLdapContext context, ResultCode resultCode, string matchedDn, string errorMessage, string[] referral) { if (context.ServerVersion == AdtsLdapVersion.V2) { return(this.encoderv2.CreateModifyDnResponse( context, resultCode, matchedDn, errorMessage, referral)); } else { return(this.encoderv3.CreateModifyDnResponse( context, resultCode, matchedDn, errorMessage, referral)); } }
/// <summary> /// Creates a BindResponse for normal bindings, SASL bindings and sicily bindings. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn"> /// Matched DN. Required for normal bindings, SASL bindings; but optional for sicily bind.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional and for LDAP v3 only.</param> /// <param name="serverCredentials">Server credentials, optional for normal and sicily bind.</param> /// <returns>The packet that contains the response.</returns> public AdtsBindResponsePacket CreateBindResponse( AdtsLdapContext context, ResultCode resultCode, string matchedDn, string errorMessage, string[] referral, byte[] serverCredentials) { if (context.Security == null) { context.Security = new AdtsLdapSimpleSecurityLayer(); } if (context.ServerVersion == AdtsLdapVersion.V2) { return(this.encoderv2.CreateBindResponse( context, resultCode, matchedDn, errorMessage, referral, serverCredentials)); } else { return(this.encoderv3.CreateBindResponse( context, resultCode, matchedDn, errorMessage, referral, serverCredentials)); } }
/// <summary> /// Expects a packet. /// </summary> /// <param name="timeout">The timeout to be waited.</param> /// <param name="context">The context to be returned.</param> /// <returns>The packet received.</returns> public AdtsLdapPacket ExpectPacket(TimeSpan timeout, out AdtsLdapContext context) { while (true) { TransportEvent transportEvent = this.transportStack.ExpectTransportEvent(timeout); if (transportEvent.EventType == EventType.ReceivedPacket) { AdtsLdapPacket packet = (AdtsLdapPacket)transportEvent.EventObject; context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); return(packet); } else if (transportEvent.EventType == EventType.Disconnected) { // Remove context if disconnected. this.transportStack.Disconnect((IPEndPoint)transportEvent.EndPoint); context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); this.contextManager.RemoveContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); return(null); } else if (transportEvent.EventType == EventType.Exception) { throw (Exception)transportEvent.EventObject; } } }
/// <summary> /// Creates a SearchResultEntry packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="attributes">The attributes and values that are contained in the entry.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultEntryPacket CreateSearchedResultEntry( AdtsLdapContext context, string matchedDn, params KeyValuePair <string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; PartialAttributeList_element[] partialAttributeElementArray = new PartialAttributeList_element[length]; for (int i = 0; i < length; i++) { partialAttributeElementArray[i] = new PartialAttributeList_element( new AttributeDescription(attributes[i].Key), CreateAttributeValueSet(attributes[i].Value)); } PartialAttributeList attributeList = new PartialAttributeList(partialAttributeElementArray); SearchResultEntry entry = new SearchResultEntry( new LDAPDN(matchedDn ?? string.Empty), attributeList); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResEntry, entry); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultEntryPacket packet = new AdtsSearchResultEntryPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Adds a context. /// </summary> /// <param name="context">The context to be added</param> /// <exception cref="ArgumentException"> /// Thrown if the context exists already. /// </exception> internal void AddContext(AdtsLdapContext context, bool isTcp) { string key = GetKey(context.RemoteAddress, isTcp); lock (this.lockObject) { this.serverContexts.Add(key, context); } }
/// <summary> /// Disconnects with specified client. The corresponding context will be removed. /// </summary> /// <param name="context">The context that contains the client information.</param> public void Disconnect(AdtsLdapContext context) { if (this.isTcp) { this.transportStack.Disconnect(context.RemoteAddress); } this.contextManager.RemoveContext(context.RemoteAddress, this.isTcp); }
/// <summary> /// Adds a context. /// </summary> /// <param name="context">The context to be added</param> /// <exception cref="ArgumentException"> /// Thrown if the context exists already. /// </exception> internal void AddContext(AdtsLdapContext context, bool isTcp) { string key = GetKey(context.RemoteAddress, isTcp); lock (this.lockObject) { this.serverContexts.Add(key, context); } }
/// <summary> /// Creates a SearchResultDone packet. For LDAP v3 only. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultDonePacket CreateSearchResultDone( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral) { throw new NotSupportedException(); }
/// <summary> /// Creates an ExtendedResponse packet. For LDAP v3 only. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional. Used for LDAP v3 only.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsExtendedResponsePacket CreateExtendedResponse( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral) { throw new NotSupportedException(); }
/// <summary> /// Creates a SearchRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="dn">The DN to be searched.</param> /// <param name="sizeLimit">Size limit.</param> /// <param name="timeLimit">Time limit, in seconds.</param> /// <param name="scope">Search scope. Base, single level, or subtree.</param> /// <param name="dereferenceAliases">Dereference aliase options.</param> /// <param name="filter">Search filter.</param> /// <param name="typesOnly"> /// Specifies whether the search returns only the attribute names without the attribute values. /// </param> /// <param name="attributes">The attributes to be retrieved.</param> /// <returns>The packet that contains the request.</returns> internal abstract AdtsSearchRequestPacket CreateSearchRequest( AdtsLdapContext context, string dn, long sizeLimit, long timeLimit, SearchScope scope, DereferenceAlias dereferenceAliases, Asn1Choice filter, bool typesOnly, params string[] attributes);
public AdtsSearchResultReferencePacket CreateSearchResultReference( AdtsLdapContext context, string[] referenceUrls) { if (context.ServerVersion == AdtsLdapVersion.V2) { throw new NotSupportedException(); } else { return(this.encoderv3.CreateSearchResultReference(context, referenceUrls)); } }
/// <summary> /// to receive bytes from connection.<para/> /// the transport must be TcpServer or NetbiosServer. /// </summary> /// <param name="timeout"> /// a TimeSpan object that specifies the timeout for this operation. /// </param> /// <param name="maxCount"> /// an int value that specifies the maximum count of expect bytes. /// </param> /// <param name="remoteEndPoint"> /// an object that indicates the connection to received data from.<para/> /// if Tcp, it's an IPEndPoint that specifies the target endpoint.<para/> /// if Netbios, it's an int value that specifies the client session id. /// </param> /// <returns> /// a bytes array that contains the received bytes. /// </returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentException"> /// thrown when maxCount is negative. /// </exception> public virtual byte[] ExpectBytes(TimeSpan timeout, int maxCount, AdtsLdapContext remoteEndPoint) { if (disposed) { throw new ObjectDisposedException("TransportStack"); } if (maxCount < 0) { throw new ArgumentException("max count must not be negative", "maxCount"); } return(this.transportStack.ExpectBytes(timeout, maxCount, remoteEndPoint.RemoteAddress)); }
/// <summary> /// server authenticate over SSL/TLS with client. /// </summary> /// <param name="context"> /// an AdtsLdapContext object that indicates the context of LDAP. /// </param> /// <param name="certificate"> /// a X509Certificate that specifies the certificate used to authenticate the server. /// </param> /// <param name="encryptMessage"> /// a bool value that indicates whether encrypt message. /// </param> /// <exception cref="ArgumentNullException"> /// thrown when context is null. /// </exception> public void SslStartup(AdtsLdapContext context) { if (context == null) { throw new ArgumentNullException("context"); } // if null or other security, initialize the ssl security. // when bind before start tls, the security will be set to other security. if (context.Security == null || !(context.Security is AdtsLdapSslTlsSecurityLayer)) { context.Security = new AdtsLdapSslTlsSecurityLayer(this, context); } }
/// <summary> /// Creates an AbandonRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="messageId">The ID of message to be abandoned.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAbandonRequestPacket CreateAbandonRequest(AdtsLdapContext context, long messageId) { AbandonRequest abandonRequest = new AbandonRequest(messageId); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, abandonRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsAbandonRequestPacket packet = new AdtsAbandonRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a SearchResultEntry packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="attributes">The attributes and values that are contained in the entry.</param> /// <returns>The packet that contains the response.</returns> public AdtsSearchResultEntryPacket CreateSearchedResultEntry( AdtsLdapContext context, string matchedDn, params KeyValuePair <string, string[]>[] attributes) { if (context.ServerVersion == AdtsLdapVersion.V2) { return(this.encoderv2.CreateSearchedResultEntry(context, matchedDn, attributes)); } else { return(this.encoderv3.CreateSearchedResultEntry(context, matchedDn, attributes)); } }
/// <summary> /// Creates a sicily response BindRequest packet. Usually it's the last packet of authentication during /// the bind process. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="credential">The credential to be sent, it can be calculated with SSPI.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSicilyResponseBindRequest( AdtsLdapContext context, byte[] credential) { BindRequest_authentication authentication = new BindRequest_authentication(); authentication.SetData(BindRequest_authentication.sicilyResponse, new Asn1OctetString(credential ?? (new byte[0]))); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(string.Empty), authentication); return(CreateBindRequestPacket(context, bindRequest)); }
/// <summary> /// Creates an UnbindRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsUnbindRequestPacket CreateUnbindRequest(AdtsLdapContext context) { UnbindRequest unbindRequest = new UnbindRequest(); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.unbindRequest, unbindRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsUnbindRequestPacket packet = new AdtsUnbindRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates an AbandonRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="messageId">The ID of message to be abandoned.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAbandonRequestPacket CreateAbandonRequest(AdtsLdapContext context, long messageId) { AbandonRequest abandonRequest = new AbandonRequest(messageId); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.abandonRequest, abandonRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation); AdtsAbandonRequestPacket packet = new AdtsAbandonRequestPacket(); packet.ldapMessagev2 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Creates a BindRequest with simple bind. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="name"> /// The name field of BindRequest, see TD Section 5.1.1.1.1 for full list of legal names. /// </param> /// <param name="password">The password credential of the object.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSimpleBindRequest( AdtsLdapContext context, string name, string password) { BindRequest_authentication authentication = new BindRequest_authentication(); authentication.SetData(BindRequest_authentication.simple, new Asn1OctetString(password ?? string.Empty)); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(name ?? string.Empty), authentication); return(CreateBindRequestPacket(context, bindRequest)); }
/// <summary> /// Creates a DelRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be deleted.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsDelRequestPacket CreateDelRequest(AdtsLdapContext context, string objectDn) { DelRequest delRequest = new DelRequest(objectDn ?? string.Empty); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.delRequest, delRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsDelRequestPacket packet = new AdtsDelRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return(packet); }
/// <summary> /// Sends packet data to client (to keep compliant with Stack SDK conventions). /// </summary> /// <param name="context">The context that contains related info about client.</param> /// <param name="packetData">The packet data.</param> public void SendBytes(AdtsLdapContext context, byte[] packetData) { transportStack.SendBytes(context.RemoteAddress, packetData); }
/// <summary> /// Creates a SicilyBindResponse packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="serverCredentials">Server credentials, optional for normal and sicily bind.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSicilyBindResponsePacket CreateSicilyBindResponse( AdtsLdapContext context, MsLdap.ResultCode resultCode, byte[] serverCredentials, string errorMessage) { SicilyBindResponse sicilyBindResponse = new SicilyBindResponse( new SicilyBindResponse_resultCode((long)resultCode), new Asn1OctetString(serverCredentials ?? (new byte[0])), new LDAPString(errorMessage ?? string.Empty)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.sicilybindResponse, sicilyBindResponse); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSicilyBindResponsePacket packet = new AdtsSicilyBindResponsePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a SearchRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="dn">The DN to be searched.</param> /// <param name="sizeLimit">Size limit.</param> /// <param name="timeLimit">Time limit, in seconds.</param> /// <param name="scope">Search scope. Base, single level, or subtree.</param> /// <param name="dereferenceAliases">Dereference aliase options.</param> /// <param name="filter">Search filter.</param> /// <param name="typesOnly"> /// Specifies whether the search returns only the attribute names without the attribute values. /// </param> /// <param name="attributes">The attributes to be retrieved.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsSearchRequestPacket CreateSearchRequest( AdtsLdapContext context, string dn, long sizeLimit, long timeLimit, MsLdap.SearchScope scope, MsLdap.DereferenceAlias dereferenceAliases, Asn1Choice filter, bool typesOnly, params string[] attributes) { int length = (attributes != null) ? attributes.Length : 0; AttributeDescription[] attributeDescriptionArray = new AttributeDescription[length]; for (int i = 0; i < length; i++) { attributeDescriptionArray[i] = new AttributeDescription(attributes[i]); } AttributeDescriptionList attributeList = new AttributeDescriptionList(attributeDescriptionArray); SearchRequest searchRequest = new SearchRequest( new LDAPDN(dn ?? string.Empty), new SearchRequest_scope((long)scope), new SearchRequest_derefAliases((long)dereferenceAliases), new Asn1Integer(sizeLimit), new Asn1Integer(timeLimit), new Asn1Boolean(typesOnly), (Filter)filter, attributeList); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchRequest, searchRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchRequestPacket packet = new AdtsSearchRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a SearchResultDone packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultDonePacket CreateSearchResultDone( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral) { SearchResultDone searchResultDone = new SearchResultDone( new LDAPResult_resultCode((long)resultCode), new LDAPDN(matchedDn ?? string.Empty), new LDAPString(errorMessage ?? string.Empty), CreateReferral(referral)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResDone, searchResultDone); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultDonePacket packet = new AdtsSearchResultDonePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a BindRequest with SASL bind. This method is for LDAP v3 only. /// Note that for GSS-SPNEGO with NTLM, two rounds of bind requests is required. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="mechanism">Authentication mechanism used, e.g., GSS-SPNEGO, etc.</param> /// <param name="credential">The credential to be sent, it can be calculated with SSPI.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSaslBindRequest( AdtsLdapContext context, string mechanism, byte[] credential) { AuthenticationChoice authentication = new AuthenticationChoice(); authentication.SetData( AuthenticationChoice.sasl, new SaslCredentials( new LDAPString(mechanism ?? string.Empty), new Asn1OctetString(credential ?? (new byte[0])))); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(new byte[0]), // For SASL, DN is not required. authentication); return CreateBindRequestPacket(context, bindRequest); }
/// <summary> /// Creates a SearchResultEntry packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="matchedDn">Matched DN.</param> /// <param name="attributes">The attributes and values that are contained in the entry.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsSearchResultEntryPacket CreateSearchedResultEntry( AdtsLdapContext context, string matchedDn, params KeyValuePair<string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; PartialAttributeList_element[] partialAttributeElementArray = new PartialAttributeList_element[length]; for (int i = 0; i < length; i++) { partialAttributeElementArray[i] = new PartialAttributeList_element( new AttributeDescription(attributes[i].Key), CreateAttributeValueSet(attributes[i].Value)); } PartialAttributeList attributeList = new PartialAttributeList(partialAttributeElementArray); SearchResultEntry entry = new SearchResultEntry( new LDAPDN(matchedDn ?? string.Empty), attributeList); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.searchResEntry, entry); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsSearchResultEntryPacket packet = new AdtsSearchResultEntryPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a ModifyDNRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="oldDn">The original DN to be modified.</param> /// <param name="newRdn">The new relative DN.</param> /// <param name="newParentDn"> /// The new parent DN. For LDAP v3 only. Ignored when creating LDAP v2 requests. /// </param> /// <param name="delOldRdn"> /// Whether to delete old RDN. For LDAP v3 only. Ignored when creating LDAP v2 requests. /// </param> /// <returns>The packet that contains the request.</returns> internal override AdtsModifyDnRequestPacket CreateModifyDnRequest( AdtsLdapContext context, string oldDn, string newRdn, string newParentDn, bool delOldRdn) { ModifyDNRequest modifyDnRequest = new ModifyDNRequest( new LDAPDN(oldDn ?? string.Empty), new RelativeLDAPDN(newRdn ?? string.Empty), new Asn1Boolean(delOldRdn), new LDAPDN(newParentDn ?? string.Empty)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.modDNRequest, modifyDnRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsModifyDnRequestPacket packet = new AdtsModifyDnRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// to receive bytes from connection.<para/> /// the transport must be TcpServer or NetbiosServer. /// </summary> /// <param name="timeout"> /// a TimeSpan object that specifies the timeout for this operation. /// </param> /// <param name="maxCount"> /// an int value that specifies the maximum count of expect bytes. /// </param> /// <param name="remoteEndPoint"> /// an object that indicates the connection to received data from.<para/> /// if Tcp, it's an IPEndPoint that specifies the target endpoint.<para/> /// if Netbios, it's an int value that specifies the client session id. /// </param> /// <returns> /// a bytes array that contains the received bytes. /// </returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentException"> /// thrown when maxCount is negative. /// </exception> public virtual byte[] ExpectBytes(TimeSpan timeout, int maxCount, AdtsLdapContext remoteEndPoint) { if (disposed) { throw new ObjectDisposedException("TransportStack"); } if (maxCount < 0) { throw new ArgumentException("max count must not be negative", "maxCount"); } return this.transportStack.ExpectBytes(timeout, maxCount, remoteEndPoint.RemoteAddress); }
/// <summary> /// Decodes an LDAP v3 packet. /// </summary> /// <param name="messageBytes">The message bytes that contains the packet data.</param> /// <param name="context">The context that contains decode-related information.</param> /// <returns>Decoded LDAP v3 packet.</returns> internal override AdtsLdapPacket ParseAdtsLdapPacket(byte[] messageBytes, AdtsLdapContext context) { LDAPMessage message = new LDAPMessage(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(messageBytes); message.BerDecode(decodeBuffer); Type innerMessageType = message.protocolOp.GetData().GetType(); AdtsLdapPacket packet = CreatePacketFromType(innerMessageType); context.MessageId = (long)message.messageID.Value; packet.messageId = (long)message.messageID.Value; packet.ldapMessagev3 = message; return packet; }
/// <summary> /// Expects a packet. /// </summary> /// <param name="timeout">The timeout to be waited.</param> /// <param name="context">The context to be returned.</param> /// <returns>The packet received.</returns> public AdtsLdapPacket ExpectPacket(TimeSpan timeout, out AdtsLdapContext context) { while (true) { TransportEvent transportEvent = this.transportStack.ExpectTransportEvent(timeout); if (transportEvent.EventType == EventType.ReceivedPacket) { AdtsLdapPacket packet = (AdtsLdapPacket)transportEvent.EventObject; context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); return packet; } else if (transportEvent.EventType == EventType.Disconnected) { // Remove context if disconnected. this.transportStack.Disconnect((IPEndPoint)transportEvent.EndPoint); context = this.contextManager.GetContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); this.contextManager.RemoveContext((IPEndPoint)transportEvent.EndPoint, this.isTcp); return null; } else if (transportEvent.EventType == EventType.Exception) { throw (Exception)transportEvent.EventObject; } } }
/// <summary> /// Creates a BindRequestPacket with context and BindRequest. /// </summary> /// <param name="context">The context.</param> /// <param name="bindRequest">The BindRequest message.</param> /// <returns>The BindRequestPacket.</returns> private AdtsBindRequestPacket CreateBindRequestPacket( AdtsLdapContext context, BindRequest bindRequest) { LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.bindRequest, bindRequest); MessageID messageId = new MessageID(context.MessageId); LDAPMessage message = new LDAPMessage(messageId, operation, null); AdtsBindRequestPacket packet = new AdtsBindRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a BindRequest with simple bind. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="name"> /// The name field of BindRequest, see TD Section 5.1.1.1.1 for full list of legal names. /// </param> /// <param name="password">The password credential of the object.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSimpleBindRequest( AdtsLdapContext context, string name, string password) { AuthenticationChoice authentication = new AuthenticationChoice(); authentication.SetData(AuthenticationChoice.simple, new Asn1OctetString(password ?? string.Empty)); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(name ?? string.Empty), authentication); return CreateBindRequestPacket(context, bindRequest); }
/// <summary> /// Creates a sicily response BindRequest packet. Usually it's the last packet of authentication during /// the bind process. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="credential">The credential to be sent, it can be calculated with SSPI.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsBindRequestPacket CreateSicilyResponseBindRequest( AdtsLdapContext context, byte[] credential) { AuthenticationChoice authentication = new AuthenticationChoice(); authentication.SetData(AuthenticationChoice.sicilyResponse, new Asn1OctetString(credential ?? (new byte[0]))); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(new byte[0]), authentication); return CreateBindRequestPacket(context, bindRequest); }
/// <summary> /// Sends a packet. /// </summary> /// <param name="context">The context that contains related info about client.</param> /// <param name="packet">The packet to be sent.</param> public void SendPacket(AdtsLdapContext context, AdtsLdapPacket packet) { transportStack.SendPacket(context.RemoteAddress, packet); }
/// <summary> /// Creates a ModifyRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of object to be modified.</param> /// <param name="modificationList">Modification list of attributes.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsModifyRequestPacket CreateModifyRequest( AdtsLdapContext context, string objectDn, params MsLdap.DirectoryAttributeModification[] modificationList) { int length = (modificationList != null) ? modificationList.Length : 0; ModifyRequest_modification_element[] modificationElements = new ModifyRequest_modification_element[length]; for (int i = 0; i < length; i++) { byte[][] values = (byte[][])modificationList[i].GetValues(typeof(byte[])); modificationElements[i] = new ModifyRequest_modification_element( new ModifyRequest_modification_element_operation((long)modificationList[i].Operation), new AttributeTypeAndValues( new AttributeDescription(modificationList[i].Name), CreateAttributeValueSet(values))); } Asn1SequenceOf<ModifyRequest_modification_element> modificationSequence = new Asn1SequenceOf<ModifyRequest_modification_element>(modificationElements); ModifyRequest modifyRequest = new ModifyRequest( new LDAPDN(objectDn ?? string.Empty), modificationSequence); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.modifyRequest, modifyRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsModifyRequestPacket packet = new AdtsModifyRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a sicily package discovery BindRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <returns>The sicily package discovery BindRequest.</returns> internal override AdtsBindRequestPacket CreateSicilyPackageDiscoveryBindRequest(AdtsLdapContext context) { AuthenticationChoice authentication = new AuthenticationChoice(); authentication.SetData(AuthenticationChoice.sicilyPackageDiscovery, new Asn1OctetString(string.Empty)); BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(new byte[0]), // For Sicily package discovery, DN is not required. authentication); return CreateBindRequestPacket(context, bindRequest); }
/// <summary> /// Disconnects with specified client. The corresponding context will be removed. /// </summary> /// <param name="context">The context that contains the client information.</param> public void Disconnect(AdtsLdapContext context) { if (this.isTcp) { this.transportStack.Disconnect(context.RemoteAddress); } this.contextManager.RemoveContext(context.RemoteAddress, this.isTcp); }
/// <summary> /// Creates a BindRequest with simple bind for Active Directory Domain Services(AD DS). /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="username">User name which doesn't include domain prefix.</param> /// <param name="password">Password of user.</param> /// <param name="domainNetbiosName">NetBIOS domain name(with suffix like ".com" removed).</param> /// <returns>The packet that contains the request.</returns> /// <exception cref="ArgumentNullException">Thrown when username is null.</exception> internal override AdtsBindRequestPacket CreateSimpleBindRequest( AdtsLdapContext context, string username, string password, string domainNetbiosName) { if (username == null) { throw new ArgumentNullException("username"); } AuthenticationChoice authentication = new AuthenticationChoice(); authentication.SetData(AuthenticationChoice.simple, new Asn1OctetString(password ?? string.Empty)); string fullname = (domainNetbiosName != null) ? (domainNetbiosName + "\\" + username) : username; BindRequest bindRequest = new BindRequest( new Asn1Integer((long)version), new LDAPDN(fullname), authentication); return CreateBindRequestPacket(context, bindRequest); }
/// <summary> /// Creates a BindResponse for normal bindings, SASL bindings and sicily bindings. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param> /// <param name="matchedDn">Matched DN. Required, but can be an empty string.</param> /// <param name="errorMessage">Error message for result code. Required.</param> /// <param name="referral">Referral. Optional and for LDAP v3 only.</param> /// <param name="serverCredentials">Server credentials, optional for normal bind.</param> /// <returns>The packet that contains the response.</returns> internal override AdtsBindResponsePacket CreateBindResponse( AdtsLdapContext context, MsLdap.ResultCode resultCode, string matchedDn, string errorMessage, string[] referral, byte[] serverCredentials) { BindResponse bindResponse = new BindResponse( new LDAPResult_resultCode((long)resultCode), new LDAPDN(matchedDn ?? string.Empty), new LDAPString(errorMessage ?? string.Empty), CreateReferral(referral), new Asn1OctetString(serverCredentials ?? (new byte[0]))); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.bindResponse, bindResponse); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsBindResponsePacket packet = new AdtsBindResponsePacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates an UnbindRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsUnbindRequestPacket CreateUnbindRequest(AdtsLdapContext context) { UnbindRequest unbindRequest = new UnbindRequest(); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.unbindRequest, unbindRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsUnbindRequestPacket packet = new AdtsUnbindRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a CompareRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be compared.</param> /// <param name="attributeName">The name of the attribute.</param> /// <param name="attributeValue">The value of the attribute.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsCompareRequestPacket CreateCompareRequest( AdtsLdapContext context, string objectDn, string attributeName, string attributeValue) { CompareRequest compareRequest = new CompareRequest( new LDAPDN(objectDn ?? string.Empty), new AttributeValueAssertion( new AttributeDescription(attributeName ?? string.Empty), new AssertionValue(attributeValue ?? string.Empty))); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, compareRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsCompareRequestPacket packet = new AdtsCompareRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates an AddRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be added.</param> /// <param name="attributes">Attributes to be set.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsAddRequestPacket CreateAddRequest( AdtsLdapContext context, string objectDn, params KeyValuePair<string, string[]>[] attributes) { int length = (attributes != null) ? attributes.Length : 0; AttributeList_element[] attributeArray = new AttributeList_element[length]; for (int i = 0; i < length; i++) { AttributeValue[] attributeValues = new AttributeValue[attributes[i].Value.Length]; for (int j = 0; j < attributes[i].Value.Length; i++) { attributeValues[j] = new AttributeValue(attributes[i].Value[j]); } attributeArray[i] = new AttributeList_element(new AttributeDescription(attributes[i].Key), new Asn1SetOf<AttributeValue>(attributeValues)); } AddRequest addRequest = new AddRequest( new LDAPDN(objectDn ?? string.Empty), new AttributeList(attributeArray)); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, addRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsAddRequestPacket packet = new AdtsAddRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }
/// <summary> /// Creates a DelRequest packet. /// </summary> /// <param name="context">The user context which contains message ID.</param> /// <param name="objectDn">The DN of the object to be deleted.</param> /// <returns>The packet that contains the request.</returns> internal override AdtsDelRequestPacket CreateDelRequest(AdtsLdapContext context, string objectDn) { DelRequest delRequest = new DelRequest(objectDn ?? string.Empty); LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp(); operation.SetData(LDAPMessage_protocolOp.extendedReq, delRequest); LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null); AdtsDelRequestPacket packet = new AdtsDelRequestPacket(); packet.ldapMessagev3 = message; packet.messageId = context.MessageId; return packet; }