Point de partage :exécution de stsadm à partir d'un travail de minuterie + droits SHAREPOINT\System

StackOverflow https://stackoverflow.com/questions/3739

Question

Je me trouve dans une situation inhabituelle dans laquelle j'ai besoin d'un travail de minuterie SharePoint pour disposer à la fois des privilèges Windows d'administrateur local et d'avoir SHAREPOINT\System Privilèges SharePoint.

Je peux obtenir les privilèges Windows en configurant simplement le service de minuterie pour utiliser un compte membre des administrateurs locaux.Je comprends que ce n'est pas une bonne solution car elle donne au service de minuterie SharePoint plus de droits qu'il n'est censé en avoir.Mais cela permet au moins à mon travail de minuterie SharePoint de s'exécuter stsadm.

Un autre problème lié à l'exécution du service de minuterie sous un administrateur local est que cet utilisateur n'aura pas nécessairement SHAREPOINT\System Privilèges SharePoint dont j'ai également besoin pour ce travail SharePoint.Il se trouve que SPSecurity.RunWithElevatedPrivileges ne fonctionnera pas dans ce cas.Le réflecteur montre que RunWithElevatedPrivileges vérifie si le processus en cours est owstimer (le processus de service qui exécute les tâches SharePoint) et n'effectue aucune élévation, c'est le cas (le rationnel ici, je suppose, est que le service de minuterie est censé s'exécuter sous NT AUTHORITY\NetworkService compte Windows qui a SHAREPOINT\System Privilèges SharePoint, et il n'est donc pas nécessaire d'élever les privilèges pour un travail programmé).

La seule solution possible ici semble être d'exécuter le service de minuterie sous son compte Windows NetworkService habituel et d'exécuter stsadm en tant qu'administrateur local en stockant les informations d'identification de l'administrateur quelque part et en les transmettant à System.Diagnostics.Process.Run() via le nom d'utilisateur de StarInfo. , domaine et mot de passe.

Il semble que tout devrait fonctionner maintenant, mais voici un autre problème avec lequel je suis actuellement confronté.Stsamd échoue avec la fenêtre contextuelle d'erreur suivante (!) (Winternals filemon montre que stsadm s'exécute sous l'administrateur dans ce cas) :

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

L'Observateur d'événements n'enregistre rien sauf la fenêtre contextuelle.

L'utilisateur administrateur local est mon compte et quand je viens de lancer stsadm de manière interactive sous ce compte, tout va bien.Cela fonctionne également très bien lorsque je configure le service de minuterie pour qu'il s'exécute sous ce compte.

Toutes les suggestions sont appréciées :)

Pas de solution correcte

Autres conseils

Je ne suis pas au travail, donc cela me vient à l'esprit, mais :Si vous obtenez une référence au site, pouvez-vous essayer de créer un nouveau SPSite avec le SYSTEM-UserToken ?

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

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

Les travaux du minuteur SharePoint s'exécutent avec les informations d'identification de l'administrateur de l'entreprise SharePoint, car les informations entrent dans la base de données de configuration SharePoint.Ainsi, le pool d’applications n’y aura pas accès.

Pour tester le travail du minuteur dans un environnement de développement, nous pouvons temporairement remplacer le compte du pool d'applications par le compte du pool d'applications utilisé pour l'administration centrale.

D'autres applications sont exécutées de cette façon (c.-à-d.à partir d'un travail de minuterie avec des informations d'identification explicites) échouent de la même manière avec "L'application n'a pas pu s'initialiser correctement".J'écris juste une application simple qui prend le chemin d'un autre exécutable et ses arguments comme paramètres et lorsqu'elle est exécutée à partir de ce travail de minuterie, elle échoue de la même manière.

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 fait essentiellement la même chose que le fragment ci-dessus, mais sans nom d'utilisateur ni mot de passe

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top