<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>ADXSTUDIO</title>
        <link>http://blogs.interakting.co.uk/danmatthews/category/35.aspx</link>
        <description>Articles related to the ADXSTUDIO CMS</description>
        <language>en-GB</language>
        <copyright>Dan Matthews</copyright>
        <managingEditor>dmatthews@businessdecision.co.uk</managingEditor>
        <generator>Subtext Version 1.9.5.177</generator>
        <item>
            <title>EPiServer vs. Open Source</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2008/11/11/episerver-vs.-open-source.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Interakting use both Open Source and proprietary products to deliver solutions for many companies. We always try to select the best tool for the job, and when it comes to Content Management it is no different. We have a range of tools we consider using including various Open Source tools (e.g. &lt;a href="http://www.nuxeo.com/"&gt;Nuxeo&lt;/a&gt;, &lt;a href="http://www.dotnetnuke.com/"&gt;DotNetNuke&lt;/a&gt;) and also our proprietary offerings (&lt;a href="http://www.episerver.com/"&gt;EPiServer&lt;/a&gt;, &lt;a href="http://www.adxstudio.com/"&gt;ADXSTUDIO&lt;/a&gt;). In the context of many projects it would certainly be possible to deliver a ‘successful’ project in either a proprietary or an Open Source solution. However, when we consider budgetary, functionality, deadline, support and longevity constraints, all of these areas are problematic in the Open Source arena, whereas proprietary systems such as EPiServer can provide an arguably better and more cost-effective solution. This article discusses some of the reasons for this. The majority of 'pure CMS' sites we deliver are on the EPiServer platform and so this will form the basis of our discussion. Interakting is an EPiServer Solution Partner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Budgetary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With a proprietary CMS such as EPiServer, the main costs are ‘up front’. The client would be buying a licence to use EPiServer CMS, and the cost of this covers the effort and time taken by the vendor to develop and support the product. This means that the vendor does not need to find other ways to recoup their costs beyond the licence fee and an optional small annual support fee. The client can therefore budget for the outright licence as a clearly transparent and defined cost.&lt;/p&gt;
&lt;p&gt;Open Source costs are far less clear, as companies who ‘own’ an Open Source initiative may give the software away ‘free’ but then seek to recoup their costs, even if only running costs. This is usually done by support contracts, consulting or selling additional ‘modules’. It is easy to be trapped into a ‘free’ product and then find that the actual cost is far higher.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Functionality&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As proprietary systems are designed to be sold as widely as possible to reach the maximum number of customers, functionality in proprietary systems is usually excellent and if additional functionality would assist their sales then the company owning the product will often update their core product or provide value-add modules at low or no cost. This is very much the case with EPiServer, who have grown rapidly due to their responsiveness to customer demands and now have many thousands of seats worldwide. The CMS is particularly user-friendly and intutitive and can be used by novice users without the need for costly training.&lt;/p&gt;
&lt;p&gt;In the Open Source arena this becomes more complex. The popular view is that the community ‘works together’ to build a product for the good of the community. This works well, to a point, but ultimately people are not entirely altruistic. Sooner or later (and sometimes always) they only contribute to things that benefit themselves. This means that the ‘out of the box’ product is often minimal functionality, and even if it is fairly well featured then those features are often not very flexible and designed for the use of the company that commissioned them with specific needs. It is unlikely the community will help add or update functionality and therefore it is left to the project team to do so, which can be fairly hard and time consuming. User training is likely to be required, particularly post deplyoment when users change jobs and new users need to work with the CMS. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deadline&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a general rule, any proprietary systems must be designed to provide a very rapid solution as this is a key selling point since the market is very competitive and unforgiving. In this regard EPiServer stands up very well which is one of the many reasons that Interakting has selected this tool. The well-featured out of the box nature of EPiServer, together with the well-documented and supported APIs, mean that a robust solution can be built rapidly and efficiently. The tools are built with the clients business needs clearly in mind as much as the developers.&lt;/p&gt;
&lt;p&gt;In an Open Source project, it has generally built by developers with a very code-centric approach. There is an expectation that the basic product will be customised by developers as needed, and the out-of-the-box functionality capability is usually minimal. Even with ‘starter’ kits for a particular tool, there is often a large amount of code and customisation to be done. Agencies promoting open source solutions capitalise on this aspect as it is very lucrative to develop the added functionality needed for more complex reqirements such as multi-lingual non-Latin support &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With EPiserver, as part of the licence agreement, the vendor undertakes to provide support and their reputation relies on this support being accessible and effective. The support is also usually rapid and efficient to respond with managed Help Desks staffed by knowledgeble individuals. They are able to respond with authority on support issues as they designed, wrote, maintain and own the codebase.&lt;/p&gt;
&lt;p&gt;For an Open Source tool, the support is either an expensive add-on from the company providing the tool or is community based. If a company is supporting a tool this is often not so much of a problem, although there is an issue that they are supporting code that they quite possibly did not write. From our experience (remember that we also work with Open Source solutions when we feel it appropriate), support from the community is often slow and inadequate for projects that have a critical path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Longevity&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;EPiServer is committed to the products they sell and even if they discontinue a product will generally provide migration or upgrade paths. Generally speaking, it will also be clear in advance whether a product will be passing out of support and therefore a proper exit or migration strategy can be planned well in advance. EPiServer is also helpful in that, in the event of it ceasing to trade, it has made its code available to its licensees through an escrow arrangement at a nominal annual cost (although this is optional).&lt;/p&gt;
&lt;p&gt;Open Source projects are often left unfinished or unsupported once the community using them has moved onto something different. As a general rule, Open Source projects have a limited time in which they are actively updated and maintained and once a critical inactivity threshold is reached then they effectively become ‘legacy’, are taken into closed source or amalgamated into something larger. It can also be harder to plan an exit strategy as the ‘lifetime’ of a product is usually unclear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In summary, we believe that for the many projects, the unknowns and variables involved in taking the Open Source route will result in a slightly higher initial cost of development and deployment and a significantly higher cost of ownership over a two year period following the initial go-live.&lt;/p&gt;
&lt;p&gt;By choosing to use a well-proven CMS which uses the .NET framework, a project is grounded on a solid, well defined and tightly costed product and the real cost of deployment and support over a 2-5 year lifetime can be estimated with a far higher degree of accuracy. Ongoing maintenance, functional enhancements and support will also be easier to define and budget. Finally, a large pool of .NET developers able to work with EPiServer and are readily available at competitive day rates meaning the client has total flexibility and would not be locked into any single supplier in the future.&lt;/p&gt;
&lt;p&gt;If you're looking for a CMS solution for your web site, &lt;a href="http://www.interakting.co.uk/en-gb/additional-menu/contact-us/"&gt;shouldn't we be talking&lt;/a&gt;?&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/360.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2008/11/11/episerver-vs.-open-source.aspx</guid>
            <pubDate>Tue, 11 Nov 2008 10:58:05 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/360.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2008/11/11/episerver-vs.-open-source.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/360.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Writing your own AD/ADAM permissions editor - Part 3</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2008/02/20/206.aspx</link>
            <description>&lt;p&gt;In my last post we discussed the DACL and how to get the Access List from a Directory Entry object. We finished the post by grabbing our (D)ACL as an &lt;a href="http://msdn2.microsoft.com/en-us/library/system.security.accesscontrol.authorizationrulecollection.aspx"&gt;AuthorizationRuleCollection&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post we are going to look at what that collection contains; a set of &lt;font face="Arial"&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/4869cs60.aspx"&gt;AuthorizationRule&lt;/a&gt; objects. Just to make things a little more interesting, the AuthorizationRuleCollection can contain two types of rule - Access Rules (for the DACL) and Audit Rules (for the SACL). As we are looking at the DACL rather than the SACL we will be looking at a type that is inherited from the AuthorizationRule called an &lt;a href="http://msdn2.microsoft.com/en-us/library/hy5zbkx0.aspx"&gt;AccessRule&lt;/a&gt;. If you were dealing with Audit Rules you would use the AuditRule type but we're not looking at those - we know that we only have AccessRule objects because we called the GetAccessRules method. If we wanted the SACL, or Audit Rules, then we'd call... yes you guessed it... GetAuditRules.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;So we have our AccessRule objects. What does an AccessRule actually consist of? You can look on MSDN but frankly that won't help you too much. There isn't many properties or methods. This is because we actually want to deal with an object that is inherited from THAT one! Specifically, we want to deal with &lt;a href="http://msdn2.microsoft.com/en-us/library/system.directoryservices.activedirectoryaccessrule.aspx"&gt;ActiveDirectoryAccessRule&lt;/a&gt; objects. So lets put this in perspective. We have our AuthorizationRule collection, but what do we actually want to work with?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;System.Object&lt;/strong&gt; - everything inherits from this&lt;br /&gt;
&lt;strong&gt; System.Security.AccessControl.AuthorizationRule&lt;/strong&gt; - what we started with&lt;br /&gt;
&lt;strong&gt;  System.Security.AccessControl.AccessRule&lt;/strong&gt; - we know we want a DACL&lt;br /&gt;
&lt;strong&gt;   System.Security.AccessControl.ObjectAccessRule&lt;/strong&gt; - adds some stuff, don't worry about this&lt;br /&gt;
&lt;strong&gt;    System.DirectoryServices.ActiveDirectoryAccessRule&lt;/strong&gt; - Bingo!&lt;/p&gt;
&lt;p&gt;This is one of the real gotchas of developing with ACLs because unless you know to jump to a class in another namespace you could get as far as an ObjectAccessRule and get stuck there. Thankfully, once you know you know and it's not really as bad as all that. Yes, phew :)  All we need to do is just cast our AuthorizationRule all the way to an ActiveDirectoryAccessRule:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;foreach (ActiveDirectoryAccessRule rule in aclRules)&lt;br /&gt;
{&lt;br /&gt;
    // do stuff&lt;br /&gt;
}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;So now, at last, we have our rule and we can have a poke around it. Now bear with me on this one because it's a little cryptic, but you need to know what every part of a rule does. &lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;BREAKOUT:&lt;/p&gt;
&lt;p&gt;Here's a little something for you to consider as this point. Any ACL editor you write should be able to deal with EVERY aspect of an ACL. Why? Well, it's down to the way the API works.&lt;/p&gt;
&lt;p&gt;As we'll see later, the API provides ways to delete and add rules, but &lt;em&gt;not to edit rules&lt;/em&gt;. You cannot just edit a particular attribute of an ACL without having to worry what all the rest do because there is no method to do that. This means that if you are working on existing rules, you effectively have to rebuild them &lt;em&gt;from scratch&lt;/em&gt; with any appropriate change and then re-add them. If you start ignoring stuff on the existing rule when you rebuild it from scratch then you'll lose information.&lt;/p&gt;
&lt;p&gt;For example, lets say you have an ACL that says "Allow John Smith to Add, Remove and List the Contents of all types of Foobar objects but only if they are direct children of the current object".  If you miss one of the ACL properties, you could miss the fact that this only applies to Foobar objects. You could then end up with "Allow John Smith to Add, Remove and List Contents of all types of objects that are direct children of the current object." You can see that this could lead to all sorts of undesirable consequences!&lt;/p&gt;
&lt;p&gt;An interesting aside is that the permissions editor for Active Directory / ADAM (ADSIEdit Security) does not fully support all aspects of the Active Directory permissions model. Yes, I know thats crazy. It is possible though to do some clever things with inherited permissions and objects they apply to that will be wiped out if you use the security tools. They are quite advanced permissions and it's unlikely you would come across them. I guess the tools MS provide cover 99% of cases and they figured that was good enough, and besides they probably doubted anyone would be doing anything that advanced programatically. &lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;So what can our rule contain? &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;AccessControlType - Enumerator that determines whether this is an Allow or Deny rule. It's a bit clunky, but lets say you want to Allow A and B rights to an object and Deny X and Y rights. You will actually need two rules to do this, one for the Allow and one for the Deny. Note also that if you Allow A and B rights and Deny B and C, for example, then B will be denied as the denial ALWAYS overrides. &lt;/li&gt;
    &lt;li&gt;AccessMask - This is the access mask we set to do the rule search earlier, so it's not really that important other then for interest &lt;/li&gt;
    &lt;li&gt;ActiveDirectoryRights - OK, this is the meaty bit :)  We'll give this better coverage later &lt;/li&gt;
    &lt;li&gt;IdentityReference - This is where the identity of the user/group to whom this ACL is applied is stored. If you remember on our previous post we discussed SIDs and NT Accounts - well this is where that information will be. &lt;/li&gt;
    &lt;li&gt;InheritanceFlags - Sets whether inheritance applies to containers or leaves... we'll always use Container or a bitwise of Container and Leaf &lt;/li&gt;
    &lt;li&gt;InheritanceType - Determines how far down the tree below this object the ACL applies &lt;/li&gt;
    &lt;li&gt;InheritedObjectType - this is the type of object that can inherit this rule. For example, you could say 'only allow Computer objects to inherit this Rule'. It is stored as an object GUID and we'll show how to work out what it is later. &lt;/li&gt;
    &lt;li&gt;IsInherited - shows whether this is an inherited rule. If it is, then chances are we'll show it in our ACL editor as a read-only rule as it should be changed up the tree where it actually originates &lt;/li&gt;
    &lt;li&gt;ObjectFlags - info flag that we shouldn't need to worry about unless we build in some checking code &lt;/li&gt;
    &lt;li&gt;ObjectType - an object to which this rule applies, which in reality will be some kind of property in the AD Schema. For example if this is a read permission rule then this could say 'allow reading of property X' &lt;/li&gt;
    &lt;li&gt;PropagationFlags - shouldn't ever need to worry about this as it's related to inheritance but the inheritance is more important &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even though I've explained the properties a bit, you're probably not much better off than when you started. I think it best to give an example of a rule and we can see where the various attributes fit into things.&lt;/p&gt;
&lt;p&gt;Lets say you have a rule like the following:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"Allow John Smith to Read or Change the displayName property of all objects of type User on every child object of this DirectoryEntry, but not this entry itself"&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In terms of our object properties, we say the following:&lt;/p&gt;
&lt;p&gt;"[AccessControlType: &lt;strong&gt;Allow&lt;/strong&gt;] [IdentityReference: &lt;strong&gt;SID for John Smith&lt;/strong&gt;] [ActiveDirectoryRights: &lt;strong&gt;Read and Change&lt;/strong&gt;] [ObjectType: &lt;strong&gt;Object GUID for displayName&lt;/strong&gt;] [InheritedObjectType: &lt;strong&gt;Object GUID for User&lt;/strong&gt;] [InheritanceType: &lt;strong&gt;Descendents&lt;/strong&gt;]"&lt;/p&gt;
&lt;p&gt;By this point we should have a basic understanding of the kind of information that we have on an ActiveDirectoryAccessRule, which is the basic building block for an ACL. In my next post I'll look at a bit more detail at what information some of these properties actually contain and where we can find what they mean.&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/206.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2008/02/20/206.aspx</guid>
            <pubDate>Wed, 20 Feb 2008 08:48:23 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/206.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2008/02/20/206.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/206.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Writing your own AD/ADAM permissions editor - Part 2</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2008/01/02/131.aspx</link>
            <description>&lt;p&gt;In my last post on creating your own AD/ADAM permissions editor I covered the basic terminology used with Active Directory and also introduced the DirectoryEntry class. In this post I will discuss how to read, filter and understand an ACL on a DirectoryEntry.&lt;/p&gt;
&lt;p&gt;The first thing we need to decide is what part of the ACL we want to read. As mentioned in the glossary on my last post, an ACL actually contains TWO types of ACL record - those to do with reading/modifying the object itself (DACL) and those to do with reading/modifying the audit settings (SACL). For the purposes of what we are doing, we're only bothered about the DACL. Let's see how we identify in code what type of ACL records we want to see:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;myDirectoryEntry.SecurityMasks = SecurityMasks.Dacl;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;And it really is that easy. It feels a bit odd just setting this on the DirectoryEntry and then (for now) doing nothing with it, but the reason for this is that it is a mask which is applied when you do security-based operations on the DirectoryEntry. The SecurityMasks enumerator contains other values such as Group, Owner, Sacl or None (which shows all records in the ACL of every type... nice and confusing).&lt;/p&gt;
&lt;p&gt;Setting the mask is all well and good, but now we actually need to get the ACL - or, strictly speaking, the DACL - and see what entries it contains. To do that we use the 'ObjectSecurity' property of the DirectoryEntry. This will return an &lt;a href="http://msdn2.microsoft.com/en-us/library/system.directoryservices.activedirectorysecurity.aspx"&gt;ActiveDirectorySecurity&lt;/a&gt; object which is really a worker class to get and modify ACLs. An example of getting this is shown below:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;ActiveDirectorySecurity securityWorker = myDirectoryEntry.ObjectSecurity;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;As this point we are ready to start getting our ACLs, and this is where it starts to get a little more complex. You see, the type of 'user' to which an ACL entry refers is represented as an IdentityReference, as far as .NET is concerned. Only problem is that when you ask for the ACL, you don't ask for the entries by IdentityReference, but rather you have to ask for them by either NT Account or by SecurityIdentifier (SID). The reason for this is because the information for the account can be 'wrapped' in different ways. Sometimes you'll need one wrapper, sometimes another. Typically, the SID would be something you'd pass around as an ID, but the NT Account would be used when you want to display an account name. Things are a bit more complex than this, but I'll deal with that later.&lt;/p&gt;
&lt;p&gt;For now, then, let's see how we get that all important DACL from the ObjectSecurity object that we assigned above. The rules themselves are put into a collection of type &lt;a href="http://msdn2.microsoft.com/en-us/library/system.security.accesscontrol.authorizationrulecollection.aspx"&gt;AuthorizationRuleCollection&lt;/a&gt;. First, lets get them as rules with SecurityIdentifier object (SID):&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;AuthorizationRuleCollection aclRules = securityWorker.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;And now lets see how we get them with NT Account details:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;AuthorizationRuleCollection aclRules = securityWorker.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;The two boolean settings are for explicit rules and inherited rules. You can grab everything and then look at the access rule itself to see what object it refers to if you like, or you can decide what kind of rules to grab up front if you prefer. Techie note - When you have an inherited rule it's not always easy to find what object it orignated from. By stepping through the ACLs on the parent objects and asking for explicit rules you can determine what object an inherited ACL started from.&lt;/p&gt;
&lt;p&gt;We are now at the point where we have a read an ACL - filtered to the DACL, in this case - and have a collection of rules ready for us to step through. We have understood that when asking for the rules we have had to choose how to represent the identities of the accounts for the rules. In my &lt;a href="http://blogs.bdnet.co.uk/danmatthews/archive/2008/02/20/206.aspx"&gt;next post&lt;/a&gt; I will explain what an access rule itself consists of and what the various parts of it mean, and how to get that data out.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/131.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2008/01/02/131.aspx</guid>
            <pubDate>Wed, 02 Jan 2008 15:58:21 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/131.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2008/01/02/131.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/131.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Writing your own AD/ADAM permissions editor - Part 1</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2007/11/30/120.aspx</link>
            <description>&lt;p&gt;So we deployed an ADXSTUDIO site onto ADAM (see my earlier post) but the out-the-box permissions editor didn't support ADAM, only full AD. We managed however to override the default permissions editor with our own - more on how we did that with ADXSTUDIO later.&lt;/p&gt;
&lt;p&gt;For now I'd like to take our experiences and do a short blog series on writing your own permissions editor for AD or ADAM by using ONLY the DirectoryServices namespace in .NET2. The Microsoft documentation is pretty poor on the DirectoryServices side of things and badly lacking in examples and explanations. There's plenty of tidbits in blogs here and there and even a couple of  books on the subject, but all of them are lacking in bringing together exactly what you need to know and why. So, by trial, error and sheer pigheadedness, I had to get to the bottom of it all. I'd like to share it with you and hopefully it will be of use.&lt;/p&gt;
&lt;p&gt;To set expectations - I'm not going to plaster my blog with code samples. You're a coder - you write code. You can do that yourself. What I will do is explain what classes you need, why you need them and what you do with them. This will apply equally to doing most things with AD/ADAM permissions, not just writing a permissions editor.&lt;/p&gt;
&lt;p&gt;So firstly let's do a quick glossary/terminology check. There's a lot of acronyms etc. that fly around when talking about permissions and you probably know some or most of them already, but let's summarise them so that we're all starting from the same point:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;AD - Active Directory, Microsoft's LDAP implementation - I might call it 'full AD' by which I mean that it is a domain-wide AD implementation. AD is licensed by CAL and cost can be high &lt;/li&gt;
    &lt;li&gt;ADAM (or AD/AM) - Active Directory Application Mode - a FREE version of AD which runs as a standalone 'instance' as opposed to a domain. It is effectively an LDAP provider for use by an application rather than an enterprise. You can have multiple ADAM 'instances' per server, but an ADAM instance cannot talk to other 'instances' or join a full AD farm. Otherwise, it is identical to AD in terms of API calls. &lt;/li&gt;
    &lt;li&gt;CAL - Client Access License, a way of licensing per-user and typically how Windows Server 2003 / AD is licensed &lt;/li&gt;
    &lt;li&gt;ACE - Access Control Entry - something attached to an object which says that somebody can (or cannot) do something with it. ACE's can be applied to files, websites and AD objects but we're only bothered about ACE's on AD objects. A typical ACE might be something like 'User [John Doe] can [Read the contents] of the AD container [Computers]' &lt;/li&gt;
    &lt;li&gt;ACL - Access Control List - A list containing a number of ACE's. All objects in AD have an ACL which contains the ACE's that apply to that object. &lt;/li&gt;
    &lt;li&gt;DACL - Discretionary Access Control List - There are two ACL's on all AD objects and this is the main one - A strange name for the general permissions on who can do what on the object like read the object, write the object, create children of the object, delete the object etc. &lt;/li&gt;
    &lt;li&gt;SACL - System Access Control List - This is the second ACL on all AD objects and it's actually to do with writing/reading audit entries for the object. We won't be worrying about this one too much &lt;/li&gt;
    &lt;li&gt;LDAP - Lightweight Directory Access Protocol - a standards-defined way of storing information in a directory repository. Usually used just for users and domains but actually a very efficient way of storing many types of hierarchical data. &lt;/li&gt;
    &lt;li&gt;AD Schema - the definition of all the object types in the actual AD repository for a domain (or instance, if using ADAM) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That should be all we need to know for the moment... lets start thinking about what our .NET namespace is.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.directoryservices.aspx"&gt;System.DirectoryServices&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The key class that we'll be using as we go through these blog posts is the &lt;a href="http://msdn2.microsoft.com/en-us/library/z9cddzaa.aspx"&gt;DirectoryEntry&lt;/a&gt; class. Every object within the AD repository is represented as a DirectoryEntry. How does this work when AD stores everything from computer definitions to users to documents? Well, the DirectoryEntry class has a property called 'SchemaClassName' which defines what sort of entry it is. This SchemaClassName will map to an object that you can look up in the AD schema. So the DirectoryEntry is really just a generic container for various types of data in AD.&lt;/p&gt;
&lt;p&gt;A DirectoryEntry has lots of properties and methods, some of which we'll cover as we go, but for now suffice it to say that if you want to write some samples and tests then you can get a DirectoryEntry with literally one line of code using its constuctor, like so (replacing the options in square brackets with their values:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;DirectoryEntry oEntry = new DirectoryEntry([LDAP path], [username], [password]);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color="#3366ff"&gt;DirectoryEntry oEntry = new DirectoryEntry("LDAP://localhost/CN=SomeContainer,OU=mydomain,OU=com", "administrator", "password99");&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Remember to add the 'using' statement to DirectoryServices and include any relevant DLL references when playing with examples.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.bdnet.co.uk/danmatthews/archive/2008/01/02/131.aspx"&gt;Next post - Part 2 - How to read, filter and understand the ACL for a DirectoryEntry object&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/120.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2007/11/30/120.aspx</guid>
            <pubDate>Fri, 30 Nov 2007 11:25:57 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/120.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2007/11/30/120.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/120.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ADXSTUDIO and ADAM</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/19/105.aspx</link>
            <description>&lt;p&gt;According to ADXSTUDIO, you need Active Directory when deploying ADXSTUDIO 2006, &lt;a href="http://docs.adxstudio.com/Default.aspx?DN=6c5d1f19-2106-45bb-b5f5-8fa9d7cdf210"&gt;even if using ADAM&lt;/a&gt;. Fortunately, that doesn't seem to be ENTIRELY the case.&lt;/p&gt;
&lt;p&gt;We've successfully deployed a site using the IUSR account using a local account and still managed to deploy a site fine using ADAM - to a point. Critically, the server is &lt;em&gt;on a Workgroup&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Only problem is the document access and web permissions editors in the administration console. They don't like it :)&lt;/p&gt;
&lt;p&gt;We'll be seeing if we can crack that nut next!&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/105.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/19/105.aspx</guid>
            <pubDate>Fri, 19 Oct 2007 10:13:53 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/105.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/19/105.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/105.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Nuxeo</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/08/103.aspx</link>
            <description>&lt;p&gt;Historically we've been seen as a Microsoft shop within the UK eBusiness division - quite rightly too. As part of the wider B&amp;amp;D group though we have a lot of experience in the Java/Open Source arena to bring to the party as well. For example, currently we provide solutions expertise in all the following ECM/CMS systems:&lt;/p&gt;
&lt;p&gt;SME                 /\       ADXSTUDIO (Closed Source / .NET)&lt;br /&gt;
                        |       Pelikan (Open Source / PHP)&lt;br /&gt;
                        |       EPiServer( Closed Source / .NET)&lt;br /&gt;
                        |       Nuxeo (Open Source / Java)&lt;br /&gt;
Enterprise        \/       MOSS (Closed Source / .NET)&lt;/p&gt;
&lt;p&gt;This means that we've got a solution to fit any client, any size, any budget. It's a nice place to be in this marketplace where there is often an established platform that constrains the system (UNIX/Windows).&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/103.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/08/103.aspx</guid>
            <pubDate>Mon, 08 Oct 2007 14:43:36 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/103.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2007/10/08/103.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/103.aspx</wfw:commentRss>
        </item>
        <item>
            <title>MCTS - MOSS 2007</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2007/09/12/96.aspx</link>
            <description>&lt;p&gt;Well the cram fest paid off - now the MCTS in config. and admin. of MOSS 2007 is under my belt too.&lt;/p&gt;
&lt;p&gt;Now to put this into practice, but before that I have to tie off an EPiServer project and also get stuck into an ADXSTUDIO one!&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/96.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2007/09/12/96.aspx</guid>
            <pubDate>Wed, 12 Sep 2007 09:46:34 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/96.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2007/09/12/96.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/96.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ADXSTUDIO Web Permissions</title>
            <link>http://blogs.interakting.co.uk/danmatthews/archive/2007/07/03/74.aspx</link>
            <description>&lt;p&gt;I've found a little glitch (by design?) in ADXSTUDIO 2006. The scenario is this... I want to give an 'Approvers' group access to approve across the whole site &lt;em&gt;except for &lt;/em&gt;a 'Sensitive' folder, that can only be approved my managers.&lt;/p&gt;
&lt;p&gt;According to ADXSTUDIO, the way to do this is to explicitly GIVE permissions to the Approvers group everywhere except where I don't want them to have permissions. Yeah right. It's a big site :)&lt;/p&gt;
&lt;p&gt;You might think 'no probs, I'll just DENY them access to that one folder'. Nice, in theory... but in practive it spams out a nasty error when you try to do that. I guess it can't handle deny-access being added to an object with grant-access set on it as well (albeit inherited).&lt;/p&gt;
&lt;p&gt;Solution? Resort to ADSIEdit. Locate the Sensitive folder within the AD object hierarchy (no, not easy) and take off the inheritance of permissions. I suggest copying the existing permissions otherwise you'll have fun adding them all in. Then just strip everything but read permissions away from the Approvers group.&lt;/p&gt;
&lt;p&gt;Now, when someone in the Approvers group tries to edit pages in the Sensitive folder, they get an Access Denied error. In the rest of the site, they are able to edit pages.&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/danmatthews/aggbug/74.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dan Matthews</dc:creator>
            <guid>http://blogs.interakting.co.uk/danmatthews/archive/2007/07/03/74.aspx</guid>
            <pubDate>Tue, 03 Jul 2007 10:23:32 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/danmatthews/comments/74.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/danmatthews/archive/2007/07/03/74.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/danmatthews/comments/commentRss/74.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>