diff options
18 files changed, 853 insertions, 18 deletions
diff --git a/mcs/class/Novell.Directory.Ldap/ChangeLog b/mcs/class/Novell.Directory.Ldap/ChangeLog index eba803a256c..b7b128ec104 100644 --- a/mcs/class/Novell.Directory.Ldap/ChangeLog +++ b/mcs/class/Novell.Directory.Ldap/ChangeLog @@ -1,3 +1,60 @@ +2007-19-09 Palaniappan N <npalaniappan@novell.com> + + The folder is made in sync. with the Novell Forge's C# LDAP SDK with the following updates: + + *Novell.Directory.Ldap : + - Connection.cs: Checked the condition, whether the sockets + created by BOTH SSL and cleartext connections are open / null + in Connection.cs + - Connection.cs: Added a new catch block in Connection.cs to + catch the socket exceptions. + - Connection.cs: Version has been updated to 2.1.8 + - LdapResponse.cs: Changes made to monitor the events which + caused problems with eDirectory 8.8 SP1 release, because of the + LdapResponse structure. + - LdapException.cs: A fix for the bug which deals about the + exceptions caused while using events with lots of create/modify events + - LdapAttributeSchema.cs: Superior was not set properly. Corrected. + - Message.cs: To fix the issue of seeing duplicate records while searching + + *Novell.Directory.Ldap.Extensions : + - Added support for Backup-Restore of LDAP by including the following classes + # LdapBackupRequest.cs + # LdapBackupResponse.cs + # LdapRestoreRequest.cs + # BackupRestoreConstants.cs + + *Novell.Directory.Ldap.Utilclass : + - DN.cs: Done a fix in by correcting the misplaced decrement operator + which caused malfunctioning of isDescendantOf() method + + *Novell.Directory.Ldap.Events : + - LdapEventSource.cs: Exception has been thrown in case of supply of + negative sleep interval + + *Novell.Directory.Ldap.Events.Edir.EventData : + - ValueEventData.cs: A new property BinaryData has been implemented in the + class to enable applications retrieve the binary data as such from the + ASN1OctetString with out converting it in to a String + + *Novell.Directory.Ldap.Rfc2251 : + - RfcIntermediateResponse.cs: The variable m_responseNameIndex has been + modified to get value 0 also to fix an issue related to parsing the response. + - RfcModifyDNRequest.cs: SetIdentifier method has been applied to newSuperior + to make rename work properly with all LDAP servers. + + * Changelog: + - Updated + + * Novell.Directory.Ldap.dll.sources: + - Added the new file entries of the Backup-Restore Extension + + * Novell.Directory.Ldap.vmwcsproj: + - Added the new file entries of the Backup-Restore Extension + + * Novell.Directory.Ldap20.csproj: + - Added the new file entries of the Backup-Restore Extension + 2005-12-06 Konstantin Triger <kostat@mainsoft.com> * Novell.Directory.Ldap.vmwcsproj: fixing conditional compilation constants. diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events.Edir.EventData/ValueEventData.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events.Edir.EventData/ValueEventData.cs index 23a7720d946..ce3a3575023 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events.Edir.EventData/ValueEventData.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events.Edir.EventData/ValueEventData.cs @@ -68,6 +68,14 @@ namespace Novell.Directory.Ldap.Events.Edir.EventData } } + protected byte[] binData; + public byte[] BinaryData + { + get + { + return binData; + } + } protected string strEntry; public string Entry { @@ -118,6 +126,7 @@ namespace Novell.Directory.Ldap.Events.Edir.EventData : base(eventDataType, message) { int[] length = new int[1]; + Asn1OctetString octData; strPerpetratorDN = ((Asn1OctetString) decoder.decode(decodedData, length)).stringValue(); @@ -134,7 +143,9 @@ namespace Novell.Directory.Ldap.Events.Edir.EventData timeStampObj = new DSETimeStamp((Asn1Sequence) decoder.decode(decodedData, length)); - strData = ((Asn1OctetString) decoder.decode(decodedData, length)).stringValue(); + octData = ((Asn1OctetString) decoder.decode(decodedData, length)); + strData = octData.stringValue(); + binData = SupportClass.ToByteArray(octData.byteValue()); nVerb = ((Asn1Integer) decoder.decode(decodedData, length)).intValue(); @@ -152,6 +163,7 @@ namespace Novell.Directory.Ldap.Events.Edir.EventData buf.AppendFormat("(Attribute={0})", strAttribute); buf.AppendFormat("(Classid={0})", strClassId); buf.AppendFormat("(Data={0})", strData); + buf.AppendFormat("(Data={0})", binData); buf.AppendFormat("(Entry={0})", strEntry); buf.AppendFormat("(Perpetrator={0})", strPerpetratorDN); buf.AppendFormat("(Syntax={0})", strSyntax); diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events/LdapEventSource.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events/LdapEventSource.cs index 82731d97a85..3135bc2f9c5 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events/LdapEventSource.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events/LdapEventSource.cs @@ -66,7 +66,10 @@ namespace Novell.Directory.Ldap.Events } set { - sleep_interval = value; + if(value <= 0) + throw new ArgumentOutOfRangeException("SleepInterval","cannot take the negative or zero values "); + else + sleep_interval = value; } } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/BackupRestoreConstants.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/BackupRestoreConstants.cs new file mode 100644 index 00000000000..088ddf48d6e --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/BackupRestoreConstants.cs @@ -0,0 +1,69 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2006 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.Extensions.BackupRestoreConstants.cs +// +// Author: +// Palaniappan N (NPalaniappan@novell.com) +// +// (C) 2006 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Extensions +{ + public class BackupRestoreConstants + { + + /** + * A constant for eDirectory LDAP Based Backup Request OID. + */ + public const String NLDAP_LDAP_BACKUP_REQUEST = "2.16.840.1.113719.1.27.100.96"; + + /** + * A constant for eDirectory LDAP Based Backup Response OID. + */ + public const String NLDAP_LDAP_BACKUP_RESPONSE = "2.16.840.1.113719.1.27.100.97"; + + /** + * A constant for eDirectory LDAP Based Restore Request OID. + */ + public const String NLDAP_LDAP_RESTORE_REQUEST = "2.16.840.1.113719.1.27.100.98"; + + + /** + * A constant for eDirectory LDAP Based Restore Response OID. + */ + public const String NLDAP_LDAP_RESTORE_RESPONSE = "2.16.840.1.113719.1.27.100.99"; + + /** + * Default constructor + */ + public BackupRestoreConstants():base() + { + return; + } + + } +}
\ No newline at end of file diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupRequest.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupRequest.cs new file mode 100644 index 00000000000..bb9ba0f71a3 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupRequest.cs @@ -0,0 +1,192 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2006 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.Extensions.BackupRestoreConstants.cs +// +// Author: +// Palaniappan N (NPalaniappan@novell.com) +// +// (C) 2006 Novell, Inc (http://www.novell.com) +// + + +using System; +using System.IO; + +using Novell.Directory.Ldap; +using Novell.Directory.Ldap.Asn1; + +/** +* +* This class provides an LDAP interface for object based backup +* of eDirectory objects. The backup API not only get the objects +* but all the DS level attributes associated with the objects. +* +* <p>The information available includes such items as modification timestamp, +* revision,data blob consisting of backup data of any eDirectory Object. The API +* support backing of both non-encrypted and encrypted objects +* </p> +* +* <p>To get information about any eDirectory Object, you must +* create an instance of this class and then call the +* extendedOperation method with this object as the required +* LdapExtendedOperation parameter.</p> +* +* <p>The getLdapBackupRequest extension uses the following OID:<br> +* 2.16.840.1.113719.1.27.100.96</p><br> +* +* <p>The requestValue has the following format:<br> +* +* requestValue ::=<br> +* objectDN LDAPDN<br> +* mts(modification timestamp) INTEGER<br> +* revision INTEGER<br> +* passwd OCTET STRING</p> +*/ + +namespace Novell.Directory.Ldap.Extensions +{ + public class LdapBackupRequest: LdapExtendedOperation + { + + static LdapBackupRequest() + { + /* + * Register the extendedresponse class which is returned by the server + * in response to a LdapBackupRequest + */ + try + { + LdapExtendedResponse.register( + BackupRestoreConstants.NLDAP_LDAP_BACKUP_RESPONSE, + Type.GetType("Novell.Directory.Ldap.Extensions.LdapBackupResponse")); + } + catch (TypeLoadException e) + { + Console.Error.WriteLine("Could not register Extended Response - Class not found"); + } + catch (Exception e) + { + Console.Error.WriteLine(e.StackTrace); + } + } + + /** + * + * Constructs an extended operations object for getting data about any Object. + * + * @param objectDN The DN of the object to be backed up + * <br> + * @param passwd The encrypted password required for the object to + * be backed up + * <br> + * @param stateInfo The state information of the object to backup. + * This parameter is a String which contains combination of modification + * timestamp and revision number of object being backed up. The format + * of both modification time stamp and revision should pertain to eDirectoty + * standard format of taking modification timestamp and revision. + * Separator being used between these two is a '+' character.<br> + * + * + * @exception LdapException A general exception which includes an error + * message and an LDAP error code. + */ + public LdapBackupRequest(String objectDN, byte[] passwd, String stateInfo): + base(BackupRestoreConstants.NLDAP_LDAP_BACKUP_REQUEST, null) + { + + int mts; // Modifaction time stamp of the Object + int revision; // Revision number of the Object + String mtsStr, revisionStr; + + try + { + if (objectDN == null) + throw new ArgumentException("PARAM_ERROR"); + + //If encrypted password has null reference make it null String + if(passwd == null) + passwd = System.Text.Encoding.UTF8.GetBytes(""); + + + if (stateInfo == null) + { + // If null reference is passed in stateInfo initialize both + // mts and revision + mts = 0; + revision = 0; + } + else + { + // Parse the passed stateInfo to obtain mts and revision + stateInfo = stateInfo.Trim(); + int index = stateInfo.IndexOf('+'); + if(index == -1) + throw new ArgumentException("PARAM_ERROR"); + mtsStr = stateInfo.Substring(0, index); + revisionStr = stateInfo.Substring(index + 1); + try + { + mts = int.Parse(mtsStr); + } + catch (FormatException e) + { + throw new LdapLocalException("Invalid Modification Timestamp send in the request", LdapException.ENCODING_ERROR); + } + try + { + revision = int.Parse(revisionStr); + } + catch (FormatException e) + { + throw new LdapLocalException( + "Invalid Revision send in the request", + LdapException.ENCODING_ERROR); + } + } + + MemoryStream encodedData = new MemoryStream(); + LBEREncoder encoder = new LBEREncoder(); + + // Encode data of objectDN, mts and revision + Asn1OctetString asn1_objectDN = new Asn1OctetString(objectDN); + Asn1Integer asn1_mts = new Asn1Integer(mts); + Asn1Integer asn1_revision = new Asn1Integer(revision); + Asn1OctetString asn1_passwd = new Asn1OctetString(SupportClass.ToSByteArray(passwd)); + + asn1_objectDN.encode(encoder, encodedData); + asn1_mts.encode(encoder, encodedData); + asn1_revision.encode(encoder, encodedData); + asn1_passwd.encode(encoder, encodedData); + + // set the value of operation specific data + setValue(SupportClass.ToSByteArray(encodedData.ToArray())); + + } + catch (IOException ioe) + { + throw new LdapException("ENCODING_ERROR", LdapException.ENCODING_ERROR, (String) null); + } + } + } +}
\ No newline at end of file diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupResponse.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupResponse.cs new file mode 100644 index 00000000000..7fc3a44dc02 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapBackupResponse.cs @@ -0,0 +1,263 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2006 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.Extensions.BackupRestoreConstants.cs +// +// Author: +// Palaniappan N (NPalaniappan@novell.com) +// +// (C) 2006 Novell, Inc (http://www.novell.com) +// + +using System; +using System.IO; + +using Novell.Directory.Ldap; +using Novell.Directory.Ldap.Asn1; +using Novell.Directory.Ldap.Rfc2251; + + + +/** + * This object represent the data returned from a LdapBackupRequest. + * + * <p>An object in this class is generated from an ExtendedResponse object + * using the ExtendedResponseFactory class.</p> + * + * <p>The LdapBackupResponse extension uses the following OID:<br> + * 2.16.840.1.113719.1.27.100.97</p> + * + */ + +namespace Novell.Directory.Ldap.Extensions +{ + + public class LdapBackupResponse:LdapExtendedResponse + { + + private int bufferLength; //Represents the length of backup data + private String stateInfo; //Represent the state Information of data + + /* + * The String representing the number of chunks and each elements in chunk + * array as returned by server. + * Data from server is parsed as follows before sending to any Application:: + * no_of_chunks;sizeOf(chunk1);sizeOf(chunk2)…sizeOf(chunkn) + * where + * no_of_chunks => Represents the number of chunks of data returned from server + * sizeOf(chunkn) => Represents the size of data in chunkn + */ + private String chunkSizesString; + + /* + * Actual data of returned eDirectoty Object in byte[] + */ + private byte[] returnedBuffer; + + /** + * Constructs an object from the responseValue which contains the backup data. + * <p>The constructor parses the responseValue which has the following + * format:<br> + * responseValue ::=<br> + * <p>databufferLength ::= INTEGER <br> + * mts(modification time stamp) ::= INTEGER<br> + * revision ::= INTEGER<br> + * returnedBuffer ::= OCTET STRING<br> + * dataChunkSizes ::= <br> + * SEQUENCE{<br> + * noOfChunks INTEGER<br> + * SET of [<br> + * SEQUENCE of {eachChunksize INTEGER}]<br> + * }</p> + * + * @exception IOException The responseValue could not be decoded. + */ + + public LdapBackupResponse(RfcLdapMessage rfcMessage): base(rfcMessage) + { + int modificationTime = 0; // Modifaction timestamp of the Object + int revision = 0; // Revision number of the Object + int chunksSize = 0; + int[] chunks = null; //Holds size of each chunks returned from server + + //Verify if returned ID is not proper + if (ID == null || !(ID.Equals(BackupRestoreConstants.NLDAP_LDAP_BACKUP_RESPONSE))) + throw new IOException("LDAP Extended Operation not supported"); + + if (ResultCode == LdapException.SUCCESS) { + // Get the contents of the reply + + byte[] returnedValue = SupportClass.ToByteArray(this.Value); + if (returnedValue == null) + throw new Exception("LDAP Operations error. No returned value."); + + // Create a decoder object + LBERDecoder decoder = new LBERDecoder(); + + if (decoder == null) + throw new Exception("Decoding error"); + + // Parse the parameters in the order + MemoryStream currentPtr = new MemoryStream(returnedValue); + + // Parse bufferLength + Asn1Integer asn1_bufferLength = (Asn1Integer) decoder + .decode(currentPtr); + if (asn1_bufferLength == null) + throw new IOException("Decoding error"); + bufferLength = asn1_bufferLength.intValue(); + + // Parse modificationTime + Asn1Integer asn1_modificationTime = (Asn1Integer) decoder + .decode(currentPtr); + if (asn1_modificationTime == null) + throw new IOException("Decoding error"); + modificationTime = asn1_modificationTime.intValue(); + + // Parse revision + Asn1Integer asn1_revision = (Asn1Integer) decoder + .decode(currentPtr); + if (asn1_revision == null) + throw new IOException("Decoding error"); + revision = asn1_revision.intValue(); + + //Format stateInfo to contain both modificationTime and revision + this.stateInfo = modificationTime + "+" + revision; + + // Parse returnedBuffer + Asn1OctetString asn1_returnedBuffer = (Asn1OctetString) decoder.decode(currentPtr); + if (asn1_returnedBuffer == null) + throw new IOException("Decoding error"); + + returnedBuffer = SupportClass.ToByteArray(asn1_returnedBuffer.byteValue()); + + + /* + * Parse chunks array + * Chunks returned from server is encoded as shown below:: + * SEQUENCE{ + * chunksSize INTEGER + * SET of [ + * SEQUENCE of {eacChunksize INTEGER}] + * } + */ + + Asn1Sequence asn1_chunksSeq = (Asn1Sequence) decoder + .decode(currentPtr); + if (asn1_chunksSeq == null) + throw new IOException("Decoding error"); + + //Get number of chunks returned from server + chunksSize = ((Asn1Integer)asn1_chunksSeq.get_Renamed(0)).intValue(); + + //Construct chunks array + chunks = new int[chunksSize]; + + Asn1Set asn1_chunksSet = (Asn1Set)asn1_chunksSeq.get_Renamed(1); + //Iterate through asn1_chunksSet and put each size into chunks array + + for (int index = 0; index < chunksSize; index++) + { + Asn1Sequence asn1_eachSeq = (Asn1Sequence)asn1_chunksSet.get_Renamed(index); + chunks[index] = ((Asn1Integer)asn1_eachSeq.get_Renamed(0)).intValue(); + } + + //Construct a temporary StringBuffer and append chunksSize, each size + //element in chunks array and actual data of eDirectoty Object + System.Text.StringBuilder tempBuffer = new System.Text.StringBuilder(); + tempBuffer.Append(chunksSize); + tempBuffer.Append(";"); + int i = 0; + + for (; i < (chunksSize - 1); i++) + { + tempBuffer.Append(chunks[i]); + tempBuffer.Append(";"); + } + + tempBuffer.Append(chunks[i]); + + //Assign tempBuffer to parsedString to be returned to Application + this.chunkSizesString = tempBuffer.ToString(); + } + else + { + //Intialize all these if getResultCode() != LdapException.SUCCESS + this.bufferLength = 0; + this.stateInfo = null; + this.chunkSizesString = null; + this.returnedBuffer = null; + } + + } + + /** + * Returns the data buffer length + * + * @return bufferLength as integer. + */ + public int getBufferLength() + { + return bufferLength; + } + + /** + * Returns the stateInfo of returned eDirectory Object. + * This is combination of MT (Modification Timestamp) and + * Revision value with char '+' as separator between two.<br> + * Client application if want to use both MT and Revision need to break + * this string to get both these data. + * + * @return stateInfo as String. + */ + public String getStatusInfo() + { + return stateInfo; + } + + /** + * Returns the data in String as::<br> + * no_of_chunks;sizeOf(chunk1);sizeOf(chunk2)…sizeOf(chunkn)<br> + * where<br> + * no_of_chunks => Represents the number of chunks of data returned from server<br> + * sizeOf(chunkn) => Represents the size of data in chunkn<br> + * + * @return chunkSizesString as String. + */ + public String getChunkSizesString() + { + return chunkSizesString; + } + + /** + * Returns the data buffer as byte[] + * + * @return returnedBuffer as byte[]. + */ + public byte[] getReturnedBuffer() + { + return returnedBuffer; + } + +} +}
\ No newline at end of file diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapRestoreRequest.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapRestoreRequest.cs new file mode 100644 index 00000000000..e9f3e84a015 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Extensions/LdapRestoreRequest.cs @@ -0,0 +1,197 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2006 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.Extensions.BackupRestoreConstants.cs +// +// Author: +// Palaniappan N (NPalaniappan@novell.com) +// +// (C) 2006 Novell, Inc (http://www.novell.com) +// + + +using System; +using System.IO; + +using Novell.Directory.Ldap; +using Novell.Directory.Ldap.Asn1; + +/** +* +* This class provides an LDAP interface for object based +* restore of eDirectory objects. +* +* <p>The information need for restore includes such items as object DN, +* data buffer length, string containing the number of chunks and each chunk +* elements representing the size of each chunk, data blob in byte[]. The API +* support restoring of both non-encrypted and encrypted objects. +* </p> +* +* <p>To send this request to eDirectory, you must +* create an instance of this class and then call the +* extendedOperation method with this object as the required +* LdapExtendedOperation parameter.</p><br> +* +* <p>The getLdapRestoreRequest extension uses the following OID:<br> +* 2.16.840.1.113719.1.27.100.98</p><br> +* +* <p>The requestValue has the following format:<br> +* +* <p>requestValue ::=<br> +* objectDN ::= LDAPDN<br> +* passwd ::= OCTET STRING<br> +* bufferLength ::= INTEGER<br> +* retunedBuffer::= OCTET STRING<br> +* dataChunkSizes ::=<br> +* SEQUENCE {<br> +* noOfChunks INTEGER<br> +* SET of [<br> +* SEQUENCE of {eacChunksize INTEGER}]<br> +* }<br> </p> +*/ + +namespace Novell.Directory.Ldap.Extensions +{ + public class LdapRestoreRequest : LdapExtendedOperation + { + /** + * + * Constructs an extended operations object which contains the ber encoded + * restore data. + * + * @param objectDN The object DN to restore + * <br> + * @param passwd The encrypted password required for the object to + * be backed up + * <br> + * @param bufferLength The length of backed up data + * <br> + * @param chunkSizesString The String containing number of chunks and + * each chunk elements representing chunk sizes + * <br> + * @param returnedBuffer The actual data in byte[] + * <br><br> + * @exception LdapException A general exception which includes an error + * message and an LDAP error code. + */ + + public LdapRestoreRequest(String objectDN, byte[] passwd, + int bufferLength, String chunkSizesString, byte[] returnedBuffer): + base(BackupRestoreConstants.NLDAP_LDAP_RESTORE_REQUEST, null) + { + try + { + //Verify the validity of arguments + if (objectDN == null || bufferLength == 0 || + chunkSizesString == null || returnedBuffer == null) + throw new ArgumentException("PARAM_ERROR"); + + //If encrypted password has null reference make it null String + if(passwd == null) + passwd = System.Text.Encoding.UTF8.GetBytes(""); + + /* + * From the input argument chunkSizesString get:: + * chunkSize => Represents the number of chunks of data returned from server + * sizeOf each chunk => int represents the size of each chunk + */ + int index; + int chunkSize; + int[] chunks = null; + index = chunkSizesString.IndexOf(';'); + try + { + chunkSize = int.Parse(chunkSizesString.Substring(0, index)); + } + catch (FormatException e) + { + throw new LdapLocalException( + "Invalid data buffer send in the request", + LdapException.ENCODING_ERROR); + } + //Return exception if chunkSize == 0 + if (chunkSize == 0) + throw new ArgumentException("PARAM_ERROR"); + + chunkSizesString = chunkSizesString.Substring(index + 1); + + int chunkIndex; + //Construct chunks array + chunks = new int[chunkSize]; + /* + * Iterate through each member in buffer and + * assign to chunks array elements + */ + for (int i = 0; i < chunkSize; i++) + { + chunkIndex = chunkSizesString.IndexOf(';'); + if(chunkIndex == -1) + { + chunks[i] = int.Parse(chunkSizesString); + break; + } + chunks[i] = int.Parse(chunkSizesString.Substring(0, + chunkIndex)); + chunkSizesString = chunkSizesString.Substring(chunkIndex + 1); + } + + MemoryStream encodedData = new MemoryStream(); + LBEREncoder encoder = new LBEREncoder(); + + //Form objectDN, passwd, bufferLength, data byte[] as ASN1 Objects + Asn1OctetString asn1_objectDN = new Asn1OctetString(objectDN); + Asn1OctetString asn1_passwd = new Asn1OctetString(SupportClass.ToSByteArray(passwd)); + Asn1Integer asn1_bufferLength = new Asn1Integer(bufferLength); + Asn1OctetString asn1_buffer = new Asn1OctetString(SupportClass.ToSByteArray(returnedBuffer)); + + //Form the chunks sequence to be passed to Server + Asn1Sequence asn1_chunksSeq = new Asn1Sequence(); + asn1_chunksSeq.add(new Asn1Integer(chunkSize)); + Asn1Set asn1_chunksSet = new Asn1Set(); + for (int i = 0; i < chunkSize; i++) + { + Asn1Integer tmpChunk = new Asn1Integer(chunks[i]); + Asn1Sequence tmpSeq = new Asn1Sequence(); + tmpSeq.add(tmpChunk); + asn1_chunksSet.add(tmpSeq); + } + asn1_chunksSeq.add(asn1_chunksSet); + + //Encode data to send to server + asn1_objectDN.encode(encoder, encodedData); + asn1_passwd.encode(encoder, encodedData); + asn1_bufferLength.encode(encoder, encodedData); + asn1_buffer.encode(encoder, encodedData); + asn1_chunksSeq.encode(encoder, encodedData); + + // set the value of operation specific data + setValue(SupportClass.ToSByteArray(encodedData.ToArray())); + + } + catch (IOException ioe) + { + throw new LdapException("ENCODING_ERROR", LdapException.ENCODING_ERROR, (String) null); + } + } + } +}
\ No newline at end of file diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcIntermediateResponse.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcIntermediateResponse.cs index f5a705833b3..236e4b9afd4 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcIntermediateResponse.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcIntermediateResponse.cs @@ -168,7 +168,7 @@ namespace Novell.Directory.Ldap.Rfc2251 public RfcLdapOID getResponseName() { - return (m_responseNameIndex != 0) ? (RfcLdapOID)get_Renamed(m_responseNameIndex) + return (m_responseNameIndex >= 0) ? (RfcLdapOID)get_Renamed(m_responseNameIndex) : null; } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcModifyDNRequest.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcModifyDNRequest.cs index 72d4ff9a4ba..ad51fa020b4 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcModifyDNRequest.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcModifyDNRequest.cs @@ -64,7 +64,9 @@ namespace Novell.Directory.Ldap.Rfc2251 add(entry); add(newrdn); add(deleteoldrdn); - if (newSuperior != null) { + if (newSuperior != null) + { + newSuperior.setIdentifier(new Asn1Identifier(Asn1Identifier.CONTEXT,false,0)); add(newSuperior); } } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs index ff17c6b8ab8..1f57f6c14f5 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs @@ -694,8 +694,9 @@ namespace Novell.Directory.Ldap.Utilclass int j = this.rdnList.Count - 1; //index to an RDN of the ContainedDN //Search from the end of the DN for an RDN that matches the end RDN of //containerDN. - while (!((RDN) this.rdnList[j--]).equals((RDN) containerDN.rdnList[i])) + while (!((RDN) this.rdnList[j]).equals((RDN) containerDN.rdnList[i])) { + j--; if (j <= 0) return false; //if the end RDN of containerDN does not have any equal diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.dll.sources b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.dll.sources index da4cd2a142d..d5010fd1970 100755 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.dll.sources +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.dll.sources @@ -173,6 +173,10 @@ Novell.Directory.Ldap.Extensions/MergePartitionsRequest.cs Novell.Directory.Ldap.Extensions/SplitPartitionRequest.cs Novell.Directory.Ldap.Extensions/NamingContextConstants.cs Novell.Directory.Ldap.Extensions/TriggerBackgroundProcessRequest.cs +Novell.Directory.Ldap.Extensions/BackupRestoreConstants.cs +Novell.Directory.Ldap.Extensions/LdapBackupRequest.cs +Novell.Directory.Ldap.Extensions/LdapBackupResponse.cs +Novell.Directory.Ldap.Extensions/LdapRestoreRequest.cs Novell.Directory.Ldap.Controls/LdapEntryChangeControl.cs Novell.Directory.Ldap.Controls/LdapPersistSearchControl.cs Novell.Directory.Ldap.Controls/LdapSortControl.cs diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.vmwcsproj b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.vmwcsproj index 6a97c60fbf5..3f0b9efbda5 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.vmwcsproj +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.vmwcsproj @@ -160,6 +160,10 @@ <File RelPath="Novell.Directory.Ldap.Extensions\SplitOrphanPartitionRequest.cs" SubType="Code" BuildAction="Compile"/>
<File RelPath="Novell.Directory.Ldap.Extensions\SplitPartitionRequest.cs" SubType="Code" BuildAction="Compile"/>
<File RelPath="Novell.Directory.Ldap.Extensions\TriggerBackgroundProcessRequest.cs" SubType="Code" BuildAction="Compile"/>
+ <File RelPath="Novell.Directory.Ldap.Extensions\BackupRestoreConstants.cs" SubType="Code" BuildAction="Compile"/>
+ <File RelPath="Novell.Directory.Ldap.Extensions\LdapBackupRequest.cs" SubType="Code" BuildAction="Compile"/>
+ <File RelPath="Novell.Directory.Ldap.Extensions\LdapBackupResponse.cs" SubType="Code" BuildAction="Compile"/>
+ <File RelPath="Novell.Directory.Ldap.Extensions\LdapRestoreRequest.cs" SubType="Code" BuildAction="Compile"/>
<File RelPath="Novell.Directory.Ldap.Rfc2251\RfcAbandonRequest.cs" SubType="Code" BuildAction="Compile"/>
<File RelPath="Novell.Directory.Ldap.Rfc2251\RfcAddRequest.cs" SubType="Code" BuildAction="Compile"/>
<File RelPath="Novell.Directory.Ldap.Rfc2251\RfcAddResponse.cs" SubType="Code" BuildAction="Compile"/>
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Connection.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Connection.cs index f280fcd9727..e9df5a92fe5 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Connection.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Connection.cs @@ -810,10 +810,20 @@ namespace Novell.Directory.Ldap } } + catch (System.Net.Sockets.SocketException se) + { + // Unable to connect to server host:port + freeWriteSemaphore(semId); + sock = null; + socket = null; + throw new LdapException(ExceptionMessages.CONNECTION_ERROR, new System.Object[] { host, port }, LdapException.CONNECT_ERROR, null, se); + } catch (System.IO.IOException ioe) { // Unable to connect to server host:port - // freeWriteSemaphore(semId); + freeWriteSemaphore(semId); + sock = null; + socket = null; throw new LdapException(ExceptionMessages.CONNECTION_ERROR, new System.Object[]{host, port}, LdapException.CONNECT_ERROR, null, ioe); } // Set host and port @@ -1117,10 +1127,11 @@ namespace Novell.Directory.Ldap } bindProperties = null; - if (socket != null) + if (socket != null || sock != null) { #if !TARGET_JVM // Just before closing the sockets, abort the reader thread + if ((reader != null) && (reason != "reader: thread stopping")) reader.Abort(); #endif // Close the socket @@ -1252,7 +1263,15 @@ namespace Novell.Directory.Ldap */ // NetworkStream nstream = new NetworkStream(this.socket,true); // Load Mono.Security.dll - Assembly a = Assembly.LoadFrom("Mono.Security.dll"); + Assembly a = null; + try + { + a = Assembly.LoadFrom("Mono.Security.dll"); + } + catch(System.IO.FileNotFoundException) + { + throw new LdapException(ExceptionMessages.SSL_PROVIDER_MISSING, LdapException.SSL_PROVIDER_NOT_FOUND, null); + } Type tSslClientStream = a.GetType("Mono.Security.Protocol.Tls.SslClientStream"); BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); @@ -1679,7 +1698,7 @@ namespace Novell.Directory.Ldap static Connection() { nameLock = new System.Object(); - sdk = new System.Text.StringBuilder("2.1.4").ToString(); + sdk = new System.Text.StringBuilder("2.1.8").ToString(); protocol = 3; } } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapAttributeSchema.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapAttributeSchema.cs index 5e1cb867c46..0255a1fb09e 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapAttributeSchema.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapAttributeSchema.cs @@ -277,6 +277,7 @@ namespace Novell.Directory.Ldap this.collective = collective; this.userMod = isUserModifiable; this.usage = usage; + this.superior = superior; base.Value = formatString(); return ; } @@ -306,7 +307,7 @@ namespace Novell.Directory.Ldap if ((System.Object) parser.Syntax != null) syntaxString = parser.Syntax; if ((System.Object) parser.Superior != null) - syntaxString = parser.Superior; + superior = parser.Superior; single = parser.Single; base.obsolete = parser.Obsolete; System.Collections.IEnumerator qualifiers = parser.Qualifiers; diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapException.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapException.cs index a69650c0bd1..5625ded8584 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapException.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapException.cs @@ -180,7 +180,7 @@ namespace Novell.Directory.Ldap { get { - return InnerException; + return rootException; } } @@ -251,6 +251,8 @@ namespace Novell.Directory.Ldap private System.Object[] arguments = null; // The Matched DN private System.String matchedDN = null; + // The Root Cause + private System.Exception rootException = null; // A message from the server private System.String serverMessage = null; @@ -1011,13 +1013,14 @@ namespace Novell.Directory.Ldap /// be matched by the server on a search operation. /// </param> /* package */ - internal LdapException(System.String messageOrKey, System.Object[] arguments, int resultCode, System.String serverMsg, System.String matchedDN, System.Exception rootException):base(messageOrKey, rootException) + internal LdapException(System.String messageOrKey, System.Object[] arguments, int resultCode, System.String serverMsg, System.String matchedDN, System.Exception rootException) //:base(Novell.Directory.Ldap.Utilclass.ResourcesHandler.getMessage(messageOrKey, arguments)) //Once resorcehandler starts working properly need to uncomment { this.messageOrKey = messageOrKey; this.arguments = arguments; this.resultCode = resultCode; + this.rootException = rootException; this.matchedDN = matchedDN; this.serverMessage = serverMsg; return ; @@ -1140,9 +1143,9 @@ namespace Novell.Directory.Ldap msg = msg + '\n' + tmsg; } - if (InnerException != null) + if (rootException != null) { - msg = msg + '\n' + InnerException.ToString(); + msg = msg + '\n' + rootException.ToString(); } return msg; } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapResponse.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapResponse.cs index 8ddf9aed5a7..8cb530b9adf 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapResponse.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapResponse.cs @@ -168,6 +168,8 @@ namespace Novell.Directory.Ldap { return exception.ResultCode; } + if (((RfcResponse) message.Response) is RfcIntermediateResponse) + return 0; return ((RfcResponse) message.Response).getResultCode().intValue(); } @@ -198,7 +200,6 @@ namespace Novell.Directory.Ldap default: ex = new LdapException(LdapException.resultCodeToString(ResultCode), ResultCode, ErrorMessage, MatchedDN); -// ex = new LdapException("49", 49, "hello error", "hi error.."); break; } diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Message.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Message.cs index 998e76c72fd..a181b87c838 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Message.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/Message.cs @@ -466,7 +466,10 @@ namespace Novell.Directory.Ldap { return ; } - replies.Add(message); + lock(replies) + { + replies.Add(message); + } message.RequestingMessage = msg; // Save request message info switch (message.Type) { diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap20.csproj b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap20.csproj index 79e99bda929..481a2fc3f0e 100755 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap20.csproj +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap20.csproj @@ -183,7 +183,11 @@ <Compile Include="Novell.Directory.Ldap.Extensions\SetReplicationFilterRequest.cs" />
<Compile Include="Novell.Directory.Ldap.Extensions\SplitOrphanPartitionRequest.cs" />
<Compile Include="Novell.Directory.Ldap.Extensions\SplitPartitionRequest.cs" />
- <Compile Include="Novell.Directory.Ldap.Extensions\TriggerBackgroundProcessRequest.cs" />
+ <Compile Include="Novell.Directory.Ldap.Extensions\TriggerBackgroundProcessRequest.cs" />
+ <Compile Include="Novell.Directory.Ldap.Extensions\BackupRestoreConstants.cs" />
+ <Compile Include="Novell.Directory.Ldap.Extensions\LdapBackupRequest.cs" />
+ <Compile Include="Novell.Directory.Ldap.Extensions\LdapBackupResponse.cs" />
+ <Compile Include="Novell.Directory.Ldap.Extensions\LdapRestoreRequest.cs" />
<Compile Include="Novell.Directory.Ldap.Rfc2251\RfcAbandonRequest.cs" />
<Compile Include="Novell.Directory.Ldap.Rfc2251\RfcAddRequest.cs" />
<Compile Include="Novell.Directory.Ldap.Rfc2251\RfcAddResponse.cs" />
@@ -349,4 +353,4 @@ <UserProperties REFS-JarPath-rt="..\lib\rt.jar" REFS-JarPath-system="..\..\..\..\..\..\Program Files\Mainsoft\Visual MainWin for J2EE 2\java_refs\framework\System.jar" REFS-JarPath-j2se-helpers="..\lib\J2SE.Helpers.jar" REFS-JarPath-mscorlib="..\..\..\..\..\Program Files\Mainsoft\Visual MainWin for J2EE 2\java_refs\framework\mscorlib.jar" />
</VisualStudio>
</ProjectExtensions>
-</Project>
\ No newline at end of file +</Project>
|