Impersonation not working

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I have a desktop app that uses Win32 TaskScheduler to create scheduled tasks. The code which creates the task is called
when the currently logged in user logs off. This user will not be admin on the PC (only domain user) so seeing as the code is running under the users profile, the code must have the proper priveleges to create Scheduled Tasks (I was getting
an access denied exception when RegisterTaskDefinition was called).<br/>
No problem I said; I can get around this by using Impersonations (see code below) and impersonate this user. I created a user on the domain called TaskScheduler and made it domain admin (this user has rights to create scheduled tasks).<br/>
The code is definitley working as the message boxes I have put in that appear after impersonation show the user name "TaskScheduler" (the code now "thinks" TaskScheduler is the logged in user)
As you can see from the code below
1. I use LogonUser (logging on as the TaskScheduler user) to get a
token
2. I use WindowsIdentity to create a new WindowsIdentity . I pass the token I have created into that new
WindowsIdentity.
3. I then use that WindowsIdentity to call CreateProcessAsUser.
The variable returnValue below is "true" in the messagebox when the call to
LogonUser is executed and when I call CreateProcessAsUser the variable result
is true also.<br/>

However I still get an access denied error even under impersonation.<br/>
Can anyone help?
<br/>

<pre class="prettyprint try
{
TaskDefinition tdall = ts.NewTask();
DailyTrigger dtall = new DailyTrigger();

string userName, domainName;
domainName = "domain.com";
userName = "TaskScheduler";

const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_NETWORK = 3;
IntPtr token = IntPtr.Zero;
bool returnValue = LogonUser(userName, domainName, "password", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, out token);
WindowsIdentity ID = new WindowsIdentity(token);


MessageBox.Show("returnValue is " + returnValue.ToString());


if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
//MessageBox.Show("FAILED");
throw new System.ComponentModel.Win32Exception(ret);
}




else
{

//MessageBox.Show("Did LogonUser Succeed? " + returnValue.ToString());

bool result = false;

//MessageBox.Show("Before impersonation: " + WindowsIdentity.GetCurrent().Name.ToString());
CloseHandle(token);
/*Now impersonate the ID.*/
ID.Impersonate();
SECURITY_ATTRIBUTES procAttrs = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES threadAttrs = new SECURITY_ATTRIBUTES();
IntPtr pNewEnvironmentBlock = new IntPtr();
STARTUPINFO startupInfo = new STARTUPINFO();
PROCESS_INFORMATION _processInfo = new PROCESS_INFORMATION();


using (ID)
{




// MessageBox.Show(@"C:Program FilesApplicationPathApplication.exe");
result = CreateProcessAsUser(token, @"C:Program FilesApplicationPathApplication.exe", null,
ref procAttrs, ref threadAttrs, false, 0x00000400,
pNewEnvironmentBlock, null, ref startupInfo, ref _processInfo);

if (!result)
{



Logger.append("Marshal " + Marshal.GetLastWin32Error().ToString(), Logger.ALL);
}
else
{
MessageBox.Show("marshal is " + result.ToString());

}

MessageBox.Show("After impersonation: " + WindowsIdentity.GetCurrent().Name.ToString());







tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();

// tdall.Principal.LogonType = TaskLogonType.;



tdall.Principal.UserId = WindowsIdentity.GetCurrent().Name;



// Add a trigger that will fire the task at this time every day
dtall = (DailyTrigger)tdall.Triggers.Add(new DailyTrigger { DaysInterval = 1 });


dtall.StartBoundary = schtime;


tdall.Actions.Add(new ExecAction("psshutdown.exe", "-d -accepteula", @"C:folderApp_Files"));

i++;





try
{
string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();



ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.Create, System.Security.Principal.WindowsIdentity.GetCurrent().Name, null, TaskLogonType.InteractiveToken);








}
catch (Exception t)
{
Logger.append("t is " + t.Message + Environment.NewLine + t.StackTrace, Logger.ALL);
MessageBox.Show("t is : " + t.Message.ToString() + t.StackTrace.ToString());
}
}
}

}
catch (Exception j)
{
Logger.append("j is " + j.Message + Environment.NewLine + j.StackTrace, Logger.ALL);
// MessageBox.Show("j is " + j.ToString());
}[/code]
<br/>
<br/>


View the full article
 
Back
Top