Applicaiton Security, Part 13

Manipulating ADAM programmatically can be a little challenging. First, the documentation that is installed with ADAM does not cover its programming interfaces. However, that documentation can be found within MSDN, under Networking and Directory Services. Second, while that documentation provides samples in VBScript, Visual Basic and C#, I could only get the VBScript code to work and translated that into C# code myself. When manipulating ADAM programmatically, one uses the same tools as one would use to manipulate Active Directory, which brings us to the last of our challenges. The .NET Framework Class Library includes a DirectoryServices namespace for working with entries in a Directory Service, but that namespace has very limited facilities, which is why I often refer to it as the ghetto of the .NET Framework. The most important class in the namespace, the DirectoryEntry class, has a property called NativeObject that allows one to work with the directory using the COM Active Directory Service Interface library.

 

Here, then, is the code for creating the application directory partition for TaskVision II within ADAM, and for creating a container for users within it.

 

using

System;

using

System.Configuration;

using

System.DirectoryServices;

namespace

Microsoft.DeveloperAndPlatformEvangelism.Demonstrations.TaskVisionII.Utility

{

public class CConfigurator

{

private const string c_sConfigurationSection_Credentials = @"Credentials";

private const string c_sConfigurationSection_ADAMInstance = @"ADAMInstance";

private const string c_sKey_Credentials_UserName = @"UserName";

private const string c_sKey_Credentials_Password = @"Password";

private const string c_sKey_ADAMInstance_ADsPath = @"ADsPath";

private const string c_sKey_ADAMInstance_Server = @"Server";

private const string c_sKey_ADAMInstance_Port = @"Port";

private const string c_sKey_ADAMInstance_Country = @"Country";

private const string c_sKey_ADAMInstance_ApplicationDirectoryPartition = @"ApplicationDirectoryPartition";

private const string c_sKey_ADAMInstance_ApplicationDirectoryPartitionDescription = @"ApplicationDirectoryPartitionDescription";

private const string c_sProvider = "LDAP";

private const string c_sMessage_Exception_Unknown = @"Unknown exception.";

private const string c_sMessage_Exception_Known = @"Exception: ";

[FlagsAttribute]

private enum DIRECTORY_SERVICE_CONTAINER_PROPERTIES

{

HEAD = 1,

WRITABLE = 4

};

[STAThread]

static void Main()

{

try

{

//Read configuration data

System.Collections.Hashtable rConfigurationSection =

null;

rConfigurationSection = (System.Collections.Hashtable)System.Configuration.ConfigurationSettings.GetConfig(CConfigurator.c_sConfigurationSection_Credentials);

string sUserName = (string)rConfigurationSection[c_sKey_Credentials_UserName];

string sPassword = (string)rConfigurationSection[c_sKey_Credentials_Password];

rConfigurationSection = (System.Collections.Hashtable)System.Configuration.ConfigurationSettings.GetConfig(CConfigurator.c_sConfigurationSection_ADAMInstance);

string sServer = (string)rConfigurationSection[CConfigurator.c_sKey_ADAMInstance_Server];

string sPort = (string)rConfigurationSection[CConfigurator.c_sKey_ADAMInstance_Port];

string sCountry = (string)rConfigurationSection[CConfigurator.c_sKey_ADAMInstance_Country];

string sADsPath = string.Format("{0}://{1}:{2}/C={3}",CConfigurator.c_sProvider,sServer,sPort,sCountry);

string sApplicationDirectoryPartition = (string)rConfigurationSection[CConfigurator.c_sKey_ADAMInstance_ApplicationDirectoryPartition];

string sADsPath_ApplicationDirectoryPartition = string.Format("{0}://{1}:{2}/O={4},C={3}",CConfigurator.c_sProvider,sServer,sPort,sCountry,sApplicationDirectoryPartition);

string sApplicationDirectoryPartitionDescription = (string)rConfigurationSection[CConfigurator.c_sKey_ADAMInstance_ApplicationDirectoryPartitionDescription];

bool fExists = true;

//Deterimine if the application directory partition already exists.

try

{

DirectoryEntry.Exists(sADsPath_ApplicationDirectoryPartition);

}

catch(Exception)

{

fExists =

false;

}

if(!(fExists))

{

//Create the application directory partition.

ActiveDs.IADsOpenDSObject rOpenObject = (ActiveDs.IADsOpenDSObject)

new DirectoryEntry(string.Format("{0}:",CConfigurator.c_sProvider)).NativeObject;

ActiveDs.IADsContainer rContainer = (ActiveDs.IADsContainer)rOpenObject.OpenDSObject(sADsPath,sUserName,sPassword,(

int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_USE_DELEGATION|(int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_FAST_BIND|(int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_SECURE_AUTHENTICATION);

ActiveDs.IADs rObject = (ActiveDs.IADs)rContainer.Create("organization",

string.Format("O={0}",sApplicationDirectoryPartition));

rObject.Put("instanceType",DIRECTORY_SERVICE_CONTAINER_PROPERTIES.HEAD|DIRECTORY_SERVICE_CONTAINER_PROPERTIES.WRITABLE);

rObject.Put("description",sApplicationDirectoryPartitionDescription);

rObject.SetInfo();

//Create the container for users within that partition.

rContainer = (ActiveDs.IADsContainer)rOpenObject.OpenDSObject(sADsPath_ApplicationDirectoryPartition,sUserName,sPassword,(

int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_USE_DELEGATION|(int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_FAST_BIND|(int)ActiveDs.ADS_AUTHENTICATION_ENUM.ADS_SECURE_AUTHENTICATION);

rObject = (ActiveDs.IADs)rContainer.Create("container",

string.Format("CN={0}","Users"));

rObject.SetInfo();

}

}

catch(Exception rException)

{

System.Console.WriteLine(((rException.Message ==

null)||(rException.Message == string.Empty))?CConfigurator.c_sMessage_Exception_Unknown:string.Concat(CConfigurator.c_sMessage_Exception_Known,rException.Message));

}

return;

}

}

}

 

The app.config file:

 

<?

xml version="1.0" encoding="utf-8" ?>

<

configuration>

<configSections>

<section name="Credentials"

type="System.Configuration.DictionarySectionHandler"

/>

<section name="ADAMInstance"

type="System.Configuration.DictionarySectionHandler"

/>

</configSections>

<Credentials>

<add key="UserName" value="Administrator" />

<add key="Password" value="PERCY123marta" />

</Credentials>

<ADAMInstance>

<add key="Server" value="localhost" />

<add key="Port" value="50000" />

<add key="Country" value="US" />

<add key="ApplicationDirectoryPartition" value="TaskVisionII" />

<add key="ApplicationDirectoryPartitionDescription" value="TaskVisionII Directory Partition" />

</ADAMInstance>

</

configuration>

 

The .NET Directory Entry class is used merely to check whether or not the application directory partition already exists, and if it does not, to retrieve a reference to the COM Active Directory Service Interfaces. Those interfaces are then used to create a directory partition for the application, with the path, o=TaskVisionII,c=US, and then to create a container for users, CN=Users,o=TaskVisionII,c=US, within that partition.

 

[This posting is provided "AS IS" with no warranties, and confers no rights.]