Will the Real User Please Stand Up
August 27th, 2007
In my previous article, Impersonation Class, I had provided code that allowed you to impersonate a user for critical parts of your program. Another common use of impersonation is when an application needs to run under a different ID than the currently logged in user. This is usually done by the system administrator to allow a program to access resources that regular users are locked out of, for example, the registry or a remote network drive.
This can create a problem if your program needs to log the current user to the database or file or needs the real users name for other reasons while impersonation is active. If you use the My.User.Name property it will return the name of the current, impersonated, user, not the user who is logged into the computer. Related .NET Framework methods will do the same. Fortunately, we’re not limited to only looking at our own process to determine who the real user is.
The System.Management Namespace provides easy access to the Windows Management Instrumentation (WMI) infrastructure. This allows us to gather a lot of information about the system, including who the owner of a specified process is. In our case, we want to look for explorer.exe, the Windows shell program.
To begin with, we will need to add a reference to System.Management to our project. Next, to look for this process, we will use the ManagementObjectSearcher. This object retrieves a collection of management objects from a WMI query. These queries look very much like standard SQL queries. In our case, we’re going to return all of the running processes. Once we have this collection, we’re going to search through it for explorer.exe, extract the user name from the object, and return it.
The Code
Public Function GetActualUserName() As String
Dim ActualUserName As String = ""
Dim ProcessSearch As New Management.ManagementObjectSearcher("Select * from Win32_Process")
Dim CurrentProcesses As Management.ManagementObjectCollection = ProcessSearch.Get
For Each ProcessItem As Management.ManagementObject In CurrentProcesses
Dim ProcessOwner(2) As String
ProcessItem.InvokeMethod("GetOwner", ProcessOwner)
If (ProcessItem("Name").ToString = "explorer.exe") Then
ActualUserName = ProcessOwner(0).ToString
Exit For
End If
Next
Return ActualUserName
End Function
Limitations
Using the System.Management objects does require having fully trusted code and sufficient security on the target system. Usually this isn’t a problem because most of the time impersonated processes will be running at a higher level of security. However, you need to bear this in mind for your design.
Another limitation would be on terminal service systems or other situations where multiple users might be logged in and have a desktop session. This may require more WMI queries to narrow down the specific user you want to capture or it may not be doable in this manner and you’ll have to try something else.
I hope you’ve found this code example helpful. Let me know if you did or didn’t or if I left something important out or if you want more details on this subject area or whatever by leaving me a comment.
Entry Filed under: Code Examples
Rate This Article:











1 Comment Add your own
1. Saravanan | April 16th, 2008 at 9:45 am
Hi,
Interesting artilcle. Cannot help but notice that the sample code can be optimised further.
If (ProcessItem(”Name”).ToString = “explorer.exe”) Then
Dim ProcessOwner(2) As String
ProcessItem.InvokeMethod(”GetOwner”, ProcessOwner)
ActualUserName = ProcessOwner(0).ToString
Exit For
End If
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed