G
Guest
Hi
I made a naff web application which uses the impersonation method in MSDN
(can't find it now, but it basically revolves around creating a token by
calling the LogonUser API, calling DuplicateToken API on it, and then calling
w.Impersonate() where w is a System.Security.Principal.WindowsIdentity
object). This is the only real point of the said web application if I'm
brutally honest with myself ;-) however it leaves me curious, as does any
test project!
I set up this web application, the idea of which being to shell commands on
the web server and see the output in a webforms text box, from a remote
machine.
I thought the impersonation worked because all the return values were as
expected, and what's more a totally independent Environment.UserName function
returned the username I had impersonated. However, when I try to do
"dir "c:\documents and settings\bonj\*.txt" /b /s
from the web application, it returns 'file not found' but when I copy that
command into a DOS box (logged on as bonj) it returns a whole list of text
files. I'm suspicous that there's some permissions thing that windows is
hiding from me. What, though?
The code for the impersonation is this:
Public Class Impersonator
Implements IDisposable
Const LOGON32_LOGON_INTERACTIVE As Int32 = 2
Const LOGON32_PROVIDER_DEFAULT As Int32 = 0
Const SecurityImpersonation As Int32 = 2
Dim impersonationContext As WindowsImpersonationContext
Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUserName
As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Int32, _
ByVal dwLogonProvider As Int32, _
ByRef phToken As IntPtr) As Int32
Declare Auto Function DuplicateToken Lib "advapi32.dll" _
(ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Int32, _
ByRef DuplicateTokenHandle As IntPtr) As Int32
Public Function Impersonate(ByVal UserName As String, ByVal Domain As
String, ByVal Password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr
Dim tokenDuplicate As IntPtr
If LogonUser(UserName, Domain, password, LOGON32_LOGON_INTERACTIVE, _
LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
Return Not (impersonationContext Is Nothing)
End If
End If
End Function
Public Sub Dispose() Implements System.IDisposable.Dispose
If Not impersonationContext Is Nothing Then
impersonationContext.Undo()
End Sub
End Class
and the code for the cmdCommand click button on the web form is:
Private Sub cmdGo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles cmdGo.Click
txtResults.Text = ""
Dim p As New Process
Dim psi As New
ProcessStartInfo(Environment.GetEnvironmentVariable("comspec"), _
"/c """ + txtCommand.Text + """")
psi.UseShellExecute = False
psi.CreateNoWindow = True
psi.RedirectStandardOutput = True
psi.RedirectStandardError = True
psi.WindowStyle = ProcessWindowStyle.Hidden
p.StartInfo = psi
p.Start()
Dim s As String, err As String
Do
s = p.StandardOutput.ReadLine
err = p.StandardError.ReadLine
If Not s Is Nothing Then txtResults.Text += s + Environment.NewLine
If Not err Is Nothing Then txtResults.Text += err +
Environment.NewLine
Loop Until s Is Nothing
p.Dispose()
End Sub
I made a naff web application which uses the impersonation method in MSDN
(can't find it now, but it basically revolves around creating a token by
calling the LogonUser API, calling DuplicateToken API on it, and then calling
w.Impersonate() where w is a System.Security.Principal.WindowsIdentity
object). This is the only real point of the said web application if I'm
brutally honest with myself ;-) however it leaves me curious, as does any
test project!
I set up this web application, the idea of which being to shell commands on
the web server and see the output in a webforms text box, from a remote
machine.
I thought the impersonation worked because all the return values were as
expected, and what's more a totally independent Environment.UserName function
returned the username I had impersonated. However, when I try to do
"dir "c:\documents and settings\bonj\*.txt" /b /s
from the web application, it returns 'file not found' but when I copy that
command into a DOS box (logged on as bonj) it returns a whole list of text
files. I'm suspicous that there's some permissions thing that windows is
hiding from me. What, though?
The code for the impersonation is this:
Public Class Impersonator
Implements IDisposable
Const LOGON32_LOGON_INTERACTIVE As Int32 = 2
Const LOGON32_PROVIDER_DEFAULT As Int32 = 0
Const SecurityImpersonation As Int32 = 2
Dim impersonationContext As WindowsImpersonationContext
Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUserName
As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Int32, _
ByVal dwLogonProvider As Int32, _
ByRef phToken As IntPtr) As Int32
Declare Auto Function DuplicateToken Lib "advapi32.dll" _
(ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Int32, _
ByRef DuplicateTokenHandle As IntPtr) As Int32
Public Function Impersonate(ByVal UserName As String, ByVal Domain As
String, ByVal Password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr
Dim tokenDuplicate As IntPtr
If LogonUser(UserName, Domain, password, LOGON32_LOGON_INTERACTIVE, _
LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
Return Not (impersonationContext Is Nothing)
End If
End If
End Function
Public Sub Dispose() Implements System.IDisposable.Dispose
If Not impersonationContext Is Nothing Then
impersonationContext.Undo()
End Sub
End Class
and the code for the cmdCommand click button on the web form is:
Private Sub cmdGo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles cmdGo.Click
txtResults.Text = ""
Dim p As New Process
Dim psi As New
ProcessStartInfo(Environment.GetEnvironmentVariable("comspec"), _
"/c """ + txtCommand.Text + """")
psi.UseShellExecute = False
psi.CreateNoWindow = True
psi.RedirectStandardOutput = True
psi.RedirectStandardError = True
psi.WindowStyle = ProcessWindowStyle.Hidden
p.StartInfo = psi
p.Start()
Dim s As String, err As String
Do
s = p.StandardOutput.ReadLine
err = p.StandardError.ReadLine
If Not s Is Nothing Then txtResults.Text += s + Environment.NewLine
If Not err Is Nothing Then txtResults.Text += err +
Environment.NewLine
Loop Until s Is Nothing
p.Dispose()
End Sub