Example #1
0
        internal void CommitIfNotCaching()
        {
            if (justCreated)
            {
                return;   // Do not write changes, beacuse the entry is just under construction until CommitChanges() is called.
            }
            if (useCache)
            {
                return;
            }

            if (!Bound)
            {
                return;
            }

            if (!writeGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Write, this.path);
                permission.Demand();
                writeGranted = true;
            }

            adsObject.SetInfo();
        }
Example #2
0
        /// <include file='doc\DirectoryEntry.uex' path='docs/doc[@for="DirectoryEntry.CommitChanges"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Saves any
        ///       changes to the entry in the directory store.
        ///    </para>
        /// </devdoc>
        public void CommitChanges()
        {
            if (justCreated)
            {
                // Note: Permissions Demand is not necessary here, because entry has already been created with appr. permissions.
                // Write changes regardless of Caching mode to finish construction of a new entry.
                adsObject.SetInfo();
                justCreated = false;
                return;
            }
            if (!useCache)
            {
                // nothing to do
                return;
            }

            if (!Bound)
            {
                return;
            }

            if (!writeGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Write, this.path);
                permission.Demand();
                writeGranted = true;
            }

            adsObject.SetInfo();
        }
 /// <include file='doc\DirectoryServicesPermissionEntryCollection.uex' path='docs/doc[@for="DirectoryServicesPermissionEntryCollection.DirectoryServicesPermissionEntryCollection"]/*' />
 ///<internalonly/>
 internal DirectoryServicesPermissionEntryCollection(DirectoryServicesPermission owner, ResourcePermissionBaseEntry[] entries)
 {
     this.owner = owner;
     for (int index = 0; index < entries.Length; ++index)
     {
         this.InnerList.Add(new DirectoryServicesPermissionEntry(entries[index]));
     }
 }
 internal DirectoryServicesPermissionEntryCollection(DirectoryServicesPermission owner, ResourcePermissionBaseEntry[] entries)
 {
     this.owner = owner;
     for (int i = 0; i < entries.Length; i++)
     {
         base.InnerList.Add(new DirectoryServicesPermissionEntry(entries[i]));
     }
 }
		internal DirectoryServicesPermissionEntryCollection (DirectoryServicesPermission owner)
		{
			this.owner = owner;
			ResourcePermissionBaseEntry[] entries = owner.GetEntries ();
			if (entries.Length > 0) {
				foreach (ResourcePermissionBaseEntry entry in entries) {
					DirectoryServicesPermissionAccess dspa = (DirectoryServicesPermissionAccess) entry.PermissionAccess;
					DirectoryServicesPermissionEntry dspe = new DirectoryServicesPermissionEntry (dspa, entry.PermissionAccessPath [0]);
					// we don't want to add them (again) to the base class
					InnerList.Add (dspe);
				}
			}
		}
Example #6
0
        // Create new entry with the same data, but different IADs object, and grant it Browse Permission.
        internal DirectoryEntry CloneBrowsable()
        {
            if (!browseGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Browse, this.path);
                permission.Demand();
                browseGranted = true;
            }
            DirectoryEntry newEntry = new DirectoryEntry(this.Path, this.UsePropertyCache, this.Username, this.Password, this.AuthenticationType);

            newEntry.browseGranted = true;
            return(newEntry);
        }
Example #7
0
 internal DirectoryServicesPermissionEntryCollection(DirectoryServicesPermission owner)
 {
     this.owner = owner;
     ResourcePermissionBaseEntry[] entries = owner.GetEntries();
     if (entries.Length > 0)
     {
         foreach (ResourcePermissionBaseEntry entry in entries)
         {
             DirectoryServicesPermissionAccess dspa = (DirectoryServicesPermissionAccess)entry.PermissionAccess;
             DirectoryServicesPermissionEntry  dspe = new DirectoryServicesPermissionEntry(dspa, entry.PermissionAccessPath [0]);
             // we don't want to add them (again) to the base class
             InnerList.Add(dspe);
         }
     }
 }
Example #8
0
        /// <include file='doc\DirectoryEntry.uex' path='docs/doc[@for="DirectoryEntry.DeleteTree"]/*' />
        /// <devdoc>
        ///    <para>Deletes this entry and its entire subtree from the
        ///       Active Directory hierarchy.</para>
        /// </devdoc>
        public void DeleteTree()
        {
            if (!(AdsObject is UnsafeNativeMethods.IAdsDeleteOps))
            {
                throw new InvalidOperationException(Res.GetString(Res.DSCannotDelete));
            }

            if (!writeGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Write, this.path);
                permission.Demand();
                writeGranted = true;
            }

            UnsafeNativeMethods.IAdsDeleteOps entry = (UnsafeNativeMethods.IAdsDeleteOps)AdsObject;
            entry.DeleteObject(0);
        }
		public void PermissionState_Unrestricted ()
		{
			PermissionState ps = PermissionState.Unrestricted;
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (ps);
			Assert.AreEqual (0, dsp.PermissionEntries.Count, "PermissionEntries");
			Assert.IsTrue (dsp.IsUnrestricted (), "IsUnrestricted");

			SecurityElement se = dsp.ToXml ();
			// only class and version are present
			Assert.AreEqual ("true", se.Attribute ("Unrestricted"), "Xml-Unrestricted");
			Assert.IsNull (se.Children, "Xml-Children");

			DirectoryServicesPermission copy = (DirectoryServicesPermission)dsp.Copy ();
			Assert.IsFalse (Object.ReferenceEquals (dsp, copy), "ReferenceEquals");
			Assert.AreEqual (dsp.PermissionEntries.Count, copy.PermissionEntries.Count, "copy-PermissionEntries");
			Assert.AreEqual (dsp.IsUnrestricted (), copy.IsUnrestricted (), "copy-IsUnrestricted ()");
		}
Example #10
0
        /// <include file='doc\DirectoryEntry.uex' path='docs/doc[@for="DirectoryEntry.CopyTo1"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Creates a copy of this entry as a child of the given parent and
        ///       gives it a new name.
        ///    </para>
        /// </devdoc>
        public DirectoryEntry CopyTo(DirectoryEntry newParent, string newName)
        {
            if (!newParent.IsContainer)
            {
                throw new InvalidOperationException(Res.GetString(Res.DSNotAContainer, newParent.Path));
            }

            if (!newParent.writeGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Write, newParent.path);
                permission.Demand();
                newParent.writeGranted = true;
            }

            object copy = newParent.ContainerObject.CopyHere(Path, newName);

            return(new DirectoryEntry(copy, newParent.UsePropertyCache, Username, Password, AuthenticationType));
        }
Example #11
0
        /// <include file='doc\DirectoryEntry.uex' path='docs/doc[@for="DirectoryEntry.Invoke"]/*' />
        /// <devdoc>
        ///    <para>Calls
        ///       a method on the native Active Directory.</para>
        /// </devdoc>
        public object Invoke(string methodName, params object[] args)
        {
            if (!writeGranted)
            {
                DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Write, this.path);
                permission.Demand();
                writeGranted = true;
            }

            object target = this.NativeObject;
            Type   type   = target.GetType();
            object result = type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, target, args);

            if (result is UnsafeNativeMethods.IAds)
            {
                return(new DirectoryEntry(result, UsePropertyCache, Username, Password, AuthenticationType));
            }
            else
            {
                return(result);
            }
        }
		public void Union_Self ()
		{
			foreach (DirectoryServicesPermissionAccess ppl in AllAccess) {
				DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
				dsp.PermissionEntries.Add (new DirectoryServicesPermissionEntry (ppl, ppl.ToString ()));
				DirectoryServicesPermission union = (DirectoryServicesPermission)dsp.Union (dsp);
				Assert.IsFalse (union.IsUnrestricted (), "IsUnrestricted " + ppl.ToString ());
				Assert.AreEqual (1, union.PermissionEntries.Count, "Count " + ppl.ToString ());
			}
		}
		public void Union_Null ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			dsp.PermissionEntries.Add (new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.None, String.Empty));
			// Union with null is a simple copy
			DirectoryServicesPermission union = (DirectoryServicesPermission)dsp.Union (null);
			Assert.IsNotNull (dsp.PermissionEntries.Count, "Count");
		}
		public void IsSubset_Unrestricted ()
		{
			// IsSubset with unrestricted
			// a. source (this) is unrestricted -> target is never a subset
			// b. destination (target) is unrestricted -> source is always a subset
			DirectoryServicesPermission dsp1 = new DirectoryServicesPermission (PermissionState.Unrestricted);
			foreach (DirectoryServicesPermissionAccess ppl in AllAccess) {
				DirectoryServicesPermission dsp2 = new DirectoryServicesPermission (PermissionState.None);
				dsp2.PermissionEntries.Add (new DirectoryServicesPermissionEntry (ppl, ppl.ToString ()));
				Assert.IsFalse (dsp1.IsSubsetOf (dsp2), "target " + ppl.ToString ());
				Assert.IsTrue (dsp2.IsSubsetOf (dsp1), "source " + ppl.ToString ());
			}
			Assert.IsTrue (dsp1.IsSubsetOf (dsp1), "Unrestricted.IsSubsetOf(Unrestricted)");
		}
		public void IsSubset_Self ()
		{
			foreach (DirectoryServicesPermissionAccess ppl in AllAccess) {
				DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
				dsp.PermissionEntries.Add (new DirectoryServicesPermissionEntry (ppl, ppl.ToString ()));
				Assert.IsTrue (dsp.IsSubsetOf (dsp), ppl.ToString ());
			}
		}
 /// <include file='doc\DirectoryServicesPermissionEntryCollection.uex' path='docs/doc[@for="DirectoryServicesPermissionEntryCollection.DirectoryServicesPermissionEntryCollection"]/*' />        
 ///<internalonly/>   
 internal DirectoryServicesPermissionEntryCollection(DirectoryServicesPermission owner, ResourcePermissionBaseEntry[] entries) {
     this.owner = owner;
     for (int index = 0; index < entries.Length; ++index)
         this.InnerList.Add(new DirectoryServicesPermissionEntry(entries[index]));
 } 
		public void PermissionState_Bad ()
		{
			PermissionState ps = (PermissionState)77;
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (ps);
			Assert.IsFalse (dsp.IsUnrestricted (), "IsUnrestricted");
		}
		public void FromXml_NoVersion ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			SecurityElement se = dsp.ToXml ();

			SecurityElement w = new SecurityElement (se.Tag);
			w.AddAttribute ("class", se.Attribute ("class"));
			dsp.FromXml (w);
		}
		public void FromXml_NoClass ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			SecurityElement se = dsp.ToXml ();

			SecurityElement w = new SecurityElement (se.Tag);
			w.AddAttribute ("version", se.Attribute ("version"));
			dsp.FromXml (w);
			// doesn't even care of the class attribute presence
		}
		public void FromXml_WrongTagCase ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			SecurityElement se = dsp.ToXml ();
			se.Tag = "IPERMISSION"; // instead of IPermission
			dsp.FromXml (se);
			// note: normally IPermission classes (in corlib) DO care about the
			// IPermission tag
		}
		public void Union_Unrestricted ()
		{
			// Union with unrestricted is unrestricted
			DirectoryServicesPermission dsp1 = new DirectoryServicesPermission (PermissionState.Unrestricted);
			foreach (DirectoryServicesPermissionAccess ppl in AllAccess) {
				DirectoryServicesPermission dsp2 = new DirectoryServicesPermission (PermissionState.None);
				dsp2.PermissionEntries.Add (new DirectoryServicesPermissionEntry (ppl, ppl.ToString ()));
				DirectoryServicesPermission union = (DirectoryServicesPermission)dsp1.Union (dsp2);
				Assert.IsTrue (union.IsUnrestricted (), "target.IsUnrestricted " + ppl.ToString ());
				Assert.AreEqual (0, union.PermissionEntries.Count, "target.Count " + ppl.ToString ());

				union = (DirectoryServicesPermission)dsp2.Union (dsp1);
				Assert.IsTrue (union.IsUnrestricted (), "source.IsUnrestricted " + ppl.ToString ());
				Assert.AreEqual (0, union.PermissionEntries.Count, "source.Count " + ppl.ToString ());
			}
		}
		public void IsSubset_Null ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			Assert.IsTrue (dsp.IsSubsetOf (null), "null");
		}
		public void FromXml_Null ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			dsp.FromXml (null);
		}
		public void PermissionEntries () 
		{
			DirectoryServicesPermissionAccess dspa = DirectoryServicesPermissionAccess.None;
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (dspa, String.Empty);
			DirectoryServicesPermissionEntryCollection dspec = dsp.PermissionEntries;
			Assert.AreEqual (1, dspec.Count, "Count==1");

			DirectoryServicesPermissionEntry dspe = new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.Browse, "*");
			dsp.PermissionEntries.Add (dspe);
			Assert.AreEqual (2, dspec.Count, "Count==2");

			// remove (same instance)
			dsp.PermissionEntries.Remove (dspe);
			Assert.AreEqual (1, dspec.Count, "Count==1 (b)");

			// remove different instance (doesn't work)
			dspe = new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.None, String.Empty);
			Assert.AreEqual (1, dspec.Count, "Count==1");
		}
		public void FromXml_WrongClass ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			SecurityElement se = dsp.ToXml ();

			SecurityElement w = new SecurityElement (se.Tag);
			w.AddAttribute ("class", "Wrong" + se.Attribute ("class"));
			w.AddAttribute ("version", se.Attribute ("version"));
			dsp.FromXml (w);
			// doesn't care of the class name at that stage
			// anyway the class has already be created so...
		}
		public void Copy ()
		{
			foreach (DirectoryServicesPermissionAccess ppl in AllAccess) {
				DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
				DirectoryServicesPermissionEntry dspe = new DirectoryServicesPermissionEntry (ppl, ppl.ToString ());
				dsp.PermissionEntries.Add (dspe);
				DirectoryServicesPermission copy = (DirectoryServicesPermission)dsp.Copy ();
				Assert.AreEqual (1, copy.PermissionEntries.Count, "Count==1");
				Assert.AreEqual (ppl, dsp.PermissionEntries [0].PermissionAccess, ppl.ToString ());
				Assert.AreEqual (ppl.ToString (), dsp.PermissionEntries [0].Path, ppl.ToString () + "-Path");
			}
		}
		public void FromXml_WrongVersion ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			SecurityElement se = dsp.ToXml ();
			se.Attributes.Remove ("version");
			se.Attributes.Add ("version", "2");
			dsp.FromXml (se);
		}
		public void Intersect_Null ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
			// No intersection with null
			Assert.IsNull (dsp.Intersect (null), "None N null");
		}
		public void Intersect_None ()
		{
			DirectoryServicesPermission dsp1 = new DirectoryServicesPermission (PermissionState.None);
			DirectoryServicesPermission dsp2 = new DirectoryServicesPermission (PermissionState.None);
			// 1. None N None
			DirectoryServicesPermission result = (DirectoryServicesPermission) dsp1.Intersect (dsp2);
			Assert.IsNull (result, "Empty N Empty");
			// 2. None N Entry
			dsp2.PermissionEntries.Add (new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.None, String.Empty));
			result = (DirectoryServicesPermission) dsp1.Intersect (dsp2);
			Assert.IsNull (result, "Empty N Entry");
			// 3. Entry N None
			result = (DirectoryServicesPermission) dsp2.Intersect (dsp1);
			Assert.IsNull (result, "Entry N Empty");
		}
		public void Intersect_Unrestricted ()
		{
			// Intersection with unrestricted == Copy
			// a. source (this) is unrestricted
			DirectoryServicesPermission dsp1 = new DirectoryServicesPermission (PermissionState.Unrestricted);
			DirectoryServicesPermission dsp2 = new DirectoryServicesPermission (PermissionState.None);

			// 1. Unrestricted N None
			DirectoryServicesPermission result = (DirectoryServicesPermission) dsp1.Intersect (dsp2);
			Assert.IsFalse (result.IsUnrestricted (), "(Unrestricted N None).IsUnrestricted");
			Assert.AreEqual (0, result.PermissionEntries.Count, "(Unrestricted N None).Count");

			// 2. None N Unrestricted
			result = (DirectoryServicesPermission) dsp2.Intersect (dsp1);
			Assert.IsFalse (result.IsUnrestricted (), "(None N Unrestricted).IsUnrestricted");
			Assert.AreEqual (0, result.PermissionEntries.Count, "(None N Unrestricted).Count");

			// 3. Unrestricted N Unrestricted
			result = (DirectoryServicesPermission) dsp1.Intersect (dsp1);
			Assert.IsTrue (result.IsUnrestricted (), "(Unrestricted N Unrestricted).IsUnrestricted");
			Assert.AreEqual (0, result.PermissionEntries.Count, "(Unrestricted N Unrestricted).Count");

			// 4. Unrestricted N Entry
			dsp2.PermissionEntries.Add (new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.None, String.Empty));
			result = (DirectoryServicesPermission)dsp1.Intersect (dsp2);
			Assert.IsFalse (result.IsUnrestricted (), "(Unrestricted N Entry).IsUnrestricted");
			Assert.AreEqual (1, result.PermissionEntries.Count, "(Unrestricted N Entry).Count");

			// 5. Entry N Unrestricted
			result = (DirectoryServicesPermission)dsp2.Intersect (dsp1);
			Assert.IsFalse (result.IsUnrestricted (), "(Entry N Unrestricted).IsUnrestricted");
			Assert.AreEqual (1, result.PermissionEntries.Count, "(Entry N Unrestricted).Count");

			// 6. Unrestricted N Unrestricted
			dsp1.PermissionEntries.Add (new DirectoryServicesPermissionEntry (DirectoryServicesPermissionAccess.None, String.Empty));
			result = (DirectoryServicesPermission)dsp1.Intersect (dsp1);
			Assert.IsTrue (result.IsUnrestricted (), "(Unrestricted N Unrestricted).IsUnrestricted");
			Assert.AreEqual (1, result.PermissionEntries.Count, "(Unrestricted N Unrestricted).Count");
		}
		public void DirectoryServicesPermissionAccesss_Bad ()
		{
			DirectoryServicesPermissionAccess dspa = (DirectoryServicesPermissionAccess) Int32.MinValue;
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (dspa, String.Empty);
			Assert.AreEqual (1, dsp.PermissionEntries.Count, "Count");
			Assert.AreEqual ((DirectoryServicesPermissionAccess)Int32.MinValue, dsp.PermissionEntries [0].PermissionAccess, "PermissionAccess");
			Assert.AreEqual (String.Empty, dsp.PermissionEntries [0].Path, "Path");
		}
		public void IsSubset_Null ()
		{
			DirectoryServicesPermission dsp = new DirectoryServicesPermission (PermissionState.None);
#if NET_2_0
			Assert.IsTrue (dsp.IsSubsetOf (null), "null");
#else
			Assert.IsFalse (dsp.IsSubsetOf (null), "null");
#endif
		}
        private SearchResultCollection FindAll(bool findMoreThanOne)
        {
            //if it is not of valid searching type, then throw an exception
            if (SearchRoot == null)
            {
                Version adsVersion = GetAdsVersion();
                throw new InvalidOperationException(Res.GetString(Res.DSVersion, adsVersion.ToString()));
            }

            DirectoryEntry clonedRoot = null;

            if (assertDefaultNamingContext == null)
            {
                clonedRoot = SearchRoot.CloneBrowsable();
            }
            else
            {
                //SECREVIEW: If the SearchRoot was created by this object
                //                        it is safe to assert its browse permission to get
                //                        the inner IAds.
                DirectoryServicesPermission dsPermission = new DirectoryServicesPermission(
                    DirectoryServicesPermissionAccess.Browse, assertDefaultNamingContext);
                dsPermission.Assert();
                try {
                    clonedRoot = SearchRoot.CloneBrowsable();
                }
                finally {
                    DirectoryServicesPermission.RevertAssert();
                }
            }

            UnsafeNativeMethods.IAds adsObject = clonedRoot.AdsObject;
            if (!(adsObject is UnsafeNativeMethods.IDirectorySearch))
            {
                throw new NotSupportedException(Res.GetString(Res.DSSearchUnsupported, SearchRoot.Path));
            }

            UnsafeNativeMethods.IDirectorySearch adsSearch = (UnsafeNativeMethods.IDirectorySearch)adsObject;
            SetSearchPreferences(adsSearch, findMoreThanOne);

            string[] properties = null;
            if (PropertiesToLoad.Count > 0)
            {
                if (!PropertiesToLoad.Contains("ADsPath"))
                {
                    // if we don't get this property, we won't be able to return a list of DirectoryEntry objects!
                    PropertiesToLoad.Add("ADsPath");
                }
                properties = new string[PropertiesToLoad.Count];
                PropertiesToLoad.CopyTo(properties, 0);
            }

            IntPtr resultsHandle;

            if (properties != null)
            {
                adsSearch.ExecuteSearch(Filter, properties, properties.Length, out resultsHandle);
            }
            else
            {
                adsSearch.ExecuteSearch(Filter, null, -1, out resultsHandle);
                properties = new string[0];
            }

            SearchResultCollection result = new SearchResultCollection(clonedRoot, resultsHandle, properties, Filter);

            return(result);
        }
Example #34
0
        private void Bind(bool throwIfFail)
        {
            //Cannot rebind after the object has been disposed, since finalization has been suppressed.

            if (this.disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (Path != null && Path.Length != 0)
            {
                //SECREVIEW: Need to demand permission event if adsObject is not null
                //                         this entry might be the result of a search, need to verify
                //                         if the user has permission to browse the object first.
                if (!browseGranted)
                {
                    DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Browse, Path);
                    permission.Demand();
                    browseGranted = true;
                }
            }

            if (adsObject == null)
            {
                string pathToUse = Path;
                if (pathToUse == null || pathToUse.Length == 0)
                {
                    // get the default naming context. This should be the default root for the search.
                    DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE");

                    //SECREVIEW: Looking at the root of the DS will demand browse permissions
                    //                     on "*" or "LDAP://RootDSE".
                    string defaultNamingContext = (string)rootDSE.Properties["defaultNamingContext"][0];
                    rootDSE.Dispose();

                    pathToUse = "LDAP://" + defaultNamingContext;

                    if (!browseGranted)
                    {
                        DirectoryServicesPermission permission = new DirectoryServicesPermission(DirectoryServicesPermissionAccess.Browse, pathToUse);
                        permission.Demand();
                        browseGranted = true;
                    }
                }

                // Ensure we've got a thread model set, else CoInitialize() won't have been called.
                if (Thread.CurrentThread.ApartmentState == ApartmentState.Unknown)
                {
                    Thread.CurrentThread.ApartmentState = ApartmentState.MTA;
                }

                Guid   g     = new Guid("00000000-0000-0000-c000-000000000046"); // IID_IUnknown
                object value = null;
                int    hr    = UnsafeNativeMethods.ADsOpenObject(pathToUse, Username, Password, (int)authenticationType, ref g, out value);

                if (hr != 0)
                {
                    if (throwIfFail)
                    {
                        throw CreateFormattedComException(hr);
                    }
                }
                else
                {
                    adsObject = (UnsafeNativeMethods.IAds)value;
                }
            }
        }