Search code examples
.netwindows-authentication

Run .Net program as another user, but still access logged in windows user


We use Windows Auth in Sql Server and on the network to control access to any kind of resource.

There are two users involved. The user logged into Windows and the user who has the authority to do things in the database and folders. So this is more of a windows thing than a sql thing.

I have a windows program. Right now it runs as whoever is logged on to windows. When it did database inserts, the "Last User" column was correctly populated with my user name, because we want to track the specific user making the changes. I got this value by sending My.User.Name in the Sql.

Then the situation changed. My program broke when the DBA took away my database priviledges. We worked around it by using Run As , and the program does not fail. However, inserts to the database show the auth user and not my user.

I think it would be unrealistic to expect all our users to have to CTRL+SHIFT+Right click and do Run As Different user. They don't know that password anyway.

So I have two questions:

  1. Instead of Run As, what .Net code can I use to (internally) switch my program to be running under the auth user? It needs to access folders and not just databases under that user, who has elevated privs over regular users.

  2. Once I'm running as that auth user, how can I discover the windows logged on user so I can stick that into my logging?

EDIT:

Here's my code to go back and get the windows user. The sid returned does not match anything.

Public Function WindowsUser() As String
    Dim DesktopHandle As IntPtr = GetProcessWindowStation()

    If DesktopHandle = IntPtr.Zero Then Return Nothing

    ' get the length of the name.
    Dim Length As Integer = 0
    Dim name As String = [String].Empty
    Dim UOI_USER_SID As Integer = 4
    GetUserObjectInformation(DesktopHandle, UOI_USER_SID, IntPtr.Zero, 0, Length)

    'get the name.
    Dim SID As IntPtr = Marshal.AllocHGlobal(Length)
    Dim result As Boolean = GetUserObjectInformation(DesktopHandle, UOI_USER_SID, SID, Length, Length)

    Dim StringPointer As IntPtr
    ConvertSidToStringSid(SID, StringPointer)
    Dim SidString As String = Marshal.PtrToStringAuto(StringPointer)

    Dim s As New SecurityIdentifier(SidString)
    Return s.Translate(GetType(NTAccount)).ToString
  End Function

Solution

      • You can always do a stunt with CreateProcessAsUser/CreateProcessWithLogonW or something like sudo for Windows to run a program as another user without specifying a password manually. (You do understand that the 1st two ways are effectively giving your password to any user who puts enough effort to have a look?)
      • You can try to do impersonation (the process's account needs to have SeImpersonatePrivilege); WindowsIdentity is effectively a wrapper around those facilities. I never bothered with this as it proved times and times again to be a constant source of trouble.
    1. You can

    But, first of all, I'd try organizational means (as they were the root cause). As things currently are, mssql-related operations are in no way connected to the "current user", their "names" becoming but random strings that you personally decide on. And your program now takes upon itself the burden to control access to DB instead of the integrated security settings! Is your DBA (or whoever is in charge of your environment) really okay with this?