1 /******************************************************************************
3 * Copyright (c) 2003 Novell Inc., www.novell.com
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 *******************************************************************************/
25 // System.DirectoryServices.DirectoryEntry.cs
28 // Sunil Kumar (sunilk@novell.com)
29 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
30 // Boris Kirzner (borisk@mainsoft.com)
35 using System.ComponentModel;
36 using Novell.Directory.Ldap;
37 using Novell.Directory.Ldap.Utilclass;
38 using System.Globalization;
39 using System.DirectoryServices.Design;
40 using System.Collections.Specialized;
41 using System.Configuration;
42 using System.Runtime.InteropServices;
44 namespace System.DirectoryServices
48 ///Encapsulates a node or object in the Ldap Directory hierarchy.
50 [TypeConverter (typeof (DirectoryEntryConverter))]
51 public class DirectoryEntry : Component
53 private static readonly string DEFAULT_LDAP_HOST = "System.DirectoryServices.DefaultLdapHost";
54 private static readonly string DEFAULT_LDAP_PORT = "System.DirectoryServices.DefaultLdapPort";
56 private LdapConnection _conn = null;
57 private AuthenticationTypes _AuthenticationType=AuthenticationTypes.None;
58 private DirectoryEntries _Children;
59 private string _Fdn = null;
60 private string _Path="";
61 private string _Name=null;
62 private DirectoryEntry _Parent=null;
63 private string _Username;
64 private string _Password;
65 //private string _Nativeguid;
66 private PropertyCollection _Properties = null;
67 private string _SchemaClassName=null;
68 private bool _Nflag = false;
69 private bool _usePropertyCache=true;
70 private bool _inPropertiesLoading;
73 /// Returns entry's Fully distinguished name.
79 LdapUrl lUrl = new LdapUrl (ADsPath);
80 string fDn=lUrl.getDN();
91 /// Returns the connection object used to communicate with
94 internal LdapConnection conn
108 /// Flag to check whether the entry is to be cerated or it already
121 /// <summary> Initializes the Connection and other properties.
124 private void InitBlock()
127 _conn= new LdapConnection ();
128 LdapUrl lUrl = new LdapUrl (ADsPath);
129 _conn.Connect(lUrl.Host,lUrl.Port);
130 _conn.Bind(Username,Password, (Novell.Directory.Ldap.AuthenticationTypes)AuthenticationType);
132 catch(LdapException ex) {
141 /// Initializes the Entry specific properties e.g entry DN etc.
145 LdapUrl lUrl = new LdapUrl (ADsPath);
146 string dn = lUrl.getDN();
148 if (String.Compare (dn,"rootDSE",true) == 0)
149 InitToRootDse (lUrl.Host,lUrl.Port);
151 DN userDn = new DN (dn);
152 String[] lRdn = userDn.explodeDN(false);
153 _Name = (string)lRdn[0];
154 _Parent = new DirectoryEntry(conn);
155 _Parent.Path = GetLdapUrlString (lUrl.Host,lUrl.Port,userDn.Parent.ToString ());
159 _Name=lUrl.Host+":"+lUrl.Port;
160 _Parent = new DirectoryEntry(conn);
161 _Parent.Path = "Ldap:";
166 /// Initializes a new instance of the DirectoryEntry class
168 public DirectoryEntry()
173 /// Initializes a new instance of the DirectoryEntry class that binds
174 /// to the specified native Active Directory object.
176 /// <param name="adsObject"> native active directory object</param>
177 public DirectoryEntry(object adsObject)
179 throw new NotImplementedException();
183 /// Initializes a new instance of the DirectoryEntry class that binds
184 /// this instance to the node in Ldap Directory located at the
187 /// <param name="path"> Path of the entry i.e Ldap URL specifying
188 /// entry path</param>
189 public DirectoryEntry(string path)
195 /// Initializes a new instance of the DirectoryEntry class. The Path,
196 /// Username, and Password properties are set to the specified values.
198 /// <param name="path">Path of the entry i.e Ldap URL specifying
199 /// entry path</param>
200 /// <param name="username">user name to use when authenticating the client
202 /// <param name="password">password to use when authenticating the client
204 public DirectoryEntry(string path,string username,string password)
212 /// Initializes a new instance of the DirectoryEntry class. The Path,
213 /// Username, and Password properties are set to the specified values.
215 /// <param name="path">Path of the entry i.e Ldap URL specifying
216 /// entry path</param>
217 /// <param name="username">user name to use when authenticating the client
219 /// <param name="password">password to use when authenticating the client
221 /// <param name="authenticationType"> type of authentication to use</param>
222 public DirectoryEntry(
226 AuthenticationTypes authenticationType)
231 _AuthenticationType=authenticationType;
235 /// Creates the entry object
237 /// <param name="lconn">Connection object used to communicate with
238 /// Ldap server</param>
239 internal DirectoryEntry(LdapConnection lconn)
245 /// Returns Type of authentication to use while Binding to Ldap server
247 [DSDescription ("Type of authentication to use while Binding to Ldap server")]
248 [DefaultValue (AuthenticationTypes.None)]
249 public AuthenticationTypes AuthenticationType
253 return _AuthenticationType;
257 _AuthenticationType = value;
262 /// Gets a DirectoryEntries containing the child entries of this node
263 /// in the Ldap Directory hierarchy.
265 /// <value>A DirectoryEntries containing the child entries of this node
266 /// in the Ldap Directory hierarchy.</value>
268 /// The child entries are only the immediate children of this node.
269 /// Use this property to find, retrieve, or create a directory entry
270 /// in the hierarchy. This property is a collection that, along with
271 /// usual iteration capabilities, provides an Add method through which
272 /// you add a node to the collection directly below the parent node
273 /// that you are currently bound to. When adding a node to the
274 /// collection, you must specify a name for the new node and the name of
275 /// a schema template that you want to associate with the node. For
276 /// example, you might want to use a schema titled "Computer" to add
277 /// new computers to the hierarchy.
279 [DSDescription ("Child entries of this node")]
280 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
282 public DirectoryEntries Children
286 _Children = new DirectoryEntries(ADsPath, conn);
292 /// Gets the globally unique identifier (GUID) of the DirectoryEntry
294 /// <value>The globally unique identifier of the DirectoryEntry.</value>
296 /// Not implemented yet.
298 [DSDescription ("A globally unique identifier for this DirectoryEntry")]
299 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
306 throw new NotImplementedException();
312 /// Gets the name of the object as named with the underlying directory
315 /// <value>The name of the object as named with the underlying directory
317 /// <remarks>This name, along with SchemaClassName, distinguishes this
318 /// entry from its siblings and must be unique amongst its siblings
319 /// in each instance of DirectoryEntry.</remarks>
320 [DSDescription ("The name of the object as named with the underlying directory")]
321 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
327 if(CheckEntry(conn,ADsPath))
330 throw new SystemException("There is no such object on the server");
337 /// Gets this entry's parent in the Ldap Directory hierarchy.
339 /// <value>This entry's parent in the Active Directory hierarc</value>
340 [DSDescription ("This entry's parent in the Ldap Directory hierarchy.")]
341 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
343 public DirectoryEntry Parent
347 if(CheckEntry(conn,ADsPath))
350 throw new SystemException("There is no such object on the server");
357 /// Gets the globally unique identifier of the DirectoryEntry, as
358 /// returned from the provider
361 /// The globally unique identifier of the DirectoryEntry, as returned
362 /// from the provider.
365 /// Not implemented yet.
367 [DSDescription ("The globally unique identifier of the DirectoryEntry, as returned from the provider")]
368 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
371 public string NativeGuid
374 throw new NotImplementedException();
379 /// Gets the native Active Directory Service Interfaces (ADSI) object.
382 /// Not implemented yet
383 [DSDescription ("The native Active Directory Service Interfaces (ADSI) object.")]
384 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
386 public object NativeObject
390 throw new NotImplementedException();
395 /// Determines if a cache should be used.
397 [DSDescription ("Determines if a cache should be used.")]
398 [DefaultValue (true)]
399 public bool UsePropertyCache
403 return _usePropertyCache;
407 _usePropertyCache = value;
411 [DSDescription ("The provider-specific options for this entry.")]
414 public DirectoryEntryConfiguration Options
417 throw new NotImplementedException ();
422 /// Gets or sets the password to use when authenticating the client.
425 /// The password to use when authenticating the client.
428 /// You can set the Username and password in order to specify alternate
429 /// credentials with which to access the information in Ldap Directory.
430 /// Any other DirectoryEntry objects retrieved from this instance (for
431 /// example, through Children) are automatically created with the same
432 /// alternate credentials.
434 [DSDescription ("The password to use when authenticating the client.")]
435 [DefaultValue (null)]
437 public string Password
449 /// Gets or sets the user name to use when authenticating the client.
452 /// The user name to use when authenticating the client.
455 /// You can set the user name and Password in order to specify alternate
456 /// credentials with which to access the information in Ldap Directory.
457 /// Any other DirectoryEntry objects retrieved from this instance (for
458 /// example, through Children) are automatically created with the same
461 [DSDescription ("The user name to use when authenticating the client.")]
462 [DefaultValue (null)]
464 [TypeConverter ("System.Diagnostics.Design.StringValueConverter, " + Consts.AssemblySystem_Design)]
465 public string Username
477 /// Gets or sets the path for this DirectoryEntry.
480 /// The path of this DirectoryEntry. The default is an empty string ("").
483 /// The Path property uniquely identifies this entry in a networked
484 /// environment. This entry can always be retrieved using this Path.
486 /// Setting the Path retrieves a new entry from the directory store; it
487 /// does not change the path of the currently bound entry.
489 /// The classes associated with the DirectoryEntry component can be used
490 /// with any of the Directory service providers. Some of the current
491 /// providers are Internet Information Services (IIS), Lightweight Directory
492 /// Access Protocol (Ldap), Novell NetWare Directory Service (NDS), and WinNT.
494 /// Currently we Support only Ldap provider.
495 /// e.g Ldap://[hostname]:[port number]/[ObjectFDN]
497 [DSDescription ("The path for this DirectoryEntry.")]
499 [RecommendedAsConfigurable (true)]
500 [TypeConverter ("System.Diagnostics.Design.StringValueConverter, " + Consts.AssemblySystem_Design)]
508 _Path = String.Empty;
514 internal string ADsPath
517 if (Path == null || Path == String.Empty) {
518 DirectoryEntry rootDse = new DirectoryEntry ();
519 rootDse.InitToRootDse (null,-1);
520 string namingContext = (string) rootDse.Properties ["defaultNamingContext"].Value;
521 if ( namingContext == null )
522 namingContext = (string) rootDse.Properties ["namingContexts"].Value;
524 LdapUrl actualUrl= new LdapUrl (DefaultHost,DefaultPort,namingContext);
525 return actualUrl.ToString ();
532 /// Gets a PropertyCollection of properties set on this object.
535 /// A PropertyCollection of properties set on this object.
537 [DSDescription ("Properties set on this object.")]
538 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
540 public PropertyCollection Properties
543 return GetProperties (true);
548 /// Gets the name of the schema used for this DirectoryEntry
551 /// The name of the schema used for this DirectoryEntry.
553 [DSDescription ("The name of the schema used for this DirectoryEntry.")]
554 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
556 public string SchemaClassName
559 if(_SchemaClassName==null) {
560 _SchemaClassName = FindAttrValue("structuralObjectClass");
562 return _SchemaClassName;
567 /// Gets the current schema directory entry.
570 /// Not implemented yet
571 [DSDescription ("The current schema directory entry.")]
572 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
574 public DirectoryEntry SchemaEntry
578 throw new NotImplementedException();
582 private string DefaultHost
585 string defaultHost = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_HOST);
587 if (defaultHost == null) {
588 NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings");
590 defaultHost = config ["servername"];
592 if (defaultHost == null)
593 defaultHost = "localhost";
595 AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_HOST,defaultHost);
601 private int DefaultPort
604 string defaultPortStr = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_PORT);
606 if (defaultPortStr == null) {
607 NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings");
609 defaultPortStr = config ["port"];
611 if (defaultPortStr == null)
612 defaultPortStr = "389";
614 AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_PORT,defaultPortStr);
616 return Int32.Parse (defaultPortStr);
620 private void InitToRootDse(string host,int port)
627 LdapUrl rootPath = new LdapUrl (host,port,String.Empty);
628 string [] attrs = new string [] {"+","*"};
629 DirectoryEntry rootEntry = new DirectoryEntry (rootPath.ToString (),this.Username,this.Password,this.AuthenticationType);
630 DirectorySearcher searcher = new DirectorySearcher (rootEntry,null,attrs,SearchScope.Base);
632 SearchResult result = searcher.FindOne ();
633 // copy properties from search result
634 PropertyCollection pcoll = new PropertyCollection ();
635 foreach (string propertyName in result.Properties.PropertyNames) {
636 System.Collections.IEnumerator enumerator = result.Properties [propertyName].GetEnumerator ();
637 if (enumerator != null)
638 while (enumerator.MoveNext ())
639 if (String.Compare (propertyName,"ADsPath",true) != 0)
640 pcoll [propertyName].Add (enumerator.Current);
642 this.SetProperties (pcoll);
643 this._Name = "rootDSE";
646 private void SetProperties(PropertyCollection pcoll)
652 /// Returns entry properties.
654 /// <param name="forceLoad">Specifies whenever to force the properties load from the server if local property cache is empty.</param>
655 /// <returns></returns>
656 private PropertyCollection GetProperties(bool forceLoad)
658 if (_Properties == null) {
659 // load properties into a different collection
660 // to preserve original collection state if exception occurs
661 PropertyCollection properties = new PropertyCollection (this);
662 if (forceLoad && !Nflag)
663 LoadProperties (properties,null);
665 _Properties = properties ;
671 /// Loads the values of the specified properties into the property cache.
673 /// <param name="propertyNames">An array of the specified properties.</param>
674 private void LoadProperties(PropertyCollection properties,string[] propertyNames)
676 _inPropertiesLoading = true;
678 LdapSearchResults lsc=conn.Search (Fdn,LdapConnection.SCOPE_BASE,"objectClass=*",propertyNames,false);
679 if (lsc.hasMore ()) {
680 LdapEntry nextEntry = lsc.next ();
681 string [] lowcasePropertyNames = null;
683 if (propertyNames != null) {
684 length = propertyNames.Length;
685 lowcasePropertyNames = new string [length];
686 for(int i=0; i < length; i++)
687 lowcasePropertyNames [i] = propertyNames [i].ToLower ();
689 foreach (LdapAttribute attribute in nextEntry.getAttributeSet ()) {
690 string attributeName = attribute.Name;
691 if ((propertyNames == null) || (Array.IndexOf (lowcasePropertyNames,attributeName.ToLower ()) != -1)) {
692 properties [attributeName].Value = null;
693 properties [attributeName].AddRange (attribute.StringValueArray);
694 properties [attributeName].Mbit=false;
700 _inPropertiesLoading = false;
705 /// Searches an entry in the Ldap directory and returns the attribute value
707 /// <param name="attrName">attribute whose value is required</param>
708 /// <returns> value of the attribute stored in Ldap directory</returns>
709 private string FindAttrValue(string attrName)
712 string[] attrs={attrName};
714 LdapSearchResults lsc=conn.Search( Fdn,
715 LdapConnection.SCOPE_BASE,
719 while(lsc.hasMore()) {
720 LdapEntry nextEntry = null;
722 nextEntry = lsc.next();
724 catch(LdapException e) {
725 // Exception is thrown, go for next entry
728 LdapAttribute attribute = nextEntry.getAttribute(attrName);
729 aValue = attribute.StringValue;
736 /// Modifies an entry in the Ldap directory with the input LdapModification
739 /// <param name="mods">Array consisting of the entry attribute name and the
740 /// attribute values to be modified.</param>
741 private void ModEntry(LdapModification[] mods)
745 conn.Modify(Fdn,mods);
747 catch(LdapException le) {
753 /// Checks whether the entry exists in the Ldap directory or not
755 /// <param name="lconn">
756 /// Connection used to communicate with directory
758 /// <param name="epath">
759 /// path of the entry
762 /// true of the entry exists in the Ldap directory
763 /// false if entry doesn't exists
765 private static bool CheckEntry(LdapConnection lconn, string epath)
767 LdapUrl lUrl=new LdapUrl(epath);
768 string eDn=lUrl.getDN();
773 // rootDSE is a "virtual" entry that always exists
774 else if (String.Compare (eDn,"rootDSE",true) == 0)
777 string[] attrs={"objectClass"};
780 LdapSearchResults lsc=lconn.Search( eDn,
781 LdapConnection.SCOPE_BASE,
787 LdapEntry nextEntry = null;
790 nextEntry = lsc.next();
792 catch(LdapException e)
794 // Exception is thrown, go for next entry
801 catch(LdapException le)
803 if(le.ResultCode == LdapException.NO_SUCH_OBJECT)
820 /// Closes the DirectoryEntry and releases any system resources associated
821 /// with this component.
824 /// Following a call to Close, any operations on the DirectoryEntry might
825 /// raise exceptions.
829 if (_conn != null && _conn.Connected) {
835 /// Creates a copy of this entry as a child of the specified parent.
837 /// <param name="newParent">The parent DirectoryEntry. </param>
838 /// <returns>A copy of this entry as a child of the specified parent.
840 public DirectoryEntry CopyTo(DirectoryEntry newParent)
842 throw new NotImplementedException();
846 /// Deletes this entry and its entire subtree from the Active Directory
850 /// CAUTION The entry and its entire subtree are deleted from the
851 /// Ldap Directory hierarchy.
853 public void DeleteTree()
855 System.Collections.IEnumerator ienum = Children.GetEnumerator();
856 while(ienum.MoveNext())
858 DirectoryEntry de=(DirectoryEntry)ienum.Current;
865 /// Searches the directory store at the specified path to see whether
868 /// <param name="path">
869 /// The path at which to search the directory store.
872 /// true if an entry exists in the directory store at the specified
873 /// path; otherwise, false.
875 public static bool Exists(string path)
877 LdapConnection aconn=new LdapConnection();
878 LdapUrl lurl=new LdapUrl(path);
879 aconn.Connect(lurl.Host,lurl.Port);
881 if(CheckEntry(aconn,path))
888 /// Moves this entry to the specified parent.
890 /// <param name="pentry">
891 /// The parent to which you want to move this entry
893 public void MoveTo(DirectoryEntry newParent)
895 string oldParentFdn = Parent.Fdn;
896 conn.Rename(Fdn, Name, newParent.Fdn, true);
897 // TBD : threat multiple name instance in path
898 Path = Path.Replace(oldParentFdn,newParent.Fdn);
903 /// Moves this entry to the specified parent and changes its name to
904 /// the value of the newName parameter.
906 /// <param name="newParent"> The parent to which you want to move
909 /// <param name="newName">
910 /// The new name of this entry.
912 public void MoveTo( DirectoryEntry newParent,
915 string oldParentFdn = Parent.Fdn;
916 conn.Rename(Fdn, newName, newParent.Fdn, true);
917 // TBD : threat multiple name instance in path
918 Path = Path.Replace(oldParentFdn,newParent.Fdn).Replace(Name,newName);
923 /// Changes the name of this entry.
925 /// <param name="newName">
926 /// The new name of the entry.
929 /// Note This will also affect the path used to refer to this entry.
931 public void Rename( string newName )
933 string oldName = Name;
934 conn.Rename( Fdn, newName, true);
935 // TBD : threat multiple name instance in path
936 Path = Path.Replace(oldName,newName);
941 /// Calls a method on the native Active Directory.
943 /// <param name="methodName">The name of the method to invoke.
945 /// <param name="args">
946 /// An array of type Object that contains the arguments of the method
949 /// <returns>The return value of the invoked method</returns>
953 public object Invoke(string methodName,
954 params object[] args)
956 throw new NotImplementedException();
960 /// Gets a property value from the native Active Directory Entry.
962 /// <param name="propertyName">The name of the property to get.
964 /// <returns>The value of the property</returns>
966 /// Not implemented yet.
967 [ComVisibleAttribute (false)]
968 [MonoNotSupported ("")]
969 public object InvokeGet (string propertyName)
971 throw new NotImplementedException ();
975 /// Sets a property value on the native Active Directory Entry.
977 /// <param name="propertyName">The name of the property to get.
979 /// <param name="args">
980 /// An array of type Object that contains the arguments of the property
984 /// Not implemented yet.
985 [ComVisibleAttribute (false)]
986 [MonoNotSupported ("")]
987 public void InvokeSet (string propertyName, params object [] args)
989 throw new NotImplementedException ();
993 /// Creates a copy of this entry, as a child of the specified parent, with
994 /// the specified new name.
996 /// <param name="newParent">The parent DirectoryEntry. </param>
997 /// <param name="newName"> The name of the copy of this entry.
999 /// <returns>A renamed copy of this entry as a child of the specified parent.
1001 public DirectoryEntry CopyTo( DirectoryEntry newParent,
1004 throw new NotImplementedException();
1008 /// Saves any changes to the entry in the Ldap Directory store.
1011 /// By default, changes to properties are done locally to a cache, and
1012 /// property values to be read are cached after the first read. For more
1013 /// information, see UsePropertyCache.
1014 /// Changes made to the cache include changes to the properties as well as
1015 /// calls to Add (if this is the newly created entry).
1017 public void CommitChanges()
1019 if(UsePropertyCache)
1025 private void CommitEntry()
1027 PropertyCollection properties = GetProperties(false);
1030 System.Collections.ArrayList modList = new System.Collections.ArrayList();
1031 foreach (string attribute in properties.PropertyNames)
1033 LdapAttribute attr=null;
1034 if (properties [attribute].Mbit)
1036 switch (properties [attribute].Count) {
1038 attr = new LdapAttribute (attribute, new string [0]);
1039 modList.Add (new LdapModification (LdapModification.DELETE, attr));
1042 string val = (string) properties [attribute].Value;
1043 attr = new LdapAttribute (attribute, val);
1044 modList.Add (new LdapModification (LdapModification.REPLACE, attr));
1047 object [] vals = (object [])properties [attribute].Value;
1048 string [] aStrVals = new string [properties [attribute].Count];
1049 Array.Copy (vals, 0, aStrVals, 0, properties [attribute].Count);
1050 attr = new LdapAttribute (attribute, aStrVals);
1051 modList.Add (new LdapModification (LdapModification.REPLACE, attr));
1054 properties [attribute].Mbit=false;
1057 if (modList.Count > 0) {
1058 LdapModification[] mods = new LdapModification[modList.Count];
1059 Type mtype = typeof (LdapModification);
1060 mods = (LdapModification[])modList.ToArray(mtype);
1066 LdapAttributeSet attributeSet = new LdapAttributeSet();
1067 foreach (string attribute in properties.PropertyNames)
1069 if (properties [attribute].Count == 1)
1071 string val = (string) properties [attribute].Value;
1072 attributeSet.Add(new LdapAttribute(attribute, val));
1076 object[] vals = (object []) properties [attribute].Value;
1077 string[] aStrVals = new string [properties [attribute].Count];
1078 Array.Copy (vals,0,aStrVals,0,properties [attribute].Count);
1079 attributeSet.Add( new LdapAttribute( attribute , aStrVals));
1082 LdapEntry newEntry = new LdapEntry( Fdn, attributeSet );
1083 conn.Add( newEntry );
1088 internal void CommitDeferred()
1090 if (!_inPropertiesLoading && !UsePropertyCache && !Nflag)
1102 _SchemaClassName = null;
1107 /// Loads the values of the specified properties into the property cache.
1109 public void RefreshCache ()
1111 // note that GetProperties must be called with false, elswere infinite loop will be caused
1112 PropertyCollection properties = new PropertyCollection ();
1113 LoadProperties(properties, null);
1114 SetProperties (properties);
1118 /// Loads the values of the specified properties into the property cache.
1120 /// <param name="propertyNames">An array of the specified properties. </param>
1121 public void RefreshCache (string[] propertyNames)
1123 // note that GetProperties must be called with false, elswere infinite loop will be caused
1124 LoadProperties(GetProperties(false),propertyNames);
1127 protected override void Dispose (bool disposing)
1132 base.Dispose (disposing);
1135 internal static string GetLdapUrlString(string host, int port, string dn)
1138 if (port == LdapConnection.DEFAULT_PORT)
1139 lUrl = new LdapUrl (host,0,dn);
1141 lUrl = new LdapUrl (host,port,dn);
1142 return lUrl.ToString();