Windows Server 2008 impersonation.



I have an application that ran fine under Server 2003 x32 and now has
intermittent failures under Windows Server 2008 x64.

The application allow users to reset their password in the active directory
when the have lost their password entirely.

When the problem occurrs, no error is returned, but the password is not reset.

I suspect that the problem may be with the impersonation, but I have not
been able to locate any documentation on the correct way to accomplish an
impersonation under Windows Server 2008. Any help would be appreciated.

There was no change to the domain when we started using Windows Server 2008
and the website appears to run just fine on the old Windows Server 2003

One issue that I am not sure of…the impersonator uses the advapi32.dll and
kernel32.dll libraries. Note that the machine is a Windows Server 2008 x64

Basically it does the following.
1) Impersonate a user with password set access to the OU that contains the
2) objUSer.AuthenticationType = AuthenticationTypes.Secure
3) objUSer.Invoke("SetPassword", strPassword)
4) objUSer.CommitChanges()
5) Undo Impersonation

Impersonation is by:
Public Function ImpersonateUser( _
ByVal Domain As String, _
ByVal userName As String, _
ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
Dim iError As Integer
Dim ret As Integer
Dim strErr As String

If RevertToSelf() Then
iError = LogonUserA(userName, Domain, password,
LogonProvider.LOGON32_PROVIDER_DEFAULT, token)
If iError <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
ImpersonateUser = True
ret = Marshal.GetLastWin32Error()
strErr = "No Context returned:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
ret = Marshal.GetLastWin32Error()
strErr = "Failed To Duplicate Token:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
ret = Marshal.GetLastWin32Error()
strErr = "LogonUser failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)

End If
ret = Marshal.GetLastWin32Error()
strErr = "RevertToSelf Failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
End If
If Not token.Equals(IntPtr.Zero) Then
End If

Catch appEx As ApplicationException
sError = appEx.Message
'objErrorLog.WriteTOErrorLog(sLoginUserName, Err.Number, appEx.Source,
appEx.TargetSite.Name, appEx.Message, appEx.StackTrace)
ImpersonateUser = False

End Try

End Function

Joe Kaplan

Invoke of the ADSI SetPassword method should throw an exception if the
password modification operation fails. So, it seems like something may be
getting lost in translation here.

Normally, you don't need impersonation code for this. You would just put
the creds used for impersonation directly into the DirectoryEntry
constructor. That's quite a bit less code. :)

Normally I'd use a network login type for this sort of impersonation too
rather than interactive, but as long as the user has interactive login
rights on the server where this runs, that should still work.


When that was first developed, we could not get the password to reset without
doing the impersonation. That was several years ago, however.

Thanks for your help...I will try it with the authorization in the
DirectoryEntry constructor.

Joe Kaplan

ADSI was more limited years ago so perhaps that was the issue. In some
cases, the SetPassword method can be a pain to deal with in general and some
use cases may actually require the impersonation.

It is often cleaner just to set up a separate app pool for this app on the
server, run it as the admin user, add the user to the appropriate IIS_WPG
group and get rid of the impersonation AND the hard coded credentials. The
key is getting the right windows identity to do the work on the remote
machine and any of those approaches could work but this one is probably
easiest and most secure in that the admin is more in charge since the config
change to the app pool is made externally.

Best of luck!

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Latest member

Latest Threads