LDAP is platform neutral, which means you can access and manage data in Active Directory from a variety of platforms.. Throughout this chapter I will cover how you can access, manage, an
Trang 1Recipe 17.9 Delegating Control of Managing an
Application Partition
17.9.1 Problem
You want to delegate control over the management of an application partition
17.9.2 Solution
17.9.2.1 Using a graphical user interface
1 Open ADSI Edit
2 Connect to the Configuration naming context of the forest the application partition is in if
it is not already present in the left pane
3 Expand the Configuration naming context and click on the Partitions container
4 In the right pane, right-click on the crossRef object that represents the application partition and select Properties
5 Click the Security tab
6 Click the Advanced button
7 Click the Add button
8 Use the object picker to find the user or group you want to delegate control to and click
OK
9 Click the Properties tab
10 Under Allow, check the boxes beside Write NC-Replica-Locations, Write msDS-SDReferenceDomain, Write msDS-Replication-Notify-First-DSA-Delay, and Write msDS-Replication-Notify-Subsequent-DSA-Delay
11 Click OK
17.9.2.2 Using a command-line interface
> dsacls <AppPartitionCrossRefDN> /G
<UserOrGroup>:RPWP;msDS-NC-Replica-Locations
> dsacls <AppPartitionCrossRefDN> /G
<UserOrGroup>:RPWP;msDS-SDReferenceDomain
> dsacls <AppPartitionCrossRefDN> /G
<UserOrGroup>:RPWP;msDS-Replication-Notify-[RETURN]
First-DSA-Delay
> dsacls <AppPartitionCrossRefDN> /G
<UserOrGroup>:RPWP;msDS-Replication-Notify-[RETURN]
Subsequent-DSA-Delay
17.9.2.3 Using VBScript
' This script delegates control over the four key attributes
' of an app partition to the specified user or group
' - SCRIPT CONFIGURATION -
' Fully qualified DNS name of app partition
strAppPart = "<AppPartitionFQDN>" ' e.g apps.rallencorp.com
' User or group to delegate control to
strUser = "<UserOrGroup>" ' e.g joe@rallencorp.com or RALLENCORP\joe
Trang 2' - END CONFIGURATION -
'############################
' Constants
'############################
' ADS_ACETYPE_ENUM
Const ADS_ACETYPE_ACCESS_ALLOWED = &h0
Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &h5
' ADS_FLAGTYPE_ENUM
Const ADS_FLAG_OBJECT_TYPE_PRESENT = &h1
' ADS_RIGHTS_ENUM
Const ADS_RIGHT_DS_WRITE_PROP = &h20
Const ADS_RIGHT_DS_READ_PROP = &h10
' schemaIDGUID values
Const REPLICA_LOCATIONS = "{97de9615-b537-46bc-ac0f-10720f3909f3}" Const SDREFERENCEDOMAIN = "{4c51e316-f628-43a5-b06b-ffb695fcb4f3}" Const NOTIFY_FIRST_DSA_DELAY = "{85abd4f4-0a89-4e49-bdec-6f35bb2562ba}" Const NOTIFY_SUBSEQUENT_DSA_DELAY = "{d63db385-dd92-4b52-b1d8-0d3ecc0e86b6}" '############################
' Find App Partition
'############################
set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://cn=Partitions," & _
objRootDSE.Get("ConfigurationNamingContext") & ">;"
strFilter = "(&(objectcategory=crossRef)(dnsRoot=" & _
strAppPart & "));"
strAttrs = "cn,distinguishedName;"
strScope = "onelevel"
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
Set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
if objRS.RecordCount <> 1 then
WScript.Echo "Did not find a match for " & strAppPart
else
objRS.MoveLast
set objAppPart = GetObject("LDAP://" & _
objRS.Fields("distinguishedName").Value )
end if
'############################
' Create ACL
'############################
set objSD = objAppPart.Get("ntSecurityDescriptor")
set objDACL = objSD.DiscretionaryAcl
' Read/Write Property: msDS-NC-Replica-Locations
Trang 3objACE1.AceFlags = 0
objACE1.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
objACE1.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE1.ObjectType = REPLICA_LOCATIONS '
' Read/Write Property: msDS-SDReferenceDomain
set objACE2 = CreateObject("AccessControlEntry")
objACE2.Trustee = strUser
objACE2.AccessMask = ADS_RIGHT_DS_WRITE_PROP Or ADS_RIGHT_DS_READ_PROP
objACE2.AceFlags = 0
objACE2.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
objACE2.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE2.ObjectType = SDREFERENCEDOMAIN
' Read/Write Property: msDS-Replication-Notify-First-DSA-Delay
set objACE3 = CreateObject("AccessControlEntry")
objACE3.Trustee = strUser
objACE3.AccessMask = ADS_RIGHT_DS_WRITE_PROP Or ADS_RIGHT_DS_READ_PROP
objACE3.AceFlags = 0
objACE3.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
objACE3.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE3.ObjectType = NOTIFY_FIRST_DSA_DELAY
' Read/Write Property: msDS-Replication-Notify-Subsequent-DSA-Delay
set objACE4 = CreateObject("AccessControlEntry")
objACE4.Trustee = strUser
objACE4.AccessMask = ADS_RIGHT_DS_WRITE_PROP Or ADS_RIGHT_DS_READ_PROP
objACE4.AceFlags = 0
objACE4.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
objACE4.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE4.ObjectType = NOTIFY_SUBSEQUENT_DSA_DELAY
objDACL.AddAce objACE1
objDACL.AddAce objACE2
objDACL.AddAce objACE3
objDACL.AddAce objACE4
'############################
' Set ACL
'############################
objSD.DiscretionaryAcl = objDACL
objAppPart.Put "ntSecurityDescriptor", objSD
objAppPart.SetInfo
WScript.Echo "Delegated control of " & strAppPart & " to " & strUser
17.9.3 Discussion
If you want to delegate control of management of application partitions, you must grant control over four key attributes Here is a description of each attribute and what can be accomplished by having control over it:
msDS-NC-Replica-Locations
Trang 4By having write access to this attribute, a user can add replica servers for the application partition See Recipe 17.3 for more information
msDS-SDReferenceDomain
By having write access to this attribute, a user can define the default security descriptor domain for the application partition See Recipe 17.8 for more information
msDS-Replication-Notify-First-DSA-Delay
See Recipe 17.7 for more information
msDS-Replication-Notify-Subsequent-DSA-Delay
See Recipe 17.7 for more information
If you want to delegate control over managing objects within the application partition, you need
to follow the same procedures you would when delegating control over objects in a domain naming context See Recipe 14.5 for more information on delegating control
17.9.4 See Also
Recipe 14.5 for delegating control, Recipe 17.3 for more on adding and removing replica servers,
Recipe 17.7 for more on the replication delay attributes, and Recipe 17.8 for more on the default security descriptor domain
Trang 5Chapter 18 Interoperability and
Integration
Introduction
Recipe 18.1 Accessing AD from a Non-Windows Platform
Recipe 18.2 Programming with NET
Recipe 18.3 Programming with DSML
Recipe 18.4 Programming with Perl
Recipe 18.5 Programming with Java
Recipe 18.6 Programming with Python
Recipe 18.7 Integrating with MIT Kerberos
Recipe 18.8 Integrating with Samba
Recipe 18.9 Integrating with Apache
Recipe 18.10 Replacing NIS
Recipe 18.11 Using BIND for DNS
Recipe 18.12 Authorizing a Microsoft DHCP Server
Recipe 18.13 Using VMWare for Testing AD
Introduction
Active Directory supports several important industry standards, which allow other services and platforms to interoperate and integrate with it The Lightweight Directory Access Protocol (LDAP) is the standards-based protocol used by all major directory service vendors for directory access and management LDAP is platform neutral, which means you can access and manage data in Active Directory from a variety of platforms Active Directory uses the Domain Name System (DNS) for its name resolution services so you can use tools, such as nslookup, to locate domain controllers by making DNS queries Kerberos is the most widely used network
authentication protocol and is supported by Active Directory, so even non-Windows-based Kerberos-enabled clients can authenticate These are just a few of the standards Active Directory
Trang 6supports Throughout this chapter I will cover how you can access, manage, and integrate Active Directory in ways that are not typically documented
Recipe 18.1 Accessing AD from a Non-Windows
Platform
18.1.1 Problem
You want to access or manage AD from a non-Windows platform
18.1.2 Solution
18.1.2.1 Using a graphical user interface
One of the best platform-neutral graphical user interfaces for managing an LDAP directory, such
as Active Directory, is the LDAP Browser/Editor It was written in Java and can run on virtually any machine that has Java 1.2.2 or greater installed It can be downloaded from the following site:
http://www.iit.edu/~gawojar/ldap/
18.1.2.2 Using a command-line interface
The original LDAP server produced at the University of Michigan included a set of command-line utilities that can query and update an LDAP directory Over time these tools have become very popular on the UNIX platforms, and they can even be used to query and update Active Directory The OpenLDAP project took over maintenance of the University of Michigan's LDAP server and also the command-line tools To download the latest version of the tools, go to the following site: http://www.openldap.org/
18.1.2.3 Using a programming language
Any programming language that supports LDAP can be used to programmatically access and manage Active Directory See the other recipes in this chapter for using Perl, Python, Java, and PHP
18.1.3 Discussion
Due to the fact that LDAP is an open standard, it has been adopted on many platforms and
programming languages While you can perform 90% of the things you would need to do from a non-Windows platform, some tasks do still require a Windows GUI, CLI, or API For example, there is no easy way to manage ACLs in Active Directory from a non-Windows platform You can, however, do virtually anything you need to do as far as adding, modifying, and removing objects in Active Directory with the basic LDAP-enabled tools
Trang 718.1.4 See Also
Recipe 18.4, Recipe 18.5, and Recipe 18.6 for more on how to programmatically query and update Active Directory using Perl, Java, and Python
Recipe 18.2 Programming with NET
18.2.1 Problem
You want to programmatically access Active Directory using the NET Framework
18.2.2 Solution
The System.DirectoryServices namespace can be used to interface with Active Directory using the NET Framework The following code is a simple VB.NET program that prints the attributes of the RootDSE:
Imports System.DirectoryServices
Module Module1
Sub Main( )
Dim objRootDSE As New DirectoryEntry("LDAP://RootDSE")
Dim strAttrName As String
Dim objValue As Object
For Each strAttrName In objRootDSE.Properties.PropertyNames
For Each objValue In objRootDSE.Properties(strAttrName)
Console.WriteLine(strAttrName & " : " & objValue.ToString) Next objValue
Next strAttrName
End Sub
End Module
18.2.3 Discussion
The System.DirectoryServices namespace is a generic directory service interface that is intended to replace ADSI It provides a rich set of properties and methods for accessing,
querying, and manipulating objects in Active Directory Currently, there is no native support for scripting languages, such as VBScript and Perl, but you can use Microsoft's version of JavaScript (i.e., JScript) with NET to utilize System.DirectoryServices
The System.DirectoryServices DirectorySearcher class is a simple interface for making LDAP queries The DirectoryEntry class is used for instantiating existing objects or creating new ones In the Solution section, I used the DirectoryEntry class to access the RootDSE
Trang 8DirectorySearcher and DirectoryEntry are the two main classes to become familiar with if you want to do Active Directory programming with NET For more information and examples
on using System.DirectoryServices, see Chapter 28 of Active Directory, Second Edition (O'Reilly)
System.DirectoryServices does not currently provide interfaces for everything that could be done with ADSI Instead, you can use the NativeObject property on an instantiated object to return an ADSI object, which you can then use to access any ADSI properties or methods for the object
18.2.4 See Also
Chapter 28 in Active Directory, Second Edition (O'Reilly) and System.DirectoryServices
reference information can be found at
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDirectoryServices.asp
Recipe 18.3 Programming with DSML
18.3.1 Problem
You want to programmatically access Active Directory using the Directory Services Markup Language (DSML) DSML is the answer for all programmers who have been longing for an XML-based interface to query and access a directory
18.3.2 Solution
To use DSML with Active Directory, you have to install the Windows DSML client (DSFW) on
a Windows 2000 or Windows Server 2003 computer that is running IIS The DSML client can be downloaded from the following site:
http://www.microsoft.com/windows2000/server/evaluation/news/bulletins/dsml.asp If you are installing the client on a Windows 2000 machine, you will also need to make sure MSXML 3.0 SP2 is installed
After the client is installed, you can perform DSML queries against that server, which will
translate the calls into LDAP queries to Active Directory No additional software needs to be installed on domain controllers to support DSML
The following code shows a DSML request for the RootDSE:
<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/">
<se:Body xmlns="urn:oasis:names:tc:DSML:2:0:core">
<batchRequest>
<searchRequest dn="" scope="baseObject">
<filter>
<present name="objectclass"/>
Trang 9</batchRequest>
</se:Body>
</se:Envelope>
18.3.3 Discussion
DSML is an XML alternative to using LDAP to access and manage a directory server The Oasis standards body has driven the development of DSML (
http://www.oasis-open.org/committees/dsml/) and now most directory vendors support it as of Version 2
(DSMLv2)
DSML encodes LDAP-like functions in XML messages and transmits them to a SOAP client that can sit directly on the directory server or a separate server Currently, Active Directory domain controllers do not support DSML directly and, thus, a separate client must be installed For more information including the DSML specification, see the Oasis web site
18.3.4 See Also
DSMLfW home page:
http://www.microsoft.com/windows2000/server/evaluation/news/bulletins/dsml.asp
Recipe 18.4 Programming with Perl
18.4.1 Problem
You want to programmatically access Active Directory using Perl
18.4.2 Solution
There are two options for accessing Active Directory with Perl You can use the Net::LDAP modules that are cross platform and use the LDAP protocol, or you can use the Win32::OLE module that gives you access to ADSI and must be run on a Windows machine Both modules can be downloaded from the Comprehensive Perl Archive Network (CPAN) web site,
http://www.cpan.org/
The following example shows how to use the Net::LDAP modules to query the RootDSE:
#!/usr/SD/perl/bin/perl
use strict;
use Net::LDAP;
my $ldap_server = $ARGV[0] || 'dc1';
my $ldapobj = Net::LDAP->new($ldap_server) or die " Could not connect: $@";
my $rootdse = $ldapobj->search(
base => '',
filter => '(objectclass=*)',
scope => 'base',
Trang 10);
die $rootdse->error if $rootdse->code;
foreach $entry($rootdse->entries) {
foreach $attr(sort $entry->attributes) {
foreach ($entry->get($attr)) {
print "$attr: $_\n";
}
}
}
This next example uses the Win32::OLE module and ADSI to display the attributes of the
RootDSE:
use strict;
use Win32::OLE 'in';
my $rootdse = Win32::OLE->GetObject("LDAP://RootDSE");
$rootdse->GetInfo;
for my $i ( 0 $rootdse->PropertyCount - 1) {
my $prop = $rootdse->Item($i);
print $prop->Name,"\n";
foreach my $val (in $prop->Values) {
print " ",$val->CaseIgnoreString,"\n";
}
}
It is worth noting that with Net::LDAP, you generally need to bind to the target domain
controller before performing a search or any other operation In the Net::LDAP example above, I didn't need to do that because I queried the RootDSE, which allows anonymous (i.e.,
unauthenticated) connections A bind can be done using the following code:
$ldapobj->bind('administrator@rallencorp.com', password => 'galt');
In the second code sample where I used ADSI with Win32::OLE, the credentials of the user running the script are used by default, so you only need to do an explicit bind if you need to authenticate as a different user
18.4.3 Discussion
The Net::LDAP modules are a robust set of modules for querying and modifying an LDAP directory Net::LDAP also supports DSML, the abstract schema, and LDIF Net::LDAP is a native Perl implementation, which means that it does not rely on an external LDAP SDK Since
it is a pure Perl implementation, you can write Net::LDAP-based scripts on a variety of platforms
to interface with Active Directory or other LDAP-based directories Graham Barr initially
developed the Net::LDAP modules and more information can be found about the modules on the following web site: http://perl-ldap.sourceforge.net/
The Win32::OLE modules provide an interface into Microsoft's Component Object Model