Domanda

Mi trovo in una situazione insolita in cui ho bisogno di un processo timer di SharePoint per avere sia i privilegi di amministratore locale che per avere SHAREPOINT\System Privilegi di SharePoint.

Posso ottenere i privilegi di Windows semplicemente configurando il servizio timer per utilizzare un account membro degli amministratori locali.Capisco che questa non è una buona soluzione poiché fornisce al servizio timer di SharePoint più diritti di quelli che dovrebbe avere.Ma almeno consente l'esecuzione del processo timer di SharePoint stsadm.

Un altro problema con l'esecuzione del servizio timer sotto l'amministratore locale è che questo utente non lo avrà necessariamente SHAREPOINT\System Privilegi di SharePoint di cui ho bisogno anche per questo lavoro di SharePoint.Si scopre che SPSecurity.RunWithElevatedPrivileges non funzionerà in questo caso.Il riflettore lo dimostra RunWithElevatedPrivileges controlla se il processo corrente lo è owstimer (il processo di servizio che esegue i lavori di SharePoint) e non esegue alcuna elevazione, questo è il caso (la logica qui, immagino, è che il servizio timer dovrebbe essere eseguito sotto NT AUTHORITY\NetworkService account Windows quale quale ha SHAREPOINT\System privilegi di SharePoint e quindi non è necessario elevare i privilegi per un processo timer).

L'unica soluzione possibile qui sembra essere quella di eseguire il servizio timer con il suo solito account Windows NetworkService ed eseguire stsadm come amministratore locale memorizzando le credenziali dell'amministratore da qualche parte e passandole a System.Diagnostics.Process.Run() tramite il nome utente di StarInfo , dominio e password.

Sembra che ora tutto dovrebbe funzionare, ma ecco un altro problema con cui sono bloccato al momento.Stsamd non funziona con il seguente popup di errore (!) (il filemon Winternals mostra che stsadm è in esecuzione sotto l'amministratore in questo caso):

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

Il Visualizzatore eventi non registra nulla tranne il popup.

L'utente amministratore locale è il mio account e quando corro stsadm in modo interattivo con questo account è tutto ok.Funziona bene anche quando configuro il servizio timer per l'esecuzione con questo account.

Qualsiasi suggerimento è apprezzato :)

Nessuna soluzione corretta

Altri suggerimenti

Non sono al lavoro, quindi non mi viene in mente questa cosa, ma:Se ricevi un riferimento al Sito, puoi provare a creare un nuovo SPSite con SYSTEM-UserToken?

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

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

I processi timer di SharePoint vengono eseguiti con le credenziali di amministratore dell'azienda di SharePoint poiché le informazioni entrano nel database di configurazione di SharePoint.Pertanto il pool di applicazioni non avrà accesso.

Per testare il processo timer nell'ambiente di sviluppo, possiamo modificare temporaneamente l'account del pool di applicazioni con l'account del pool di applicazioni utilizzato per l'amministrazione centrale.

Altre applicazioni se eseguite in questo modo (ad es.da un processo timer con credenziali esplicite) falliscono allo stesso modo con "Impossibile inizializzare l'applicazione".Ho appena scritto una semplice app che prende il percorso di un altro eseguibile e i suoi argomenti come parametri e quando viene eseguita da quel processo timer fallisce allo stesso modo.

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();
    }
}

AppRunner sostanzialmente fa la stessa cosa del frammento precedente, ma senza nome utente e password

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top