Get Help:Ask a Question in our Forums|Report a Bug|More Help Resources
Last post Oct 16, 2011 04:41 PM by Bdieckman
Oct 14, 2011 08:13 PM|LINK
IIS7 running on Windows Server 2008 R2. Development environment is VWDE 2010.
I'm setting up a simple "machine status" page to monitor a server. I want to display the Drives on the machine, including mapped network drives and show their free space, etc.
I'm using System.IO.DriveInfo.GetDrives() to return a collection of DriveInfo objects. I then itterate that collection to display the relevant information.
The issue I'm having is that only local drives appear. (A:\, C:\ and D:\) No mapped drives "Network Locations" appear in the collection.
I'm thinking it has to do with the user account that's executing the code (if that makes any sense). So if the code is executing under the user "ASPNET" (or whatever it is) the drives would have to be mapped under that user. As it happens, I have the server
set up like a workstation and it logs in automatically under the user with the mapped drives.
What I've done:
- I have set the Web Site's Anonymous Authentication user to that same user
- I have set the Identity of the Application Pool to which my web site is assigned to be that same user.
And still, only local drives show up.
Little help? Thanks in advance... this is driving me NUTS!
Oct 14, 2011 08:24 PM|LINK
Don't you hate it when people reply to their own posts?
So I just verified that System.IO.DriveInfo.GetDrives() is returning the mapped drives when ran as the local user. I duplicated my code in a Windows Forms project and the following code returns all the drives.
For Each di As DriveInfo In DriveInfo.GetDrives()
That same exact code (except the listbox reference) only returns local drives in my Web application. This has got to be a user issue, but I'm at a loss as to configure exactly what account should execute the code in the page. I'm assuming it's a setting
in IIS7 but I can't find any more than the ones I've pointed out above.
Oct 16, 2011 01:50 AM|LINK
If you are sure it is a user context issue, then you should be able to solve this via "impersonation" at runtime. Pretty simple stuff to get a token that represents the context of the user you would prefer to run under to see the mappings. Take
a look to the following for a detailed code example on doing this:
Oct 16, 2011 01:59 AM|LINK
but I'm at a loss as to configure exactly what account should execute the code in the page
Use Environment.Username to identify the user the ASP.NET application is running under....
Oct 16, 2011 01:06 PM|LINK
That's a great tool, Hans. Thank you for that.
I have verified that the code is running under the correct acount; The user name with the mapped drives is the user returned by Environment.UserName. I think it has been all along. This must be a permissions issue.
The User has Full Contol over the Web Site's directory, so I don't think that's the issue. Does a user need special permission to simply list drives? I can't see that as the problem, either, because when I log on as that user, I can see the drives fine.
(In fact I'm always logged in as that user)
Oct 16, 2011 04:41 PM|LINK
Thank you for your reply. I used the code
here to create this:
Partial Class Default2
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
Public Shared Function GetLastError() As Integer
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
'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", "MACHINENAME", "PASSWORD", 3, 0, token1)
'Call GetLastError to try to determine why logon failed if it did not succeed.
Dim ret As Integer = GetLastError()
Response.Write("<p>LogonUser Success? " + loggedOn.ToString + "<br />")
Response.Write("NT Token Value: " + token1.ToString + "</p>")
If ret <> 0 Then
Response.Write("Error code (126 == ""Specified module could not be found""): " + ret.ToString + "</p>")
'Starting impersonation here:
Response.Write("<p><b>Before impersonation:</b><br />")
Dim mWI1 As WindowsIdentity = WindowsIdentity.GetCurrent()
Response.Write(mWI1.Name.ToString + "<br />")
Response.Write(mWI1.Token.ToString + "</p>")
Dim token2 As IntPtr = New IntPtr(token1)
Response.Write("<p><b>New identity created:</b><br />")
Dim mWI2 As WindowsIdentity = New WindowsIdentity(token2)
Response.Write(mWI2.Name.ToString + "<br />")
Response.Write(mWI2.Token.ToString + "</p>")
'Impersonate the user.
Dim mWIC As WindowsImpersonationContext = mWI2.Impersonate()
Response.Write("<p><b>After impersonation:</b><br />")
Dim mWI3 As WindowsIdentity = WindowsIdentity.GetCurrent()
Response.Write(mWI3.Name.ToString + "<br />")
Response.Write(mWI3.Token.ToString + "</p>")
'Revert to previous identity.
Response.Write("<p><b>After impersonation is reverted:</b><br />")
Dim mWI4 As WindowsIdentity = WindowsIdentity.GetCurrent()
Response.Write(mWI4.Name.ToString + "<br />")
Response.Write(mWI4.Token.ToString + "</p>")
And it appeared to work properly. (I am sucessfully impersonating the correct user)So I added my drive list collection code but it returns the exact same list before and after impersonation.
I am at a total loss here. Clearly the code executed by ASP even when impersonating another user does not have the same rights or visibility as when that user is actually logged in.