Solved

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

Posted on 2004-03-31
11
672 Views
Last Modified: 2008-02-01
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
Comment
Question by:Magadass
  • 7
  • 3
11 Comments
 

Author Comment

by:Magadass
ID: 10723960
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
 

Author Comment

by:Magadass
ID: 10724297
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
 
LVL 86

Expert Comment

by:jkr
ID: 10725700
The article lists only a new privilege - have you tried to grant that to the account your application is running under?
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 

Author Comment

by:Magadass
ID: 10726934
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
 

Author Comment

by:Magadass
ID: 10733625
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
 
LVL 86

Expert Comment

by:jkr
ID: 10734670
>>JKR have you been able to duplicate this?

Just me and a laptop with XP here at the moment, sorry :o)
0
 

Author Comment

by:Magadass
ID: 10735629
Microsoft VirtualPC is your friend :)
0
 

Author Comment

by:Magadass
ID: 10735632
I have opened a ticker with microsoft premier support, I will post the resolution as soon as I get one...
0
 

Accepted Solution

by:
Magadass earned 0 total points
ID: 10847331
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
 
LVL 86

Expert Comment

by:jkr
ID: 10847351
>>JKR please take notice to the gotchas at the bottom

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

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
SendMessage fails while PostMessage works 2 114
C Language combined operators 28 109
FMX enumerated colours 2 99
Add values of each row in an array 3 57
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question