Sobre el error "La operación solicitada requiere elevación" que puede devolver Runas.exe en Windows Vista/7
En un foro que frecuento un usuario tenía el siguiente problema: Al intentar ejecutar como administrador un programa en Windows 7 usando el comando Runas.exe, le aparecía el siguiente mensaje de error:
740: La operación solicitada requiere elevación.
Ciertamente el usuario estaba proporcionando el nombre de usuario y la contraseña de un usuario con privilegios administrativos así que... ¿dónde estaría el problema?
En primer lugar, vamos a analizar con calma lo que quiere decir el mensaje de error. El mensaje de error "La operación solicitada requiere elevación" está recogido en el fichero de cabecera Ntstatus.h del SDK de Windows Vista y posteriores. Concretamente está definido con el nombre de macro ERROR_ELEVATION_REQUIRED.
¿Cuándo se devuelve ese código de error durante el funcionamiento de Windows?
En Windows los procesos se crean usando la API CreateProcess. Uno de los pasos que se siguen antes de crear un proceso en Windows Vista y posteriores es comprobar si el proceso en cuestión necesita elevar sus privilegios o no. A la hora de determinar este aspecto, entran en juego, entre otros, dos parámetros: El nivel de ejecución (runlevel) impuesto por el manifiesto de la propia aplicación, y el token del usuario que está lanzando ese programa. Existen tres posibles niveles de ejecución para una aplicación:
- asInvoker: El nivel de ejecución es el mismo que el del proceso padre.
- highestAvailable: El nivel de ejecución es el de mayores privilegios posibles, considerando el tipo de cuenta desde la cual se ejecuta el proceso.
- requireAdministrator: El nivel de ejecución es administrativo, independientemente de las demás circunstancias.
Esta tabla recoge de forma básica las posibilidades:
| Nivel de ejecución de la aplicación |
Token del usuario |
Requiere elevación o no |
| AsInvoker |
Cualquiera |
No |
| highestAvailable |
Administrador "elevado" |
No |
| highestAvailable |
Administrador "estándar" |
Sí |
| highestAvailable |
Otro caso |
No |
| requireAdministrator |
Administrador "elevado" |
No |
| requireAdministrator |
Otro caso |
Sí |
Por administrador "elevado" me refiero a aquella cuenta con privilegios administrativos pero que, o bien ya ha elevado explícitamente sus privilegios (a través de un cuadro de UAC), o bien no tiene activada la característica Modo de aprobación del administrador (Admin Approval Mode). Esta característica se puede desactivar desde Directiva de grupo, pero yo personalmente lo desaconsejo. Un ejemplo de este tipo de cuentas es la cuenta "Administrador", creada durante la instalación del sistema operativo. Recuerde que el resto de cuentas con privilegios administrativos poseen dos tokens: uno limitado, con el que "actúan" por defecto, y otro "administrativo", que pueden aplicar si el usuario así lo indica a través de un cuadro de UAC.
Una vez que CreateProcess falla (devuelve un valor distinto de 1) y el último error se establece como ERROR_ELEVATION_REQUIRED (columna "Requiere elevación o no" de la tabla anterior), es asunto del proceso padre el tratar convenientemente este error. Si no lo hace, se registrará en Visor de sucesos, apartado dedicado a UAC, un evento informando de que el proceso padre no trató apropiadamente el error ERROR_ELEVATION_REQUIRED.
¿Qué ocurre cuando se lanza una aplicación desde la línea de comandos?
Imaginemos que el usuario intenta ejecutar el desfragmentador de disco de Windows 7 usando para ello una sintaxis de Runas.exe como esta:
runas /u:UsuarioAdministrador dfrgui.exe
Básicamente la línea de comandos detecta que no se trata de un comando interno, sino que se trata del programa Runas.exe, y por tanto se dispone a ejecutarlo usando CreateProcess. Como Runas.exe no es un programa que está marcado para requerir elevación de privilegios, CreateProcess retorna éxito.
Una vez que el planificador del sistema operativo cede el control al proceso Runas.exe recién creado, este se dispone a analizar su línea de comandos. Se encuentra con una petición de ejecutar Dfrgui.exe como si fuera el usuario administrador pasado como parámetro. Sin embargo, Runas.exe es poco más que un "envoltorio" de la API CreateProcessWithLogonW, que a su vez es poco más que un envoltorio de la API CreateProcess, pero pasando otro perfil de usuario distinto como parámetro.
Durante su ejecución, CreateProcess determina que Dfrgui.exe requiere privilegios administrativos (puesto que así se lo indica su manifiesto), y por ello devuelve falso y establace el último error como ERROR_ELEVATION_REQUIRED. Como Runas.exe es una herramienta que no está diseñada para tratar apropiadamente ese error, simplemente lo devuelve por pantalla de la forma "740: La operación solicitada requiere elevación".
Una vez desvelado el misterio, resta por comentar un aspecto que a estas alturas quizá ya se haya planteado:
¿Cómo es posible que ejecutando Dfrgui.exe desde la línea de comandos -sin usar Runas.exe- sí que aparezca un cuadro de UAC?
El secreto está en que la línea de comandos, antes de llamar a CreateProcess, informa al sistema de que va a tratar los posibles ERROR_ELEVATION_REQUIRED que puedan surgir. Esto lo consigue estableciendo unos atributos no documentados a la estructura STARTUPINFOEX, que se pasa como parámetro a la familia de API CreateProcess. Esto hace que no se registre el correspondiente error en el apartado UAC del Visor de sucesos. Seguidamente, la línea de comandos, sabiendo que se trata de un programa que debe elevar sus privilegios, lo intenta ejecutar mediante la API ShellExecuteEx. Esta API sí muestra el correspondiente cuadro de UAC, así que es la vía apropiada para ejecutar una aplicación que requiera privilegios administrativos.
En resumen, me gustaría resaltar estos puntos del tema del artículo:
- En Windows Vista y Windows 7 la única forma de ejecutar algo con privilegios administrativos es mediante un cuadro de UAC. No vale con poner el nombre de usuario y la contraseña de un administrador en la línea de comandos.
- Todo lo que se ejecute mediante la API CreateProcess, o alguna derivada de ella, no hará que aparezca un cuadro de UAC. Un ejemplo de ello es la utilidad Runas.exe.
- Runas.exe, en Windows Vista/7, sirve para ejecutar una aplicación como si fuera otro usuario, pero no sirve para ejecutarla con mayores privilegios.
- Si quiere que se ejecute una aplicación que requiere privilegios administrativos, use la API ShellExecuteEx, o alguna de sus derivadas. Esta API sí permite la aparición de un cuadro de UAC para que el usuario eleve sus privilegios.