Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

C# Impersonation not working

Options
  • 25-10-2012 9:41am
    #1
    Registered Users Posts: 4,010 ✭✭✭


    I have a desktop app that uses Win32 TaskScheduler to create scheduled tasks. The scheduled task I am creating needs to have the box "run with highest priveleges" ticked. 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 user's profile, the code does not have the proper priveleges to tick this box (I was getting an access denied exception when RegisterTaskDefinition was called)
    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).
    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)
    However I still get an access denied error even under impersonation.
    Can anyone help?
     {
                            try
                            {
                                TaskDefinition tdall = ts.NewTask();
                                DailyTrigger dtall = new DailyTrigger();
                                SafeTokenHandle safeTokenHandle;
                                string userName, domainName;
                                domainName = "[B]domainname[/B]";
                               [B] userName = "TaskScheduler";[/B]
    
                                const int LOGON32_PROVIDER_DEFAULT = 0;
                                //This parameter causes LogonUser to create a primary token. 
                                const int LOGON32_LOGON_INTERACTIVE = 2;
    
                                bool returnValue = LogonUser(userName, domainName, "[B]password[/B]",
                    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                    out safeTokenHandle);
    
                                if (false == returnValue)
                                {
                                    int ret = Marshal.GetLastWin32Error();
                                    MessageBox.Show("FAILED");
                                    throw new System.ComponentModel.Win32Exception(ret);
                                }
    
    
    
    
                                using (safeTokenHandle)
                                {
                                    MessageBox.Show("Did LogonUser Succeed? " + returnValue.ToString());
    
    
    
                                    MessageBox.Show("Before impersonation: " + WindowsIdentity.GetCurrent().Name.ToString());
    
                                    using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                                    {
    
                                        MessageBox.Show("After impersonation: " + WindowsIdentity.GetCurrent().Name.ToString());
    
    
    
    
    
    
                                       
                                            tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();
                                        
                                            tdall.Principal.LogonType = TaskLogonType.S4U;
    
                                        
                                       
                                            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:\EnergyWatchIT\App_Files\"));
    
                                            i++;
    
    
    
                                       
    
                                        try
                                        {
                                            string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();
    
    
    
                                            ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.Create, WindowsIdentity.GetCurrent().Name.ToString());
    
    
    
    
    
    
    
    
                                        }
                                        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());
                            }
                        }
    
    
    


Comments

  • Moderators, Society & Culture Moderators Posts: 9,689 Mod ✭✭✭✭stevenmu


    What version of Windows is it running on, if it's Vista or later and if UAC is enabled then I think you'll still get an access denied error.


  • Registered Users Posts: 4,010 ✭✭✭lukin


    stevenmu wrote: »
    What version of Windows is it running on, if it's Vista or later and if UAC is enabled then I think you'll still get an access denied error.

    Windows 7, even if I lower UAC down to the lowest, I still get the error (I don't reboot after I do it as that's not the way the app is supposed to work in reality). At present I am messing about with CreateProcessAsUser but that isn't working either.

    Edit:
    From what I have read I need to obtain the user token that you want to start the code as (I think I have done this above). However that doesn't seem to be enough as once I have the token I have to use CreateProcessAsUser after.


Advertisement