7

We are trying to make a site read-only from the code-behind of an application page.

When executing the code-snippet from a timer job or a console application it works perfectly, but it throws an

Access Denied

when run from the code-behind of the application page.

    SPSecurity.RunWithElevatedPrivileges(delegate
    {
        using (SPSite site = new SPSite([Site GUID here])
        {              
            site.ReadOnly = true;
        }
    }

We have tried reflecting what SharePoint does on the application page in Central Admin, but it was not clear why it works there and not on our page (Some internal methods gets the parameter RequireCentralAdmin though, what ever that means)

Any clues?

1 Answer 1

4

RunWithElevatedPrivileges elevates to the AppPool account of the particular WebApp which might not have permissions to change the SPSite because it is not a Site Collection owner/admin.

From http://technet.microsoft.com/en-us/library/hh344224%28v=office.15%29.aspx

Using highly privileged accounts for application pools or services poses a security risk to the farm, and could allow malicious code to execute.

Instead of using RunWithElevatedPrivileges, I'd rather use SPUserToken like this:

SPSite site = new SPSite([Site GUID here], SPUserToken.SystemAccount)
{              
    site.ReadOnly = true;
}

This ensures that the code runs as SharePoint\System which IMHO should have the required permissions.

See also: http://extreme-sharepoint.com/2012/05/30/impersonation-elevation-of-privileges

Using SPUserToken also has the additional benefit of being faster because it doesn't change the Windows Security Context like RunWithElevatedPrivileges does.

6
  • We tried using your code instead (by impersonation instead of elevation). Nothing changed, still Access Denied if setting read-only to false. Interestingly you can set "WriteLocked", "ReadLocked", "Archived" with our first code. It is just the "ReadOnly" that fails terribly Commented Aug 28, 2014 at 12:34
  • I'd some more code to check what account is used with the TimerJob and also what role/permissions it has. I'm starting to believe that FarmAdmin permissions are required.
    – Sig Weber
    Commented Aug 28, 2014 at 12:41
  • But the system account should be Farm admin, right? Or what permissions does this account really hold? Commented Aug 28, 2014 at 12:43
  • AFAIK, yes the system account should be FarmAdmin. Another idea is that special content DB permissions are required but missing. Can you try to run your code from an application page deployed under Central Admin?
    – Sig Weber
    Commented Aug 28, 2014 at 12:46
  • That is in idea, but not really doable in our real-life scenario where users should not have access to CA (right now we are reverting to using a timer job, but it feels like a work-around) Commented Aug 28, 2014 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.