2009-04-07 47 views
5

Tengo una aplicación que se ejecuta como usuario normal y un servicio que se ejecuta como sistema local. Quiero que la aplicación pueda decirle al servicio que vuelva a iniciar la aplicación, una vez que el servicio haya hecho otras cosas. (De modo que la aplicación no se ejecutará mientras el servicio lo está haciendo). Para que el servicio pueda iniciar la aplicación como el usuario que la inició por primera vez, necesita un token de usuario. La aplicación envía el token al servicio antes de que se cierre, pero el token/handle no es válido cuando el servicio intenta usarlo. (Lo primero que hace con él es DuplicateTokenEx para obtener un token primario.)¿Cómo obtengo un token de usuario válido para CreateProcessAsUser?

¿Es un token de usuario siempre solo válido en el proceso que llamó OpenProcessToken?

¿Hay alguna otra manera de que esto se pueda hacer? No quiero que el usuario tenga que "iniciar sesión" en la aplicación con logonuser. Eso sería simplemente tonto. Supongo que podría entregar un identificador de proceso para "explorer.exe" de la aplicación al servicio, que el servicio podría usar para obtener un token de usuario, pero eso requeriría el derecho PROCESS DUP HANDLE. No estoy entusiasmado con esa solución, pero tal vez es la forma de hacerlo?

Respuesta

2
+0

Gracias, voy con el primer artículo, creando un token con ZwCreateToken. Es un poco complicado empacar todo lo que necesito en un mensaje, pero aparentemente ha funcionado para otros ... –

+0

El primer artículo parece tener algunos errores, el segundo parece bastante bueno.Pero no estoy seguro de por qué usaría ZwCreateToken (un método no documentado, no compatible y no del todo estable) cuando existen métodos documentados para hacer lo que desea. –

+0

Lo siento, quise decir segundo. Ni siquiera pude encontrar el primero. Estoy haciendo algo como http://www.apnilife.com/E-Books_apnilife/Windows%20Programming_apnilife/Windows%20NT%20Undocumented%20APIs/1996%20Ch08_apnilife.pdf. ¿Está refiriéndose a CreateToken? –

3

Tiene varias cuestiones aquí, así que voy a tratar de abordarlos por separado y que me puedo corregir si he entendido bien:

  1. Parece que tiene un servicio y una aplicación de usuario que no puede ejecutar ciertas funcionalidades al mismo tiempo. Para lograr esto, tiene el servicio detener la aplicación, ejecutar la funcionalidad especial, luego reiniciar la aplicación. Si esto es correcto, entonces, en mi opinión, tiene un defecto de diseño. En lugar de detenerse, entonces, al reiniciar la aplicación, debe coordinar el acceso al recurso compartido a través de la exclusión mutua utilizando un mutex con nombre y/o utilizando un método IPC como canalizaciones con nombre para comunicar intenciones.

  2. ¿Un token de usuario siempre solo es válido en el proceso llamado OpenProcessToken? Sí, el identificador del token que recibió es un índice en la tabla de manejo del proceso, no es directamente transferible. Tendría que usar DuplicateHandle, que puede ser lo que quiere, pero podría ser complicado.

  3. Desea encontrar la mejor manera de obtener el token del usuario para iniciar la aplicación en la sesión del usuario (¿interactiva?). Si este es el caso, la mejor manera es recuperar el token de sesión del usuario y usarlo. Puede consultar this article y el código de muestra, está en C# pero debería ser relativamente fácil de transferir a su idioma de elección.

EDIT: Se ha actualizado para incluir Windows 2000. Dado que se está ejecutando el servicio bajo el sistema de cuenta se puede abrir un identificador para el proceso en sí mismo (si es necesario el proceso puede enviar su ID de proceso). Luego puede abrir el token adjunto a ese proceso, duplicarlo y usar el token resultante para iniciar (o relanzar) la aplicación de destino.

+0

1. Puede parecer un defecto de diseño. El caso es que el servicio podría querer actualizar la aplicación: es posible que ni siquiera sea la misma aplicación que se debe iniciar. 2. De acuerdo, lo es. Intentaré crear un nuevo token en su lugar. 3. Debe funcionar en 2000, se olvidó de mencionar que ... –

+0

¿Por qué el servicio no solo llama a OpenProcessToken y DuplicateTokenEx en lugar de hacer que el proceso envíe algo al servicio? –

+0

¿No se ejecutaría el proceso creado como sistema local en ese caso? Si hago eso, también podría llamar a CreateProcess y no molestarme con los tokens de usuario. –

Cuestiones relacionadas