Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

347 lines
10 KiB
C#

/******************************************************************************
* 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
{
/// <summary> Represents an Ldap Message.
///
/// <pre>
/// 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 }
/// </pre>
///
///
/// 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.)
/// </summary>
public class RfcLdapMessage:Asn1Sequence
{
/// <summary> Returns this RfcLdapMessage's messageID as an int.</summary>
virtual public int MessageID
{
get
{
return ((Asn1Integer) get_Renamed(0)).intValue();
}
}
/// <summary> Returns this RfcLdapMessage's message type</summary>
virtual public int Type
{
get
{
return get_Renamed(1).getIdentifier().Tag;
}
}
/// <summary> 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
/// </summary>
virtual public Asn1Object Response
{
get
{
return get_Renamed(1);
}
}
/// <summary> Returns the optional Controls for this RfcLdapMessage.</summary>
virtual public RfcControls Controls
{
get
{
if (size() > 2)
return (RfcControls) get_Renamed(2);
return null;
}
}
/// <summary> Returns the dn of the request, may be null</summary>
virtual public System.String RequestDN
{
get
{
return ((RfcRequest) op).getRequestDN();
}
}
/// <summary> returns the original request in this message
///
/// </summary>
/// <returns> the original msg request for this response
/// </returns>
/// <summary> sets the original request in this message
///
/// </summary>
/// <param name="msg">the original request for this response
/// </param>
virtual public LdapMessage RequestingMessage
{
get
{
return requestMessage;
}
set
{
requestMessage = value;
return ;
}
}
private Asn1Object op;
private RfcControls controls;
private LdapMessage requestMessage = null;
/// <summary> Create an RfcLdapMessage by copying the content array
///
/// </summary>
/// <param name="origContent">the array list to copy
/// </param>
/* 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 ;
}
/// <summary> Create an RfcLdapMessage using the specified Ldap Request.</summary>
public RfcLdapMessage(RfcRequest op):this(op, null)
{
return ;
}
/// <summary> Create an RfcLdapMessage request from input parameters.</summary>
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 ;
}
/// <summary> Create an RfcLdapMessage using the specified Ldap Response.</summary>
public RfcLdapMessage(Asn1Sequence op):this(op, null)
{
return ;
}
/// <summary> Create an RfcLdapMessage response from input parameters.</summary>
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 ;
}
/// <summary> Will decode an RfcLdapMessage directly from an InputStream.</summary>
[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.INTERMEDIATE_RESPONSE:
set_Renamed(1, new RfcIntermediateResponse(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
//*************************************************************************
/// <summary> Returns the request associated with this RfcLdapMessage.
/// Throws a class cast exception if the RfcLdapMessage is not a request.
/// </summary>
public RfcRequest getRequest()
{
return (RfcRequest) get_Renamed(1);
}
public virtual bool isRequest()
{
return get_Renamed(1) is RfcRequest;
}
/// <summary> Duplicate this message, replacing base dn, filter, and scope if supplied
///
/// </summary>
/// <param name="dn">the base dn
///
/// </param>
/// <param name="filter">the filter
///
/// </param>
/// <param name="reference">true if a search reference
///
/// </param>
/// <returns> the object representing the new message
/// </returns>
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;
}
}
}