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;
412 /// Gets or sets the password to use when authenticating the client.
415 /// The password to use when authenticating the client.
418 /// You can set the Username and password in order to specify alternate
419 /// credentials with which to access the information in Ldap Directory.
420 /// Any other DirectoryEntry objects retrieved from this instance (for
421 /// example, through Children) are automatically created with the same
422 /// alternate credentials.
424 [DSDescription ("The password to use when authenticating the client.")]
425 [DefaultValue (null)]
427 public string Password
439 /// Gets or sets the user name to use when authenticating the client.
442 /// The user name to use when authenticating the client.
445 /// You can set the user name and Password in order to specify alternate
446 /// credentials with which to access the information in Ldap Directory.
447 /// Any other DirectoryEntry objects retrieved from this instance (for
448 /// example, through Children) are automatically created with the same
451 [DSDescription ("The user name to use when authenticating the client.")]
452 [DefaultValue (null)]
454 [TypeConverter ("System.Diagnostics.Design.StringValueConverter, " + Consts.AssemblySystem_Design)]
455 public string Username
467 /// Gets or sets the path for this DirectoryEntry.
470 /// The path of this DirectoryEntry. The default is an empty string ("").
473 /// The Path property uniquely identifies this entry in a networked
474 /// environment. This entry can always be retrieved using this Path.
476 /// Setting the Path retrieves a new entry from the directory store; it
477 /// does not change the path of the currently bound entry.
479 /// The classes associated with the DirectoryEntry component can be used
480 /// with any of the Directory service providers. Some of the current
481 /// providers are Internet Information Services (IIS), Lightweight Directory
482 /// Access Protocol (Ldap), Novell NetWare Directory Service (NDS), and WinNT.
484 /// Currently we Support only Ldap provider.
485 /// e.g Ldap://[hostname]:[port number]/[ObjectFDN]
487 [DSDescription ("The path for this DirectoryEntry.")]
489 [RecommendedAsConfigurable (true)]
490 [TypeConverter ("System.Diagnostics.Design.StringValueConverter, " + Consts.AssemblySystem_Design)]
498 _Path = String.Empty;
504 internal string ADsPath
507 if (Path == null || Path == String.Empty) {
508 DirectoryEntry rootDse = new DirectoryEntry ();
509 rootDse.InitToRootDse (null,-1);
510 string namingContext = (string) rootDse.Properties ["defaultNamingContext"].Value;
511 if ( namingContext == null )
512 namingContext = (string) rootDse.Properties ["namingContexts"].Value;
514 LdapUrl actualUrl= new LdapUrl (DefaultHost,DefaultPort,namingContext);
515 return actualUrl.ToString ();
522 /// Gets a PropertyCollection of properties set on this object.
525 /// A PropertyCollection of properties set on this object.
527 [DSDescription ("Properties set on this object.")]
528 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
530 public PropertyCollection Properties
533 return GetProperties (true);
538 /// Gets the name of the schema used for this DirectoryEntry
541 /// The name of the schema used for this DirectoryEntry.
543 [DSDescription ("The name of the schema used for this DirectoryEntry.")]
544 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
546 public string SchemaClassName
549 if(_SchemaClassName==null) {
550 _SchemaClassName = FindAttrValue("structuralObjectClass");
552 return _SchemaClassName;
557 /// Gets the current schema directory entry.
560 /// Not implemented yet
561 [DSDescription ("The current schema directory entry.")]
562 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
564 public DirectoryEntry SchemaEntry
568 throw new NotImplementedException();
572 private string DefaultHost
575 string defaultHost = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_HOST);
577 if (defaultHost == null) {
578 NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings");
580 defaultHost = config ["servername"];
582 if (defaultHost == null)
583 defaultHost = "localhost";
585 AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_HOST,defaultHost);
591 private int DefaultPort
594 string defaultPortStr = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_PORT);
596 if (defaultPortStr == null) {
597 NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings");
599 defaultPortStr = config ["port"];
601 if (defaultPortStr == null)
602 defaultPortStr = "389";
604 AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_PORT,defaultPortStr);
606 return Int32.Parse (defaultPortStr);
610 private void InitToRootDse(string host,int port)
617 LdapUrl rootPath = new LdapUrl (host,port,String.Empty);
618 string [] attrs = new string [] {"+","*"};
619 DirectoryEntry rootEntry = new DirectoryEntry (rootPath.ToString (),this.Username,this.Password,this.AuthenticationType);
620 DirectorySearcher searcher = new DirectorySearcher (rootEntry,null,attrs,SearchScope.Base);
622 SearchResult result = searcher.FindOne ();
623 // copy properties from search result
624 PropertyCollection pcoll = new PropertyCollection ();
625 foreach (string propertyName in result.Properties.PropertyNames) {
626 System.Collections.IEnumerator enumerator = result.Properties [propertyName].GetEnumerator ();
627 if (enumerator != null)
628 while (enumerator.MoveNext ())
629 if (String.Compare (propertyName,"ADsPath",true) != 0)
630 pcoll [propertyName].Add (enumerator.Current);
632 this.SetProperties (pcoll);
633 this._Name = "rootDSE";
636 private void SetProperties(PropertyCollection pcoll)
642 /// Returns entry properties.
644 /// <param name="forceLoad">Specifies whenever to force the properties load from the server if local property cache is empty.</param>
645 /// <returns></returns>
646 private PropertyCollection GetProperties(bool forceLoad)
648 if (_Properties == null) {
649 // load properties into a different collection
650 // to preserve original collection state if exception occurs
651 PropertyCollection properties = new PropertyCollection (this);
652 if (forceLoad && !Nflag)
653 LoadProperties (properties,null);
655 _Properties = properties ;
661 /// Loads the values of the specified properties into the property cache.
663 /// <param name="propertyNames">An array of the specified properties.</param>
664 private void LoadProperties(PropertyCollection properties,string[] propertyNames)
666 _inPropertiesLoading = true;
668 LdapSearchResults lsc=conn.Search (Fdn,LdapConnection.SCOPE_BASE,"objectClass=*",propertyNames,false);
669 if (lsc.hasMore ()) {
670 LdapEntry nextEntry = lsc.next ();
671 string [] lowcasePropertyNames = null;
673 if (propertyNames != null) {
674 length = propertyNames.Length;
675 lowcasePropertyNames = new string [length];
676 for(int i=0; i < length; i++)
677 lowcasePropertyNames [i] = propertyNames [i].ToLower ();
679 foreach (LdapAttribute attribute in nextEntry.getAttributeSet ()) {
680 string attributeName = attribute.Name;
681 if ((propertyNames == null) || (Array.IndexOf (lowcasePropertyNames,attributeName.ToLower ()) != -1)) {
682 properties [attributeName].Value = null;
683 properties [attributeName].AddRange (attribute.StringValueArray);
684 properties [attributeName].Mbit=false;
690 _inPropertiesLoading = false;
695 /// Searches an entry in the Ldap directory and returns the attribute value
697 /// <param name="attrName">attribute whose value is required</param>
698 /// <returns> value of the attribute stored in Ldap directory</returns>
699 private string FindAttrValue(string attrName)
702 string[] attrs={attrName};
704 LdapSearchResults lsc=conn.Search( Fdn,
705 LdapConnection.SCOPE_BASE,
709 while(lsc.hasMore()) {
710 LdapEntry nextEntry = null;
712 nextEntry = lsc.next();
714 catch(LdapException e) {
715 // Exception is thrown, go for next entry
718 LdapAttribute attribute = nextEntry.getAttribute(attrName);
719 aValue = attribute.StringValue;
726 /// Modifies an entry in the Ldap directory with the input LdapModification
729 /// <param name="mods">Array consisting of the entry attribute name and the
730 /// attribute values to be modified.</param>
731 private void ModEntry(LdapModification[] mods)
735 conn.Modify(Fdn,mods);
737 catch(LdapException le) {
743 /// Checks whether the entry exists in the Ldap directory or not
745 /// <param name="lconn">
746 /// Connection used to communicate with directory
748 /// <param name="epath">
749 /// path of the entry
752 /// true of the entry exists in the Ldap directory
753 /// false if entry doesn't exists
755 private static bool CheckEntry(LdapConnection lconn, string epath)
757 LdapUrl lUrl=new LdapUrl(epath);
758 string eDn=lUrl.getDN();
763 // rootDSE is a "virtual" entry that always exists
764 else if (String.Compare (eDn,"rootDSE",true) == 0)
767 string[] attrs={"objectClass"};
770 LdapSearchResults lsc=lconn.Search( eDn,
771 LdapConnection.SCOPE_BASE,
777 LdapEntry nextEntry = null;
780 nextEntry = lsc.next();
782 catch(LdapException e)
784 // Exception is thrown, go for next entry
791 catch(LdapException le)
793 if(le.ResultCode == LdapException.NO_SUCH_OBJECT)
810 /// Closes the DirectoryEntry and releases any system resources associated
811 /// with this component.
814 /// Following a call to Close, any operations on the DirectoryEntry might
815 /// raise exceptions.
819 if (_conn != null && _conn.Connected) {
825 /// Creates a copy of this entry as a child of the specified parent.
827 /// <param name="newParent">The parent DirectoryEntry. </param>
828 /// <returns>A copy of this entry as a child of the specified parent.
830 public DirectoryEntry CopyTo(DirectoryEntry newParent)
832 throw new NotImplementedException();
836 /// Deletes this entry and its entire subtree from the Active Directory
840 /// CAUTION The entry and its entire subtree are deleted from the
841 /// Ldap Directory hierarchy.
843 public void DeleteTree()
845 System.Collections.IEnumerator ienum = Children.GetEnumerator();
846 while(ienum.MoveNext())
848 DirectoryEntry de=(DirectoryEntry)ienum.Current;
855 /// Searches the directory store at the specified path to see whether
858 /// <param name="path">
859 /// The path at which to search the directory store.
862 /// true if an entry exists in the directory store at the specified
863 /// path; otherwise, false.
865 public static bool Exists(string path)
867 LdapConnection aconn=new LdapConnection();
868 LdapUrl lurl=new LdapUrl(path);
869 aconn.Connect(lurl.Host,lurl.Port);
871 if(CheckEntry(aconn,path))
878 /// Moves this entry to the specified parent.
880 /// <param name="pentry">
881 /// The parent to which you want to move this entry
883 public void MoveTo(DirectoryEntry newParent)
885 string oldParentFdn = Parent.Fdn;
886 conn.Rename(Fdn, Name, newParent.Fdn, true);
887 // TBD : threat multiple name instance in path
888 Path = Path.Replace(oldParentFdn,newParent.Fdn);
893 /// Moves this entry to the specified parent and changes its name to
894 /// the value of the newName parameter.
896 /// <param name="newParent"> The parent to which you want to move
899 /// <param name="newName">
900 /// The new name of this entry.
902 public void MoveTo( DirectoryEntry newParent,
905 string oldParentFdn = Parent.Fdn;
906 conn.Rename(Fdn, newName, newParent.Fdn, true);
907 // TBD : threat multiple name instance in path
908 Path = Path.Replace(oldParentFdn,newParent.Fdn).Replace(Name,newName);
913 /// Changes the name of this entry.
915 /// <param name="newName">
916 /// The new name of the entry.
919 /// Note This will also affect the path used to refer to this entry.
921 public void Rename( string newName )
923 string oldName = Name;
924 conn.Rename( Fdn, newName, true);
925 // TBD : threat multiple name instance in path
926 Path = Path.Replace(oldName,newName);
931 /// Calls a method on the native Active Directory.
933 /// <param name="methodName">The name of the method to invoke.
935 /// <param name="args">
936 /// An array of type Object that contains the arguments of the method
939 /// <returns>The return value of the invoked method</returns>
943 public object Invoke(string methodName,
944 params object[] args)
946 throw new NotImplementedException();
951 /// Gets a property value from the native Active Directory Entry.
953 /// <param name="propertyName">The name of the property to get.
955 /// <returns>The value of the property</returns>
957 /// Not implemented yet.
958 [ComVisibleAttribute (false)]
959 [MonoNotSupported ("")]
960 public object InvokeGet (string propertyName)
962 throw new NotImplementedException ();
966 /// Sets a property value on the native Active Directory Entry.
968 /// <param name="propertyName">The name of the property to get.
970 /// <param name="args">
971 /// An array of type Object that contains the arguments of the property
975 /// Not implemented yet.
976 [ComVisibleAttribute (false)]
977 [MonoNotSupported ("")]
978 public void InvokeSet (string propertyName, params object [] args)
980 throw new NotImplementedException ();
985 /// Creates a copy of this entry, as a child of the specified parent, with
986 /// the specified new name.
988 /// <param name="newParent">The parent DirectoryEntry. </param>
989 /// <param name="newName"> The name of the copy of this entry.
991 /// <returns>A renamed copy of this entry as a child of the specified parent.
993 public DirectoryEntry CopyTo( DirectoryEntry newParent,
996 throw new NotImplementedException();
1000 /// Saves any changes to the entry in the Ldap Directory store.
1003 /// By default, changes to properties are done locally to a cache, and
1004 /// property values to be read are cached after the first read. For more
1005 /// information, see UsePropertyCache.
1006 /// Changes made to the cache include changes to the properties as well as
1007 /// calls to Add (if this is the newly created entry).
1009 public void CommitChanges()
1011 if(UsePropertyCache)
1017 private void CommitEntry()
1019 PropertyCollection properties = GetProperties(false);
1022 System.Collections.ArrayList modList = new System.Collections.ArrayList();
1023 foreach (string attribute in properties.PropertyNames)
1025 LdapAttribute attr=null;
1026 if (properties [attribute].Mbit)
1028 switch (properties [attribute].Count) {
1030 attr = new LdapAttribute (attribute, new string [0]);
1031 modList.Add (new LdapModification (LdapModification.DELETE, attr));
1034 string val = (string) properties [attribute].Value;
1035 attr = new LdapAttribute (attribute, val);
1036 modList.Add (new LdapModification (LdapModification.REPLACE, attr));
1039 object [] vals = (object [])properties [attribute].Value;
1040 string [] aStrVals = new string [properties [attribute].Count];
1041 Array.Copy (vals, 0, aStrVals, 0, properties [attribute].Count);
1042 attr = new LdapAttribute (attribute, aStrVals);
1043 modList.Add (new LdapModification (LdapModification.REPLACE, attr));
1046 properties [attribute].Mbit=false;
1049 if (modList.Count > 0) {
1050 LdapModification[] mods = new LdapModification[modList.Count];
1051 Type mtype = typeof (LdapModification);
1052 mods = (LdapModification[])modList.ToArray(mtype);
1058 LdapAttributeSet attributeSet = new LdapAttributeSet();
1059 foreach (string attribute in properties.PropertyNames)
1061 if (properties [attribute].Count == 1)
1063 string val = (string) properties [attribute].Value;
1064 attributeSet.Add(new LdapAttribute(attribute, val));
1068 object[] vals = (object []) properties [attribute].Value;
1069 string[] aStrVals = new string [properties [attribute].Count];
1070 Array.Copy (vals,0,aStrVals,0,properties [attribute].Count);
1071 attributeSet.Add( new LdapAttribute( attribute , aStrVals));
1074 LdapEntry newEntry = new LdapEntry( Fdn, attributeSet );
1075 conn.Add( newEntry );
1080 internal void CommitDeferred()
1082 if (!_inPropertiesLoading && !UsePropertyCache && !Nflag)
1094 _SchemaClassName = null;
1099 /// Loads the values of the specified properties into the property cache.
1101 public void RefreshCache ()
1103 // note that GetProperties must be called with false, elswere infinite loop will be caused
1104 PropertyCollection properties = new PropertyCollection ();
1105 LoadProperties(properties, null);
1106 SetProperties (properties);
1110 /// Loads the values of the specified properties into the property cache.
1112 /// <param name="propertyNames">An array of the specified properties. </param>
1113 public void RefreshCache (string[] propertyNames)
1115 // note that GetProperties must be called with false, elswere infinite loop will be caused
1116 LoadProperties(GetProperties(false),propertyNames);
1119 protected override void Dispose (bool disposing)
1124 base.Dispose (disposing);
1127 internal static string GetLdapUrlString(string host, int port, string dn)
1130 if (port == LdapConnection.DEFAULT_PORT)
1131 lUrl = new LdapUrl (host,0,dn);
1133 lUrl = new LdapUrl (host,port,dn);
1134 return lUrl.ToString();