Saturday, July 26, 2008 10:45 AM bart

Using Active Directory Lightweight Directory Services (LDS) in Windows Server 2008

Introduction

It’s a while ago I’ve been posting here but as usual there are very good reasons (read: excuses) for it. It’s been incredibly busy finishing our work on the .NET Framework 3.5 SP1 release and lately I’ve been preparing for my TechEd South Africa talks for next week – I’m thrilled to present at this conference. One of my talks covers “LINQ to Anything” about writing custom LINQ providers and in this context I’m showing off LINQ to AD because of its relative simplicity compared to other more extensive LINQ providers.

However, there was a slight problem: I used to drag around laptop domain controllers for a while when doing the Microsoft SchoolServer project for Microsoft Belux a long while ago (at that time Windows Server 2003) but right now it’s a little impractical to do that because my demo machine needs to be joined to our corporate domain and obviously our IT department wouldn’t like (to say the very least) me to carry a full corporate domain controller to some random conference :-). Of course there’s virtualization technology to the rescue but the demo machine I’m using has not quite enough RAM and I’d love to run Hyper-V but the machine isn’t 64-bit capable. Oh well, time to upgrade I guess :-).

So the solution I came up with is to rely on Windows Server 2008’s Lightweight Directory Services (LDS) role, also formerly known as Active Directory Application Mode (ADAM) but now shipping as a built-in role in our server OS product (after being a separate download and a Windows Server 2003 R2 “Disc 2” component). In this post I’ll outline how to set up LDS and how to use it.

 

Preparing the installation

First of all, this post assumes you have a Windows Server 2008 installation up and running already. On to the real matters now. It’s a common phenomenon to try something new at the office and have it working but find it not working on some random flight when preparing for the talk. Here’s a headache-medication saver: loopback adapters. More than once I’ve found network-driven applications now working correctly in a fully disconnected situation for various network stack related reasons, so I realized pretty quickly I didn’t have a loopback adapter installed. Installing one is easy: in Computer Management (now known as Server Manager), go to the Device Manager and add a piece of legacy hardware:

image

Follow the instructions to select the network adapter from the list:

image image image

and let the thing install. Ultimately you’ll have an always (though fake) connected computer, ideal to save presentation missions where networks are always influenced by Murphy’s law :-).

 

Installing LDS

To install LDS, select Active Directory Lightweight Directory Services Setup Wizard from Administrative Tools:

image

This will bring up the wizard that guides you through the installation and configuration of a new LDS instance. The concept of an instance is important to understand – you can regard an instance as a stand-alone (meaning not necessarily related to any domains) Active Directory database that can be reached by clients for typical directory operations over well-known protocols like LDAP. That’s precisely what I need: a light-weight (hence the name) instance of AD that isn’t linked to any AD domain whatsoever and reachable through LDAP (LINQ to AD used to be known as LINQ to LDAP).

Click through the first steps of the wizard to create a new instance – we won’t go into advanced topics such as replication:

image image

Next we’ll give our instance a name, e.g. Demo. This information will ultimately be used to create a Windows service (whose name is prefixed with ADAM_) as well as the database under %ProgramFiles%\Microsoft ADAM\<instance name>\data.

image

Next, we’ll select the port number to listen on. If you’re not running any other directory service yet, the wizard will propose to use ports 389 (LDAP) and 636 (SSL) which are both the typical ports for the respective protocols. Indeed, it will just make your computer look like a typical directory service to client computers. However, if you already have a directory service (be it AD or AD LDS) running or plan to do so, alternative ports in the 50000 range will be proposed. We’ll stick with default 389 but make sure to remember the port number as you’ll need it when writing client apps:

image

Next, the wizard asks to create an Application Directory Partition. Expensive word, simple concept. Essentially an application partition is a part of the hierarchical directory services database that will contain your application’s data, and as every node in such a directory hierarchy it needs to have a distinguished name, e.g. CN=Demo,DC=bartdesmet,DC=local. We’ll create such a partition during the LDS instance creation but you can also choose to do it later (although that will complicate matters and require more code).

image

In the few steps following, the wizard will ask where to store the database – it’s okay to stick with the defaults – and what account to run the service under (Network Service is recommended for a more secure configuration):

image image

Obviously services need some administrator that will be allowed to reconfigure the service (using the ADSI Editor for example, see further), so we’ll have to select an account that will be granted those permissions. You can use local accounts but also accounts from the domain the computer is joined to (as I’m doing below):

image

Last but not least, we’re presented a list of LDF files that can be imported in the instance. These get installed under the Schema partition of the instance and carry the schema data for various classes available in the instance to store data with:

image

I’m just selecting MS-User.LDF for now. It’s interesting to know where the wizard gets these files from: %systemroot%\ADAM\*.LDF. In fact, LDF files are just text files that look like this (for a full LDF file, see your installation):

#==================================================================
# @@UI-Description: AD LDS user class and related classes.
#
# This file contains user extensions for default ADAM schema.
# It should be imported with the following command:
#   ldifde -i -f MS-User.ldf -s server:port -b username domain password -k -j . -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
#
#==================================================================

# Attributes

dn: CN=Serial-Number,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: Serial-Number
attributeID: 2.5.4.5
attributeSyntax: 2.5.5.5
isSingleValued: FALSE
rangeLower: 1
rangeUpper: 64
showInAdvancedViewOnly: TRUE
adminDisplayName: Serial-Number
adminDescription: Serial-Number
oMSyntax: 19
searchFlags: 0
lDAPDisplayName: serialNumber
schemaIDGUID:: MnqWv+YN0BGihQCqADBJ4g==
systemOnly: FALSE

The idea is simple: for each of the class attributes you’ll find a definition. Notice the file also has a comment for the ldifde (a command-line tool) invocation if you want to import LDF files after running the wizard.

Finally, the wizard is ready to do the installation:

image image

 

Verifying the installation

Time to check what the wizard has installed. First, you’ll find a file containing the EDB instance database:

image

and in the Service Control Manager a new service will have been registered with the name ADAM_Demo which should have been started by the wizard already:

image

Using the LDP tool (Start, Run, ldp.exe) we can connect to the instance. Use Connection, Connect and specify the name of the machine (localhost):

image

Next, do a bind using the current credentials:

image

and go to View, Tree to display the contents of the database, for example connecting to our application partition:

image

The instance will obviously be pretty empty (still):

image

In addition you can use ADSI Edit from the Administrative Tools to connect to the instance to see the imported schema data:

image

Right-click the root node and choose Connect To. The connection settings should look like this:

image

In the Schema list you’ll find CN=User which we imported (amongst others) earlier during the execution of the wizard. Search for “dn: CN=User,CN=Schema,CN=Configuration,DC=X” in the LDF file to find the import:

image

 

Using it

Finally we’ll write a tiny little bit of System.DirectoryServices code in C# to use the instance. Make sure to import the System.DirectoryServices assembly in Visual Studio:

image

and write the following piece of code:

using System;
using System.DirectoryServices;

namespace PopulateLdap
{
    class Program
    {
        static void Main()
        {
            DirectoryEntry entry = new DirectoryEntry("LDAP://localhost/CN=Demo,DC=bartdesmet,DC=local");
            foreach (DirectoryEntry e in entry.Children)
                Console.WriteLine(e.Name);

            DirectoryEntry user1 = entry.Children.Add("CN=bartde", "user");
            user1.Properties["givenName"].Value = "Bart";
            user1.Properties["sn"].Value = "De Smet";
            user1.CommitChanges();
            entry.CommitChanges();

            foreach (DirectoryEntry e in entry.Children)
                Console.WriteLine(e.Name);
        }
    }
}

where the LDAP path specified should obviously point at the application partition created above. Execution looks like:

image

and LDP will show the new directory entry:

image

Ready to rock!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Comments

# Dew Drop - July 27, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - July 27, 2008 | Alvin Ashcraft's Morning Dew

# TechEd 2008 South Africa Demo Resources

Saturday, August 09, 2008 7:39 AM by B# .NET Blog

Last week, I had the honor to speak at TechEd 2008 South Africa on a variety of topics. In this post

# Recent URLs tagged Administrator - Urlrecorder

Tuesday, May 19, 2009 4:46 AM by Recent URLs tagged Administrator - Urlrecorder

Pingback from  Recent URLs tagged Administrator - Urlrecorder