Iniciar / parar um serviço do Windows a partir de uma conta de usuário não administrador

121

Eu tenho um WindowsService chamado, digamos, BST. E eu preciso dar a um usuário não administrador, UserA, as permissões para iniciar / parar este serviço específico. Meu serviço é executado em uma variedade de sistemas operacionais Windows, a partir do Windows Server 2003 para o Windows 7.

Como posso fazer isso?

Pesquisei no Google e encontrei algumas coisas sobre como conceder permissões usando o comando [sc sdset], mas não tenho exatamente certeza sobre os parâmetros. Não quero definir as permissões para um grupo, mas apenas para um usuário específico, UserA, neste caso.

Sach
fonte

Respostas:

141

Abaixo, reuni tudo o que aprendi sobre Como iniciar / interromper um serviço do Windows a partir de uma conta de usuário não administrador, se alguém precisar saber.

Principalmente, existem duas maneiras pelas quais iniciar / parar um serviço do Windows. 1. Acesso direto ao serviço através da conta de usuário do Windows de logon. 2. Acessando o serviço pelo IIS usando a conta do Serviço de Rede.

Comando da linha de comandos para iniciar / parar serviços:

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

Código C # para iniciar / parar serviços:

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: Ao acessar o serviço pelo IIS, crie um Aplicativo Web ASP.NET do Visual Studio C # e insira o código nele. Implante o WebService na pasta raiz do IIS (C: \ inetpub \ wwwroot \) e pronto. Acesse-o pelo URL http: ///.

1. Método de Acesso Direto

Se a Conta de Usuário do Windows a partir da qual você der o comando ou executar o código for uma conta não Administradora, será necessário definir os privilégios para essa conta de usuário específica, para que você possa iniciar e interromper os Serviços do Windows. É assim que se faz. Faça logon em uma conta de administrador no computador em que a conta não seja de administrador na qual você deseja iniciar / parar o serviço. Abra o prompt de comando e dê o seguinte comando:

C:/>sc sdshow <SERVICE_NAME>

A saída disso será algo como isto:

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

Ele lista todas as permissões que cada Usuário / Grupo neste computador possui.

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.

Agora, o que precisamos fazer é definir as permissões apropriadas para Iniciar / Parar os Serviços do Windows nos grupos ou usuários que desejamos. Nesse caso, precisamos que o usuário não administrador atual possa iniciar / interromper o serviço, para definir as permissões para esse usuário. Para fazer isso, precisamos do SID dessa conta de usuário específica do Windows. Para obtê-lo, abra o Registro (Iniciar> regedit) e localize a seguinte chave do Registro.

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

De acordo com isso, existe uma chave separada para cada conta de usuário neste computador e o nome da chave é o SID de cada conta. Os SIDs geralmente têm o formato S-1-5-21-2103278432-2794320136-1883075150-1000. Clique em cada chave e você verá no painel à direita uma lista de valores para cada chave. Localize "ProfileImagePath" e, por seu valor, você pode encontrar o nome de usuário ao qual o SID pertence. Por exemplo, se o nome de usuário da conta for SACH, o valor de "ProfileImagePath" será algo como "C: \ Users \ Sach". Portanto, anote o SID da conta de usuário para a qual você deseja definir as permissões.

Nota2: Aqui está um exemplo simples de código C # que pode ser usado para obter uma lista das referidas chaves e seus 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");
}

Agora que temos o SID da conta de usuário para a qual queremos definir as permissões, vamos a ele. Vamos supor que o SID da conta do usuário seja S-1-5-21-2103278432-2794320136-1883075150-1000 . Copie a saída do comando [sc sdshow] para um editor de texto. Isso parecerá assim:

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

Agora, copie o (A ;; CCLCSWRPWPDTLOCRRC ;;; SY) parte do texto acima, e colá-lo pouco antes do S: (UA; ... parte do texto Em seguida, altere essa parte para olhar como este:. (A ;; RPWPCR ;;; S-1-5-21-2103278432-2794320136-1883075150-1000)

Em seguida, adicione sc sdset na frente e coloque a parte acima entre aspas. Seu comando final deve se parecer com o seguinte:

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)"

Agora execute isso no prompt de comando e, se for bem-sucedido, ele deverá fornecer a saída da seguinte maneira:

[SC] SetServiceObjectSecurity SUCCESS

Agora estamos prontos! Sua conta de usuário não administrador recebeu permissões para iniciar / parar seu serviço! Tente fazer login na conta do usuário e Iniciar / Parar o serviço, e você deve fazer isso.

2. Acesso através do método IIS

Nesse caso, precisamos conceder a permissão ao usuário do IIS "Serviços de rede" em vez da conta de usuário do Windows de logon. O procedimento é o mesmo, apenas os parâmetros do comando serão alterados. Como definimos a permissão para "Serviços de rede", substitua SID pela string "NS" no comando sdset final que usamos anteriormente. O comando final deve ser algo como isto:

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)"

Execute-o no prompt de comando em uma conta de usuário Admin e pronto! Você tem permissão para iniciar / parar o serviço de qualquer conta de usuário (independentemente de ser uma conta de administrador ou não) usando um WebMethod. Consulte a Nota 1 para descobrir como fazê-lo.

Sach
fonte
11
NOTA: ** Você DEVE copiar os resultados do comando shshow executado em sua própria máquina e depois editar de acordo com o que especifiquei. ** NÃO copie o código daqui e execute no seu computador como está.
Sach
5
Eu tentei essa abordagem manual e funcionou esplendidamente. Mas, se você é como eu, e precisa fazer isso em mais de 20 computadores, vai querer um programa ou script para fazer isso. Você pode usar a API do Windows que chama QueryServiceObjectSecurity e SetServiceObjectSecurity . O MSDN tem um exemplo
Drew Chapin
1
Muitos elogios! Funcionou como um encanto.
Horst Gutmann
2
para não tirar o esforço e o cuidado que foram encontrados nessa resposta, acho que algumas das outras respostas oferecem uma solução mais simples e direta. A menos que eu esteja perdendo alguma vantagem disso?
Spike0xff
1
Se você estiver fazendo isso programaticamente e quiser dividir a saída, sc sdshowpoderá usar este regex para dividir os componentes: (?:\D:)?\(.+?\)e insira a nova peça com o SID como penúltimo.
PhonicUK
115

Eu uso o utilitário SubInACL para isso. Por exemplo, se eu quisesse dar ao trabalho do usuário no computador VMX001 a capacidade de iniciar e parar o Serviço de Publicação na World Wide Web (também conhecido como w3svc), eu emitiria o seguinte comando como administrador:

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

As permissões que você pode conceder são definidas da seguinte forma (lista retirada daqui ):

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

Portanto, ao especificar a PTO, autorizo ​​o usuário do trabalho a Pausar / Continuar, Iniciar e Interromper o serviço w3svc.

arcain
fonte
18
Esta é a melhor resposta. Ele usa a ferramenta certa para o trabalho sem hackear o registro, traduzir SIDs ou dependendo da formatação obscura da ACL. Fornece tudo o que é necessário para realizar o trabalho com rapidez e facilidade, com detalhes suficientes para extrapolá-lo para qualquer cenário razoável.
pierce.jason
2
Preciso reiniciar ou sair / fazer login quando eu uso isso?
David diz Restabelecer Monica
2
@DavidGrinberg Não me lembro de precisar ter a conta afetada desconectada e novamente ativada, ou ter que reiniciar ao usar apenas o subinacl, conforme descrito aqui.
#
1
Pode confirmar que isso funciona no servidor 2012 usando sc \\server start|stop|query servicenamedo servidor remoto. No reinício \ logoff necessário
Stig Eide
Isso funcionou para iniciar um serviço localmente. No entanto ele caiu com CouldNotAccessDependentServicesusando o PowerShell remoto: Cannot access dependent services of '...'. A adição E : Enumerate Dependent Servicesaos direitos da ACL corrigiu isso.
Willem
42
  1. Faça o login como administrador.
  2. Download subinacl.exeda Microsoft:
    http://www.microsoft.com/en-us/download/details.aspx?id=23510
  3. Conceda permissões à conta de usuário comum para gerenciar os serviços BST.
    ( subinacl.exeestá dentro 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 ou
    subinacl /SERVICE \\MachineName\bst /GRANT=username=F
  5. Efetue logout e efetue login novamente como usuário. Agora eles devem poder iniciar o serviço BST.
Venkat
fonte
1
Parece muito mais fácil e melhor do que manipular manualmente as configurações.
GSK
1
O logout é necessário?
David diz Restabelecer Monica
gritos! Falha ... recebi "Erro OpenSCManager: O servidor RPC está indisponível. AVISO: / grant = mike = f: Nenhum objeto anterior foi aberto". O serviço que eu tentei foi o MySQL. Reinicialização: acesso negado, como sempre.
mike roedor
15

Existe uma ferramenta GUI gratuita ServiceSecurityEditor

O que permite editar as permissões de serviço do Windows. Usei-o com sucesso para dar a um usuário não administrador os direitos de iniciar e parar um serviço.

Eu tinha usado o "sc sdset" antes de conhecer essa ferramenta.

ServiceSecurityEditor parece trapaça, é fácil :)

FCW
fonte
1
Eu tentei o ServiceSecurityEditor com base nesta recomendação e é excelente.
Guru Josh
11

É significativamente mais fácil conceder permissões de gerenciamento a um serviço usando uma destas ferramentas:

  • Política de grupo
  • Modelo de Segurança
  • ferramenta de linha de comando subinacl.exe.

Aqui está o artigo MSKB com instruções para Windows Server 2008 / Windows 7, mas as instruções são as mesmas para 2000 e 2003.

Ryan Fisher
fonte
1

A ferramenta de linha de comando subinacl.exe é provavelmente a única viável e muito fácil de usar em qualquer parte deste post. Você não pode usar um GPO com serviços que não sejam do sistema e a outra opção é muito complicada.

JustAGuy
fonte
-2

O Serviço do Windows é executado usando uma conta do sistema local. Ele pode ser iniciado automaticamente quando o usuário efetua login no sistema ou pode ser iniciado manualmente. No entanto, um serviço do Windows diz que o BST pode ser executado usando uma conta de usuário específica na máquina. da seguinte maneira: inicie services.msc e vá para as propriedades do seu serviço Windows, BST. A partir daí, você pode fornecer os parâmetros de login do usuário necessário. O serviço é executado com essa conta de usuário e nenhum outro usuário pode executar esse serviço.

jack_sparrow
fonte
1
Obrigado pela resposta Jack. No entanto, não é o que eu quero fazer. Eu preciso do meu serviço BST para executar como agora. Eu só preciso de qualquer usuário que não seja um administrador para poder parar / iniciar.
Sach