X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.DirectoryServices%2FSystem.DirectoryServices%2FDirectoryEntry.cs;h=a1dffa258ff47f44fed1a2a93712ef84a6c9ee61;hb=95149da03ea22c4e6f7e9feda77ea2808fbf6586;hp=038b4c837c297d82ba646ce23fd791e30f6477b8;hpb=696506a7330c9a398267b0390ab2d297ac512129;p=mono.git diff --git a/mcs/class/System.DirectoryServices/System.DirectoryServices/DirectoryEntry.cs b/mcs/class/System.DirectoryServices/System.DirectoryServices/DirectoryEntry.cs index 038b4c837c2..a1dffa258ff 100644 --- a/mcs/class/System.DirectoryServices/System.DirectoryServices/DirectoryEntry.cs +++ b/mcs/class/System.DirectoryServices/System.DirectoryServices/DirectoryEntry.cs @@ -27,6 +27,7 @@ // Authors: // Sunil Kumar (sunilk@novell.com) // Andreas Nahr (ClassDevelopment@A-SoftTech.com) +// Boris Kirzner (borisk@mainsoft.com) // // (C) Novell Inc. // @@ -36,6 +37,9 @@ using Novell.Directory.Ldap; using Novell.Directory.Ldap.Utilclass; using System.Globalization; using System.DirectoryServices.Design; +using System.Collections.Specialized; +using System.Configuration; +using System.Runtime.InteropServices; namespace System.DirectoryServices { @@ -46,7 +50,9 @@ namespace System.DirectoryServices [TypeConverter (typeof (DirectoryEntryConverter))] public class DirectoryEntry : Component { - + private static readonly string DEFAULT_LDAP_HOST = "System.DirectoryServices.DefaultLdapHost"; + private static readonly string DEFAULT_LDAP_PORT = "System.DirectoryServices.DefaultLdapPort"; + private LdapConnection _conn = null; private AuthenticationTypes _AuthenticationType=AuthenticationTypes.None; private DirectoryEntries _Children; @@ -54,27 +60,28 @@ namespace System.DirectoryServices private string _Path=""; private string _Name=null; private DirectoryEntry _Parent=null; - private string _Username=""; - private string _Password=""; + private string _Username; + private string _Password; //private string _Nativeguid; private PropertyCollection _Properties = null; private string _SchemaClassName=null; private bool _Nflag = false; - private bool _disposed; + private bool _usePropertyCache=true; + private bool _inPropertiesLoading; /// /// Returns entry's Fully distinguished name. /// internal string Fdn { - get { - if (_Fdn == null) { - LdapUrl lUrl = new LdapUrl(Path); + get { + if (_Fdn == null) { + LdapUrl lUrl = new LdapUrl (ADsPath); string fDn=lUrl.getDN(); if(fDn != null) _Fdn = fDn; else - _Fdn=""; + _Fdn=String.Empty; } return _Fdn; } @@ -118,16 +125,14 @@ namespace System.DirectoryServices { try { _conn= new LdapConnection (); - LdapUrl lUrl=new LdapUrl (Path); + LdapUrl lUrl = new LdapUrl (ADsPath); _conn.Connect(lUrl.Host,lUrl.Port); - _conn.Bind(Username,Password); + _conn.Bind(Username,Password, (Novell.Directory.Ldap.AuthenticationTypes)AuthenticationType); } catch(LdapException ex) { - Console.WriteLine("Error:" + ex.LdapErrorMessage); throw ex; } catch(Exception e) { - Console.WriteLine("Error:" + e.Message); throw e; } } @@ -136,15 +141,19 @@ namespace System.DirectoryServices /// Initializes the Entry specific properties e.g entry DN etc. /// void InitEntry() - { - LdapUrl lUrl=new LdapUrl (Path); - if(lUrl.getDN()!=null) { - DN userDn = new DN(lUrl.getDN()); + { + LdapUrl lUrl = new LdapUrl (ADsPath); + string dn = lUrl.getDN(); + if (dn != null ) { + if (String.Compare (dn,"rootDSE",true) == 0) + InitToRootDse (lUrl.Host,lUrl.Port); + else { + DN userDn = new DN (dn); String[] lRdn = userDn.explodeDN(false); _Name = (string)lRdn[0]; _Parent = new DirectoryEntry(conn); - LdapUrl cUrl=new LdapUrl(lUrl.Host,lUrl.Port,userDn.Parent.ToString()); - _Parent.Path=cUrl.ToString(); + _Parent.Path = GetLdapUrlString (lUrl.Host,lUrl.Port,userDn.Parent.ToString ()); + } } else { _Name=lUrl.Host+":"+lUrl.Port; @@ -274,7 +283,7 @@ namespace System.DirectoryServices { get { - _Children = new DirectoryEntries(Path, conn); + _Children = new DirectoryEntries(ADsPath, conn); return _Children; } } @@ -315,10 +324,10 @@ namespace System.DirectoryServices { get { if(_Name==null) { - if(CheckEntry(conn,Path)) + if(CheckEntry(conn,ADsPath)) InitEntry(); else - throw new Exception("There is no such object on the server"); + throw new SystemException("There is no such object on the server"); } return _Name; } @@ -335,10 +344,10 @@ namespace System.DirectoryServices { get { if(_Parent==null) { - if(CheckEntry(conn,Path)) + if(CheckEntry(conn,ADsPath)) InitEntry(); else - throw new Exception("There is no such object on the server"); + throw new SystemException("There is no such object on the server"); } return _Parent; } @@ -389,15 +398,13 @@ namespace System.DirectoryServices [DefaultValue (true)] public bool UsePropertyCache { - [MonoTODO] get { - throw new NotImplementedException(); + return _usePropertyCache; } - [MonoTODO] set { - throw new NotImplementedException(); + _usePropertyCache = value; } } @@ -487,9 +494,28 @@ namespace System.DirectoryServices return _Path; } set { - _Path = value; + if (value == null) + _Path = String.Empty; + else + _Path = value; } + } + internal string ADsPath + { + get { + if (Path == null || Path == String.Empty) { + DirectoryEntry rootDse = new DirectoryEntry (); + rootDse.InitToRootDse (null,-1); + string namingContext = (string) rootDse.Properties ["defaultNamingContext"].Value; + if ( namingContext == null ) + namingContext = (string) rootDse.Properties ["namingContexts"].Value; + + LdapUrl actualUrl= new LdapUrl (DefaultHost,DefaultPort,namingContext); + return actualUrl.ToString (); + } + return Path; + } } /// @@ -504,49 +530,7 @@ namespace System.DirectoryServices public PropertyCollection Properties { get { - if ( _Properties == null ) { - - _Properties = new PropertyCollection(); - - try { - LdapSearchResults lsc=conn.Search( Fdn, - LdapConnection.SCOPE_BASE, - "objectClass=*", - null, - false); - while(lsc.hasMore()) { - - LdapEntry nextEntry = null; - try { - nextEntry = lsc.next(); - } - catch(LdapException e) { - Console.WriteLine("Error: " + e.LdapErrorMessage); - // Exception is thrown, go for next entry - throw e; - } - LdapAttributeSet attributeSet = nextEntry.getAttributeSet(); - System.Collections.IEnumerator ienum=attributeSet.GetEnumerator(); - if(ienum!=null) { - while(ienum.MoveNext()) { - LdapAttribute attribute=(LdapAttribute)ienum.Current; - string attributeName = attribute.Name; - _Properties[attributeName].AddRange(attribute.StringValueArray); - _Properties[attributeName].Mbit=false; - // string attributeVal = attribute.StringValue; - // _Properties[attributeName].Add(attributeVal); - } - } - break; - } - } - catch( LdapException le) { - if(le.ResultCode == LdapException.NO_SUCH_OBJECT) - { } - } - - } - return _Properties; + return GetProperties (true); } } @@ -585,6 +569,128 @@ namespace System.DirectoryServices } } + private string DefaultHost + { + get { + string defaultHost = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_HOST); + + if (defaultHost == null) { + NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings"); + if (config != null) + defaultHost = config ["servername"]; + + if (defaultHost == null) + defaultHost = "localhost"; + + AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_HOST,defaultHost); + } + return defaultHost; + } + } + + private int DefaultPort + { + get { + string defaultPortStr = (string) AppDomain.CurrentDomain.GetData (DEFAULT_LDAP_PORT); + + if (defaultPortStr == null) { + NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("mainsoft.directoryservices/settings"); + if (config != null) + defaultPortStr = config ["port"]; + + if (defaultPortStr == null) + defaultPortStr = "389"; + + AppDomain.CurrentDomain.SetData (DEFAULT_LDAP_PORT,defaultPortStr); + } + return Int32.Parse (defaultPortStr); + } + } + + private void InitToRootDse(string host,int port) + { + if ( host == null ) + host = DefaultHost; + if ( port < 0 ) + port = DefaultPort; + + LdapUrl rootPath = new LdapUrl (host,port,String.Empty); + string [] attrs = new string [] {"+","*"}; + DirectoryEntry rootEntry = new DirectoryEntry (rootPath.ToString (),this.Username,this.Password,this.AuthenticationType); + DirectorySearcher searcher = new DirectorySearcher (rootEntry,null,attrs,SearchScope.Base); + + SearchResult result = searcher.FindOne (); + // copy properties from search result + PropertyCollection pcoll = new PropertyCollection (); + foreach (string propertyName in result.Properties.PropertyNames) { + System.Collections.IEnumerator enumerator = result.Properties [propertyName].GetEnumerator (); + if (enumerator != null) + while (enumerator.MoveNext ()) + if (String.Compare (propertyName,"ADsPath",true) != 0) + pcoll [propertyName].Add (enumerator.Current); + } + this.SetProperties (pcoll); + this._Name = "rootDSE"; + } + + private void SetProperties(PropertyCollection pcoll) + { + _Properties = pcoll; + } + + /// + /// Returns entry properties. + /// + /// Specifies whenever to force the properties load from the server if local property cache is empty. + /// + private PropertyCollection GetProperties(bool forceLoad) + { + if (_Properties == null) { + // load properties into a different collection + // to preserve original collection state if exception occurs + PropertyCollection properties = new PropertyCollection (this); + if (forceLoad && !Nflag) + LoadProperties (properties,null); + + _Properties = properties ; + } + return _Properties; + } + + /// + /// Loads the values of the specified properties into the property cache. + /// + /// An array of the specified properties. + private void LoadProperties(PropertyCollection properties,string[] propertyNames) + { + _inPropertiesLoading = true; + try { + LdapSearchResults lsc=conn.Search (Fdn,LdapConnection.SCOPE_BASE,"objectClass=*",propertyNames,false); + if (lsc.hasMore ()) { + LdapEntry nextEntry = lsc.next (); + string [] lowcasePropertyNames = null; + int length = 0; + if (propertyNames != null) { + length = propertyNames.Length; + lowcasePropertyNames = new string [length]; + for(int i=0; i < length; i++) + lowcasePropertyNames [i] = propertyNames [i].ToLower (); + } + foreach (LdapAttribute attribute in nextEntry.getAttributeSet ()) { + string attributeName = attribute.Name; + if ((propertyNames == null) || (Array.IndexOf (lowcasePropertyNames,attributeName.ToLower ()) != -1)) { + properties [attributeName].Value = null; + properties [attributeName].AddRange (attribute.StringValueArray); + properties [attributeName].Mbit=false; + } + } + } + } + finally { + _inPropertiesLoading = false; + } + } + /// /// Searches an entry in the Ldap directory and returns the attribute value /// @@ -606,7 +712,6 @@ namespace System.DirectoryServices nextEntry = lsc.next(); } catch(LdapException e) { - Console.WriteLine("Error: " + e.LdapErrorMessage); // Exception is thrown, go for next entry throw e; } @@ -653,8 +758,12 @@ namespace System.DirectoryServices string eDn=lUrl.getDN(); if(eDn==null) { - eDn=""; + eDn = String.Empty; } + // rootDSE is a "virtual" entry that always exists + else if (String.Compare (eDn,"rootDSE",true) == 0) + return true; + string[] attrs={"objectClass"}; try { @@ -672,7 +781,6 @@ namespace System.DirectoryServices } catch(LdapException e) { - Console.WriteLine("Error: " + e.LdapErrorMessage); // Exception is thrown, go for next entry throw e; } @@ -708,7 +816,9 @@ namespace System.DirectoryServices /// public void Close() { - conn.Disconnect(); + if (_conn != null && _conn.Connected) { + _conn.Disconnect(); + } } /// @@ -772,7 +882,11 @@ namespace System.DirectoryServices /// public void MoveTo(DirectoryEntry newParent) { + string oldParentFdn = Parent.Fdn; conn.Rename(Fdn, Name, newParent.Fdn, true); + // TBD : threat multiple name instance in path + Path = Path.Replace(oldParentFdn,newParent.Fdn); + RefreshEntry(); } /// @@ -788,7 +902,11 @@ namespace System.DirectoryServices public void MoveTo( DirectoryEntry newParent, string newName ) { + string oldParentFdn = Parent.Fdn; conn.Rename(Fdn, newName, newParent.Fdn, true); + // TBD : threat multiple name instance in path + Path = Path.Replace(oldParentFdn,newParent.Fdn).Replace(Name,newName); + RefreshEntry(); } /// @@ -802,7 +920,11 @@ namespace System.DirectoryServices /// public void Rename( string newName ) { + string oldName = Name; conn.Rename( Fdn, newName, true); + // TBD : threat multiple name instance in path + Path = Path.Replace(oldName,newName); + RefreshEntry(); } /// @@ -824,6 +946,41 @@ namespace System.DirectoryServices throw new NotImplementedException(); } +#if NET_2_0 + /// + /// Gets a property value from the native Active Directory Entry. + /// + /// The name of the property to get. + /// + /// The value of the property + /// + /// Not implemented yet. + [ComVisibleAttribute (false)] + [MonoNotSupported ("")] + public object InvokeGet (string propertyName) + { + throw new NotImplementedException (); + } + + /// + /// Sets a property value on the native Active Directory Entry. + /// + /// The name of the property to get. + /// + /// + /// An array of type Object that contains the arguments of the property + /// beeing set. + /// + /// + /// Not implemented yet. + [ComVisibleAttribute (false)] + [MonoNotSupported ("")] + public void InvokeSet (string propertyName, params object [] args) + { + throw new NotImplementedException (); + } +#endif + /// /// Creates a copy of this entry, as a child of the specified parent, with /// the specified new name. @@ -851,83 +1008,130 @@ namespace System.DirectoryServices /// public void CommitChanges() { + if(UsePropertyCache) + { + CommitEntry(); + } + } + + private void CommitEntry() + { + PropertyCollection properties = GetProperties(false); if(!Nflag) { System.Collections.ArrayList modList = new System.Collections.ArrayList(); - System.Collections.IDictionaryEnumerator id = Properties.GetEnumerator(); - while(id.MoveNext()) + foreach (string attribute in properties.PropertyNames) { - string attribute=(string)id.Key; LdapAttribute attr=null; - if(Properties[attribute].Mbit) + if (properties [attribute].Mbit) { - if(Properties[attribute].Count==1) - { - String val = (String)Properties[attribute].Value; - attr = new LdapAttribute( attribute , val); - } - else - { - Object[] vals=(Object [])Properties[attribute].Value; - String[] aStrVals= new String[Properties[attribute].Count]; - Array.Copy(vals,0,aStrVals,0,Properties[attribute].Count); - attr = new LdapAttribute( attribute , aStrVals); + switch (properties [attribute].Count) { + case 0: + attr = new LdapAttribute (attribute, new string [0]); + modList.Add (new LdapModification (LdapModification.DELETE, attr)); + break; + case 1: + string val = (string) properties [attribute].Value; + attr = new LdapAttribute (attribute, val); + modList.Add (new LdapModification (LdapModification.REPLACE, attr)); + break; + default: + object [] vals = (object [])properties [attribute].Value; + string [] aStrVals = new string [properties [attribute].Count]; + Array.Copy (vals, 0, aStrVals, 0, properties [attribute].Count); + attr = new LdapAttribute (attribute, aStrVals); + modList.Add (new LdapModification (LdapModification.REPLACE, attr)); + break; } - modList.Add( new LdapModification(LdapModification.REPLACE, attr)); - Properties[attribute].Mbit=false; + properties [attribute].Mbit=false; } -// Console.WriteLine(attribute + "Total no of attr value" + Properties[attribute].Count); } - LdapModification[] mods = new LdapModification[modList.Count]; - Type mtype=Type.GetType("System.DirectoryServices.LdapModification"); - mods = (LdapModification[])modList.ToArray(typeof(LdapModification)); - ModEntry(mods); + if (modList.Count > 0) { + LdapModification[] mods = new LdapModification[modList.Count]; + Type mtype = typeof (LdapModification); + mods = (LdapModification[])modList.ToArray(mtype); + ModEntry(mods); + } } else { LdapAttributeSet attributeSet = new LdapAttributeSet(); - System.Collections.IDictionaryEnumerator id = Properties.GetEnumerator(); - while(id.MoveNext()) + foreach (string attribute in properties.PropertyNames) { - string attribute=(string)id.Key; -// Console.WriteLine("attribute:" + attribute + "Vals:" + Properties[attribute][0]); - if(Properties[attribute].Count==1) + if (properties [attribute].Count == 1) { - String val = (String)Properties[attribute].Value; + string val = (string) properties [attribute].Value; attributeSet.Add(new LdapAttribute(attribute, val)); } else { - Object[] vals=(Object [])Properties[attribute].Value; - String[] aStrVals= new String[Properties[attribute].Count]; - Array.Copy(vals,0,aStrVals,0,Properties[attribute].Count); + object[] vals = (object []) properties [attribute].Value; + string[] aStrVals = new string [properties [attribute].Count]; + Array.Copy (vals,0,aStrVals,0,properties [attribute].Count); attributeSet.Add( new LdapAttribute( attribute , aStrVals)); } } LdapEntry newEntry = new LdapEntry( Fdn, attributeSet ); - conn.Add( newEntry ); + conn.Add( newEntry ); + Nflag = false; } } - [MonoTODO] + internal void CommitDeferred() + { + if (!_inPropertiesLoading && !UsePropertyCache && !Nflag) + { + CommitEntry(); + } + } + + void RefreshEntry() + { + _Properties = null; + _Fdn = null; + _Name = null; + _Parent = null; + _SchemaClassName = null; + InitEntry(); + } + + /// + /// Loads the values of the specified properties into the property cache. + /// public void RefreshCache () { - throw new NotImplementedException ("System.DirectoryServices.DirectoryEntry.RefreshCache()"); + // note that GetProperties must be called with false, elswere infinite loop will be caused + PropertyCollection properties = new PropertyCollection (); + LoadProperties(properties, null); + SetProperties (properties); } - [MonoTODO] - public void RefreshCache (string[] args) + /// + /// Loads the values of the specified properties into the property cache. + /// + /// An array of the specified properties. + public void RefreshCache (string[] propertyNames) { - throw new NotImplementedException ("System.DirectoryServices.DirectoryEntry.RefreshCache(System.String[])"); + // note that GetProperties must be called with false, elswere infinite loop will be caused + LoadProperties(GetProperties(false),propertyNames); } protected override void Dispose (bool disposing) { - if (!_disposed && disposing) { + if (disposing) { Close (); - _disposed = true; } base.Dispose (disposing); } + + internal static string GetLdapUrlString(string host, int port, string dn) + { + LdapUrl lUrl; + if (port == LdapConnection.DEFAULT_PORT) + lUrl = new LdapUrl (host,0,dn); + else + lUrl = new LdapUrl (host,port,dn); + return lUrl.ToString(); + } } }