Tuesday, 27 November 2007

stsadm restore Results in Access Denied 0x80070005

Restoring a content database using stsadm -o restore usually works pretty well. We use this command to restore content backups from our authoring environment to our local development environments.

Because our authoring environment is administered by one of the operations guys, however, I frequently receive an Access Denied error from stsadm that reads like this:

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

The 12 Hive log file offers up the full stack trace but reveals nothing of any real interest. Bear in mind, I'm logged in to my development server (W2k3) using my AD credentials and I'm a local administrator. An earlier log entry tells me stsadm.exe is dealing with a request from me so I know everything is pretty much okay. Of course it's not and I'm getting the above error.

The solution lies with the fact I'm not listed as a site collection administrator for the old site collection that's being replaced.

Luckily, I can change this quite easily. Fire up the the Central Administration console and browse to the Application Management tab. Select the Site collection administrators link in the SharePoint Site Management section and configure yourself (or the relevant account name) as the Secondary Site Collection Administrator. Unfortunately you can't specify a group as either primary or secondary administrator. As a result I'll also have to do this again before the next restore since I'm not a site collection admin in authoring.

Update: Poolio (see comments) and I have both run into this problem all over again after the source site collection is locked before the backup is kicked off. To work around this, remove the lock:

stsadm -o setsitelock -url [url] -lock none 
 

Visual Studio 2008 Pros

Our team recently started development on a new MOSS-based shell for the five regional tourism operators in Western Australia. As per westernaustralia.com, the sites use custom branding and a number of custom web parts. Although we set out using Visual Studio 2005, a number of us in the development team are keen to move to Visual Studio 2008 now that it and .NET 3.5 have been officially released. We’re all excited about 2008 and it makes sense to migrate while the new sites are under development rather than post-release.

What follows is a list of ‘pros’ for moving forward with VS 2008.

Pricing
  • MSDN licenses with Visual Studio 2008 Professional are cheap ($2000USD retail and that gives you a lot more than just Visual Studio...)

Product Maturity and Future Migration

  • Visual Studio is a mature product and moving from one mature release (2005) to another mature release (2008) is expected to be low-risk. .NET 3.5 is also an "additive" release that builds on top of the .NET 2.0 Framework so the risk to an existing code base is very low.
  • The migration path from .NET 2.0 to .NET 3.5 is clear and involves none of the issues encountered migrating an ASP.NET 1.0/1.1 project to .NET 2.0.
  • As Microsoft Content Management Server 2002 moved from a minimum requirement for .NET 1.1 to .NET 2.0 between service packs, there is a small risk MOSS 2007 will take the same approach in a future release
  • Visual Studio 2003, 2005, and 2008 can be installed side-by-side if necessary

Developer Productivity, Maintenance, and Operations

  • Visual Studio 2008 and new C# language features offer productivity increases like Javascript Intellisense and debugging, enhanced CSS and master page support, automatic properties, object and collection initialisers, and extension methods. The new language features have the potential to reduce the amount of code to be written and maintained, thereby simplifying debugging, reducing the learning curve for new developers, and lowering maintenance costs
  • AJAX and .NET 3.0 SP1 are built-in to .NET 3.5, minimising installation requirements on servers and local development environments
  • .NET 3.5 includes cumulative .NET Framework patches and service packs to ensure the operating environment is up-to-date and secure
  • Visual Studio 2008 will allow us to compile existing NET 2.0 projects in the Visual Studio 2008 IDE if necessary

Thursday, 8 November 2007

Clear Your Compiler Warnings

There’s a minor problem with this code—at least as far as the compiler’s concerned. Can you spot it?
...
catch (Exception ex)
{
// Don’t do anything
}
The problem is this: the ex variable is declared but never used and the C# compiler will warn you of the fact.

warning CS0168: The variable 'ex' is declared but never used

Does this matter in terms of how the code runs? Of course not but what if everyone always did this and the explosion of compiler warnings masked a more important warning relating to something else? Building the wa.com solution spits out 56 warnings—42 of which have to do with variables never being used—and the entire warning mechanism provided by the compiler is therefore of very little use to us. If it weren’t for this mess, someone might have noticed this fairly useful warning before now:

warning CS0162: Unreachable code detected

There’s an easy way to get around this problem when it comes to exceptions... just don’t declare the exception variable. This example does exactly the same thing at runtime but compiles without the warning. If you need to inspect the exception while debugging, use $exception in a watch.
...
catch (Exception)
{
// Don’t do anything
}
For all other warnings to do with undeclared or unassigned variables, delete the offending declarations!

As for the example catch statement above, you all know this is bad, bad, bad (in all but the most extreme circumstances), right? Bugs disappear into black holes like this and a more specific exception, at the very least, should be caught instead. A better way would be to remove the try/catch statement, test thoroughly to flush out the defects in your code, and reserve exceptions for truly exceptional circumstances.

How to enable anonymous access for an existing SharePoint web application

It can be a little daunting if you're new to SharePoint and tasked with doing something you've never done before. Can it be done in SharePoint? Will doing it break your site or the entire installation? Is doing it so difficult it's not worth doing? Configuring anonymous access is one of those tasks because you're dealing with SharePoint (and ASP.NET indirectly), your site collection (and potentially your database indirectly), IIS, and occasionally the file system.

At the time of writing there are a number of sites and blog posts out there offering instructions on how to configure anonymous access. Some are extremely detailed--and depending on what you're trying to accomplish, unnecessarily so. Others are a bit vague. For my own sake I therefore thought it might be useful to file this under Things to Remember but I hope it helps you too...

What you'll find below is a detailed step-by-step set of instructions for setting up anonymous access for a fully branded web site like http://www.westernaustralia.com/. The anonymous access site gives internet users the ability to browse the site without having to log in and another site allows content editors to post content updates using their domain accounts.

A bit of background information

In brief, the steps below involve 'extending an existing web application' (that's a SharePoint concept) by creating a sister web app from an existing web app. The extended web app will use the same content database as the original and will be configured to support anonymous access. The top-level site of the database will also be configured to support anonymous access. As a final option, I'll show you how to disable all other types of non-anonymous access.

The following tasks should be completed by a server administrator and assume you have already created a web application the normal way (it might be a good idea to ensure it's working before you begin...)

1. Extend an existing web application

  • Open the Central Administration console and select the Application Management tab.
  • Select Create or extend Web application from the SharePoint Web Application Management section.
  • Select Extend an existing Web application on the next screen.
  • Select an existing web application to extend.
  • Modify the description and configure the port and, optionally, the host header.
  • Set Allow Anonymous to Yes.
  • Set the Load Balanced URL Zone to Internet (you may choose another zone here if you like but Internet generally means anonymous so it's the best option).

Once you've extended a web application, the new (i.e. extended) application seems to disapper from the Central Administration screens: it won't be listed as a web application and it doesn't appear as an option when selecting a web app. You will, however, get a new directory for the extended web app under inetpub\wwwroot\wss\virtualdirectories\ and a new IIS site; you can also remove the extended site from SharePoint if required.

2. Enable anonymous access on the site's corresponding site collection

Although the site collection will be shared by the existing web application and the anonymous web application, the following steps must be completed via the anonymous web application.
  • Browse to the home page of the extended web application
  • Select Site Settings --> Modify All Site Settings from the Site Actions drop-down menu.
  • Under Users and Permissions, select the Advanced permissions link.
  • Select Anonymous Access from the Settings menu.
  • Set Anonymous Access to Entire Web site.

Sites inherit the permissions of their parent by default so if you have any problems with a specific site you can ensure it's set to inherit permission from here as well (browse to the site settings screen for the relevant site first).

If you can’t see the Anonymous Access menu item, either the web app hasn’t been configured for anonymous access (see above or below) or you’re accessing the site via the default zone instead of the internet zone—you must access the site via the internet zone (at the extended URL).

3. Test
  • Browse to the anonymous site in Firefox (or turn off integrated windows authentication if you're using IE); the site should be rendered without the Site Actions menu and other SharePoint controls.
  • Browse to a SharePoint administration screen (eg. /_layouts/settings.aspx) and you should be prompted to supply login credentials.

At this point your site is set up to allow anonymous access but will also prompt you to log in as an administrator if you hit any of the SharePoint screens. This may be desirable but alternatively you may want to lock down external access to your public site; if that's the case, read on...

4. Remove integrated authentication from the anonymous web application (optional)
  • Open the Central Administration console and select the Application Management tab.
  • Select Authentication providers from the Application Security section.
  • Select the Internet zone (this is the zone specified when the anonymous application was extended).
  • Deselect Integrated Windows authentication.
  • Set Enable Client Integration to No.

5. Test

  • Browse to the anonymous site in Firefox (restart any open browser windows if you receive a 401 error immediately after completing step 4). The home page should appear as it did previously.
  • Browse to a SharePoint administration screen (eg. /_layouts/settings.aspx); you should receive a 401 UNAUTHORIZED HTTP error (which, in this case, is appropriate).

6. Troubleshooting

If you run into difficulties (mainly with 401s and 403s popping up where they shouldn't), these ideas may help.

  • Make sure the page you're trying to access is published. It's easy to forget this simple step in all the excitement but if a page (or image, etc) doesn't have at least one published version MOSS won't serve it up
  • Reset IIS--it's quick an easy ;-)
  • Grant the Read & Execute permission to the Authenticated Users group on the anonymous site's web.config and /bin directory (both can be found below Inetpub\wwwroot\wss\VirtualDirectories); do the same again for the authenticated site. Permissions on these files are reset every time the authentication method is changed in SharePoint.
  • Recognise extending a web app creates a new site in IIS and corresponding directory under wwwroot with its own web.config. Ensure the newly-created web.config in the extended site contains everything it needs to; ensure any virtual directories and applications are properly configured
  • Redeploy any solutions, features, etc to make sure everything’s where it needs to be (custom private assemblies in particular)
  • It's possible your custom code is doing something that requires elevated permissions. The Visual Studio debugger will help you locate the culprit. If you can't remove the offending code, you can wrap it using a delegate:

SPSecurity.CodeToRunElevated elevatedAction =
new SPSecurity.CodeToRunElevated(delegate() { /* dodgy stuff */ });
SPSecurity.RunWithElevatedPrivileges(elevatedAction);

  • If necessary, remove the extended web application using the Central Administration console (also remove the IIS site) and start again.

Saturday, 15 September 2007

Potluck 'Round the Hearth

While discussing the issues of public space for resources in Peopleware, the authors quote from Christopher Alexander's A Pattern Language:

"Without communal eating, no human group can hold together. Give each [working group] a place where people can eat together. Make the common meal a regular event."

The authors go on to highlight the relationship between shared space in broader societal terms (the home, in particular) and the office workspace.

As so many of us spend a great deal of time and a large portion of our lives at work, I believe strongly in extending my definition of "family" to include the people I work with. This fits naturally with the hierarchical structure found so often in work places: my immediate circle of co-workers becomes my brothers and sisters; my managers becomes parents, grandparents, uncles, and aunts; other colleagues in the organisation become cousins and second cousins.

From this mindset (and, admittedly from a mindset that includes fun and enjoyment!), I introduced my team to the potluck lunch about a year and a half ago. The potluck concept was not my idea: I attended a party held outside work by a colleague from my previous employer and the party was themed around the potluck; the people and layout of the workspace of my new employer simply allowed me to suggest we bring the team together on a regular basis and everyone bring a single dish of food.

Although we don't measure many things at Tourism--let alone productivity increases, the potluck lunch concept has proven successful in general. At the very least, it's a great opportunity to sit back with my work family, indulge in new and interesting food, and have a chat... a scheduled group downtime. It's also been an interesting way to introduce new team members to others in the office and give them a sense of how we work and what it feels like to be a part of our team.


We aim for a monthly potluck lunch and usually go in for some kind of theme. When our first potluck was held, we had a very diverse team and everyone brought food representative of their home culture. We'll also hold a goodbye potluck when someone leaves the team.

The rules of potluck are few and simple:
  1. Each person only brings enough food to feed one to two people (or a single dish);
  2. Each person tries their utmost to make something at home the night before--food purchased the day of the potluck is usually a rush job and tends to be deep-fried;
  3. Alcohol is a suitable food substitute (but this works at Tourism).

We don't usually plan who's bringing what--it usually just works out. As we do have a few vegetarians about we try to cater for them and generally try to arrive at a balance of savoury vs sweet (dessert is always nice!).

Thursday, 13 September 2007

Web 2.0 Graphic Design

Ever wonder what makes the latest breed of web site so attractive? http://www.webdesignfromscratch.com/ certainly has and the author has kindly produced a number of well-written articles on how to design a good looking, functional site.

There's a lot of material to go through on this site but it's all very well organised and worthwhile reading.

Burp. Excuse me.

I had a look at Burp proxy recently. If you haven't heard of Burp before, it's a debug proxy that has one unique advantage over the likes of Fiddler: you can manually intercept, modify, and forward individual requests and responses.


Burp is a little Java app and you don't need to install it in order to get up and running. Although the program worked as advertised, my biggest gripe is that you have to manually configure your browser proxy settings to use localhost:8080--Fiddler just works by comparison).



As I'm on a corporate network, I also had to figure out where to configure my domain account/password. The server returned security errors without this. Once set, it's done but I'm naturally wary of supplying my password to a potentially "black" app like this (I run as Admin on my dev box...); our security policy also requires I change my password every thirty days so this is just one more location I need to update my password every month.

The proxy works as advertised, stopping at every request/response passing through and allowing you to modify it, drop it, or forward it on. You can exclude requests for certain media types and automatically modify other aspects of the headers or content. I'm primarily using the proxy to inject an X-Forwarded-For header.

Wednesday, 12 September 2007

German site ist wunderbar!

The German version of the www.westernaustralia.com site will launch officially tomorrow via Minister Sheila McHale but it's live now: http://www.westernaustralia.com/de
This site is just a little bit of my handiwork here at Tourism Western Australia...

Tuesday, 11 September 2007

Reach for the Light


So close... yet so far.

International Resource Identifier Support in .NET 3.5

The September 2007 issue MSDN Magazine contains an interesting article about changes to the System.Net namespace. Among the discussion about sockets and other low-level changes, the authors discuss support for International Resource Identifiers (IRIs) and their benefits over URIs.

http://msdn.microsoft.com/msdnmag/issues/07/09/Networking/default.aspx

I didn't realise it was possible to use non-ASCII characters in a domain name and while many DNS servers don't support non-ASCII domain names, Punicode provides a mechanism to work around this limitation.

So in essence, you can now take a domain name containing Unicode characters (like this: http://微軟香.com) and work with it directly using the URI class. This is certainly a great thing for international visitors to our web sites but as I only read English and French, I was really clinging to the English URLs as the last remaining way to identify our pages in SharePoint! Ah well, modern times, 'tis a global world...