Solved

How to execute code with current user privilege on the service application.

Posted on 2009-07-08
5
696 Views
Last Modified: 2012-05-07
Hello.
I made a serivce application. ( it is executed with System user account )

When i trying to some jobs on the service application, the code does not work.
Because of service application has limitted privileges.
So, i must made other win32 program which is executed by service application with current logon user system privileges.

I think this way is not efficient. Because i must made another program.

So, I looking for the solution that execute some procedure or function with current logon user privileges at the service application.

For Example)
// Service application body
begin
....
   do_excute_some_code( parameter 1 ); // this procedure will execute with current logon user privileges

end;

Is this possible ???
If you know how to do this, please let me know or give me some example code.

Thanks.
0
Comment
Question by:schiva
  • 2
5 Comments
 
LVL 14

Expert Comment

by:SteveBay
ID: 24813662
I am almost certain you will not be able to change the account under which you are running while running.
Is there a reason why you can not just run the entire service from a user's account with all of the approriate priveleges?

As an alternative you could perhaps write two services and run them under different accounts and have service1 send a message to service2 that will then execute some code but it sounds like alot of work.
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 24815866
you need to change to the user you need with impersonate user and then run that task

  if LogonUser(user, domain or empty string , pass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, h) then

  try

    if ImpersonateLoggedOnUser(h) then

    try

      do whatever as user

    finally

      if not RevertToSelf then// either this, or exit the thread

        showmessage(syserrormessage(getlasterror));

    end

    else

      showmessage(syserrormessage(getlasterror));

  finally

    closehandle(h);        

  end;

Open in new window

0
 
LVL 2

Accepted Solution

by:
Wegelin earned 500 total points
ID: 24912639
I have a class wher you can do both
Run a Process as logged on user  or run Code as loggen on user
Import the Class ProcessAsUser

How you can Start a Process as Logged On User ?

ProcessAsUser.launch("c:\wondos\notepad.exe")


How you run Code as logged On User ?



WindowsImpersonationContext impctx = WindowsIdentity.Impersonate(ProcessAsUser.GetUserToken);

 do_excute_some_code( parameter 1 ); // this procedure will execute with current logon user privileges

impctx.Undo();

Imports System.Runtime.InteropServices

Imports System.Security.Permissions

Imports System.Reflection

Public Class ProcessAsUser

    <StructLayout(LayoutKind.Sequential)> _

Friend Structure PROCESS_INFORMATION

        Public hProcess As IntPtr

        Public hThread As IntPtr

        Public dwProcessId As Int32

        Public dwThreadId As Int32

    End Structure

    <StructLayout(LayoutKind.Sequential)> _

    Friend Structure SECURITY_ATTRIBUTES

        Public nLength As Int32

        Public lpSecurityDescriptor As IntPtr

        Public bInheritHandle As Boolean

    End Structure
 

    <StructLayout(LayoutKind.Sequential)> _

    Public Structure STARTUPINFO

        Public cb As Int32

        Public lpReserved As String

        Public lpDesktop As String

        Public lpTitle As String

        Public dwX As Int32

        Public dwY As Int32

        Public dwXSize As Int32

        Public dwYSize As Int32

        Public dwXCountChars As Int32

        Public dwYCountChars As Int32

        Public dwFillAttribute As Int32

        Public dwFlags As Int32

        Public wShowWindow As Short

        Public cbReserved2 As Short

        Public lpReserved2 As IntPtr

        Public hStdInput As IntPtr

        Public hStdOutput As IntPtr

        Public hStdError As IntPtr

    End Structure
 

    Public Enum SECURITY_IMPERSONATION_LEVEL

        SecurityAnonymous

        SecurityIdentification

        SecurityImpersonation

        SecurityDelegation

    End Enum

    Public Enum TOKEN_TYPE
 

        TokenPrimary = 1
 

        TokenImpersonation

    End Enum
 

    Private Shared STANDARD_RIGHTS_REQUIRED As UInteger = 983040
 

    Private Shared STANDARD_RIGHTS_READ As UInteger = 131072
 

    Private Shared TOKEN_ASSIGN_PRIMARY As UInteger = 1
 

    Private Shared TOKEN_DUPLICATE As UInteger = 2
 

    Private Shared TOKEN_IMPERSONATE As UInteger = 4
 

    Private Shared TOKEN_QUERY As UInteger = 8
 

    Private Shared TOKEN_QUERY_SOURCE As UInteger = 16
 

    Private Shared TOKEN_ADJUST_PRIVILEGES As UInteger = 32
 

    Private Shared TOKEN_ADJUST_GROUPS As UInteger = 64
 

    Private Shared TOKEN_ADJUST_DEFAULT As UInteger = 128
 

    Private Shared TOKEN_ADJUST_SESSIONID As UInteger = 256
 

    Private Shared TOKEN_READ As UInteger = (STANDARD_RIGHTS_READ Or TOKEN_QUERY)

    Private Shared TOKEN_ALL_ACCESS As UInteger = (STANDARD_RIGHTS_REQUIRED _

                   Or (TOKEN_ASSIGN_PRIMARY _

                   Or (TOKEN_DUPLICATE _

                   Or (TOKEN_IMPERSONATE _

                   Or (TOKEN_QUERY _

                   Or (TOKEN_QUERY_SOURCE _

                   Or (TOKEN_ADJUST_PRIVILEGES _

                   Or (TOKEN_ADJUST_GROUPS _

                   Or (TOKEN_ADJUST_DEFAULT Or TOKEN_ADJUST_SESSIONID)))))))))
 

    ' Private Declare Auto Function CreateProcessAsUser Lib "advapi32.dll" (ByVal token As IntPtr, ByVal applicationName As String, ByVal commandLine As String, ByRef processAttributes As SECURITY_ATTRIBUTES, ByRef threadAttributes As SECURITY_ATTRIBUTES, ByVal inheritHandles As Boolean, ByVal creationFlags As UInteger, ByVal environment As IntPtr, ByVal currentDirectory As String, ByRef startupInfo As STARTUPINFO, ByRef processInformation As PROCESS_INFORMATION) As Boolean

    Private Declare Auto Function CreateProcessAsUser Lib "advapi32" ( _

      ByVal hToken As IntPtr, _

      ByVal strApplicationName As String, _

      ByVal strCommandLine As String, _

      ByRef lpProcessAttributes As SECURITY_ATTRIBUTES, _

      ByRef lpThreadAttributes As SECURITY_ATTRIBUTES, _

      ByVal bInheritHandles As Boolean, _

      ByVal dwCreationFlags As Integer, _

      ByVal lpEnvironment As IntPtr, _

      ByVal lpCurrentDriectory As String, _

      ByRef lpStartupInfo As STARTUPINFO, _

      ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean
 

    Public Declare Function DuplicateTokenEx Lib "advapi32.dll" (ByVal existingToken As IntPtr, ByVal desiredAccess As UInteger, ByVal tokenAttributes As IntPtr, ByVal impersonationLevel As SECURITY_IMPERSONATION_LEVEL, ByVal tokenType As TOKEN_TYPE, ByRef newToken As IntPtr) As Boolean

    Declare Function CreateEnvironmentBlock Lib "userenv.dll" (ByRef lpEnvironment As IntPtr, ByVal hToken As IntPtr, ByVal bInherit As Boolean) As Boolean

    Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As IntPtr) As Boolean

    Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
 

    Declare Function DestroyEnvironmentBlock Lib "userenv.dll" (ByVal lpEnvironment As IntPtr) As Boolean

    Private Const SW_SHOW As Short = 5

    Private Const SW_SHOWMAXIMIZED As Short = 7

    ' Private Const TOKEN_QUERY = 8

    'Private Const TOKEN_DUPLICATE = 2

    'Private Const TOKEN_ASSIGN_PRIMARY = 1

    Private Const GENERIC_ALL_ACCESS = 268435456

    Private Const STARTF_USESHOWWINDOW = 1

    Private Const STARTF_FORCEONFEEDBACK = 64

    Private Const CREATE_UNICODE_ENVIRONMENT = 1024

    Public Shared ErrStr As String = ""
 

    Private Shared Function LaunchProcessAsUser(ByVal cmdLine As String, ByVal _

      token As IntPtr, ByVal envBlock As IntPtr) As Boolean

        Dim result As Boolean = False

        Dim pi As PROCESS_INFORMATION = New PROCESS_INFORMATION

        Dim saProcess As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES

        Dim saThread As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES
 

        saProcess.nLength = Marshal.SizeOf(saProcess)

        saThread.nLength = Marshal.SizeOf(saThread)

        Dim si As STARTUPINFO = New STARTUPINFO

        si.cb = Marshal.SizeOf(si)

        'si.lpDesktop = "WinSta0\Default"

        si.lpDesktop = Nothing

        si.dwFlags = STARTF_USESHOWWINDOW Or STARTF_FORCEONFEEDBACK

        si.wShowWindow = SW_SHOW

        result = CreateProcessAsUser(token, cmdLine, "", saProcess, saThread, _

          False, CREATE_UNICODE_ENVIRONMENT, envBlock, Nothing, si, pi)

        If result = False Then

            Dim iError As Integer = Marshal.GetLastWin32Error

            ErrStr = String.Format("CreateProcessAsUser Error:" & _

              "{0}", iError)

            ' Debug.WriteLine(message)

        Else

            CloseHandle(token)

        End If

        Return result

    End Function
 

    Private Shared Function GetPrimaryToken(ByVal processId As Integer) As  _

      IntPtr

        Dim token As IntPtr = IntPtr.Zero

        Dim primaryToken As IntPtr = IntPtr.Zero

        Dim retVal As Boolean = False

        Dim p As Process = Nothing

        Try

            p = Process.GetProcessById(processId)

        Catch generatedExceptionVariable0 As ArgumentException

            Dim details As String = String.Format("ProcessID {0} Not" & _

              "Available", processId)

            Debug.WriteLine(details)

            Return primaryToken

        End Try

        retVal = OpenProcessToken(p.Handle, TOKEN_DUPLICATE, token)

        If retVal = True Then

            Dim sa As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES

            sa.nLength = Marshal.SizeOf(sa)

            retVal = DuplicateTokenEx(token, TOKEN_ASSIGN_PRIMARY Or _

              TOKEN_DUPLICATE Or TOKEN_QUERY, IntPtr.Zero, CType( _

              SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, Integer), _

              CType(TOKEN_TYPE.TokenPrimary, Integer), primaryToken)

            If retVal = False Then

                ErrStr = String.Format("DuplicateTokenEx Error:" & _

                  "{0}", Marshal.GetLastWin32Error)
 

                'Debug.WriteLine(message)

            End If

        Else

            ErrStr = String.Format("OpenProcessToken Error:" & _

              "{0}", Marshal.GetLastWin32Error)

            'Debug.WriteLine(message)

        End If

        Return primaryToken

    End Function
 

    Private Shared Function GetEnvironmentBlock(ByVal token As IntPtr) As IntPtr

        Dim envBlock As IntPtr = IntPtr.Zero

        Dim retVal As Boolean = CreateEnvironmentBlock(envBlock, token, False)

        If retVal = False Then

            Dim message As String = String.Format("CreateEnvironmentBlock" & _

              "Error: {0}", Marshal.GetLastWin32Error)

            ' Debug.WriteLine(message)

        End If

        Return envBlock

    End Function
 

    Public Shared Function Launch(ByVal appCmdLine As String) As Boolean

        Dim ret As Boolean = False

        Dim ps As Process() = Process.GetProcessesByName("explorer")

        Dim processId As Integer = -1

        If ps.Length > 0 Then

            processId = ps(0).Id

        End If

        If processId > 1 Then

            Dim token As IntPtr = GetPrimaryToken(processId)

            If Not (token.Equals(IntPtr.Zero)) Then

                Dim envBlock As IntPtr = GetEnvironmentBlock(token)

                ret = LaunchProcessAsUser(appCmdLine, token, envBlock)

                If Not (envBlock.Equals(IntPtr.Zero)) Then

                    DestroyEnvironmentBlock(envBlock)

                End If

            End If

        End If

        Return ret

    End Function

    Public Shared Function GetUserToken() As IntPtr

        ErrStr = ""

        Dim token As IntPtr

        Dim ps As Process() = Process.GetProcessesByName("explorer")

        Dim processId As Integer = -1

        If ps.Length > 0 Then

            processId = ps(0).Id

        End If

        If processId > 1 Then

            token = GetPrimaryToken(processId)
 

        End If
 

        Return token

    End Function
 

    Public Sub New()

        MyBase.New()

    End Sub

End Class

Open in new window

0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 25138086
lol, mlmcc
accepting a VB solution in a Delphi zone

ahh, there is general programming languages too
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
The purpose of this article is to demonstrate how we can use conditional statements using Python.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now