Save File to Different Domain - 2nd Post

B

BethC327

Sorry to re-post, but apparently I was not registered correctly to receive a
reply when I posted this the first time.


I need to save a file from an ASP.Net page to a folder on a separate file
server. The file server is on a different domain than the web server. I
have been told that due to a complex networking structure, I must use a UNC
to access the folder on the file server. Both servers are running Win2K.
The web server is running IIS6.

I followed the following example in the .Net Developer's guide to try to
impersonate a user with the proper permissions on the file server:

Sometimes you might need to obtain a Windows NT account token to impersonate
a Windows account. For example, your ASP.NET-based application might have to
act on behalf of several users at different times. Your application might
accept a token that represents an administrator from Internet Information
Services (IIS), impersonate that user, perform an operation, and revert to
the previous identity. Next, it might accept a token from IIS that represents
a user with fewer rights, perform some operation, and revert again.

In situations where your application must impersonate a Windows account that
has not been attached to the current thread by IIS, you must retrieve that
account's token and use it to activate the account. You can do this by
performing the following tasks:

Retrieve an account token for a particular user by making a call to the
unmanaged LogonUser method. This method is not in the .NET Framework base
class library, but is located in the unmanaged advapi32.dll. Accessing
methods in unmanaged code is an advanced operation and is beyond the scope of
this discussion. For more information, see Interoperating with Unmanaged
Code. For more information about the LogonUser method and advapi32.dll, see
the Platform SDK documentation.
Create a new instance of the WindowsIdentity class, passing the token. The
following code demonstrates this call, where hToken represents a Windows
token.
[C#]
WindowsIdentity ImpersonatedIdentity = new WindowsIdentity(hToken);

[Visual Basic]
Dim ImpersonatedIdentity As New WindowsIdentity(hToken)

Begin impersonation by creating a new instance of the
WindowsImpersonationContext class and initializing it with the
WindowsIdentity.Impersonate method of the initialized class, as shown in the
following code.
[C#]
WindowsImpersonationContext MyImpersonation =
ImpersonatedIdentity.Impersonate();

[Visual Basic]
WindowsImpersonationContext MyImpersonation =
ImpersonatedIdentity.Impersonate()

When you no longer need to impersonate, call the
WindowsImpersonationContext.Undo method to revert the impersonation, as shown
in the following code.
[C#]
MyImpersonation.Undo();

[Visual Basic]
MyImpersonation.Undo()

If trusted code has already attached a WindowsPrincipal object to the
thread, you can call the instance method Impersonate, which does not take an
account token. Note that this is only useful when the WindowsPrincipal object
on the thread represents a user other than the one under which the process is
currently executing. For example, you might encounter this situation using
ASP.NET with Windows authentication turned on and impersonation turned off.
In this case, the process is running under an account configured in Internet
Information Services (IIS) while the current principal represents the Windows
user that is accessing the page.

Note that neither Impersonate nor Undo changes the Principal object
associated with the current call context. Rather, impersonation and reverting
change the token associated with the current operating system process..



BELOW IS THE CODE FOR THE ASP.NET PAGE RUNNING ON MY WEB SERVER:

Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Web
Imports System.Web.SessionState
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Security.Principal
Imports System.Security.Permissions
Imports System.Runtime.InteropServices
Imports System.Environment

Public Class ImageUpload
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

End Sub

'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
Dim fileName As String
If Request.Files.Count <> 0 Then
' Save the file to the server.
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGON32_LOGON_NETWORK As Integer = 3
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Dim tokenHandle As New IntPtr(0)
tokenHandle = IntPtr.Zero
LogonUser("Webuser", "ct.fileserver.com", "webuser",
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)
Dim ImpersonatedIdentity As New WindowsIdentity(tokenHandle)
Dim MyImpersonation As WindowsImpersonationContext
MyImpersonation = ImpersonatedIdentity.Impersonate(tokenHandle)
fileName = "\\fileserver\uploads\123\" &
Request.Files(0).FileName.ToString
Request.Files(0).SaveAs(fileName)
CloseHandle(tokenHandle)
MyImpersonation.Undo()
End If
End Sub
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function LogonUser(ByVal lpszUsername As String, ByVal
lpszDomain As String, _
ByVal lpszPassword As String, ByVal dwLogonType As Integer, ByVal
dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean
End Function

<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Private Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function

End Class


Webuser is a user in the ct.fileserver.com domain. The password for user
Webuser is "webuser". The "\\fileserver\uploads\123" folder has Full Control
set for the Everyone group in the fileserver domain.

When I run the application I receive the error "Token cannot be zero".

Any insights into what I'm doing wrong here would be appreciated.
 
M

[MSFT]

Hello,

You may run the code in debug mode and catch the line generating the error,
then we should find the exact the problem. Also, You need make sure your
ASP.NET app is running under a local administrator account. Impersonate
also need enough permission on local system.

Addiotnally, below is a sample on ASP.NET impersonate. Its code is a little
more robust. you may try the code in it and see the results.

http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q306158

Luke
 
P

Peter Jakab

Just some ideas:

It seems, that logonuser cannot logon the user with the parameters you
specified, this maybe caused by one of the following:

- the name of the domain is not correctly specified
- the two domains dont have the necessary trust relationship, so the other
domains user cannot login on the web server
- maybe the user doesn't have logon permissions on the server

maybe you could also check why logonuser failed with getlasterror

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/getlasterror.asp


You must also declare closehandle as shared, otherwise you will receive an
error.

Regards

Peter

BethC327 said:
Sorry to re-post, but apparently I was not registered correctly to receive
a
reply when I posted this the first time.


I need to save a file from an ASP.Net page to a folder on a separate file
server. The file server is on a different domain than the web server. I
have been told that due to a complex networking structure, I must use a
UNC
to access the folder on the file server. Both servers are running Win2K.
The web server is running IIS6.

I followed the following example in the .Net Developer's guide to try to
impersonate a user with the proper permissions on the file server:

Sometimes you might need to obtain a Windows NT account token to
impersonate
a Windows account. For example, your ASP.NET-based application might have
to
act on behalf of several users at different times. Your application might
accept a token that represents an administrator from Internet Information
Services (IIS), impersonate that user, perform an operation, and revert to
the previous identity. Next, it might accept a token from IIS that
represents
a user with fewer rights, perform some operation, and revert again.

In situations where your application must impersonate a Windows account
that
has not been attached to the current thread by IIS, you must retrieve that
account's token and use it to activate the account. You can do this by
performing the following tasks:

Retrieve an account token for a particular user by making a call to the
unmanaged LogonUser method. This method is not in the .NET Framework base
class library, but is located in the unmanaged advapi32.dll. Accessing
methods in unmanaged code is an advanced operation and is beyond the scope
of
this discussion. For more information, see Interoperating with Unmanaged
Code. For more information about the LogonUser method and advapi32.dll,
see
the Platform SDK documentation.
Create a new instance of the WindowsIdentity class, passing the token. The
following code demonstrates this call, where hToken represents a Windows
token.
[C#]
WindowsIdentity ImpersonatedIdentity = new WindowsIdentity(hToken);

[Visual Basic]
Dim ImpersonatedIdentity As New WindowsIdentity(hToken)

Begin impersonation by creating a new instance of the
WindowsImpersonationContext class and initializing it with the
WindowsIdentity.Impersonate method of the initialized class, as shown in
the
following code.
[C#]
WindowsImpersonationContext MyImpersonation =
ImpersonatedIdentity.Impersonate();

[Visual Basic]
WindowsImpersonationContext MyImpersonation =
ImpersonatedIdentity.Impersonate()

When you no longer need to impersonate, call the
WindowsImpersonationContext.Undo method to revert the impersonation, as
shown
in the following code.
[C#]
MyImpersonation.Undo();

[Visual Basic]
MyImpersonation.Undo()

If trusted code has already attached a WindowsPrincipal object to the
thread, you can call the instance method Impersonate, which does not take
an
account token. Note that this is only useful when the WindowsPrincipal
object
on the thread represents a user other than the one under which the process
is
currently executing. For example, you might encounter this situation using
ASP.NET with Windows authentication turned on and impersonation turned
off.
In this case, the process is running under an account configured in
Internet
Information Services (IIS) while the current principal represents the
Windows
user that is accessing the page.

Note that neither Impersonate nor Undo changes the Principal object
associated with the current call context. Rather, impersonation and
reverting
change the token associated with the current operating system process..



BELOW IS THE CODE FOR THE ASP.NET PAGE RUNNING ON MY WEB SERVER:

Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Web
Imports System.Web.SessionState
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Security.Principal
Imports System.Security.Permissions
Imports System.Runtime.InteropServices
Imports System.Environment

Public Class ImageUpload
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

End Sub

'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
Dim fileName As String
If Request.Files.Count <> 0 Then
' Save the file to the server.
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGON32_LOGON_NETWORK As Integer = 3
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Dim tokenHandle As New IntPtr(0)
tokenHandle = IntPtr.Zero
LogonUser("Webuser", "ct.fileserver.com", "webuser",
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)
Dim ImpersonatedIdentity As New WindowsIdentity(tokenHandle)
Dim MyImpersonation As WindowsImpersonationContext
MyImpersonation = ImpersonatedIdentity.Impersonate(tokenHandle)
fileName = "\\fileserver\uploads\123\" &
Request.Files(0).FileName.ToString
Request.Files(0).SaveAs(fileName)
CloseHandle(tokenHandle)
MyImpersonation.Undo()
End If
End Sub
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function LogonUser(ByVal lpszUsername As String, ByVal
lpszDomain As String, _
ByVal lpszPassword As String, ByVal dwLogonType As Integer, ByVal
dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean
End Function

<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Private Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function

End Class


Webuser is a user in the ct.fileserver.com domain. The password for user
Webuser is "webuser". The "\\fileserver\uploads\123" folder has Full
Control
set for the Everyone group in the fileserver domain.

When I run the application I receive the error "Token cannot be zero".

Any insights into what I'm doing wrong here would be appreciated.
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top