Tory Hill
Tory Hill

Reputation: 103

.GetDirectoryEntry throws COM exception, code:0x800720720 when attempting to bind to object

My application is running on IIS 7.0, it is supposed to impersonate the authenticated user and unlock or reset other user accounts. It worked fine when I was developing it on my workstation, but when I uploaded it to the server the impersonation stopped working, it won't bind to the AD objects and keeps throwing the same exception. I had the same problem earlier with using PrincipalContext but I was able to get around that using using(HostingEnvironment.Impersonate()) because I didn't need the authenticated user for that action. But now I do so I can't use that workaround. I need an actual fix for the issue and I would really appreciate some input. I've been searching far and wide for a solution to the problem and so far none of them have worked. Here is the code I'm using that keeps throwing the exception.

using (DirectorySearcher search = new DirectorySearcher(directoryEntries[counter]))
{
    //Sets the filter to find a user object with the target user username
    search.Filter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
    //Sets the searchscope to search the whole AD
    search.SearchScope = SearchScope.Subtree;
    //Executes the search for one result and stores it in result.
    SearchResult result = search.FindOne();
    //Creates a directory entry from the result.

    using (DirectoryEntry targetUser = result.GetDirectoryEntry())
    {
        //This if-else statement checks if the user is locked, if it is then
        //the unlock is performed, and the unlockPerformed variable is set to
        //true, if it isn't then unlockPerformed is set to false.
        if (Convert.ToBoolean(targetUser.InvokeGet("IsAccountLocked")))
        {
            targetUser.InvokeSet("IsAccountLocked", false);
            targetUser.CommitChanges();
            unlockPerformed = true;
        }
        else
        {
            unlockPerformed = false;
        }
    }
}

This code worked perfectly before I uploaded it, any suggestions are greatly appreciated, I'll be monitoring this so I can get a fix asap. Thanks in advance.

UPDATE: FIXED THE ISSUE

Apparently the program running from the hosting machine but not from a remote machine is actually a very telling symptom according to this article: http://msdn.microsoft.com/en-us/library/vstudio/ms730088(v=vs.100).aspx . According to that article, the problem is that the impersonate setting was set to impersonation which causes this behaviour, I wanted DELEGATION. In order to do this I used this page to get information on different methods of delegation and impersonation, I used the "Impersonating Original Caller Temporarily" section.

In the web.config file:

 <identity impersonate="false"/>

If this is set to false then it tries to impersonate the user for every action, which can cause issues like the one I was experiencing and isn't what I was trying to achieve.

In the code:

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
  // Start impersonating
  ctx = winId.Impersonate();
  // Now impersonating
  // Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
  // Revert impersonation
  if (ctx != null)
    ctx.Undo();
}
// Back to running under the default ASP.NET process identity

This fix is fairly easy, but its damn near impossible to find good clear information on this topic, I hope someone will find this useful some day, I can't be the only one experiencing these issues.

Upvotes: 1

Views: 165

Answers (1)

Tory Hill
Tory Hill

Reputation: 103

Apparently the program running from the hosting machine but not from a remote machine is actually a very telling symptom according to this article: http://msdn.microsoft.com/en-us/library/vstudio/ms730088(v=vs.100).aspx . According to that article, the problem is that the impersonate setting was set to impersonation which causes this behaviour, I wanted DELEGATION. In order to do this I used this page to get information on different methods of delegation and impersonation, I used the "Impersonating Original Caller Temporarily" section.

In the web.config file:

<identity impersonate="false"/>

If this is set to false then it tries to impersonate the user for every action, which can cause issues like the one I was experiencing and isn't what I was trying to achieve.

In the code:

using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
  // Start impersonating
  ctx = winId.Impersonate();
  // Now impersonating
  // Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch
{
}
finally
{
  // Revert impersonation
  if (ctx != null)
    ctx.Undo();
}
// Back to running under the default ASP.NET process identity

This fix is fairly easy, but its damn near impossible to find good clear information on this topic, I hope someone will find this useful some day, I can't be the only one experiencing these issues.

Upvotes: 1

Related Questions