Save File to Different Domain - 2nd Post

Discussion in 'ASP .Net Security' started by BethC327, Oct 20, 2005.

  1. BethC327

    BethC327 Guest

    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.
     
    BethC327, Oct 20, 2005
    #1
    1. Advertising

  2. BethC327

    [MSFT] Guest

    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
     
    [MSFT], Oct 21, 2005
    #2
    1. Advertising

  3. BethC327

    Peter Jakab Guest

    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" <> wrote in message
    news:...
    > 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.
    >
    >
    >
     
    Peter Jakab, Oct 21, 2005
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris
    Replies:
    20
    Views:
    971
    Chris Uppal
    Jul 23, 2004
  2. Chris
    Replies:
    2
    Views:
    441
    Boudewijn Dijkstra
    Jan 8, 2005
  3. BethC327

    Save File to Server on Different Domain

    BethC327, Oct 14, 2005, in forum: ASP .Net Security
    Replies:
    0
    Views:
    444
    BethC327
    Oct 14, 2005
  4. Julia
    Replies:
    7
    Views:
    253
    Bill Puetz
    Oct 22, 2004
  5. Cindy Lee
    Replies:
    2
    Views:
    160
Loading...

Share This Page