Showing posts with label SPSecurity. Show all posts
Showing posts with label SPSecurity. Show all posts

Wednesday, April 1, 2009

Who is "The Farm Administrator"

New SharePoint developers can often be confused about farm administration.  In the Central Administration -> Operations -> Update Farm Administrators there are a list of users who are farm administrators.  These users are farm administrators but they are not “The Farm Administrator.”  This is actually a wrapper on the local operating system group WSS_ADMIN_WPG which has the description: “Members of this group have write access to system resources used by Windows SharePoint Services.” The group exists locally on each server in the farm and the Central Administration application propagates changes to all servers in the farm.

If you wish to know who is “The Farm Administrator” you need to look at the local group WSS_RESTRICTED_WPG.  This group has the description: “Group for the Windows SharePoint Services farm administrator.” Normally this group contains one and only one user.  This should be the same user that was entered in “Specify Database Access Account” in the “Advanced” SharePoint configuration path.  It is also the same user used for the Central Administration Application Pool  as well as the Timer Service process. Any time a SharePoint object is updated by this user will be marked as changed by “SHAREPOINT\system”. This is “The Farm Administrator.” For the “Basic” SharePoint configuration path this user is always NT AUTHORITY\NETWORK SERVICE. This user is called the “Server farm account” in Microsoft’s Office SharePoint Server security account requirements document.

There is an erroneous perception amongst new SharePoint programmers that this user is all powerful.  This is not quite true.  Here are the facts.

Does “The Farm Administrator” have operating system administration rights on each of the SharePoint servers? NO. If configured correctly (for best security) this user has no power outside of the SharePoint domain.

Does “The Farm Administrator” have read and write rights on all site collections in SharePoint? NO. If configured correctly (for best security) this user does not have direct access to business data. That access has been delegated to the site collection administrators.  There are several methods of indirect access (1) (2), but there is no assumption that any farm administrator can simply ask for any Site or Web in the system.

There is one last group worth mention in this article.  The local WSS_WPG group which has the description: “Members of this group have read access to system resources used by Windows SharePoint Services.” The process users who run SharePoint services are added to this group.  This includes the web application pool users as well as any windows service that SharePoint oversees.

 

Monday, March 23, 2009

Using WindowsIdentity.Impersonate in SharePoint applicatons

Linking legacy code to your SharePoint application can pose several issues.  One of these issues is how to run the code as the correct user.  When threads enter your business logic through IIS and SharePoint they already impersonate the user connecting to the Web Application.  Threads in the SPTimerService run as the timer service process user. Threads in your custom SPWindowService run as the service process user that you have specified.  Getting your thread to assume the right WindowsIdentity can be a challenge.

WindowsIdentity.Impersonate should not be used as a method to access SPSite objects in pure non-legacy SharePoint applications.  That should be done by passing an SPUserToken object into the SPSite constructor.  Still legacy code may require the change in WindowsIdentity and glue code may access the SPSite object to communicate data back into SharePoint.  There are two steps to accomplishing this. 

First convert the SPUser to a WindowsIdentity. To accomplish this, create the user principal name (UPN) for the user.  Then instantiate a new WindowsIdentity using the UPN.

private static string GetUpn(SPUser spUser)
{
    string[] tmp = spUser.LoginName.Split('\\');
    System.DirectoryServices.ActiveDirectory.Domain domain =
        System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();
    return tmp[1] + "@" + domain.Name;
}
.
.
.
SPUser spUser = GetMySPUser();
WindowsIdentity spUserIdentity = new WindowsIdentity(GetUpn(spUser));

Restrictions: This approach will only work when the user is actually a member of the Domain.GetCurrentDomain.  Otherwise you need to search for the domain name through the active directory service. Also this approach will only work if the process user has the local security policy “Act As Part of the Operating System” = “true”.  By default the NT Authority\Network Service user has this privilege. Additionally the WindowsIdentity instantiation is also restricted to the Server 2003 or Sever 2008 operating systems, but so is SharePoint.

Next perform the impersonation.

WindowsImpersonationContext context = spUserIdentity.Impersonate();
try {
    MyLegacyData data = ExecuteLegacyLogic();
    using (SPSite site = new SPSite(mySiteId))
    {
        using (SPWeb web = site.OpenWeb(myWeb)
        {
            AddLegacyDataResults( web, data );
        }
    }
}
finally
{
    context.Undo();
}

Notes: In the above block the SPSite object access is the same as if were performed using new SPSite(mySiteId, spUser.UserToken).

Restrictions: Never run this code block inside a SPSecurity.RunWithElevatedPrivileges delegate.  This appears to be unsupported by SharePoint.  The resulting SPSite and SPWeb objects will be unusable.  In this condition, a StackOverflowExcetion will be thrown if you attempt to access an SPUser in the SPWeb.Users collection and will bring down the entire process.

Outside of the above restriction, the code appears to work as expected.