Iniciar / detener un servicio de Windows desde una cuenta de usuario que no sea administrador

121

Tengo un servicio de Windows llamado, digamos, BST. Y necesito otorgar a un usuario que no sea Administrador, UserA, los permisos para Iniciar / Detener este servicio en particular. Mi servicio se ejecuta en una variedad de sistemas operativos Windows, comenzando desde Windows Server 2003 hasta Windows 7.

¿Cómo puedo hacer esto?

Busqué en Google y encontré algunas cosas sobre dar permisos usando el comando [sc sdset], pero no estoy exactamente seguro acerca de los parámetros. No quiero establecer los permisos para un grupo, sino SOLO para un usuario en particular, UserA en este caso.

Sach
fuente

Respuestas:

141

A continuación, he reunido todo lo que aprendí sobre Iniciar / Detener un servicio de Windows desde una cuenta de usuario que no sea administrador, si alguien necesita saberlo.

Principalmente, hay dos formas de iniciar / detener un servicio de Windows. 1. Acceder directamente al servicio a través de la cuenta de usuario de Windows de inicio de sesión. 2. Accediendo al servicio a través de IIS utilizando la cuenta del Servicio de red.

Comando de línea de comando para iniciar / detener servicios:

C:/> net start <SERVICE_NAME>
C:/> net stop <SERVICE_NAME>

Código C # para iniciar / detener servicios:

ServiceController service = new ServiceController(SERVICE_NAME);

//Start the service
if (service.Status == ServiceControllerStatus.Stopped)
{
      service.Start();
      service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10.0));
}

//Stop the service
if (service.Status == ServiceControllerStatus.Running)
{
      service.Stop();
      service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10.0));
}

Nota 1: Al acceder al servicio a través de IIS, cree una aplicación web de Visual Studio C # ASP.NET y coloque el código allí. Implemente el servicio web en la carpeta raíz de IIS (C: \ inetpub \ wwwroot \) y estará listo. Acceda por la url http: ///.

1. Método de acceso directo

Si la cuenta de usuario de Windows desde la que le da el comando o ejecuta el código no es una cuenta de administrador, entonces debe establecer los privilegios para esa cuenta de usuario en particular para que pueda iniciar y detener los servicios de Windows. Así es como lo haces. Inicie sesión en una cuenta de administrador en la computadora que tiene la cuenta que no es de administrador desde la que desea iniciar / detener el servicio. Abre el símbolo del sistema y da el siguiente comando:

C:/>sc sdshow <SERVICE_NAME>

La salida de esto será algo como esto:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

Enumera todos los permisos que cada usuario / grupo en esta computadora tiene con respecto.

A description of one part of above command is as follows:

    D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)

It has the default owner, default group, and it has the Security descriptor control flags (A;;CCLCSWRPWPDTLOCRRC;;;SY):

ace_type - "A": ACCESS_ALLOWED_ACE_TYPE,
ace_flags - n/a,
rights - CCLCSWRPWPDTLOCRRC,  please refer to the Access Rights and Access Masks and Directory Services Access Rights
CC: ADS_RIGHT_DS_CREATE_CHILD - Create a child DS object.
LC: ADS_RIGHT_ACTRL_DS_LIST - Enumerate a DS object.
SW: ADS_RIGHT_DS_SELF - Access allowed only after validated rights checks supported by the object are performed. This flag can be used alone to perform all validated rights checks of the object or it can be combined with an identifier of a specific validated right to perform only that check.
RP: ADS_RIGHT_DS_READ_PROP - Read the properties of a DS object.
WP: ADS_RIGHT_DS_WRITE_PROP - Write properties for a DS object.
DT: ADS_RIGHT_DS_DELETE_TREE - Delete a tree of DS objects.
LO: ADS_RIGHT_DS_LIST_OBJECT - List a tree of DS objects.
CR: ADS_RIGHT_DS_CONTROL_ACCESS - Access allowed only after extended rights checks supported by the object are performed. This flag can be used alone to perform all extended rights checks on the object or it can be combined with an identifier of a specific extended right to perform only that check.
RC: READ_CONTROL - The right to read the information in the object's security descriptor, not including the information in the system access control list (SACL). (This is a Standard Access Right, please read more http://msdn.microsoft.com/en-us/library/aa379607(VS.85).aspx)
object_guid - n/a,
inherit_object_guid - n/a,
account_sid - "SY": Local system. The corresponding RID is SECURITY_LOCAL_SYSTEM_RID.

Ahora, lo que debemos hacer es establecer los permisos apropiados para Iniciar / Detener los Servicios de Windows para los grupos o usuarios que queramos. En este caso, necesitamos que el usuario actual no administrador pueda iniciar / detener el servicio, por lo que vamos a establecer los permisos para ese usuario. Para hacer eso, necesitamos el SID de esa cuenta de usuario de Windows en particular. Para obtenerlo, abra el Registro (Inicio> regedit) y busque la siguiente clave de registro.

LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

Debajo hay una clave separada para cada cuenta de usuario en esta computadora, y el nombre de la clave es el SID de cada cuenta. Los SID generalmente tienen el formato S-1-5-21-2103278432-2794320136-1883075150-1000. Haga clic en cada clave y verá en el panel de la derecha una lista de valores para cada clave. Busque "ProfileImagePath" y, por su valor, puede encontrar el nombre de usuario al que pertenece SID. Por ejemplo, si el nombre de usuario de la cuenta es SACH, el valor de "ProfileImagePath" será algo así como "C: \ Users \ Sach". Por lo tanto, anote el SID de la cuenta de usuario para la que desea establecer los permisos.

Nota 2: Aquí hay una muestra de código C # simple que se puede usar para obtener una lista de dichas claves y sus valores.

//LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList RegistryKey
RegistryKey profileList = Registry.LocalMachine.OpenSubKey(keyName);

//Get a list of SID corresponding to each account on the computer
string[] sidList = profileList.GetSubKeyNames();

foreach (string sid in sidList)
{
    //Based on above names, get 'Registry Keys' corresponding to each SID
    RegistryKey profile = Registry.LocalMachine.OpenSubKey(Path.Combine(keyName, sid));

    //SID
    string strSID = sid;
    //UserName which is represented by above SID    
    string strUserName = (string)profile.GetValue("ProfileImagePath");
}

Ahora que tenemos el SID de la cuenta de usuario para la que queremos establecer los permisos, vamos a hacerlo. Supongamos que el SID de la cuenta de usuario es S-1-5-21-2103278432-2794320136-1883075150-1000 . Copie la salida del comando [sc sdshow] en un editor de texto. Se verá así:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

Ahora, copie la parte (A ;; CCLCSWRPWPDTLOCRRC ;;; SY) del texto anterior, y péguelo justo antes de la S: (AU; ... parte del texto. Luego cambie esa parte para que se vea así: (A ;; RPWPCR ;;; S-1-5-21-2103278432-2794320136-1883075150-1000)

Luego agregue sc sdset en el frente y encierre la parte anterior con comillas. Su comando final debería parecerse a lo siguiente:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

Ahora ejecute esto en su símbolo del sistema, y ​​debería dar el resultado de la siguiente manera si tiene éxito:

[SC] SetServiceObjectSecurity SUCCESS

¡Ahora estamos listos para irnos! ¡Su cuenta de usuario no administrador ha recibido permisos para iniciar / detener su servicio! Intente iniciar sesión en la cuenta de usuario e iniciar / detener el servicio y debería permitirle hacerlo.

2. Acceso a través del método IIS

En este caso, debemos otorgar el permiso al usuario de IIS "Servicios de red" en lugar de iniciar sesión en la cuenta de usuario de Windows. El procedimiento es el mismo, solo se cambiarán los parámetros del comando. Como configuramos el permiso para "Servicios de red", reemplace SID con la cadena "NS" en el comando sdset final que usamos anteriormente. El comando final debería verse así:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;NS)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

Ejecútelo en el símbolo del sistema desde una cuenta de usuario administrador, ¡y listo! Tiene permiso para iniciar / detener el servicio desde cualquier cuenta de usuario (independientemente de si se trata de una cuenta de administrador o no) utilizando un método web. Consulte la Nota 1 para saber cómo hacerlo.

Sach
fuente
11
NOTA: ** DEBE copiar los resultados del comando shshow ejecutado en su propia máquina y luego editar de acuerdo con lo que he especificado. ** NO simplemente copie el código desde aquí y ejecútelo en su computadora tal como está.
Sach
55
Intenté este enfoque manual y funcionó espléndidamente. Pero, si eres como yo, y necesitas hacer esto en más de 20 computadoras, entonces querrás un programa o script para hacerlo. Puede usar las llamadas a la API de Windows QueryServiceObjectSecurity y SetServiceObjectSecurity . MSDN tiene un ejemplo
Drew Chapin
1
Grandes felicitaciones! Trabajado como un encanto.
Horst Gutmann
2
Para no quitarle el esfuerzo y la atención que se dedicó a esta respuesta, creo que algunas de las otras respuestas ofrecen una solución más simple y directa. A menos que me falte alguna ventaja de esto?
Spike0xff
1
Si está haciendo esto programáticamente y desea dividir la salida sc sdshow, puede usar esta expresión regular para dividir los componentes: (?:\D:)?\(.+?\)y luego insertar la nueva parte con el SID como penúltimo.
PhonicUK
115

Yo uso la utilidad SubInACL para esto. Por ejemplo, si quería dar al usuario el trabajo en el equipo VMX001 la capacidad de iniciar y detener la Wide Web servicio de publicación World (también conocido como W3svc), me gustaría emitir el siguiente comando como administrador:

subinacl.exe /service w3svc /grant=VMX001\job=PTO

Los permisos que puede otorgar se definen de la siguiente manera (lista tomada de aquí ):

F : Full Control
R : Generic Read
W : Generic Write
X : Generic eXecute
L : Read controL
Q : Query Service Configuration
S : Query Service Status
E : Enumerate Dependent Services
C : Service Change Configuration
T : Start Service
O : Stop Service
P : Pause/Continue Service
I : Interrogate Service 
U : Service User-Defined Control Commands

Entonces, al especificar PTO, autorizo ​​al usuario del trabajo a Pausar / Continuar, Iniciar y Detener el servicio w3svc.

arcain
fuente
18
Esta es la mejor respuesta. Utiliza la herramienta adecuada para el trabajo sin hackear el registro, traducir SID o depender de un formato ACL oscuro. Proporciona todo lo que se necesita para realizar el trabajo de forma rápida y sencilla con suficientes detalles para extrapolarlo a cualquier escenario razonable.
pierce.jason
2
¿Necesito reiniciar o cerrar sesión / iniciar sesión cuando lo uso?
David dice que reinstale a Mónica
2
@DavidGrinberg No recuerdo haber necesitado que la cuenta afectada se desconectara y luego volviera a encenderse, o que tuviera que reiniciar cuando solo usaba subinacl como se describe aquí.
arcain
1
Puede confirmar que esto funciona en el servidor 2012 usando sc \\server start|stop|query servicenamedesde un servidor remoto. No es necesario reiniciar ni cerrar sesión
Stig Eide
Esto funcionó para iniciar un servicio localmente. Sin embargo, chocó con CouldNotAccessDependentServicesel uso de PowerShell remoto: Cannot access dependent services of '...'. Agregar E : Enumerate Dependent Servicesa los derechos de ACL solucionó eso.
Willem el
42
  1. Inicie sesión como administrador.
  2. Descargar subinacl.exedesde Microsoft:
    http://www.microsoft.com/en-us/download/details.aspx?id=23510
  3. Otorgue permisos a la cuenta de usuario normal para administrar los servicios BST.
    ( subinacl.exeestá adentro C:\Program Files (x86)\Windows Resource Kits\Tools\)
  4. cd C:\Program Files (x86)\Windows Resource Kits\Tools\
    subinacl /SERVICE \\MachineName\bst /GRANT=domainname.com\username=F o
    subinacl /SERVICE \\MachineName\bst /GRANT=username=F
  5. Cerrar sesión y volver a iniciar sesión como usuario. Ahora deberían poder iniciar el servicio BST.
Venkat
fuente
1
Parece mucho más fácil y mejor que manipular manualmente las configuraciones.
gsk
1
¿Se requiere cerrar sesión?
David dice que reinstale a Mónica
whoops! Falló ... Obtuve "Error OpenSCManager: el servidor RPC no está disponible. ADVERTENCIA: / grant = mike = f: No se abrió ningún objeto anterior". El servicio que probé fue MySQL. Reinicio: el acceso está denegado, como siempre.
Mike roedor
15

Existe una herramienta GUI gratuita ServiceSecurityEditor

Lo que le permite editar los permisos del Servicio de Windows. Lo he utilizado con éxito para dar a un usuario que no sea administrador los derechos para iniciar y detener un servicio.

Había usado "sc sdset" antes de conocer esta herramienta.

ServiceSecurityEditor tiene ganas de hacer trampa, es así de fácil :)

FCW
fuente
1
Intenté ServiceSecurityEditor basándome en esta recomendación y es excelente.
Guru Josh
11

Es significativamente más fácil otorgar permisos de administración a un servicio utilizando una de estas herramientas:

  • Política de grupo
  • Plantilla de seguridad
  • herramienta de línea de comandos subinacl.exe.

Aquí está el artículo de MSKB con instrucciones para Windows Server 2008 / Windows 7, pero las instrucciones son las mismas para 2000 y 2003.

Ryan Fisher
fuente
1

La herramienta de línea de comandos subinacl.exe es probablemente la única viable y muy fácil de usar de cualquier cosa en esta publicación. No puede usar un GPO con servicios que no sean del sistema y la otra opción es demasiado complicada.

JustAGuy
fuente
-2

El servicio de Windows se ejecuta utilizando una cuenta del sistema local. Puede iniciarse automáticamente cuando el usuario inicia sesión en el sistema o puede iniciarse manualmente. Sin embargo, un servicio de Windows dice que BST puede ejecutarse utilizando una cuenta de usuario particular en la máquina. Esto puede hacerse de la siguiente manera: inicie services.msc y vaya a las propiedades de su servicio de Windows, BST. Desde allí puede proporcionar los parámetros de inicio de sesión del usuario requerido. El servicio se ejecuta con esa cuenta de usuario y ningún otro usuario puede ejecutar ese servicio.

jack_sparrow
fuente
1
Gracias por la respuesta Jack. Sin embargo, no es lo que quiero hacer. Necesito que mi servicio BST se ejecute como lo hace ahora. Solo necesito que cualquier usuario que no sea administrador pueda detenerlo / iniciarlo.
Sach