Hey, Where the hell did IP restrictions go?

I spent about 30 minutes looking around IIS7 for the IP restrictions that used to be a easily accessible part of IIS6. 

I finally gave up and emailed jorke asking if they were left out of IIS7.  I got back :

They definately are available, check that you've installed the feature

Now I'm publishing my ignorance about this, I must have missed the checkbox when I was installing the webserver roles.  It was right there under "IP and Domain Restrictions". 

Unable to activate publishing features.

I've seen a bug a couple of times where you for no great reason just can't activate publishing features on your site collection.  I click the button to activate the feature, and absolutely nothing happens, it stays deactivated.  The error appears to be caused because the application pool that the sharepoint site is running as can't activate that particular feature. 

There are a couple of blog posts out there with solutions to these, such as the following :

http://blog.thekid.me.uk/archive/2007/02/05/activating-office-sharepoint-server-publishing-infrastructure-access-denied.aspx
http://brijesh.spaces.live.com/blog/cns!BFBD772FBDA58C6D!196.entry

The fixes suggested are to changing the user your application pool runs as to the one used by CA, but I'm pretty lazy, and that seems like alot of work.

My way of fixing it?  Open up a command prompt and run the following for your site.

stsadm -o activatefeature -name PublishingSite -url http://sitecollection/
stsadm -o activatefeature -name PublishingWeb -url http://sitecollection/site

Same result, much less effort 🙂

Enumerating user and group membership for an entire site.

Stsadm will let you list the groups on your sharepoint site.  It will also let you list the users on your sharepoint site.  It just wont let you enumerate the group memberships of the users on your site. 

This really simple SQL query will list all active users on the site and the groups they are members of.

SELECT Groups.Title, UserInfo.tp_Login, UserInfo.tp_Title, UserInfo.tp_Email
FROM GroupMembership INNER JOIN
Groups ON GroupMembership.GroupId = Groups.ID INNER JOIN
UserInfo ON GroupMembership.MemberId = UserInfo.tp_ID
where userinfo.tp_isactive = '1'
order by userinfo.tp_Login

It does the trick, but not as well as a custom stsadm extension.  Maybe next time.

Fixing Local Activation DCOM errors in the eventlog

I'm sure this has been covered elsewhere, but its been a while since I put anything here.

Every now and again you might find an annoying error popping up in the event logs like the following :

The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
{61738644-F196-11D0-9953-00C04FD919C1} to the user DOMAINusername SID.
This security permission can be modified using the Component Services administrative tool.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
 

This just means that an application pool user does not have launch or activate permissions set for a specific component, or permissions are incorrectly set.

The first task is to track down which component is causing the error, and the easiest way is to take the CLSID and just search the registry for it.  The local service key will probably give you a decent idea of what it is, in the case of the above error it was the IIS Admin Service.

Next open up Component Services and drill down until you find the previously mentioned service.  If you open up the properties and view the security tab you should be able to click edit and modify the "Launch and Activation" permissions.  Add your missing user to this and ensure both "Local Launch" and "Local Activation" are both set, as "Local Launch" is the default permission.

Viola!

Blob Caching and Web Gardens

I've had a case open for a long time in regards to blob caching not functioning properly under MOSS SP1.   Why SP1?  Because we only noticed the problem occuring after SP1 was installed, and the header information (see an earlier post) appeared to indicate that post-SP1 the problems were occuring.

One of the really switched on Australian escalation engineers, who doesn't even specialise in sharepoint, cottoned onto this and figured out that blob caching will not work with web gardens. 

Once you actually know this, its easy to google or livesearch for "blob caching web garden" and find a couple of items, including a technet article on why this happens.

Web garden settings

Web garden settings can also inadvertently cause the BLOB cache to work inconsistently. Because only one process can acquire the lock necessary to manage the cache, successful use the cache depends on which thread services a request. If a Web garden that does not have the BLOB cache lock services a request, the content it sends in response will not have caching directives associated with it. That increases both the number of requests and the amount of the data sent over the network. Therefore, if you intend to use the BLOB cache, you should not use Web gardens.

So now theres a bit of a trade off.  Do you want to have multiple worker processes serving your content?  or would you rather cache your large objects on your local filesystem instead of retrieving them from an SQL server repeatedly?  Thats not going to be easy to answer and its really going to depend on the situation.  I'd suggest if your backend is the bottleneck to your farm, then blob caching would be the most valueable.

Locking down your custom sharepoint code

This might be truely obvious to anyone who is a web developer or an application developer, I'm neither of those.   I recently created a set of custom web parts to administer user access on a hosted MOSS solution, and one of the challenges I have just come across was locking these pages down so that only administrators could use them.

The first one was pretty easy : Only display the actual link in site settings if you are an administrator :

  <CustomAction
    Id="CreateUser"
    GroupId="UsersAndPermissions"
    Location="Microsoft.SharePoint.SiteSettings"
    RequireSiteAdministrator="TRUE"
    Sequence="50"
    Title="Create User">
    <UrlAction
      Url="_layouts/CreateUser.aspx" />
  </CustomAction>

While this hides the menu link, it you know the URL you can still access it without appropriate permissions.  Finding an answer to this was more challenging and when I eventually did find it, it wasn't really the fix I wanted – but it works.

public class ApplicationPage3 : LayoutsPageBase {
    protected override bool RequireSiteAdministrator
        { get { return true; }
    }

    protected override void OnLoad(EventArgs e) {
       // Your code goes here 
    }
}

This (to the non coders) will check to see if the user accessing the page is a Site Administrator.  If Not, they get a standard access denied splash page.  If they are, the code in the // Your code goes here area will be run happily.

Both of these little gems can be found here – http://msdn2.microsoft.com/en-us/library/bb892187.aspx – and I really hope that this saves someone else the amount of time I spent looking for it.

Dodgy header information in MOSS SP1?

Came across this today when inspecting the HTTP headers for a site.

MOSS SP1 HTTP Headers

 Very odd because…

Sharepoint Versions

I'm guessing the headers have not been updated, and its just a typo in the expires statement for the caching.

I'll go more into the caching at a later point, still compiling research.

Renaming a site collection made easy

If you've ever tried to rename a site collection without SP1 for wss installed you know the headache it can be.  A high level overview of this is :

1. Backup Site Collection to file.
2. Delete Site Collection.
3. Create Site Collection with the new name.
4. Restore Site collection from backup taken in step 1.

Its a fairly clunky way to do it, fortunately since SP1 has been released its become really simple :

stsadm -o renamesite -oldurl http://OLDURL -newurl http://NEWURL

Its really made my life easier 🙂

Audit Log Reports

I had a forced introduction to Auditing Reports, a subject which isn't very well convered pretty much anywhere.

What is it?  A history of all actions taken on a site collection since the creation of the site collection. 
Where is it stored?  Dbo.auditData
What does it look like?  Heres a row from the table

Site Id Item Id Item Type User Id Machine Name Machine IP Document Location Location Type Occurred (GMT) Event Custom Event Name Event Source Source Name Event Data
ed91340f-e335-45d2-82f3-c6521eb23fc0 59af845e-b604-436e-9c08-0a948a27d996 Document NT AUTHORITYlocal service _catalogs/masterpage/Editing Menu/CustomSiteAction.xml URL 2008-01-02T00:44:43 View SharePoint

<Version>
<Major>0</Major>
<Minor>1</Minor>
</Version>

How do you get to it?  http://server/sitecollection/_layouts/Reporting.aspx?Category=Auditing or alternatively Site Settings > Site Collection Administratoin > Audit Log Reports

First issue you might come across starts here.  The feature has to be enabled on your site, fairly easy to do :

stsadm -o activatefeature -name Reporting -url http://server/sitecollection/ -force

That will enable the feature on your site collection, allowing you to view the URL listed above.

The usage of this page is pretty straight forward, you can view all of the audit data for your site, or if need be create a custom report.  If you do create a custom report, make sure you do not click "OK" to return to home, you'll miss your report and some of them can take a little while (minutes) to generate, especially if your site has 6 months or more of auditing data.  Even on a site with light usage your auditData table can get big very quickly, for instance one of ours hit 47,000 rows and a content viewing report was over 50 meg being generated.  This was causing timeouts from the site.

The reports will look like XML unless you have Excel installed in which case you will get a look like this :

Site Id (All)
Count of Occurred Event  
Document Location View Grand Total
_catalogs/masterpage/Editing Menu/CustomSiteAction.xml 1 1
Site Images 16 16
Style Library/Custom.css 45 45
Style Library/XSL Style Sheets/Header.xsl 3 3
Reporting Templates/audit1.xml 7 7
Site Images/kc.png 4 4
Style Library/FinalHeader.jpg 33 33
Site Images/initiatives.png 4 4
Style Library/FinalHeader.png 33 33
_catalogs/masterpage/default.master 6 6
Pages/Default.aspx 9 9
Style Library 112 112
Style Library/XSL Style Sheets 9 9
_catalogs/masterpage/Editing Menu 1 1
_catalogs/masterpage 6 6
Style Library/XSL Style Sheets/ContentQueryMain.xsl 3 3
Pages 9 9
Style Library/XSL Style Sheets/ItemStyle.xsl 3 3
administration/default.aspx 6 6
Site Images/contact_list.png 4 4
Site Images/newsletter.png 4 4
Reporting Templates 7 7
Grand Total 325 325

I should also add that if you wish to configure the audit logging you can cut it down a bit.  The "Configure Audit Settings" option under "Site Settings" will allow you to determine which events are audited, its high level but enough to significantly reduce the size of the table if needed.

Forms Based Authentication in MOSS and WSS v3

I've been looking for good documentation on FBA, and short of writing it myself, I came across these on the MS Sharepoint Team's blog.

  • Forms Authentication in MOSS 2007 and WSS 3.0 (Part 1 of 3): Introduction
  • Forms Authentication in MOSS 2007 and WSS 3.0 (Part 2 of 3): Forms Authentication Samples
  • Forms Authentication in MOSS 2007 and WSS 3.0 (Part 3 of 3): Differences Between Forms Authentication and Windows Authentication-in-office-sharepoint-server-2007-and-windows-sharepoint-services-3-0-authoritative-technical-articles-published.aspx
  • Forms based auth has been one of those features I've had difficulty getting to work smoothly, especially in a hosted environment.  Harder still is making it work with an Active Directory membership provider instead of a database.  Why would you want to do this anyway?  It looks prettier.

    A side note also, one of the things I noticed about the above documentation : While very thorough it tells you how rather than why to take certain paths.  For instance a web application is extended rather than using the default zone – why?  Setting the default zone to FBA would mean search would be unable to connect and through a plethora of fairly vague messages in the event logs.  Etc.