Home » Questions » Computers [ Ask a new question ]

Sharepoint: executing stsadm from a timer job + SHAREPOINT\System rights

Sharepoint: executing stsadm from a timer job + SHAREPOINT\System rights

"I have an unusual situation in which I need a SharePoint timer job to both have local administrator windows privileges and to have SHAREPOINT\System SharePoint privileges.

I can get the windows privileges by simply configuring the timer service to use an account which is a member of local administrators. I understand that this is not a good solution since it gives SharePoint timer service more rights then it is supposed to have. But it at least allows my SharePoint timer job to run stsadm.

Another problem with running the timer service under local administrator is that this user won't necessarily have SHAREPOINT\System SharePoint privileges which I also need for this SharePoint job. It turns out that SPSecurity.RunWithElevatedPrivileges won't work in this case. Reflector shows that RunWithElevatedPrivileges checks if the current process is owstimer (the service process which runs SharePoint jobs) and performs no elevation this is the case (the rational here, I guess, is that the timer service is supposed to run under NT AUTHORITY\NetworkService windows account which which has SHAREPOINT\System SharePoint privileges, and thus there's no need to elevate privileges for a timer job).

The only possible solution here seems to be to run the timer service under its usual NetworkService windows account and to run stsadm as a local administrator by storing the administrator credentials somewhere and passing them to System.Diagnostics.Process.Run() trough the StarInfo's Username, domain and password.

It seems everything should work now, but here is another problem I'm stuck with at the moment. Stsamd is failing with the following error popup (!) (Winternals filemon shows that stsadm is running under the administrator in this case):

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

Event Viewer registers nothing except the popup.

The local administrator user is my account and when I just run stsadm interactively under this account everything is ok. It also works fine when I configure the timer service to run under this account.

Any suggestions are appreciated :)"

Asked by: Guest | Views: 324
Total answers/comments: 2
Guest [Entry]

"The SharePoint Timer jobs runs with the SharePoint Firm Admin credentials since, the information get into the SharePoint Config Database. Thus the application pool will not have the access.

For testing the timer job in dev environment, we can temporarily change the application pool account to the application pool account being used for Central Administration."
Guest [Entry]

"Other applications if run this way (i.e. from a timer job with explicit credentials) are failing the same way with ""The application failed to initialize propely"". I just worte a simple app which takes a path of another executable and its arguments as parameres and when run from that timer job it fails the same way.

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©;
}

process.StartInfo.Password = passwordString;

process.Start();

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

process.WaitForExit();

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

AppRunner basically does the same as the above fragment, but without username and password"