Sharepoint: executando stsadm a partir de um trabalho de timer + direitos SHAREPOINT \ System

Translate

Eu tenho uma situação incomum em que preciso de um trabalho de timer do SharePoint para ter privilégios de administrador local do Windows e para terSHAREPOINT\SystemPrivilégios do SharePoint.

Posso obter os privilégios do Windows simplesmente configurando o serviço de temporizador para usar uma conta que seja membro dos administradores locais. Eu entendo que essa não é uma boa solução, pois dá ao serviço de timer do SharePoint mais direitos do que deveria. Mas pelo menos permite que meu trabalho de timer do SharePoint seja executadostsadm.

Outro problema com a execução do serviço de cronômetro sob o administrador local é que este usuário não necessariamente teráSHAREPOINT\SystemPrivilégios do SharePoint que também preciso para este trabalho do SharePoint. Acontece queSPSecurity.RunWithElevatedPrivilegesnão funcionará neste caso. Refletor mostra queRunWithElevatedPrivilegesverifica se o processo atual éowstimer(o processo de serviço que executa trabalhos do SharePoint) e não executa nenhuma elevação, este é o caso (o racional aqui, eu acho, é que o serviço de timer deve ser executado sobNT AUTHORITY\NetworkServiceconta do Windows que temSHAREPOINT\SystemPrivilégios do SharePoint e, portanto, não há necessidade de elevar os privilégios para um trabalho de timer).

A única solução possível aqui parece ser executar o serviço de timer em sua conta normal do Windows NetworkService e executar stsadm como um administrador local, armazenando as credenciais de administrador em algum lugar e passando-as para System.Diagnostics.Process.Run () por meio do nome de usuário StarInfo , domínio e senha.

Parece que tudo deve funcionar agora, mas aqui está outro problema com o qual estou preso no momento. Stsamd está falhando com o seguinte pop-up de erro (!) (O filemon do Winternals mostra que stsadm está sendo executado pelo administrador neste caso):

The application failed to initialize properly (0x0c0000142).
Click OK to terminate the application.

O Visualizador de eventos não registra nada, exceto o pop-up.

O usuário administrador local é minha conta e quando acabo de executarstsadminterativamente sob esta conta está tudo ok. Também funciona bem quando configuro o serviço de cronômetro para ser executado nesta conta.

Quaisquer sugestões são apreciadas :)

This question and all comments follow the "Attribution Required."

Todas as respostas

Translate

Não estou no trabalho, então isso está fora da minha cabeça, mas: Se você receber uma referência ao Site, pode tentar criar um novo SPSite com o SYSTEM-UserToken?

SPUserToken sut = thisSite.RootWeb.AllUsers["SHAREPOINT\SYSTEM"].UserToken;

using (SPSite syssite = new SPSite(thisSite.Url,sut)
{
    // Do what you have to do
}
Fonte
Translate

Os trabalhos do SharePoint Timer são executados com as credenciais de administrador de empresa do SharePoint, pois as informações chegam ao banco de dados de configuração do SharePoint. Portanto, o pool de aplicativos não terá acesso.

Para testar o trabalho de timer no ambiente de desenvolvimento, podemos alterar temporariamente a conta do pool de aplicativos para a conta do pool de aplicativos que está sendo usada para a Administração Central.

Fonte
axk
Translate

Outros aplicativos, se executados dessa maneira (ou seja, a partir de um trabalho de timer com credenciais explícitas), apresentam falha da mesma forma com "O aplicativo falhou ao inicializar corretamente". Eu só queria um aplicativo simples que pegasse um caminho de outro executável e seus argumentos como parâmetros e quando executado a partir desse trabalho de timer ele falhará da mesma maneira.

internal class ExternalProcess
{
    public static void run(String executablePath, String workingDirectory, String programArguments, String domain, String userName,
                           String password, out Int32 exitCode, out String output)
    {
        Process process = new Process();

        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;

        StringBuilder outputString = new StringBuilder();
        Object synchObj = new object();

        DataReceivedEventHandler outputAppender =
            delegate(Object sender, DataReceivedEventArgs args)
                {
                    lock (synchObj)
                    {
                        outputString.AppendLine(args.Data);
                    }
                };

        process.OutputDataReceived += outputAppender;
        process.ErrorDataReceived += outputAppender;

        process.StartInfo.FileName = @"C:\AppRunner.exe";
        process.StartInfo.WorkingDirectory = workingDirectory;
        process.StartInfo.Arguments = @"""" + executablePath + @""" " + programArguments;

        process.StartInfo.UserName = userName;
        process.StartInfo.Domain = domain; 
        SecureString passwordString = new SecureString();

        foreach (Char c in password)
        {
            passwordString.AppendChar(c);
        }

        process.StartInfo.Password = passwordString;

        process.Start();

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();

        exitCode = process.ExitCode;
        output = outputString.ToString();
    }
}

O AppRunner basicamente faz o mesmo que o fragmento acima, mas sem nome de usuário e senha

Fonte