Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 685
  • Last Modified:

Question for JKR, ImpersonateInteractiveUser() does not work after SP4...

JKR or to whom anyone who has an answer,

About 1 week ago I posted a question asking how to impersonate the interactive user so I could launch a process that wrote to the users desktop.  Well during testing I was getting some inconsistent results, after an extremely long amount of testing I figured out it was Windows 2000 SP4 breaks it, most likely its something microsoft has tightened down on to make the system more secure, I believe my weakness relies in how I am obtaining the Process ID of the interactive user, however I have not done enough testing to verify this.  The below code is the ENTIRE snippet I am using to Impersonate the interactive user.  Do you have any information regarding any new methods of doing this after SP4?

NOTE: Works fine in WindowsXP with all SP/Patches...

DWORD ImpersonateInteractiveUser()  //Impersonates the logged in user to create an instance in the users context...
{
      HANDLE hToken = NULL;                
      HANDLE hProcess = NULL;

      DWORD processID = GetExplorerProcessID();
      if( processID)
      {
            hProcess =
                  OpenProcess(  
                  PROCESS_ALL_ACCESS,
                  TRUE,
                  processID );

            if( hProcess)
            {
                  if( OpenProcessToken(
                        hProcess,
                        TOKEN_EXECUTE |
                        TOKEN_READ |
                        TOKEN_QUERY |
                        TOKEN_ASSIGN_PRIMARY |
                        TOKEN_QUERY_SOURCE |
                        TOKEN_WRITE |
                        TOKEN_DUPLICATE,
                        &hToken))
                  {
                        ImpersonateLoggedOnUser( hToken);
                        CloseHandle( hToken );
                  }
                  CloseHandle( hProcess );
            }
      }
      return processID;
}

DWORD GetExplorerProcessID()  //Needed to impersonate the logged in user...
{
      HANDLE hSnapshot;
      PROCESSENTRY32 pe32;
      ZeroMemory(&pe32,sizeof(pe32));
      DWORD temp = NULL;

      try
      {
            hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);

            pe32.dwSize = sizeof(PROCESSENTRY32);

            if(Process32First(hSnapshot,&pe32))
            {
                  do
                  {
                        if(!strcmp(pe32.szExeFile,"explorer.exe"))
                        {
                              temp = pe32.th32ProcessID;
                              break;
                        }

                  }while(Process32Next(hSnapshot,&pe32));
            }
      }
      catch(...)
      {
            StopService();
      }
      return temp;
}
0
Magadass
Asked:
Magadass
  • 7
  • 3
1 Solution
 
MagadassAuthor Commented:
I believe I answered my own question:

http://support.microsoft.com/default.aspx?kbid=821546

But have yet to get this to make it work, but it does appear there are changes...
0
 
MagadassAuthor Commented:
OK I cannot get these changes to make this work, perhaps this is only part of the solution maybe something has to be changed in the code as well?
0
 
jkrCommented:
The article lists only a new privilege - have you tried to grant that to the account your application is running under?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
MagadassAuthor Commented:
Yes it does not fix it...  I have tested the code also, everything is returning successful... Have no idea why its not working....According to the article it should work if I change the policy...

0
 
MagadassAuthor Commented:
JKR have you been able to duplicate this?  This is a serious issue for me and all of the microsoft documentation I find says that changing this policy should correct the proble.  However it does not!!  
0
 
jkrCommented:
>>JKR have you been able to duplicate this?

Just me and a laptop with XP here at the moment, sorry :o)
0
 
MagadassAuthor Commented:
Microsoft VirtualPC is your friend :)
0
 
MagadassAuthor Commented:
I have opened a ticker with microsoft premier support, I will post the resolution as soon as I get one...
0
 
MagadassAuthor Commented:
I have resolved this issue with the support from Microsoft Premier Support, JKR please take notice to the gotchas at the bottom.  The method for obtaining the PID of explorer.exe will not work within terminal services, also the impersonation code you provided to me is still functioning after SP4, it was part of my code that needed to be resolved, you have to use CreateProcessAsUser now due to security restrictions microsoft is implementing to make windows more secure in nature.

Hi Eric,

I have been in discussions with #### in regards to your issue with SHAppBarMessage().  Based on the information, I have reviewed, Are you doing the following:


1. The AppBarUI Application is being launched by the service with CreateProcess().  

2. Before calling CreateProcess(), you obtain the token of explorer and impersonate the Explorer (the "Interactive User").  

3. The assumption is that the AppBarUI will run in the security context of the "Interactive User".

 

The assumption is not correct, the AppBarUI will run under the context of the calling process which in this case is the service running in the LocalSystem security context.

 

You will need to launch the process with CreateProcessAsUser() using the token obtained from ImpersonateInteractiveUser().  You won't have to worry about security to winsta0\default since the security has already been granted for the "Interactive User".

 

The code will look like:

 

si.cb = sizeof(si);
si.lpDesktop = "winsta0\\default";

 

CreateProcessAsUser(hToken, ....);

 

This code will make AppBarUI run in the same security context as the "Interactive User".  

 

I'm assuming you are not running on Terminal Server and you have found the correct explorer.exe for the "Interactive User".  

 

I would also like to mention that we don't recommend launching interactive processes from a service.  The preferable solution would be to have a background process launched by the "interactive user" which would communicate with the service and the background process would launch processes on behalf of the service.

 

Another alternative would be to use the CreateProcessWithLogonW() API but this requires the password of the "Interactive User".  On Windows Server 2003, we do have the API CreateProcessWithTokenW which does accept a token. [but there is an issue with calling this API from the LocalSystem Security Context, this also applies to CreateProcessWithLogonW()]  The only reason I recommend these APIs is that they properly deal with the issues of launching processes interactively.

GOTCHAS:

1. The technique for obtaining the PID for explorer.exe is NOT robust.  The code doesn't take into account the possiblity of multiple instances of explorer.exe running on the system under different security contexts.  A simple example of this scenario is terminal server.

2. Services should not be launching interactive processes in general.  This will not be supported in the future.  If it is necessary to launch a process from a service, CreateProcessWithLogonW() or CreateProcessWithTokenW() would be better.



0
 
jkrCommented:
>>JKR please take notice to the gotchas at the bottom

Thank you *very* much for sharing this insight!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now