Home > Uncategorized > Matching the ScopeId from SPAuditEntry.EventData to SPListItem

Matching the ScopeId from SPAuditEntry.EventData to SPListItem

To match the ScopeId in the EventData property of the SPAuditEntry to a SPListItem you need to use the hidden column ‘ScopeId’ and not the Id property of SPListItem.

Here is what I mean

The following XML is returned in the EventData proprty for a SPAuditEventType of SecRoleBindUpdate. To match the Scope returned in the XML to SPSite, SPWeb and SPList object you would use the Id property of this object, but not for the SPListItem.

<roleid>1073741826</roleid>
<principalid>11</principalid>
<scope>72EEC412-B14B-4EFB-AB95-EA821A3A4C63</scope>

You need to use the ‘ScopeId’ column of the SPListItem

So why can’t I just use the SPAuditQuery.RestrictToListItem method to return the audit entries for that SPListItem.

It doesn’t work, that’s why and this has been confirmed by MS Support.

Here is a workaround that will link the ScopeId to the SPListItem that triggered the audit entry


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace ConsoleApplication1
{
  class Program
  {
  static void Main(string[] args)
  {

string siteUrl = "http://url";
  string listName = "TheList";
  string scopeIdFromItem = string.Empty;
  string scopeIdFromChange = string.Empty;

try
  {
  using (SPSite site = new SPSite(siteUrl))
  {
  using (SPWeb web = site.OpenWeb())
  {

SPList list = web.Lists[listName];

SPRegionalSettings regionalSettings = web.RegionalSettings;
  SPTimeZone timeZone = regionalSettings.TimeZone;

SPAuditQuery query = new SPAuditQuery(site);
  SPAuditEntryCollection auditEntries = site.Audit.GetEntries(query);

foreach (SPAuditEntry auditEntry in auditEntries)
  {
  if (IsSecurityEvent(auditEntry))
  {
  try
  {
  if (auditEntry.Event.ToString().ToUpper() == "SECROLEBINDUPDATE")
  {

// Should really do a proper XML query here, but for demo just do some string stuff
  scopeIdFromChange = auditEntry.EventData.ToString().Substring((auditEntry.EventData.ToString().Length - 44), 36);

foreach (SPListItem item in list.Items)
  {

// Square brackets round the scope id need to be removed
  scopeIdFromItem = item["ScopeId"].ToString().Substring(1, 36);

if (scopeIdFromChange == scopeIdFromItem)
  {
  Console.Write("Event Data : "); Console.WriteLine(auditEntry.EventData.ToString());
  Console.Write("Occurred : "); Console.WriteLine(timeZone.UTCToLocalTime(auditEntry.Occurred));

if (list.BaseType == SPBaseType.DocumentLibrary)
  {
  Console.WriteLine("Security changed on file: " + item.File.ToString());
  }
  if (list.BaseType == SPBaseType.GenericList)
  {
  Console.WriteLine("Security changed on item: " + item.Name.ToString());
  }
  }
  else
  {
  Console.WriteLine("No item found in list " + siteUrl + "/" + listName + " for " + auditEntry.EventData.ToString());
  }
  }
  }
  }
  catch (Exception ex)
  {
  Console.WriteLine(ex.Message.ToString());
  }

}
  }
  }
  }
  }
  catch (Exception ex)
  {
  Console.WriteLine(ex.Message);
  }
  }

private static bool IsSecurityEvent(SPAuditEntry entryToTest)
  {
  SPAuditEventType[] SECURITY_EVENTS = new SPAuditEventType[]
  {
  SPAuditEventType.SecGroupCreate,
  SPAuditEventType.SecGroupDelete,
  SPAuditEventType.SecGroupMemberAdd,
  SPAuditEventType.SecGroupMemberDel,
  SPAuditEventType.SecRoleBindBreakInherit,
  SPAuditEventType.SecRoleBindInherit,
  SPAuditEventType.SecRoleBindUpdate,
  SPAuditEventType.SecRoleDefBreakInherit,
  SPAuditEventType.SecRoleDefCreate,
  SPAuditEventType.SecRoleDefDelete,
  SPAuditEventType.SecRoleDefModify
  };

foreach (SPAuditEventType eventType in SECURITY_EVENTS)
  {
  if (eventType == entryToTest.Event) return true;
  }

return false;

}

}

}

Advertisements
Categories: Uncategorized Tags: ,
  1. Rohit
    21 March 2008 at 5:11 am

    Great post !! Very helpful

    One question though –

    When the settings of a group are changed, an event of type “SecRoleBindUpdate” does get fired and auditing happens, but there are entries for all the possible permission levels. To be more elaborate – Say, a site has permission levels for “Full control”, “Contribute”, “Read” and when u change the permission level of a group (say “Group1”) from “Read” to “Contribute”, then you get 3 audit entries, 1 for each of “Full Control”, “Contribute”, “Read”, so you don’t know what permissionlevels were added or removed, or even the final set of permission levels for the group at the time of audit entry creation. All these these entries contain same Time stamp, item type all other columns as well as EventData XML with just a change in RoleID value in this XML.
    Is this some kind of bug ?
    Point is, how do we know what exact permission levels does the group finally have ? or atleast what was added and what was removed from the old value. Without being able to know this, what use are these entries any ways ?

  2. Eric
    3 November 2008 at 12:56 pm

    Are there other objects that the ScopeID can refer to for the SecRoleBindUpdate event? I have entries in the log that do not match a SPSite, SPWeb, SPList, or SPListItem. I’ve also browsed the SQL database. Any help would be appreciated. Thanks.

  3. Rahul Vartak
    8 January 2009 at 7:32 am

    Very Useful Post..!!

    I’m also getting the same problem as Rohit.. Did anyone find the cause of it or any workaround..??

  4. Eric
    25 February 2009 at 5:41 am

    I don’t understand any of this, but it looks like you know what you’re doing. I found your site trying to research some custom audting of list items in a contact list. Any thoughts or pieces of advice? I’d surely apprecaite it!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: