|
-
Jul 20th, 2009, 02:38 AM
#1
Thread Starter
Fanatic Member
Impersonation
Hi,
Created a user i.e. UserA in the domain.
Added this user to the administrators group in serverA.
Using C#, I impersonate this user in my application.
Then using UserA, the application creates a vbscript on ServerA.
Problem is that the vbscript does not get run when I use the processstart call
The error is vbscript engine is not found.
Please note that if I log into the application using my credentials then all works fine and the script runs correctly on serverA.
Do you know why I get the below error if logged in as UserA?
I have also run regsvr32 vbscript on serverA but this does not help in the case of UserA
Error is:
Can not find script engine vbscript for script "path of the vbscript".
Thanks
-
Jul 20th, 2009, 05:35 AM
#2
Re: Impersonation
Can you post the code you are using to start this vbscript? Also, where are you saving it on the server - is it somewhere that the account you are running your program under will have access to?
-
Jul 20th, 2009, 07:22 AM
#3
Thread Starter
Fanatic Member
Re: Impersonation
I have now given userA exactly the same permissions to my login.
Still the same error
-
Jul 20th, 2009, 07:26 AM
#4
Re: Impersonation
OK, but you havent answered either of the things I asked in my previous post have you
-
Jul 20th, 2009, 07:33 AM
#5
Thread Starter
Fanatic Member
Re: Impersonation
Here it is
private void VBscriptExecuteAndReturn(string strServer, string strScript,
out string strResult, out string strResultFull)
{
string strSQATvbscript = @"\c$\VBscript.vbs";
string strTargetMachine = @"\\" + strServer;
string strTargetFullPath = strTargetMachine + strSQATvbscript;
//if it is selected to use an alternate user to run the checks, i.e. the Run as Check is checked...
//Attempt to impersonate specific user...
if (chkRunas.Checked == true)
{
newUser = this.ImpersonateUser(txtUsername.Text.Trim(), Environment.UserDomainName, txtPwd.Text.Trim());
}
try
{
//Create the scrip file on the remote machine so that it can be executed...
File.WriteAllText(strTargetFullPath, strScript);
}
catch (Exception ex)
{
//strResult = "";
strResult = "Access Denied to run the script.";
strResultFull = ex.Message;
//Delete the temporary created file...
System.IO.File.Delete(strTargetFullPath);
if (chkRunas.Checked == true)
{
newUser.Undo();
}
return;
}
string strScriptPath = strTargetFullPath;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cscript.exe";
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
try
{
process.Start();
}
catch (Exception ex)
{
File.Delete(strTargetFullPath);
strResult = "Can not execute script on target machine. ";
strResultFull = strResult + ex.Message;
return;
}
process.WaitForExit();
int exitCode = process.ExitCode;
string strOutput = process.StandardOutput.ReadToEnd();
strResult = strOutput;
process.Close();
//Pause for a few seconds so there is enough time for the temp file to be deleted...
System.Threading.Thread.Sleep(1000);
//Delete the temporary created file...
File.Delete(strTargetFullPath);
//This is the text that gets returned for all returned texts from the executed vbscript...
//Now get the actual text out of the retrieved text...
string strStandardText = "Microsoft (R) Windows Script Host Version 5.6\r\nCopyright (C) Microsoft Corporation 1996-2001. All rights reserved.";
int intStandardTextLength = strStandardText.Length;
strResultFull = strOutput.Substring(intStandardTextLength, strOutput.Length - intStandardTextLength);
//Pull out the value only...
strResult = strResultFull.Substring(strResultFull.IndexOf(":") + 2, strResultFull.Length - strResultFull.IndexOf(":") - 4);
//if it is selected to use an alternate user to run the checks, i.e. the Run as Check is checked...
//Now revert back to the original user...
if (chkRunas.Checked == true)
{
newUser.Undo();
}
}
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Attempts to impersonate a user. If successful, returns
/// a WindowsImpersonationContext of the new users identity.
/// </summary>
/// <param name="sUsername">Username you want to impersonate</param>
/// <param name="sDomain">Logon domain</param>
/// <param name="sPassword">User's password to logon with</param></param>
/// <returns></returns>
public WindowsImpersonationContext ImpersonateUser(string sUsername, string sDomain, string sPassword)
{
// initialize tokens
IntPtr pExistingTokenHandle = new IntPtr(0);
IntPtr pDuplicateTokenHandle = new IntPtr(0);
pExistingTokenHandle = IntPtr.Zero;
pDuplicateTokenHandle = IntPtr.Zero;
// if domain name was blank, assume local machine
if (sDomain == "")
sDomain = System.Environment.MachineName;
try
{
string sResult = null;
const int LOGON32_PROVIDER_DEFAULT = 0;
// create token
const int LOGON32_LOGON_INTERACTIVE = 2;
//const int SecurityImpersonation = 2;
// get handle to token
bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
// did impersonation fail?
if (false == bImpersonated)
{
int nErrorCode = Marshal.GetLastWin32Error();
sResult = "LogonUser() failed with error code: " + nErrorCode + "\r\n";
// show the reason why LogonUser failed
MessageBox.Show(this, sResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Get identity before impersonation
sResult += "Before impersonation: " + WindowsIdentity.GetCurrent().Name + "\r\n";
bool bRetVal = DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle);
// did DuplicateToken fail?
if (false == bRetVal)
{
int nErrorCode = Marshal.GetLastWin32Error();
CloseHandle(pExistingTokenHandle); // close existing handle
sResult += "DuplicateToken() failed with error code: " + nErrorCode + "\r\n";
// show the reason why DuplicateToken failed
MessageBox.Show(this, sResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
else
{
// create new identity using new primary token
WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
// check the identity after impersonation
//sResult += "After impersonation: " + WindowsIdentity.GetCurrent().Name + "\r\n";
//MessageBox.Show(this, sResult, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
return impersonatedUser;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
// close handle(s)
if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}
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
|