/****************************************************************************** * The MIT License * Copyright (c) 2003 Novell Inc. www.novell.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the Software), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *******************************************************************************/ // // Novell.Directory.Ldap.Rfc2251.RfcLdapMessage.cs // // Author: // Sunil Kumar (Sunilk@novell.com) // // (C) 2003 Novell, Inc (http://www.novell.com) // using System; using LdapException = Novell.Directory.Ldap.LdapException; using LdapMessage = Novell.Directory.Ldap.LdapMessage; using Novell.Directory.Ldap.Asn1; namespace Novell.Directory.Ldap.Rfc2251 { /// Represents an Ldap Message. /// ///
	/// LdapMessage ::= SEQUENCE {
	/// messageID       MessageID,
	/// protocolOp      CHOICE {
	/// bindRequest     BindRequest,
	/// bindResponse    BindResponse,
	/// unbindRequest   UnbindRequest,
	/// searchRequest   SearchRequest,
	/// searchResEntry  SearchResultEntry,
	/// searchResDone   SearchResultDone,
	/// searchResRef    SearchResultReference,
	/// modifyRequest   ModifyRequest,
	/// modifyResponse  ModifyResponse,
	/// addRequest      AddRequest,
	/// addResponse     AddResponse,
	/// delRequest      DelRequest,
	/// delResponse     DelResponse,
	/// modDNRequest    ModifyDNRequest,
	/// modDNResponse   ModifyDNResponse,
	/// compareRequest  CompareRequest,
	/// compareResponse CompareResponse,
	/// abandonRequest  AbandonRequest,
	/// extendedReq     ExtendedRequest,
	/// extendedResp    ExtendedResponse },
	/// controls       [0] Controls OPTIONAL }
	/// 
/// /// /// Note: The creation of a MessageID should be hidden within the creation of /// an RfcLdapMessage. The MessageID needs to be in sequence, and has an /// upper and lower limit. There is never a case when a user should be /// able to specify the MessageID for an RfcLdapMessage. The MessageID() /// constructor should be package protected. (So the MessageID value /// isn't arbitrarily run up.) ///
public class RfcLdapMessage:Asn1Sequence { /// Returns this RfcLdapMessage's messageID as an int. virtual public int MessageID { get { return ((Asn1Integer) get_Renamed(0)).intValue(); } } /// Returns this RfcLdapMessage's message type virtual public int Type { get { return get_Renamed(1).getIdentifier().Tag; } } /// Returns the response associated with this RfcLdapMessage. /// Can be one of RfcLdapResult, RfcBindResponse, RfcExtendedResponse /// all which extend RfcResponse. It can also be /// RfcSearchResultEntry, or RfcSearchResultReference /// virtual public Asn1Object Response { get { return get_Renamed(1); } } /// Returns the optional Controls for this RfcLdapMessage. virtual public RfcControls Controls { get { if (size() > 2) return (RfcControls) get_Renamed(2); return null; } } /// Returns the dn of the request, may be null virtual public System.String RequestDN { get { return ((RfcRequest) op).getRequestDN(); } } /// returns the original request in this message /// /// /// the original msg request for this response /// /// sets the original request in this message /// /// /// the original request for this response /// virtual public LdapMessage RequestingMessage { get { return requestMessage; } set { requestMessage = value; return ; } } private Asn1Object op; private RfcControls controls; private LdapMessage requestMessage = null; /// Create an RfcLdapMessage by copying the content array /// /// /// the array list to copy /// /* package */ internal RfcLdapMessage(Asn1Object[] origContent, RfcRequest origRequest, System.String dn, System.String filter, bool reference):base(origContent, origContent.Length) { set_Renamed(0, new RfcMessageID()); // MessageID has static counter RfcRequest req = (RfcRequest) origContent[1]; RfcRequest newreq = req.dupRequest(dn, filter, reference); op = (Asn1Object) newreq; set_Renamed(1, (Asn1Object) newreq); return ; } /// Create an RfcLdapMessage using the specified Ldap Request. public RfcLdapMessage(RfcRequest op):this(op, null) { return ; } /// Create an RfcLdapMessage request from input parameters. public RfcLdapMessage(RfcRequest op, RfcControls controls):base(3) { this.op = (Asn1Object) op; this.controls = controls; add(new RfcMessageID()); // MessageID has static counter add((Asn1Object) op); if (controls != null) { add(controls); } return ; } /// Create an RfcLdapMessage using the specified Ldap Response. public RfcLdapMessage(Asn1Sequence op):this(op, null) { return ; } /// Create an RfcLdapMessage response from input parameters. public RfcLdapMessage(Asn1Sequence op, RfcControls controls):base(3) { this.op = op; this.controls = controls; add(new RfcMessageID()); // MessageID has static counter add(op); if (controls != null) { add(controls); } return ; } /// Will decode an RfcLdapMessage directly from an InputStream. [CLSCompliantAttribute(false)] public RfcLdapMessage(Asn1Decoder dec, System.IO.Stream in_Renamed, int len):base(dec, in_Renamed, len) { sbyte[] content; System.IO.MemoryStream bais; // Decode implicitly tagged protocol operation from an Asn1Tagged type // to its appropriate application type. Asn1Tagged protocolOp = (Asn1Tagged) get_Renamed(1); Asn1Identifier protocolOpId = protocolOp.getIdentifier(); content = ((Asn1OctetString) protocolOp.taggedValue()).byteValue(); bais = new System.IO.MemoryStream(SupportClass.ToByteArray(content)); switch (protocolOpId.Tag) { case LdapMessage.SEARCH_RESPONSE: set_Renamed(1, new RfcSearchResultEntry(dec, bais, content.Length)); break; case LdapMessage.SEARCH_RESULT: set_Renamed(1, new RfcSearchResultDone(dec, bais, content.Length)); break; case LdapMessage.SEARCH_RESULT_REFERENCE: set_Renamed(1, new RfcSearchResultReference(dec, bais, content.Length)); break; case LdapMessage.ADD_RESPONSE: set_Renamed(1, new RfcAddResponse(dec, bais, content.Length)); break; case LdapMessage.BIND_RESPONSE: set_Renamed(1, new RfcBindResponse(dec, bais, content.Length)); break; case LdapMessage.COMPARE_RESPONSE: set_Renamed(1, new RfcCompareResponse(dec, bais, content.Length)); break; case LdapMessage.DEL_RESPONSE: set_Renamed(1, new RfcDelResponse(dec, bais, content.Length)); break; case LdapMessage.EXTENDED_RESPONSE: set_Renamed(1, new RfcExtendedResponse(dec, bais, content.Length)); break; case LdapMessage.MODIFY_RESPONSE: set_Renamed(1, new RfcModifyResponse(dec, bais, content.Length)); break; case LdapMessage.MODIFY_RDN_RESPONSE: set_Renamed(1, new RfcModifyDNResponse(dec, bais, content.Length)); break; default: throw new System.SystemException("RfcLdapMessage: Invalid tag: " + protocolOpId.Tag); } // decode optional implicitly tagged controls from Asn1Tagged type to // to RFC 2251 types. if (size() > 2) { Asn1Tagged controls = (Asn1Tagged) get_Renamed(2); // Asn1Identifier controlsId = protocolOp.getIdentifier(); // we could check to make sure we have controls here.... content = ((Asn1OctetString) controls.taggedValue()).byteValue(); bais = new System.IO.MemoryStream(SupportClass.ToByteArray(content)); set_Renamed(2, new RfcControls(dec, bais, content.Length)); } return ; } //************************************************************************* // Accessors //************************************************************************* /// Returns the request associated with this RfcLdapMessage. /// Throws a class cast exception if the RfcLdapMessage is not a request. /// public RfcRequest getRequest() { return (RfcRequest) get_Renamed(1); } public virtual bool isRequest() { return get_Renamed(1) is RfcRequest; } /// Duplicate this message, replacing base dn, filter, and scope if supplied /// /// /// the base dn /// /// /// the filter /// /// /// true if a search reference /// /// /// the object representing the new message /// public System.Object dupMessage(System.String dn, System.String filter, bool reference) { if ((op == null)) { throw new LdapException("DUP_ERROR", LdapException.LOCAL_ERROR, (System.String) null); } RfcLdapMessage newMsg = new RfcLdapMessage(toArray(), (RfcRequest) get_Renamed(1), dn, filter, reference); return newMsg; } } }