| File: System\DirectoryServices\ActiveDirectory\DirectoryServerCollection.cs | Web Access |
| Project: src\runtime\src\libraries\System.DirectoryServices\src\System.DirectoryServices.csproj (System.DirectoryServices) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; namespace System.DirectoryServices.ActiveDirectory { public class DirectoryServerCollection : CollectionBase { internal readonly string? siteDN; internal readonly string? transportDN; internal readonly DirectoryContext context; internal bool initialized; internal readonly Hashtable? changeList; private readonly List<object> _copyList = new(); private readonly DirectoryEntry? _crossRefEntry; private readonly bool _isADAM; private readonly bool _isForNC; internal DirectoryServerCollection(DirectoryContext context, string siteDN, string transportName) { Hashtable tempTable = new Hashtable(); changeList = Hashtable.Synchronized(tempTable); this.context = context; this.siteDN = siteDN; this.transportDN = transportName; } internal DirectoryServerCollection(DirectoryContext context, DirectoryEntry? crossRefEntry, bool isADAM, ReadOnlyDirectoryServerCollection servers) { this.context = context; _crossRefEntry = crossRefEntry; _isADAM = isADAM; _isForNC = true; foreach (DirectoryServer server in servers) { InnerList.Add(server); } } public DirectoryServer this[int index] { get => (DirectoryServer)InnerList[index]!; set { DirectoryServer server = (DirectoryServer)value; if (server == null) throw new ArgumentNullException(nameof(value)); if (!Contains(server)) List[index] = server; else throw new ArgumentException(SR.Format(SR.AlreadyExistingInCollection, server), nameof(value)); } } public int Add(DirectoryServer server) { if (server == null) throw new ArgumentNullException(nameof(server)); // make sure that it is within the current site if (_isForNC) { if ((!_isADAM)) { if (!(server is DomainController)) throw new ArgumentException(SR.ServerShouldBeDC, nameof(server)); // verify that the version >= 5.2 // DC should be Win 2003 or higher if (((DomainController)server).NumericOSVersion < 5.2) { throw new ArgumentException(SR.ServerShouldBeW2K3, nameof(server)); } } if (!Contains(server)) { return List.Add(server); } else { throw new ArgumentException(SR.Format(SR.AlreadyExistingInCollection, server), nameof(server)); } } else { string siteName = (server is DomainController) ? ((DomainController)server).SiteObjectName : ((AdamInstance)server).SiteObjectName; Debug.Assert(siteName != null); if (Utils.Compare(siteDN, siteName) != 0) { throw new ArgumentException(SR.NotWithinSite); } if (!Contains(server)) return List.Add(server); else throw new ArgumentException(SR.Format(SR.AlreadyExistingInCollection, server), nameof(server)); } } public void AddRange(DirectoryServer[] servers) { if (servers == null) throw new ArgumentNullException(nameof(servers)); foreach (DirectoryServer s in servers) { if (s == null) { throw new ArgumentException(null, nameof(servers)); } } for (int i = 0; ((i) < (servers.Length)); i = ((i) + (1))) this.Add(servers[i]); } public bool Contains(DirectoryServer server) { if (server == null) throw new ArgumentNullException(nameof(server)); for (int i = 0; i < InnerList.Count; i++) { DirectoryServer tmp = (DirectoryServer)InnerList[i]!; if (Utils.Compare(tmp.Name, server.Name) == 0) { return true; } } return false; } public void CopyTo(DirectoryServer[] array, int index) { List.CopyTo(array, index); } public int IndexOf(DirectoryServer server) { if (server == null) throw new ArgumentNullException(nameof(server)); for (int i = 0; i < InnerList.Count; i++) { DirectoryServer tmp = (DirectoryServer)InnerList[i]!; if (Utils.Compare(tmp.Name, server.Name) == 0) { return i; } } return -1; } public void Insert(int index, DirectoryServer server) { if (server == null) throw new ArgumentNullException(nameof(server)); if (_isForNC) { if ((!_isADAM)) { if (!(server is DomainController)) throw new ArgumentException(SR.ServerShouldBeDC, nameof(server)); // verify that the version >= 5.2 // DC should be Win 2003 or higher if (((DomainController)server).NumericOSVersion < 5.2) { throw new ArgumentException(SR.ServerShouldBeW2K3, nameof(server)); } } if (!Contains(server)) { List.Insert(index, server); } else { throw new ArgumentException(SR.Format(SR.AlreadyExistingInCollection, server), nameof(server)); } } else { // make sure that it is within the current site string siteName = (server is DomainController) ? ((DomainController)server).SiteObjectName : ((AdamInstance)server).SiteObjectName; Debug.Assert(siteName != null); if (Utils.Compare(siteDN, siteName) != 0) { throw new ArgumentException(SR.NotWithinSite, nameof(server)); } if (!Contains(server)) List.Insert(index, server); else throw new ArgumentException(SR.Format(SR.AlreadyExistingInCollection, server)); } } public void Remove(DirectoryServer server) { if (server == null) throw new ArgumentNullException(nameof(server)); for (int i = 0; i < InnerList.Count; i++) { DirectoryServer tmp = (DirectoryServer)InnerList[i]!; if (Utils.Compare(tmp.Name, server.Name) == 0) { List.Remove(tmp); return; } } // something that does not exist in the collection throw new ArgumentException(SR.Format(SR.NotFoundInCollection, server), nameof(server)); } protected override void OnClear() { if (initialized && !_isForNC) { _copyList.Clear(); foreach (object o in List) { _copyList.Add(o); } } } protected override void OnClearComplete() { // if the property exists, clear it out if (_isForNC) { if (_crossRefEntry != null) { try { if (_crossRefEntry.Properties.Contains(PropertyManager.MsDSNCReplicaLocations)) { _crossRefEntry.Properties[PropertyManager.MsDSNCReplicaLocations].Clear(); } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } } else if (initialized) { for (int i = 0; i < _copyList.Count; i++) { OnRemoveComplete(i, _copyList[i]); } } } #pragma warning disable CS8765 // Nullability doesn't match overridden member protected override void OnInsertComplete(int index, object value) #pragma warning restore CS8765 { if (_isForNC) { if (_crossRefEntry != null) { try { DirectoryServer server = (DirectoryServer)value; string ntdsaName = (server is DomainController) ? ((DomainController)server).NtdsaObjectName : ((AdamInstance)server).NtdsaObjectName; _crossRefEntry.Properties[PropertyManager.MsDSNCReplicaLocations].Add(ntdsaName); } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } } else if (initialized) { DirectoryServer server = (DirectoryServer)value; string name = server.Name; string serverName = (server is DomainController) ? ((DomainController)server).ServerObjectName : ((AdamInstance)server).ServerObjectName; try { if (changeList!.Contains(name)) { ((DirectoryEntry)changeList[name]!).Properties["bridgeheadTransportList"].Value = this.transportDN; } else { DirectoryEntry de = DirectoryEntryManager.GetDirectoryEntry(context, serverName); de.Properties["bridgeheadTransportList"].Value = this.transportDN; changeList.Add(name, de); } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } } #pragma warning disable CS8765 // Nullability doesn't match overridden member protected override void OnRemoveComplete(int index, object value) #pragma warning restore CS8765 { if (_isForNC) { try { if (_crossRefEntry != null) { string ntdsaName = (value is DomainController) ? ((DomainController)value).NtdsaObjectName : ((AdamInstance)value).NtdsaObjectName; _crossRefEntry.Properties[PropertyManager.MsDSNCReplicaLocations].Remove(ntdsaName); } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } else { DirectoryServer server = (DirectoryServer)value; string name = server.Name; string serverName = (server is DomainController) ? ((DomainController)server).ServerObjectName : ((AdamInstance)server).ServerObjectName; try { if (changeList!.Contains(name)) { ((DirectoryEntry)changeList[name]!).Properties["bridgeheadTransportList"].Clear(); } else { DirectoryEntry de = DirectoryEntryManager.GetDirectoryEntry(context, serverName); de.Properties["bridgeheadTransportList"].Clear(); changeList.Add(name, de); } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } } #pragma warning disable CS8765 // Nullability doesn't match overridden member protected override void OnSetComplete(int index, object oldValue, object newValue) #pragma warning restore CS8765 { OnRemoveComplete(index, oldValue); OnInsertComplete(index, newValue); } protected override void OnValidate(object value) { if (value == null) throw new ArgumentNullException(nameof(value)); if (_isForNC) { if (_isADAM) { // for adam this should be an ADAMInstance if (!(value is AdamInstance)) throw new ArgumentException(SR.ServerShouldBeAI, nameof(value)); } else { // for AD this should be a DomainController if (!(value is DomainController)) throw new ArgumentException(SR.ServerShouldBeDC, nameof(value)); } } else { if (!(value is DirectoryServer)) throw new ArgumentException(null, nameof(value)); } } internal string[] GetMultiValuedProperty() { var values = new List<string>(); for (int i = 0; i < InnerList.Count; i++) { DirectoryServer ds = (DirectoryServer)InnerList[i]!; string ntdsaName = (ds is DomainController) ? ((DomainController)ds).NtdsaObjectName : ((AdamInstance)ds).NtdsaObjectName; values.Add(ntdsaName); } return values.ToArray(); } } }