Permission scopes in Sharepoint Web Services
In a Sharepoint document library you can set permissions on files and folders in a hierarchy. Each file and folder is a member of a permissions “scope”—either its own or one inherited from its parent. Every scope has a list of associated users and groups, each of whom has a permission mask stating what they can or can’t do.
Turns out that using the Sharepoint Web Services API—the old-school XML one that predates the REST API—the mapping of scopes to permission masks is really hard to find.
After scouring the corners of the Internet I’ve found that it is possible to obtain it. The key is the SiteData.GetContent method. This is a very strange method that returns completely different XML depending on the ObjectType parameter you pass in. Out of all of the possible values, two of them randomly happen to include a list of scopes and the associated permissions. One of them is ObjectType.Folder; the other is ObjectType.ListItem. As far as I can tell the existence of this response data is documented in only a couple of forum posts: this discussion from microsoft.public.sharepoint.windowsservices.development, and another one from the MSDN Q&A section.
If you plug in the right parameters you get some scopes data tacked on the end:
<scopes>
<scope id="{9a31223c-5014-468f-b468-66e49aa41b31}">
<permission mask="206292717568" memberid="4"/>
<permission mask="9223372036854775807" memberid="5"/>
<permission mask="756052856929" memberid="6"/>
<permission mask="1856436902639" memberid="7"/>
<permission mask="206292717568" memberid="14"/>
<permission mask="206292717568" memberid="16"/>
<permission mask="206292717568" memberid="17"/>
</scope>
<scope id="{b26c8cad-f650-4faf-8836-d5e89a66fc3c}">
<permission mask="9223372036854775807" memberid="5"/>
<permission mask="1856436902639" memberid="14"/>
<permission mask="1856436902639" memberid="16"/>
</scope>
</scopes>
One of these will match the scopeId of the item in question. Don’t be fooled by the “retrieveChildItems” parameter—if a subfolder has a unique scope that scope will not be included. An additional GetContent on that particular list item is required. The objectId must be the list’s ID and the itemId must be the index of the file or folder inside the list (the numbers that count up from 1). The folderUrl can be an empty string.
The web documentation I linked above indicates that we’re not allowed to do this.
The change tracking space to report about, either “ContentDatabase” or “Site”. All other objectType values, as defined in ObjectType should not be used. The server may treat all other types as “Site”. Note that “Site” in the context of this parameter actually means site collection.
I think this is a recent change in wording. The PDF version of the documentation explains using the different objectType values in some detail. At the time of writing the scopes are provided as expected on Sharepoint 2010, 2013 and Sharepoint Online. Perhaps they want to take out some of these functions in future versions.