Saturday, 7 June 2008

Revisited: Insufficient Permissions on web.config when delegating administration of a web site to remote users in IIS 7

I have been meaning to return to this since I first posted on it and gave my talk about the remote management of IIS 7 at NxtGenUG Southampton. Well I've finally gotten around to it.

This error occurred when remote administration of an IIS 7 web site and/or application is delegated to an IIS 7 user, and that user attempts to alter a setting of the site/application from a remote machine. The solution that I originally posted was to grant the local Service account modify permissions on the web.config file in question. This always seemed unsatisfactory to me as it quite a sweeping grant that increases the surface area for security issues, breaking with the principal of least privilege as it does. However at the time I first looked into this it was already gone midnight and I had a big day the next day with work, a long drive, and then the talk to give, so I went to bed and decided to look into this again another day.

If you just want the solution then skip now to the bottom paragraph, if like me you believe that the journey is worth more than the destination (and if you've been struggling with this under pressure then I doubt you will) then here is also how I got there.

I finally got around to looking into this further last night (another post-midnight session). I ran procmon.exe (part of the Sysinternals suite) and replicated the issue on a new VM so that I could see what was going on 'under the hood'.

Image showing that the wmsvc process was impersonating the NT AUTHORITY\LOCAL SERVCE account when its' access was denied.

As the image above shows the wmsvc process was impersonating the NT AUTHORITY\LOCAL SERVICE account when it was denied access the web.config file of the site. So it would seem that in giving this account permissions on the web.config file I did the correct thing (I didn't so keep reading).

Something about all of this still puzzled me however, when I look at those events logged in procmon that show the wmsvc process accessing (successfully) the applicationHost.exe process it too is impersonating the NT AUTHORITY\LOCAL SERVICE account. Well you might think that makes sense, wmsvc is after all a service and that is the account that it is impersonating. The strange thing for me was this.

Image showing that applicationHost.config does not hanve any ACL entries for the NETWORK SERVICE account, but does have an entry for 'WMSvc'.

Looking at this what stands out to me are these two things. 1, there is no entry for NT AUTHORITY/LOCAL SERVICE. 2, there is an entry for something called WMSvc.

After a bit of Googling and reading around I have sussed what is going on, and why I couldn't work it out that evening.

With Windows Vista (and so of course Windows Server 2008) Microsoft looked to address the security risks that having services all running as the LOCAL SERVICE account poses. When I set the permissions on the web.config file to allow LOCAL SERVICE I am not just permitting the service that I am interested in (wmsvc) I am permitting any service that impersonates this user. This is after all what bothered me in the first place. Microsoft have introduced a feature termed Service Hardening that addresses this issue. What this means is that I can now give permissions that target a specific service only. Wow, that's a great (and necessary) improvement.

So the solution to the problem is this: give modify permissions to NT SERVICE\WMSvc. Do this and the remote delegated access will work like a dream, and the principal of least privelege will have been adhered to!

My only criticism of the new features in all of this is: why can't IIS Management do this setting of permission for me when I choose to delegate permissions to an IIS User for the management of a site or application? It would be a lot easier!

Friday, 6 June 2008

Team Foundation Server (TFS) 2008 Licensing Change

I'm looking into the licensing for TFS 2008 for my employers as my team are looking to migrate from VSS to TFS (hooray) and I have been asked to take the lead in this work. With TFS 2005 anyone who was going to raise issues (bugs, requests, and the like) in TFS, even if using the TeamPlain web client, had to have a valid CAL. This was a bit of an expensive pain and meant that at my last company (at least when I left) Gemini continued to be used by the Support team to raise and manage bugs, until someone (a ScrumMaster I think) moved them into an appropriate TFS project as a part of the project backlog.

Well with TFS 2008 this situation has changed. CALs are no longer required to raise bugs, add stories, and that sort of thing! This is fantastic news in my opinion as it should help encourage companies to move more wholeheartedly (and more fully) to TFS, a product which I really rate!

I can't wait to get it installed and get the new Conchango Scrum for TFS 2008 addin installed.

Check this blog for more on TFS 2008 licensing.

Wednesday, 4 June 2008

Looking for a good developer

Recently where I work we have been interviewing candidates for developer roles in our team. I have been involved in conducting some of these interviews and this has been causing me to reflect on other interviews I have been involved in, both as candidate and interviewer.

Most of the candidates that I have seen, both recently and over the years, have been fairly strong when it came to their knowledge of C#, SQL, and the .NET Framework. Where typically they fall down is in their understanding of the ways in which these tools can be used to create quality software.

An analogy that has been rolling around in my mind is that of the developer as a builder (I'm sure it's not original to me). Now I'm not a builder (as my g/f would happily attest I'm not even much good at DIY) but it strike me that a good builder has certain key areas of expertise.

A good builder will know the materials that are key to their trade. She will understand the differences between materials, such as between different types of wood, or cement, girders etc...

But there are another set of skills that are important for a builder to possess before you would want them to work for you. Beyond this knowledge of materials a good builder will also know the techniques required to build things from these materials that are fit for purpose.

To build a wall it's not enough to know about bricks and cement, its' important to also know at least some of the types of bond, that's to say the commonly accepted strategies for building the wall.

Of course, what I'm saying and the parallel is not new. The GoF design patterns were inspired by the work of Alexander in the field of architecture (not software). But it is, at least to my mind, a useful analogy. You wouldn't want a joiner (carpenter) that didn't know about types of joints, so why would you employ and trust a developer that didn't know (and couldn't discuss to some degree) some of the common design patterns, or fundamentals of object oriented development.

Tuesday, 3 June 2008

Using TextFieldParser objects and the My library in C# code

I read this article on InfoQ (a great site for information for those that don't know it) and saw that there might be some confusion about whether this useful class could be used in C# projects. The answer of course is yes. Just reference the Microsoft.VisualBasic dll in your project and away you go.

The My library is a little different it does a whole bunch of different things, providing both new methods, and a simplified model for accessing things that are both in the framework and that are specific to the project being worked in. For the new methods reflecting on the Microsoft.VisualBasic assembly soon uncovers these, and from there they can then just be referenced as above (or fronted with a simple facade if you prefer - perhaps extension methods FileInfo.OpenTextFieldParser() anyone). For the simplified navigation of the framework, and project, feature I don't know how that can be done in C#, but why would you want to? You know the framework anyway, right?

Sunday, 18 May 2008

Extension Methods - My new best friend*

No that doesn't mean that I'm going to be [ab]using extension methods everywhere - though I suspect that extension methods could become the new singleton. That said I think that I am really starting to get them. Here's an example.

Last night I'm doing some coding and I want to get some objects that I have written to serialise nicely to Xml. Now I don't want to give them public constructors as they sit within an aggregate, and should only be constructed by the Factory for that aggregate. Also I want to exercise quite a lot of control over the XML that is written. This being the case the use of the XmlSerializer class is pretty much unacceptable to me (see, it's not just because I resent spelling it with a 'z').

Now, pre C# 3.0 I would normally have a method in a helper class somewhere with a method that looked a bit like this.

public static XmlAttribute CreateAttribute(XmlDocument xmlDocument, string name, string value)
{
XmlAttribute newAttribute = xmlDocument.CreateAttribute(name);
newAttribute.Value = value;
return newAttribute;
}

Leaving aside that Helper classes offend me somewhat (if you want to know why then read this book). It would be much nicer if the XmlElement class just had an AppendAttribute method with the suitable overloads which would both create the attribute for me and append it to the element. Well, thanks to the power of extension methods this is very easy to do. Just look at the code below.

public static void AppendAttribute(this System.Xml.XmlElement xmlElement, string name, string value)
{
XmlAttribute newAttribute = xmlElement.OwnerDocument.CreateAttribute(name);
newAttribute.Value = value;
xmlElement.Attributes.Append(newAttribute);
}

public static void AppendAttribute(this System.Xml.XmlElement xmlElement, string prefix, string localName, string namespaceURI, string value)
{
XmlAttribute newAttribute = xmlElement.OwnerDocument.CreateAttribute(prefix, localName, namespaceURI);
newAttribute.Value = value;
xmlElement.Attributes.Append(newAttribute);
}

With this I now just have to make this single, easy, call when I want to add an attribute to an element:

newElement.AppendAttribute("id", _id);

Nice, eh!

* Girlfriend excluded

Tuesday, 13 May 2008

The Price of .Net's Diversity

.Net, since its' inception, has always tried to be a friend to everyone. A truly general purpose set of software development technologies. It offer both RAD and enterprise level development tools, dynamic languages, functional languages, type-safe languages, and OOP languages. With the Entity framework, Astoria, the DLR, dynamic data, and more shortly on the way the incredible breadth of the .Net offerings just continues to expand - and that's without even mentioning any of the open source technologies.

But whilst with this incredible diversity we gain a lot of flexibility we have to pay a heavy price. Perhaps the biggest cost is the discipline we must exercise when we approach problems. .Net makes it very easy, and even seem rewarding, to do things badly.

Whilst something like Ruby on Rails makes it difficult to work following patterns and practices which are not standard in its community. .Net at best does little to encourage what are generally considered good practices (separation of concerns, low coupling, explicit intent, unit testing, etc...), and at worst encourages bad practice.

Take the provider mechanism introduced in ASP.NET 2.0. Yes this makes it quick to bind a data grid to a data source, but the moment that you need to do something beyond a demo app it start to lose its shine and make life difficult. Unfortunately a lot of developers struggle on anyway and concerns that ought to belong to a data or repository layer are placed in the markup of an aspx page. Yes there is an object provider, and as CLSA.NET does, this can be usefully put to work.

Another example is the dataset, invidious things that seem to be an overt attempt to subvert OOP, AOP, or any other good practices.

I could list many more examples. Often these things are a fools gold that promise much but deliver nothing. They lead to more code being written. They make unit testing at best very difficult, and often impossible. They inhibit changes in functionality. They make maintenance and code handovers very taxing.

But what concerns me almost more is that they seem to breed 'wrong thinking' and the proliferation of anti-patterns and code smells. They become a bad influence under whose spells developers, and perhaps even more teams, can fall and remain trapped.

I like the flexibility, and the diversity I get being a .NET developer. I would just like MS to adopt a stronger lead in making it easier for me, and others, to follow good practices. Happily there does seem to be some sight of some cavalry coming over the hill. In the web world the new ASP.NET MVC framework could go a long way to meet this critique, and perhaps Prism in the WPF world.

Thursday, 17 April 2008

Insufficient Permissions on web.config when delegating administration of a web site to remote users in IIS 7

****** Note: This post has been revisited with new, and better, advice here! ******

Preparing a talk I'm giving at NxtGenUG Southampton tomorrow evening on IIS 7s ability to allow the administration of aspects of web sites and web applications to be delegated to non-admins I started to get a really frustrating error.

"Error: Cannot write configuration file due to insufficient permissions"Delegating IIS 7 admin error

I looked into this for a little while, without finding anything of use, before I spotted that the WMSvc (Web Management Service I presume) had explicit read permissions on the applicationHost.config file. Now this user/principal/whatever was no where to be found when I tried to give it permissions to my web app's so I tried giving Service permissions instead, and bingo! It worked. My remote client could now set the permissions I was trying to set.

Now I'm only a Dev, and I'm sure that this is probably not the best (or even a good) solution, so I'm open to any better ideas. What it does strike me though is that this might be a not too bad example of why Admin's don't want to give Dev's like me access to their servers, let alone administrator privileges on them, and so why this facility, which is new in IIS 7, is so great.