-
Jan 11th, 2011, 07:29 AM
#1
Thread Starter
Fanatic Member
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:
Dim iu As New ImpersonateUser
' Note: This user must be the user that installed ReaConverter Pro otherwise each image
' will be stampted with a ReaConverter logo. This is a limitation of the evaluation/trial version.
' impersonateValidUser(username, domain, password)
If iu.impersonateValidUser("myusername", "mydomain", "mypassword") = True Then
Call cFunctions.WriteToFile("Impersonating user succeeded!", False, Application("LogFilePath"), Application("LogFile"))
Try
' Execute the command
' http://stackoverflow.com/questions/206323/how-to-execute-command-line-in-c-get-std-out-results
Dim oProcess As System.Diagnostics.Process = New System.Diagnostics.Process
Dim strCmd As String = sOutputFolderPath.Replace("\pdf", "") & "ReaConvertFile.cmd" ' path and file name of command to run
With oProcess
.StartInfo.FileName = strCmd
.StartInfo.UseShellExecute = False
.StartInfo.RedirectStandardInput = True
.StartInfo.RedirectStandardOutput = True
' Start the process
.Start()
Dim strOutput As String = .StandardOutput.ReadToEnd
' Wait for process to finish
oProcess.WaitForExit(2000) '5000
If .HasExited = False Then .Kill()
.Close()
End With
sFN = System.IO.Path.GetFileNameWithoutExtension(sFilePath)
sFilePath = System.IO.Path.Combine(sOutputFolderPath.Replace("\pdf", ""), sFN & ".jpg")
'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")
Call cFunctions.WriteToFile("Success converted image to JPG: " & sFilePath & vbNewLine)
Catch ex As Exception
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")
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"))
End Try
' Finish Impersonating here
iu.undoImpersonation()
Else
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")
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"))
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.
-
Jan 11th, 2011, 09:02 AM
#2
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
-
Jan 11th, 2011, 09:27 AM
#3
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 -
-
Jan 11th, 2011, 09:44 AM
#4
Thread Starter
Fanatic Member
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?
-
Jan 11th, 2011, 10:00 AM
#5
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 -
-
Jan 11th, 2011, 10:45 AM
#6
Thread Starter
Fanatic Member
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.
-
Mar 4th, 2011, 11:39 AM
#7
Junior Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|