Results 1 to 7 of 7

Thread: Execute bat/cmd with a different user

  1. #1

    Thread Starter
    Fanatic Member aconybeare's Avatar
    Join Date
    Oct 2001
    Location
    UK
    Posts
    772

    Execute bat/cmd with a different user

    Hi,

    I'm trying to execute a cmd file with a different user but what I have isn't working the log in returns true but the command doesn't run

    vb Code:
    1. Dim iu As New ImpersonateUser
    2. ' Note:  This user must be the user that installed ReaConverter Pro otherwise each image
    3. ' will be stampted with a ReaConverter logo. This is a limitation of the evaluation/trial version.
    4. ' impersonateValidUser(username, domain, password)
    5. If iu.impersonateValidUser("myusername", "mydomain", "mypassword") = True Then
    6.     Call cFunctions.WriteToFile("Impersonating user succeeded!", False, Application("LogFilePath"), Application("LogFile"))
    7.     Try
    8.         ' Execute the command
    9.         ' http://stackoverflow.com/questions/206323/how-to-execute-command-line-in-c-get-std-out-results
    10.         Dim oProcess As System.Diagnostics.Process = New System.Diagnostics.Process
    11.         Dim strCmd As String = sOutputFolderPath.Replace("\pdf", "") & "ReaConvertFile.cmd" ' path and file name of command to run
    12.         With oProcess
    13.             .StartInfo.FileName = strCmd
    14.             .StartInfo.UseShellExecute = False
    15.             .StartInfo.RedirectStandardInput = True
    16.             .StartInfo.RedirectStandardOutput = True
    17.             ' Start the process
    18.             .Start()
    19.             Dim strOutput As String = .StandardOutput.ReadToEnd
    20.             ' Wait for process to finish
    21.             oProcess.WaitForExit(2000) '5000
    22.             If .HasExited = False Then .Kill()
    23.             .Close()
    24.         End With
    25.         sFN = System.IO.Path.GetFileNameWithoutExtension(sFilePath)
    26.         sFilePath = System.IO.Path.Combine(sOutputFolderPath.Replace("\pdf", ""), sFN & ".jpg")
    27.  
    28.         'Call cFunctions.SendMail(Server.MachineName & " - Success converted image to JPG", "Converted image to JPG: \\" & Server.MachineName & "\" & sFilePath.Replace(":", "") & vbNewLine, sSupportEmails, sSupportNames, "PDFConverter@portlandpress.com", "PDF Conversion Service")
    29.         Call cFunctions.WriteToFile("Success converted image to JPG: " & sFilePath & vbNewLine)
    30.     Catch ex As Exception
    31.         Call cFunctions.SendMail(Server.MachineName & " - Failed to convert image to JPG", "File path: \\" & Server.MachineName & "\" & sFilePath.Replace(":", "") & vbNewLine & ex.Message & vbNewLine & ex.StackTrace & vbNewLine, sSupportEmails, sSupportNames, "PDFConverter@portlandpress.com", "PDF Conversion Service")
    32.         Call cFunctions.WriteToFile("Failed to convert image to JPG" & vbNewLine & "File path: " & sFilePath & vbNewLine & ex.Message & vbNewLine & ex.StackTrace & vbNewLine, False, Application("LogFilePath"), Application("LogFile"))
    33.     End Try
    34.     ' Finish Impersonating here
    35.     iu.undoImpersonation()
    36. Else
    37.     Call cFunctions.SendMail(Server.MachineName & " - Failed to impersonate user", "Error: converting image to JPG - failed to impersonate user!" & vbNewLine & vbNewLine & "File path: \\" & Server.MachineName & "\" & sFilePath.Replace(":", "") & vbNewLine, sSupportEmails, sSupportNames, "PDFConverter@portlandpress.com", "PDF Conversion Service")
    38.     Call cFunctions.WriteToFile("Failed to impersonate user" & vbNewLine & "Error: converting image to JPG - failed to impersonate user!" & vbNewLine & "File path: " & sFilePath, False, Application("LogFilePath"), Application("LogFile"))
    39. End If

    If I remove the impersonation stuff the command executes but my images are stamped with the coversion tools logo which is a limitation of the trial version. The image conversion tool needs to be run by the user that installed and registered it. I'm confident that the impersonation works as I use this class to copy files accross the network in other areas of my applicaiton.

    The command file is also okay because if I manually run the command file (ReaConvertFile.cmd) the image file is converted.

    I know that the licence is installed correctly because if I log into the server as the relevant user and run the conversion tool manually (through the GUI or manually execute the .cmd file) the files convert and are not stamped with the conversion tools logo.

    I think something is missing the correct permissions? I tried giving my user full control of ...\system32\cmd.exe but that didn't help????

    Any thoughts or ideas will be greatly appreciated.
    Last edited by aconybeare; Jan 11th, 2011 at 07:41 AM. Reason: Fixed gramma.

  2. #2
    Frenzied Member
    Join Date
    Jan 2010
    Location
    Connecticut
    Posts
    1,687

    Re: Execute bat/cmd with a different user

    Perhaps it has protection built in where it gets the user who is logged on and ignores who it is running under. You can test that by logging on as the user who it is registered to and try to impersonate someone else and see what happens.
    VB6 Library

    If I helped you then please help me and rate my post!
    If you solved your problem, then please mark the post resolved

  3. #3
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: Execute bat/cmd with a different user

    Does it work when you do a "runas" manually?
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  4. #4

    Thread Starter
    Fanatic Member aconybeare's Avatar
    Join Date
    Oct 2001
    Location
    UK
    Posts
    772

    Re: Execute bat/cmd with a different user

    Thanks for your replies

    Stanav; Nice idea, do you know how to access the RunAs command, I'm using a win 2003 server for this. The secondary logon service is running but when I right click or shift right click the .cmd file the RunAs option isn't available?

  5. #5
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: Execute bat/cmd with a different user

    You just open command prompt and type "runas /?" then hit enter. It will show you the help menu of runas command and you can go from there. Basically, if you want to run notepad using someuser's credentials, you do this:
    Code:
    runas /user:domainname\someuser "notepad"
    It will ask for the password after you hit enter in the command above....

    Now, if this test is working, there is a version of runas you can find on the internet that let you specify the password as one of the arguments (The windows builtin runas doesn't let you specify a password - only the username. It then will prompt for the password when the command is executed... Thus this requires human interaction. And that's why you can't use the windows builtin runas command if you want to automate your program launches.)
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  6. #6

    Thread Starter
    Fanatic Member aconybeare's Avatar
    Join Date
    Oct 2001
    Location
    UK
    Posts
    772

    Re: Execute bat/cmd with a different user

    Stanav,

    Thanks for the pointer.

    I've logged into the server and run it as you suggested but it's not executing. Password is okay because I deliberately put in an incorrect password and it complained.

    I've now created a service and told it to run under my user, dumped my .cmd file into the watched folder and it's run it correctly.

    Think I'm going to have to go with this option, just monitor this folder (the service removes the cmd once it's run) do while file.exists("...\myconversion.cmd")=true. Once the cmd file has been moved then I know that the image should have been converted. Not ideal and very dirty as the service only runs/checks the watched folder every 90 seconds or so. Hey ho!!

    Edit: I've just tried the RunAs command on a cmd file with just the following in it and it doesn't work

    Code:
    echo %username% >> "c:\temp\mylog.log"
    So it appears to me as though this isn't specific to the image convert program
    Last edited by aconybeare; Jan 11th, 2011 at 11:15 AM.

  7. #7
    Junior Member
    Join Date
    May 2010
    Posts
    27

    Re: Execute bat/cmd with a different user

    1. This is the code that i have used to impersonate user in a project:
    Code:
    Public Class AliasAccount
        Private _username, _password, _domainname As String
    
        Private _tokenHandle As New IntPtr(0)
        Private _dupeTokenHandle As New IntPtr(0)
        Private _impersonatedUser As System.Security.Principal.WindowsImpersonationContext
    
    
        Public Sub New(ByVal username As String, ByVal password As String)
            Dim nameparts() As String = username.Split("\")
            If nameparts.Length > 1 Then
                _domainname = nameparts(0)
                _username = nameparts(1)
            Else
                _username = username
            End If
            _password = password
        End Sub
    
        Public Sub New(ByVal username As String, ByVal password As String, ByVal domainname As String)
            _username = username
            _password = password
            _domainname = domainname
        End Sub
    
    
        Public Sub BeginImpersonation()
            Const LOGON32_PROVIDER_DEFAULT As Integer = 0
            Const LOGON32_LOGON_INTERACTIVE As Integer = 2
            Const SecurityImpersonation As Integer = 2
    
            Dim win32ErrorNumber As Integer
    
            _tokenHandle = IntPtr.Zero
            _dupeTokenHandle = IntPtr.Zero
    
            If Not LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, _tokenHandle) Then
                win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
                Throw New ImpersonationException(win32ErrorNumber, GetErrorMessage(win32ErrorNumber), _username, _domainname)
            End If
    
            If Not DuplicateToken(_tokenHandle, SecurityImpersonation, _dupeTokenHandle) Then
                win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
    
                CloseHandle(_tokenHandle)
                Throw New ImpersonationException(win32ErrorNumber, "Unable to duplicate token!", _username, _domainname)
            End If
    
            Dim newId As New System.Security.Principal.WindowsIdentity(_dupeTokenHandle)
            _impersonatedUser = newId.Impersonate()
        End Sub
    
    
        Public Sub EndImpersonation()
            If Not _impersonatedUser Is Nothing Then
                _impersonatedUser.Undo()
                _impersonatedUser = Nothing
    
                If Not System.IntPtr.op_Equality(_tokenHandle, IntPtr.Zero) Then
                    CloseHandle(_tokenHandle)
                End If
                If Not System.IntPtr.op_Equality(_dupeTokenHandle, IntPtr.Zero) Then
                    CloseHandle(_dupeTokenHandle)
                End If
            End If
        End Sub
    
    
        Public ReadOnly Property username() As String
            Get
                Return _username
            End Get
        End Property
    
        Public ReadOnly Property domainname() As String
            Get
                Return _domainname
            End Get
        End Property
    
    
        Public ReadOnly Property currentWindowsUsername() As String
            Get
                Return System.Security.Principal.WindowsIdentity.GetCurrent().Name
            End Get
        End Property
    
    
    #Region "Exception Class"
        Public Class ImpersonationException
            Inherits System.Exception
    
            Public ReadOnly win32ErrorNumber As Integer
    
            Public Sub New(ByVal win32ErrorNumber As Integer, ByVal msg As String, ByVal username As String, ByVal domainname As String)
                MyBase.New(String.Format("Impersonation of {1}\{0} failed! [{2}] {3}", username, domainname, win32ErrorNumber, msg))
                Me.win32ErrorNumber = win32ErrorNumber
            End Sub
        End Class
    #End Region
    
    
    #Region "External Declarations and Helpers"
        Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
                ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
                ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
                ByRef phToken As IntPtr) As Boolean
    
    
        Private Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _
                    ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
                    ByRef DuplicateTokenHandle As IntPtr) As Boolean
    
    
        Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
    
    
        <System.Runtime.InteropServices.DllImport("kernel32.dll")> _
        Private Shared Function FormatMessage(ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _
                ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByRef lpBuffer As [String], _
                ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
        End Function
    
    
        Private Function GetErrorMessage(ByVal errorCode As Integer) As String
            Dim FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
            Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
            Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
    
            Dim messageSize As Integer = 255
            Dim lpMsgBuf As String
            Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS
    
            Dim ptrlpSource As IntPtr = IntPtr.Zero
            Dim prtArguments As IntPtr = IntPtr.Zero
    
            Dim retVal As Integer = FormatMessage(dwFlags, ptrlpSource, errorCode, 0, lpMsgBuf, messageSize, prtArguments)
            If 0 = retVal Then
                Throw New System.Exception("Failed to format message for error code " + errorCode.ToString() + ". ")
            End If
    
            Return lpMsgBuf
        End Function
    
    
    End Class
    2. i don't know exactly how your .cmd works, but you could try a Scheduled Tasks and run it with admin rights

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width