SharePoint security access denied permission corruption problem - Edit Item and Access Workflows

2. December 2008

During SharePoint migration from WSS 3.0 to MOSS, we experienced a very strange permission problem. After migration, whenever a new list or site was created; its edit access was somehow revoked. Not even system account could edit item??? This was a peculiar problem because user was unable to edit list items and was unable to run associated workflows.

After digging deep into the problem, we eventually found out that "PermMask" field was corrupted. It needed "RenderXMLUsingPattern" attribute to be true.

To fix it, you can refer to the following code which fixed this security problem for us :)

using(SPWebweb = newSPSite(args[1]).RootWeb)

{

web.AllowUnsafeUpdates = true;

bool excludeLists = ContainsSwitch(args, "excludelists"); //switch to exclude lists

SPField permMaskField = web.Fields.GetFieldByInternalName("PermMask"); //this is the culprit field

permMaskField.SchemaXml = UpdateSchema(permMaskField.SchemaXml);

permMaskField.Update();

Console.WriteLine("Root-Web Effective Permission Mask Updated");

if (!excludeLists)

ShowWebTree(web.Url);

web.AllowUnsafeUpdates = false;

}

private string UpdateSchema(string schemaXml)

{

XmlDocument doc = new XmlDocument();

doc.LoadXml(schemaXml);

XmlNode node = doc.SelectSingleNode("/Field");

XmlAttribute att = doc.CreateAttribute("RenderXMLUsingPattern");

att.Value = "TRUE";

node.Attributes.Append(att);

return doc.InnerXml;

}

private void ShowWebTree(string url)

{

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using (SPWeb web = new SPSite(url).OpenWeb())

{

foreach (SPWeb subWeb in web.Webs)

ShowWebTree(subWeb.Url);

Console.WriteLine("############### Updating Web : " + web.ServerRelativeUrl + "###############");

for (int i = 0; i < web.Lists.Count; i++)

{

try

{

SPField permMaskField = web.Lists[i].Fields.GetFieldByInternalName("PermMask");

permMaskField.SchemaXml = UpdateSchema(permMaskField.SchemaXml);

permMaskField.Update();

Console.WriteLine("Updating List \"" + web.Lists[i].Title + "\" ......");

}

catch { }

}

}

});

}

For thos who are not aware of how to use this code as is, follow these comments, thanks to Rob:

I came back here to copy the URL to pass on so a friend and noticed Alex's message. I guess I could have provided more information on what I did.

1) I used Visual Studio 2005 (configured with SharePoint DLLs available)
2) I created a C# console application
3) There should be some using statements that appear automatically. In addition to these, I added:
using Microsoft.SharePoint;
using System.XML;
4) The first statement of the code listed above appears as follows:
namespace <MYNAME>
{
class Program
{
static void Main(string[] args)
{
using (SPWeb web = new SPSite(args[1]).RootWeb)
5) If you cut and pasted the original code above from the web, the spacing is off - the colors helped me sort it all out.
6) I had to add the keyword static in front of all the functions in the original code:
private static string UpdateSchema(string schemaXml)
private static void ShowWebTree(string url)
7) The ContainsSwitch call really had me confused because I couldn't find it. I surmised that it must be something that each programmer creates on his/her own. I found a ContainsSwitch function that worked for me at www.java2s.com/.../CommandLine.java.htm I created the function as

private static bool ContainsSwitch(String[] arrArgs, String switch_str)
{
for (int i = 0; i < arrArgs.Length; ++i)
{
if (arrArgs[i].Equals(switch_str))
{
return true;
}
}
return false;
}
8) I then compiled this into an executable.
9) I ran it on the SharePoint server. Note that you need two arguments. The first is supposed to be any exclusions but since I did not have any, I just typed the word none. The second argument is the URL to the SharePoint site.

SharePoint

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading