UNC Path access is denied

From: Russ (Russ_at_discussions.microsoft.com)
Date: 08/30/04


Date: Mon, 30 Aug 2004 09:17:07 -0700

I have an asp.net app that needs to retrieve a list of files from a UNC path.
 All attempts to access have resulted in "Access Denied". I'm using
LogonUser in the Win32 API to authenticate using a process account in our
internal domain. Authentication is successful. After authenticating, I call
ImpersonateLoggedOnUser (I've also tried impersonate in the
WindowsImpersonationContext class) also in the Win32 api and pass in the
token received from LogonUser. All result codes are successful at this point.

Prior to the LogonUser call, I get the current WindowsIdentity which returns
the IUSR_<machinename>. After the LogonUser call and ImpersonateLoggedOnUser
calls, the current identity is changed to the process account that I used for
authentication. Using the new windowsidentity object a create a new
WindowsPrincipal object and attach it to the current thread.

At this point, I create a directoryInfo object and pass in the UNC Path.
Using the new object, I call its GetFiles method passing in the filter
"*.xls". This call thrrows an System.UnauthorizedAccessException: Access to
the path "\\myservername\\mysharename" is denied Exception.

I've included the code below. Thanks in advance for your assistance.

'======================================================================
'Code-behind Class
'======================================================================
 Imports System
Imports System.IO
Imports System.Security.Principal
Imports IMS.WSD.IMSApplication

Public Class WebForm2
    Inherits System.Web.UI.Page
    
    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
        GetFiles3()

    End Sub
   Private Sub GetFiles3()

        Try
            Dim oFileIO As New FileIO()
            Dim oSecurity As New Security()
            Dim oFileInfo As FileInfo()
            Dim strPath As String = "\\plysdev09\\prod"

            'Starting impersonation here:
            'Console.WriteLine("Before impersonation:")
            Dim mWI1 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI1.Name)
            Console.WriteLine(mWI1.Token)
            Dim token1 As Integer = oSecurity.NetworkImpersonate("rbasiura",
"password", "Domain")

            Dim token2 As IntPtr = New IntPtr(token1)

            'Console.WriteLine("New identity created:")
            Dim mWI2 As WindowsIdentity = New WindowsIdentity(token2)

            Console.WriteLine(mWI2.Name)
            Console.WriteLine(mWI2.Token)

            'Impersonate the user.
            'Dim mWIC As WindowsImpersonationContext = mWI2.Impersonate()
            Dim mWIC As WindowsImpersonationContext = mWI2.Impersonate()

            Console.WriteLine("After impersonation:")
            Dim mWI3 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI3.Name)
            Console.WriteLine(mWI3.Token)

            ' Create a new WindowsPrincipal
            Dim MyPrincipal As New WindowsPrincipal(mWI3)

            ' Attach the Principal to the HttpContext
            HttpContext.Current.User = MyPrincipal

            oFileInfo = oFileIO.GetFiles(strPath)

            'Revert to previous identity.
            mWIC.Undo()

            'Console.WriteLine("After impersonation is reverted:")
            Dim mWI4 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI4.Name)
            Console.WriteLine(mWI4.Token)

            ' Print out the names of the files in the current directory.
            Dim lstItem As ListItem
            DropDownList1.Items.Clear()
            Dim fiTemp As FileInfo
            For Each fiTemp In oFileInfo
                lstItem = New ListItem()
                lstItem.Text = fiTemp.Name.ToString
                DropDownList1.Items.Add(lstItem)
            Next fiTemp

        Catch ex As Exception
            Throw ex
        End Try

    End Sub
End Class

'======================================================================
'Security Class
'======================================================================

Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports System.Web

<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum,
UnmanagedCode:=True)>
Public Class Security

    <DllImport("C:\\WINNT\\System32\\advapi32.dll")> _
  Public 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 Integer) As Boolean

    End Function

    <DllImport("C:\\WINNT\\System32\\Kernel32.dll")> _
   Public Shared Function GetLastError() As Integer
    End Function

    Private Function ImpersonateNetworkUser()

        Try

            'The Windows NT user token.
            Dim token1 As Integer

            'Get the user token for the specified user, machine, and
password using the unmanaged LogonUser method.

            'The parameters for LogonUser are the user name, computer name,
password,
            'Logon type (LOGON32_LOGON_NETWORK_CLEARTEXT), Logon provider
(LOGON32_PROVIDER_DEFAULT),
            'and user token.
            Dim loggedOn As Boolean = LogonUser("username", "Domain",
"password", 3, 0, token1)
            'Response.Write("LogonUser called")

            'Call GetLastError to try to determine why logon failed if it
did not succeed.
            Dim ret As Integer = GetLastError()

            'Console.WriteLine("LogonUser Success? " + loggedOn)
            'Console.WriteLine("NT Token Value: " + token1)
            If ret <> 0 Then
                Console.WriteLine("Error code (126 == ""Specified module
could not be found""): " + ret)
            End If

            'Starting impersonation here:
            Console.WriteLine("Before impersonation:")
            Dim mWI1 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI1.Name)
            Console.WriteLine(mWI1.Token)

            Dim token2 As IntPtr = New IntPtr(token1)

            Console.WriteLine("New identity created:")
            Dim mWI2 As WindowsIdentity = New WindowsIdentity(token2)
            Console.WriteLine(mWI2.Name)
            Console.WriteLine(mWI2.Token)

            'Impersonate the user.
            Dim mWIC As WindowsImpersonationContext = mWI2.Impersonate()

            Console.WriteLine("After impersonation:")
            Dim mWI3 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI3.Name)
            Console.WriteLine(mWI3.Token)

            'Revert to previous identity.
            mWIC.Undo()

            Console.WriteLine("After impersonation is reverted:")
            Dim mWI4 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI4.Name)
            Console.WriteLine(mWI4.Token)

        Catch ex As Exception
            Throw ex
        End Try

    End Function

    <DllImport("C:\\WINNT\\System32\\advapi32.dll")> _
          Public Shared Function ImpersonateLoggedOnUser(ByVal token As
Integer) As Boolean

    End Function

    Public Function NetworkImpersonate(ByVal strUserName As String, _
                                        ByVal strPassword As String, _
                                        ByVal strDomain As String) As Integer

        'The Windows NT user token.
        Dim token1 As Integer

        'Get the user token for the specified user, machine, and password
using the unmanaged LogonUser method.
        'The parameters for LogonUser are the user name, computer name,
password,
        'Logon type (LOGON32_LOGON_NETWORK_CLEARTEXT), Logon provider
(LOGON32_PROVIDER_DEFAULT),
        'and user token.
        Dim loggedOn As Boolean = LogonUser(strUserName, strDomain,
strPassword, 3, 0, token1)
        'Console.WriteLine("LogonUser called")
        If loggedOn = False Then
            Throw New Exception("Authorization Failed.")
        Else
            'impersonate the logged on user
            Dim blnSuccess As Boolean = ImpersonateLoggedOnUser(token1)

            If blnSuccess = True Then
                Return token1
            End If
            'Return ImpersonateLoggedOnUser(token1)
        End If

    End Function

End Class

'======================================================================
'FileIO Class
'======================================================================

Imports System
Imports System.IO
Imports System.Collections
Imports System.Web
Imports System.Security.Principal

Public Class IMSFileIO

    Public Function GetFiles(ByVal strPath As String) As FileInfo()
        Try

            Dim mWI1 As WindowsIdentity = WindowsIdentity.GetCurrent()
            Console.WriteLine(mWI1.Name)

            ' Create a reference to the current directory.
            Dim di As New DirectoryInfo(strPath)
            ' Create an array representing the files in the current directory.
            Dim fi As FileInfo() = di.GetFiles("*.xls")
            ' Print out the names of the files in the current directory.

            GetFiles = fi

        Catch ex As Exception
            Throw ex

        End Try

    End Function

End Class