Executando um arquivo BAT como um usuário de domínio de um serviço no Windows 7

2

Primeiramente, alguns princípios básicos:

  • Estou executando um aplicativo de servidor de banco de dados que é executado como um serviço ServiceA.
  • O ServiceA está instalado no servidor1 e no servidor2
  • O ServiceA é executado somente em um dos dois servidores ao mesmo tempo (eles são servidores redundantes, se um servidor falhar, o ServiceA no outro servidor será iniciado automaticamente)
  • Eu não tenho controle sobre o código ServiceA
  • ServiceA efetua logon como a conta do sistema local
  • O ServiceB precisa ser executado no Server1 e no Server2
  • ServiceB faz logon como a conta do sistema local
  • Eu posso criar objetos de configuração no banco de dados do ServiceA. Um tipo de objeto é como uma linguagem de script que o ServiceA executa
  • A linguagem de script tem funções para permitir a manipulação de arquivos e a execução de comandos no sistema local - OPEN_FILE (), WRITE_FILE (), CLOSE_FILE () e SYSTEM ()
  • Quando esses comandos são executados, eles são executados com as credenciais da conta do sistema local
  • ServiceA gera arquivos de configuração para o ServiceB usando os comandos de manipulação de arquivos acima
  • O ServiceB precisa ser encerrado antes que os novos arquivos de configuração sejam criados (na verdade, criei-os em uma pasta temporária, encerrei o ServiceB, copiei os arquivos e iniciei o ServiceB)
  • Server1 e Server2 são ambos do Windows 7 Enterprise
  • Server1 e Server2 estão no mesmo domínio

Estou tentando obter o ServiceA para:

  • Shutdown ServiceB no servidor1 e no servidor2
  • Copie alguns arquivos para Server1 e Server2
  • Inicie o ServiceB no Server1 e no Server2

O que eu fiz:

  • Criei uma conta de domínio (DomainX / UserY) com uma senha (PasswordZ)
  • Criado um compartilhamento nos dois servidores (ShareW)
  • Dada a permissão DomainX / UserY para acessar o ShareW em ambos os servidores
  • Usou OPEN_FILE (), WRITE_FILE () e CLOSE_FILE () para criar um arquivo INSTALL.BAT
  • Usado SYSTEM ('C: \ Temp \ INSTALL.BAT > > C: \ Temp \ INSTALL.LOG 2 > & 1') para executar o INSTALL.BAT (executado pelo Serviço A como Sistema Local) e crie um log de depuração

O que funciona dentro do arquivo BAT

NET USE \Server1\ShareW PasswordZ /USER:DomainX/UserY
NET USE \Server2\ShareW PasswordZ /USER:DomainX/UserY
DEL /F /Q "\Server1\ShareW\*.*
DEL /F /Q "\Server2\ShareW\*.*
XCOPY /Y "C:\Temp\*.*" "\Server1\ShareW\"
XCOPY /Y "C:\Temp\*.*" "\Server2\ShareW\"
NET USE \Server1\ShareW /DELETE
NET USE \Server2\ShareW /DELETE

Assim, o compartilhamento e as permissões são configurados corretamente

Meu problema é tentar parar e iniciar o serviço B de dentro de INSTALL.BAT

Eu tentei:

NET USE \Server1\IPC$ PasswordZ /USER:DomainX/UserY
SC \Server1 STOP "Service B"
NET USE \Server1\IPC$ /DELETE
NET USE \Server2\IPC$ PasswordZ /USER:DomainX/UserY
SC \Server2 STOP "Service B"
NET USE \Server2\IPC$ /DELETE

O comando SC funciona para a máquina local, mas falha na máquina remota. Esta é a saída do INSTALL.BAT em execução no Server2:

C:\Windows\system32>NET USE \Server1\IPC$ PasswordZ /USER:DomainX/UserY 
The command completed successfully.

C:\Windows\system32>SC \Server1 STOP ServiceB 
[SC] OpenService FAILED 5:

Access is denied.

(Eu tentei com o ServiceA rodando em Server1 e Server2 - os mesmos resultados - Funciona localmente, falha remotamente)

Se eu usar 'Executar como usuário diferente' para executar o CMD.EXE como DomainX / UserY, o comando SC funcionará perfeitamente. Então, no Server2, executando o INSTALL.BAT do CMD.EXE como DomainX / UserY eu recebo:

C:\Temp>NET USE \Server1\IPC$ PasswordZ /USER:DomainX/UserY

The command completed successfully.
C:\Temp>SC \Server1 START ServiceB

SERVICE_NAME: ServiceB
        TYPE               : 110  WIN32_OWN_PROCESS  (interactive)
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x1
        WAIT_HINT          : 0xbb8
        PID                : 4856
        FLAGS              :

Assim, o DomainX / UserY possui as permissões necessárias para interromper e iniciar o serviço no servidor remoto. Parece ser algum tipo de bloqueio de escalonamento de privilégios da conta do Sistema Local.

Eu li sobre a configuração de LocalAccountTokenFilterPolicy em HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ System \ para 1 e reinicializando. Eu fiz isso sem alterações no resultado.

Eu tentei usar psservice.exe com resultados praticamente idênticos (saída de INSTALL.BAT executada pelo ServiceA no Server2)

C:\Windows\system32>C:\Utilities\psservice.exe \Server1 -u DomainX/UserY -p PasswordZ -accepteula stop ServiceB 

PsService v2.24 - Service information and configuration utility
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com

Access is denied.
Access is denied.
Error querying services on Server1:
Error opening ServiceB on Server1:

Eu então tentei usar psexec (de uma maneira bastante complicada para capturar todo o registro)

INSTALL2.BAT

C:\Utilities\psexec -accepteula -u DomainX/UserY -p PasswordZ C:\Temp\INSTALL3.BAT >> C:\Temp\INSTALL3.LOG 2>&1

INSTALL3.BAT

C:\Temp\INSTALL.BAT >> C:\Temp\INSTALL.LOG 2>&1

Quando executo o INSTALL2.BAT a partir da linha de comando (executando como DomainX / UserY), tudo funciona bem.

Mas corra do ServiceA, no INSTALL3.LOG eu recebo:

PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

Access is denied.

PsExec could not start C:\Temp\INSTALL3.BAT:

Então eu adicionei explicitamente DomainX / UserY com Controle Total à segurança de todos os três arquivos BAT. O resultado foi o mesmo (Acesso negado. Em INSTALL3.LOG)

Eu também tentei desativar o UAC sem impacto perceptível

Então estou praticamente preso agora - como posso obter um arquivo BAT executado por um serviço em execução como sistema local para representar outro usuário e permitir que ele pare e inicie serviços em uma máquina remota?

    
por Graeme 17.07.2014 / 05:19

1 resposta

0

A resposta é bem simples - use a opção -h do psexec

O comando SYSTEM () do script executado pelo ServiceA é agora:

C:\Utilities\psexec -accepteula -h -u DomainX/UserY -p PasswordZ C:\Temp\INSTALL.BAT >> C:\Temp\INSTALL.LOG 2>&1

Funciona perfeitamente

    
por 18.07.2014 / 03:51