Wednesday, June 16, 2010

"The SPPersistedObject, XXXXXXXXXXX, could not be updated because the current user is not a Farm Administrator" craziness in Sharepoint 2010

After upgrading from SharePoint 2007 to 2010 we noticed that our custom job scheduler web part started throwing the following error:

 "The SPPersistedObject, Microsoft.SharePoint.Administration.SPJobDefinition, could not be updated because the current user is not a Farm Administrator".

Since we were running the SPJobDefinition.Update() and related code under SPSecurity.RunWithElevatedPrivileges() I was under the impression that the code already ran as Farm Admin. After banging my head against the wall for a couple hours with no solution I decided to whip out my most trusted tool - Red Gate's Reflector - it never failed me before.

Upon detailed investigation of Microsoft.SharePoint.dll  I discovered that SharePoint guys added a new security feature to all objects inheriting from SPPersistedObject in the Microsoft.SharePoint.Administration namespace. This feature explicitly disallows modification of the above stated objects from content web applications, which is where our web part is running. The error message thrown is therefore very misleading. After some more tracing through the code I found a property in SharePoint API which controls this behavior:

Microsoft.SharePoint.Administration.SPWebService.ContentService.RemoteAdministratorAccessDenied

After setting this property from PowerShell the issue went away with no code changes. The script I used is attached to this post.



24 comments:

Anonymous said...

Are you sure this works, by reading the code from reflector, it seems it doesn't work

public bool RemoteAdministratorAccessDenied
{
get
{
return this.m_RemoteAdministratorAccessDenied;
}
set
{
this.CheckForContentWebService();
if (!base.Farm.CurrentUserIsAdministrator())
{
throw new SecurityException(SPResource.GetString("AccessDenied", new object[0]));
}
this.m_RemoteAdministratorAccessDenied = value;
}
}

The test of CurrentUserIsAdministrator() calls for

public bool CurrentUserIsAdministrator()
{
return this.CurrentUserIsAdministrator(false);
}


The parameter means: (bool allowContentApplicationAccess)

Since it is "false", it means "does not allow content application access".

Anonymous said...

I see it will work if it is run by a PowerShell, since the runner will be system admin.

It worn't work if the API is called from a web application.

Anonymous said...

I am building a web service that creates site collections and sets up an OfficialFileHosts on the SPWebApplication. I was getting the "Access Denied" error until I ran this script. Thanks for the help!

Mike S.

Anonymous said...

The script I used is attached to this post, WHERE IS IT please ?

Anonymous said...

Great script. Worked like a charm.

Matt Moriarty said...

Excellent script - Solved my problem completely.

Seenu said...

I was scracthing my head for last two days.. Finaly one of our developer found this URL and fixed the issue..

Thanks a lot..

elvisinmi said...

IM STILL THE CHEIF OF IMMERMAN SEAL INDUSTRIES NO MATTER HOW MUCH U HACKERS STOLEN

Simone said...

Hello Paul... great post thanks! I am having an issue that may fit this solution or may not... we have set up our DEV and PROD environments exactly the same besides the UAC level (Prod is tighter)... we are now seeing our workflow failing on "item level permission change" only in PROD!
any tips??

Marcelão said...

I <3 you !!!! You resolve my problem :-D

Christophe DK said...

Thanks! I needed to perform 2 extra steps:
- Make sure the application pool user of your web application has db_owner right on the config database
- I had to redeploy the WSP. (maybe an app pool recycle was sufficient)

Anonymous said...

Excellent Script.Worked out for me. BUT, I am not sure how far it is good to run this on Prod environment. Purpose I used it is for creating site collections with relevant content DBs, and we get "access denied" for using API, this will definitely unblock the road. Thankx for this script :).

@SPJeff said...

Thank you! This worked perfectly for the DOC to PDF Event Reciever I coded.

KonMan said...

Thank you. This solved our issue.

Unknown said...

Thank you so much! After two days of searching and cursing, I used the PowerShell script and it solved my Access Denied problem, when setting the content database to read-only.

Anonymous said...

where is the script please?

Anonymous said...

This took care of the problem I was having in a SharePoint 2010 to SharePoint 2013 scenario as well. Activating a Site Feature was returning that I was not a Farm Administrator even though I was.

Unknown said...

where is the script please, I need it asap. Please help.

Anonymous said...

WHERE IS THE FRIGGIN SCRIPTTT???? BULLSHIT SITE IF THE SCRIPT ISNT EVEN HERE - JUST ALL WAFFLE!

Unknown said...

where is the script?

Anonymous said...

The link is broken. It's supposed to be http://cid-3d1aa7b9ba4b05fd.office.live.com/embedicon.aspx/Public/Set-RemoteAdministratorAccessDenied-False.ps1.

Anonymous said...

KB article can be found here that adresses the issue: http://support.microsoft.com/kb/2564009?wa=wsignin1.0

Anonymous said...

function Set-RemoteAdministratorAccessDenied-False()
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration") > $null

# get content web service
$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
# turn off remote administration security
$contentService.RemoteAdministratorAccessDenied = $false
$contentService.Update()
}

Set-RemoteAdministratorAccessDenied-False

Vivek said...

Could you please post the script on the page itself.
I am unable to view attachment.