run a windows application for a specific user account?

ajeeshco

Well-known member
Joined
Sep 19, 2006
Messages
257
Location
Cochin, India
Programming Experience
3-5
Hi all,
I would like to know How to run an application for a specific windows user account. The user name and password can be supplied as hardcoded. The current user will be logged in with lower priviledges but the application will be running with the priviledges of the hardcoded username.
Thanks in advance.
 
Here is the full code listing for a form with a button to test impersonation, it is mostly API declares and some enumeration I copied from PInvoke. This code works for me, but curiously I had to use parts of several different other examples found on web (which errored/missed bits) to make a complete working code.. try this out:
VB.NET:
Imports System.Security.Principal
Imports System.Security.Permissions
Public Class Form2
 
    Declare Function LogonUser Lib "ADVAPI32.dll" Alias "LogonUserA" ( _
  ByVal lpszUsername As String, _
  ByVal lpszDomain As String, _
  ByVal lpszPassword As String, _
  ByVal dwLogonType As LogonType, _
  ByVal dwLogonProvider As LogonProvider, _
  ByRef phToken As IntPtr) As Int32
 
    Declare Function GetLastError Lib "kernel32.dll" () As Int32
 
    Public Enum LogonType As Integer
        LOGON32_LOGON_INTERACTIVE = 2
        LOGON32_LOGON_NETWORK = 3
        LOGON32_LOGON_BATCH = 4
        LOGON32_LOGON_SERVICE = 5
        LOGON32_LOGON_UNLOCK = 7
        LOGON32_LOGON_NETWORK_CLEARTEXT = 8
        LOGON32_LOGON_NEW_CREDENTIALS = 9
    End Enum
 
    Public Enum LogonProvider As Integer
        LOGON32_PROVIDER_DEFAULT = 0
    End Enum
 
    <SecurityPermissionAttribute(SecurityAction.Demand, ControlPrincipal:=True, UnmanagedCode:=True)> _
    Private Shared Function GetWindowsIdentity(ByVal UserName As String, _
    ByVal Domain As String, ByVal Password As String) As WindowsIdentity
 
        Dim SecurityToken As IntPtr
        Dim Success As Boolean = LogonUser(UserName, Domain, Password, _
            LogonType.LOGON32_LOGON_NETWORK_CLEARTEXT, _
            LogonProvider.LOGON32_PROVIDER_DEFAULT, SecurityToken)
        If Not Success Then
            Throw New System.Exception("Logon Failed. Error: " & GetLastError())
        End If
        Return New WindowsIdentity(SecurityToken)
    End Function
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MsgBox(WindowsIdentity.GetCurrent.Name)
        Dim wi As WindowsIdentity = GetWindowsIdentity("testuser", "", "test")
        Dim ic As WindowsImpersonationContext = wi.Impersonate()
        MsgBox(WindowsIdentity.GetCurrent.Name)
        ic.Undo()
        MsgBox(WindowsIdentity.GetCurrent.Name)
    End Sub
End Class
Note, the user account to impersonate also needs to have password, else logon fails.
 
How can I get more information/ resources about this?

Hi JohnH,
It really helped me a lot :). I am trying to learn the code you replied and the related things. And it is returning an errorcode = 1314. Can you please tell me how can I get more information about the errorcodes or links to any documentations that may help me.
 
Change GetLastError() in exception catch to getErrorExtended(Err.LastDllError) and add this code using FormatMessage to get more information about the Win32 error code:
VB.NET:
Declare Function FormatMessage Lib "kernel32.dll" Alias "FormatMessageA" ( _
  ByVal dwFlags As Int32, _
  ByVal lpSource As Int32, _
  ByVal dwMessageId As Int32, _
  ByVal dwLanguageId As Int32, _
  ByVal lpBuffer As System.Text.StringBuilder, _
  ByVal nSize As Int32, _
  ByRef Arguments As Int32) As Int32
 
    Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
    Private Const MAX_MESSAGE_LENGTH = 512
    Private Shared Function getErrorExtended(ByVal ApiErrNumber As Integer) As String
        Dim sError As New System.Text.StringBuilder(MAX_MESSAGE_LENGTH)
        Dim lErrorMessageLength As Int32
        lErrorMessageLength = _
           FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, _
                          0, ApiErrNumber, 0, sError, sError.Capacity, 0)
        If lErrorMessageLength > 0 Then
            Return ApiErrNumber.ToString & " " & sError.ToString
        Else
            Return ApiErrNumber.ToString
        End If
    End Function
 
I think the error 1314 is same as ERROR_PRIVILEGE_NOT_HELD as discussed in Remarks section of LogonUser documentation.
 
Back
Top