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();
+ }
}
}