views:

1319

answers:

2

I have an application that is running as normal user, and a service running as local system. I want the application to be able to tell the service to start the application again, once the service has done some other stuff. (So the application will not be running while the service is doing it's "thing".) In order for the service to be able to start the application as the user that first started it, it needs a user token. The application sends the token to the service before it quits, but the token/handle is invalid when the service is trying to use it. (First thing it does with it is DuplicateTokenEx to get a primary token.)

Is a user token always only valid in the process that called OpenProcessToken?

Is there some other way this could be done? I don't want the user having to "log on" to the application with logonuser. That would just be silly. I guess I could hand over a process handle for "explorer.exe" from the app to the service, which the service could use to get a user token, but that would require PROCESS DUP HANDLE access right. I'm not thrilled about that solution, but maybe it's the way to do it?

+2  A: 

Take a look here:

Koistya Navin
Thanks, I'm going with the first article, creating a token with ZwCreateToken. It's a bit messy to pack all the stuff I need in a message, but has apparently worked for others..
Björn
The first article appears to have some errors, the second looks quite good. But I'm not sure why you would use ZwCreateToken (an undocumented, unsupported and not altogether stable method) when there are documented methods of doing what you want.
Stephen Martin
Sorry, I meant second. Couldn't even find the first. I'm doing something like http://www.apnilife.com/E-Books_apnilife/Windows%20Programming_apnilife/Windows%20NT%20Undocumented%20APIs/1996%20Ch08_apnilife.pdf.Are you refering to CreateToken?
Björn
+2  A: 

You have multiple issues here so I'll try to address them separately and you can correct me if I have misunderstood:

  1. You appear to have a service and a user application that cannot execute certain functionality at the same time. In order to achieve this you have the service stop the application, execute the special functionality, then restart the application. If this is correct then, in my opinion, you have a design flaw. Rather than stopping, then restarting the application you should be coordinating access to the shared resource through mutual exclusion using a named mutex and/or using an IPC method such as named pipes to communicate intentions.

  2. Is a user token always only valid in the process that called OpenProcessToken? Yes, the token handle you received is an index into the handle table of the process, it is not directly transferable. You would need to use DuplicateHandle which may be what you want but could be messy.

  3. You wish to find the best way to get the user's token to launch the application into the user's (interactive?) session. If this is the case, the best way is to retrieve the user's session token and use that. You can check out this article and the sample code, it's in C# but should be relatively easy to transfer to your language of choice.

EDIT: Updated to include Windows 2000. Since you are running the service under the SYSTEM account it can open a handle to the process itself (if necessary the process can send its process ID). It can then open the token attached to that process, duplicate it and use the resultant token to launch (or re-launch) the target application.

Stephen Martin
1. Might seem like a design flaw. The thing is, the service might want to upgrade the application: it might not even be the same application that should be launched.2. Agreed, it is. I'll try to create a new token instead.3. Must work on 2000, forgot to mention that...
Björn
Why does the service not just call OpenProcessToken and DuplicateTokenEx itself rather than having the process send something to the service?
Stephen Martin
Wouldn't the created process be run as local system in that case? If I do that I might just as well call CreateProcess and not bother with user tokens at all.
Björn
Just saw the edit. That seems like a good idea. I'll try that once I failed creating a token from scratch:)
Björn