CerroTorre LogoLogoEnglish translationLink zur SitemapLink zum Impressum


Link zu SelfADSI Home Link zur Linkliste Link zu FAQs
SelfADSI Home

SelfADSI - The LDAP / ADSI Scripting Tutorial
LDAP BIND: Establishing a connection to the directory

Vorheriges Kapitel   SelfADSI Home   Nächstes Kapitel

Before accessing a directory service, we have to establish a technical connection with an object of the directory. This could be a directory container (e.g. an organisational unit) or a single object.

 

Given that the technical access is accomplished via the LDAP protocol, we use the according LDAP notation as well: Establishing a connection and logging on with respective logon information is called a Bind operation (has nothing to do with the well-known DNS server software). Many aspects of Binding are described in MSDN: MSDN Documentation of ADSI and BIND.

 

Unless otherwise mentioned, this topic describes bind operations always in Active Directory environments. The ADSI Interface also permits bind operations on other directory services. Corresponding examples can be found in the following topics.

 

Bind variations:

 

Bind using the user ID the script is run with
Bind using special credentials
Bind to the global catalog
Bind when the own domain name / forest is unknown
Bind as anonymous
   
Bind to Exchange 5.5
Bind as anonymous to Exchange 5.5
   
TopOfPage Bind to Novell eDirectory / NDS

TopOfPage Bind using the user ID the script is run with

 

This is the easiest way of connecting. You 'grab' the object for access by using a simple GetObject()-Function. At this, the ID of the user that runs the script is used automatically for authetification. This method can only be used for accesses within the own forest, if possessing sufficient permissions. In addition, the appropriate notation of the LDAP pathname needs to be considered (especially if commata or other special characters are used!)

 

Set obj = GetObject("LDAP://server.cerrotorre.de/cn=Philipp,ou=Accounts,dc=cerrotorre,dc=de")

WScript.Echo obj.name

 

After that, the object 'Philipp' of the OU 'Accounts' of the domain 'company.com' can be accessed via the variable obj. However, access to all objects of a container is possible too:

 

Set ou = GetObject("LDAP://server.cerrotorre.de/ou=Accounts,dc=cerrotorre,dc=de")

For Each obj In ou
    WScript.Echo obj.name
Next

 

Serverless Binding:
Please keep in mind that the server name can be left out in the LDAP pathname - the station where the script runs discovers a domain controller from the user's domain automatically (via DNS). A shortened LDAP pathname can be used particulary when running the script directly on a domain controller:

 

Set obj = GetObject("LDAP://cn=Philipp,ou=Accounts,dc=cerrotorre,dc=de")

For Each obj In ou
    WScript.Echo obj.name
Next

 

When developing scripts within an Active Directory environment, serverless binding should't be used in mixed environments (ADS and NT domains), because the automatic search for a domain controller might probably fail.

 

< back to top


TopOfPage Bind using special credentials

 

The common method of binding to the directory always works when a logged on user wants to access objects of his own domain respectively his own ADS forest. However, it might quite often be necessary to access a directory service where you are not an currently authenticated user. In that case, the bind variation OpenDSObject() allows to pass the username and password and thus the logon to e.g. foreign forests is possible.

 

Set dso = GetObject("LDAP:")
Set ou = dso.OpenDSObject("LDAP://controller.cerrotorre.de/ou=test,dc=cerrotorre,dc=de", _
                           "administrator", "geheim", 1)
For Each obj In ou
    WScript.Echo obj.name
Next

 

In this example the OU object of the domain company.com is accessed by logging on the server controller.domain.com with the username 'administrator' and password 'confidential'. The last parameter (1) acts as a logon-flag, ensuring a secure Kerberos logon.

 

ADSI Reference in MSDN: OpenDSObject()

The username of an ADS logon can be given in the following way:

 

Pure logon name e.g. 'administrator', for this, the logon-flag needs to be set to '1' (secure logon)
NetBIOS logon name e.g. 'DOMAIN\administrator'
User principal name e.g. 'administrator@domain.com'
Distinguished name e.g. 'cn=administrator,cn=users,dc=domain,dc=com', for this, the logon-flag needs to be set to '0' (cleartext logon).

 

The logon flag determines the type of access. Important are the two values '0' (for encrypted logon in cleartext) and '1' (for secure logon via Kerberos or NTLM). Of course, a secure logon should be preferred to cleartext logon. However, situations may arise when an insecure cleartext logon is needed. Especially when using a bind operation to logon to other directory services like Novell eDirectory or OpenLDAP systems, the logon-flag must be set to '0'. In order to avoid a disclosure of the password from the net, the use of LDAP-SSL is recommended - then the whole traffic of the LDAP protocol is encrypted.

 

Microsoft explanations of the logon flag in MSDN


The server name can be left out in the LDAP pathname of ADS environments and it is automatically bind to an accessible domain controller of the own domain. Also, username and password can be provided as NULL string (''), then the logon data of the own user is used automatically. This possibility might be useless if using the bind option for the logon to another forest DC - thus, server and logon data have to be indicated accordingly.


< back to top


TopOfPage Bind to the Global Catalog

 

When connecting to a domain controller by using ADSI, only data from the schema partition, the configuration partition and the own domain can be provided. However, if you want to request objects of the whole forest from a single domain controller, then you have to connect to a global catalog (GC). Such special domain controllers provide objects from other domains via LDAP using the special TCP port 3268.

However, these objects can only be read and simply show some (the most important) attributes!

A technical option for the bind to a global catalog is to change the LDAP pathname so that the TCP port number 3268 is used. This is possible when using the function GetObject() as well as OpenDSObject().

 

Set ou = GetObject("LDAP://server.cerrotorre.de:3268/ou=Accounts,dc=cerrotorre,dc=de")
For Each obj In ou
    WScript.Echo obj.name
Next


Set ou = dso.OpenDSObject("LDAP://server.cerrotorre.de:3268/ou=Accounts,dc=cerrotorre,dc=de", _
                           "administrator", "geheim", 1)
For Each obj In ou
    WScript.Echo obj.name
Next

 

Prerequisite, of course, is that the mentioned sever 'server.company.com' has been set up as a global catalog.

Here's an easier option that utilizes a special form of the pathname, where the term 'LDAP' is simply replaced by 'GC'. So the special port number 3268 can be omitted:

 

Set ou = GetObject("GC://server.cerrotorre.de/ou=Benutzer,dc=firma,dc=de")
For Each obj In ou
    WScript.Echo obj.name
Next


Set ou = dso.OpenDSObject("GC://server.cerrotorre.de/ou=Accounts,dc=cerrotorre,dc=de", _
                           "administrator", "geheim", 1)
For Each obj In ou
    WScript.Echo obj.name
Next

 

A Serverless Binding can be run in Active Directory environments too. Then a global catalog will automatically be searched by DNS:

 

Set ou = GetObject("GC://ou=Benutzer,dc=cerrotorre,dc=de")
For Each obj In ou
    WScript.Echo obj.name
Next


< back to top


TopOfPage Bind without knowing the own Domain / Forest name

 

In many cases you want to develop scripts that run in different ADS environments. Think about a script that e.g. displays any information about certain objects within the own domain or is responsible for specific changes. In order that this script runs in any domains, you could let pass the domain name as parameter. But it is more sophisticated to automatically identify the current domain name by querying the Active Directory itself through severless binding.

The relevant information can be read in a special directory entry, available on every domain controller: the rootDSE (Root Directory Service Entry).

You can read here the distinguished name of your own domain from the attribute 'defaultNamingContext' and make an LDAP pathname right away with which the desired domain objects can be accessed.

 

Set rootDSE = GetObject("LDAP://rootDSE")
domainDN = rootDSE.Get("defaultNamingContext")

set domain = GetObject("LDAP://" & domainDN)
For Each obj In domain
    WScript.Echo obj.name
Next

 

This script lists all objects directly in the main name context of an ADS domain - it's the container where all 'normal' user and group objects are saved in. By the way, you can (given the relevant rights) access the configuration container of the forest without knowing the accurate notation, because the respective DN is documented as 'configurationNamingContext' attribute in the rootDSE.

 

Set rootDSE = GetObject("LDAP://rootDSE")
domainDN = rootDSE.Get("defaultConfigurationContext")

Set domain = GetObject("LDAP://" & domainDN)
For Each obj In domain
    WScript.Echo obj.name
Next


< back to top


TopOfPage Bind as Anonymous

 

LDAP generally offers the possibilty to logon to a directory without any user credentials. This is the so called 'anonymous bind'. Whether this anonymous bind is allowed or not depends on the type of directory service and the current configuration. When an anonymous bind is possible, in most cases the access rights for anonymous LDAP users are quite restricted.


If you want to logon to an ADS directory as an anonymous user without user name and password, you have to distinguish between Windows 2000 forests and forests that operate on Windows 2003 or later.

 

ADS under Windows 2000: The anonymous logon is allowed by default.
ADS under Windows 2003 (and later): Initially, the anonymous access is limited to the rootDSE entry (Root Directory Service Entry). Thus, you can readout a list of naming contexts or the ADS version of the forest. But if trying an anonymous access to normal objects and attributes of the forest, it has to be allowed by a global switch first. This is the ADS attribute dsHeuristic. This value is stored as an attribute of an directory object in the configuration partition: CN=Directory Service,CN=Windows NT, CN=Services,CN=Configuration, DC=root, DC=com. The default value is 0000000, a value of 0000002 enables the anonymous access to the directory.

 

Don't forget: Which objects and attributes you are allowed to access is also determined by access standards existing for the entries ANONYMOUS LOGON and Everyone in the relevant ACLs. The out-of-the-box setting these entries have absolutely no access right to domain objects - even if an anonymous logon is generally allowed by dsHeuristics.

 

There are some more things that need to be taken into consideration during a bind operation. An anonymous user is unable to see the content of container objects. It is inevitable to access single objects like user, groups or contacts by using the complete LDAP path. For this, the logon with the function OpenDSObject(), but without user name and password, are used:

 

Set dso = GetObject("LDAP:")
Set mbx = dso.OpenDSObject("LDAP://dc1.cerrotorre.de/cn=PhilippF,ou=Consultants,dc=cerrotorre,dc=de", "", "", 0)
WScript.Echo obj.name
WScript.Echo obj.mail

 

If you want to access several objects or if you don't know the precice LDAP paths, than you may run a directory search via ADO interface. The procedure of an ADO search is explained in the SelfADSI Tutorial in the topic 'Searching objects in the directory'.

 

In order to run an anonymous ADO query within an Active Directory, some modifications need to be accomplished. First of all, the base DN string of the directory search is to be omitted - as an anonymous user you are unable to 'see' a directory container.

 

Secondly, you have to use the global catalog provider for the search, because it only allows a search without defined base string. The search starts directly with the following LDAP path:

 

<GC://Server>

 

Here is an example in which all user objects are displayed. Für eine Zugriff auf andere Objekte verändern Sie einfach den LDAP-Filter:

 

Set ado = CreateObject("ADODB.Connection")                     'Creation of the ADO connection
ado.Provider = "ADSDSOObject"
ado.Properties("User ID") = ""                                 'no credentials!
ado.Properties("Password") = ""
ado.Properties("Encrypt Password") = False
ado.Open "ADS-Anon-Search"                                     'this is a arbitrarily chosen name

serverName = "nadrash.cerrotorre.de"                           'replace this with your own server name
filterStr = "(&(objectCategory=person)(objectClass=user))"     'search for user objects

Set objectList = ado.Execute("<GC://" & serverName & ">;" & filterStr & ";ADsPath;SubTree")

While Not objectList.EOF
    WScript.Echo objectList.Fields(0).Value
    objectList.MoveNext                                        'next foudn object
Wend

 

Please note that an ADO search to the Global Catalog returns the corresponding LDAP pathname of the whole forest (because we asked for the attribute 'ADSPath' ...). The returned LDAP pathnames of the Global Catalog are displayed with the protocal answerback ' 'GC://' how you can see in the above script example:

 

Screenshot: Bind Anonym

 

You will neither be able to read all attributes nor to change / rewrite them during a following connect to these pathnames - because you are accessing the Global Catalog! Get more information about the handling of search results of the Global Catalog under the topic 'The Global Catalog' here in the SelfADSI Tutorial.


< back to top


TopOfPage Bind to Exchange 5.5 Server

 

If you want to connect to an Exchange 5.5 server in order to access mailbox information or configuration of the mail organization, you have to take some things into consideration.

You need to keep in mind that LDAP pathnames of Exchange 5.5 directories slightly differ from the 'normal' AD syntax: In an organisation with the notation 'Company-Mail', the receiving container in the site 'Karlsruhe' would have the following pathname:

cn=Recipients,ou=Karlsruhe,o=Company-Mail

Moreover, you always have to work with OpenDSObject() when doing a bind operation and state the relevant Exchange server at the same time (and, if applicable, the LDAP port number with which the server is set up with, too). The best user name is the NetBIOS logon name of a user with pertinent credentials in the Exchange directory. '1' has to be used as logon flag:

 

Set dso = GetObject("LDAP:")
Set recipients = dso.OpenDSObject("LDAP://ex55.cerrotorre.de/cn=Recipients,ou=Karlsruhe,o=Firma-Mail", _
                          "NTDOMAIN\administrator", "secret", 1)

For Each obj In recipients
    WScript.Echo obj.name
Next

 

Furthermore, Exchange 5.5 as LDAP server shows an annoying habit: It makes it difficult to access objects not displayed in the adress book. This can be avoided by using a special version of the logon name in the operation OpenDSObject():

cn=<username>, dc=<domain>, cn=admin

By the use of this administrative bind logon, it is possible to access hidden or even deleted (still in the DIR data base) objects besides normal ones.

Hidden objects are objects where the LDAP attribute Hide-From-Address-Book is set TRUE.
Deleted objects are objects where the LDAP sttribute Is-Deleted is set TRUE.

An example for such an access:

 

Set dso = GetObject("LDAP:")
Set recipients = dso.OpenDSObject("LDAP://ex55.cerrotorre.de/cn=Recipients,ou=Karlsruhe,o=Corp-Mail", _
                          "cn=administrator,dc=ntdomain,cn=admin", "secret", 0 )

For Each obj In recipients
    WScript.Echo obj.name
Next

 

Please note that the logon needs to be done with the authentication flag '0' (for simple auth with cleartext password).


< back to top


TopOfPage Bind as Anonymous to Exchange 5.5 Server

 

If you want to connect to an Exchange 5.5 server as an anomynous user without user name and password, this needs to be allowed explicitly at the relevant server or the corresponding Exchange 5.5 site at first:

 

Exchange 5.5 Admin Screenshot

 

From now on, a client trying a bind operation with empty password and user name is logged on as an anonymous user and has access to directory information - however, only those that are enabled for an anonymous access. On which attributes an anonymous logged on LDAP client is allowed to access can be seen and changed in the DS site configuration of the accordant Exchange 5.5 location.

 

Exchange 5.5 Admin Screenshot

 

 

However, there are some things that need to be taken into consideration during bind operations. An anonymous user is unable to see the content of container objects. Thus, it is inevitable to access single objects like mailboxes, custom recipients or distribution list by the use of the complete LDAP path. For this, the logon with the operation OpenDSObject but without user name and password is used:

 

Set dso = GetObject("LDAP:")
Set mbx = dso.OpenDSObject("LDAP://ex55.cerrotorre.de/cn=PhilippF,cn=Recipients,ou=Karlsruhe,o=Corp-Mail", _
                          "", "", 0)

WScript.Echo obj.name
WScript.Echo obj.mail

 

If you want to access several objects or if you don't know the precice LDAP paths, than you may run a directory search via ADO interface. The procedure of an ADO search is explained in the SelfADSI Tutorial under the paragraph, 'Searching objects in the directory'. But in order to run an anonymous ADO inquiry against an Exchange 5.5 server, some modifications need to be accomplished. They are explained inthe Microsoft KnowledgeBase article Q223049. First of all, the base string of the directory search is left out and secondly, the Global Catalog Provider with the LDAP port 389 (or the set up LDAP port of the relevant server) has to be stated in the LDAP pathname. Otherwisem, this provider is useless for accesses to Excahnge 5.5 directories, because only ADS directories do feature a Global Catalog operation. However, in this case here we use this trick in order to run an anonymous ADO search.

 

A third change compared to a common ADO search within the directory is the explicit creation of an ADODB.Command object, because its characteristic PageSize is needed for the anonymous query. In the following example all mailbox objects are indicated. For accessing other objects you just have to change the LDA filter:

 

Set dso = GetObject("LDAP:")                            'for accessing via LDAP

Set
ado = CreateObject("ADODB.Connection")              'creation of the ADO connection
ado.Provider = "ADSDSOObject"
ado.Properties("User ID") = ""                          'no logon data !
ado.Properties("Password") = ""
ado.Properties("Encrypt Password") = False
ado.Open "EX55-Anon-Search"                             'this is a arbitrarily chosen name
serverName = "kailash.cerrotorre.de"                    'replace the own server name here
filterStr = "((objectClass=organizationalPerson))"      'LDAP search filter for mailboxes

Set cmo = CreateObject("ADODB.Command")                 'Creation of the ADO connection
cmo.ActiveConnection = ado
cmo.CommandText = "<GC://" & serverName & ":389">;" & filterStr & ";ADsPath;SubTree"
cmo.Properties("Page Size") = 99

Set objectList = cmo.Execute                            'processing the search

While Not
objectList.EOF                                'anonymous and direct bind to the object
    Set mbx = dso.OpenDSObject(objectList.Fields(0).Value, "", "", 0)

    WScript.Echo mbx.name

    objectList.MoveNext                                  'next element
Wend


< back o top


TopOfPage Bind to Novell eDirectory / NDS Server

 

If you want to bind to an Exchange 5.5 server in order to access mailbox information or the set up of the mail organisation, some things will need to be considered.

First of all, it's important to bear in mind that a LDAP pathname of a Novell eDirectory is different to other Active Directories: Instead of a domain (e.g. ...,dc=cerrotorre,cd=de), the superior hierarchy of such a directory is comprised of an organisation (...,o=...) or country object (...,c=...).

cn=PFoeckel,ou=Karlsruhe,o=CerroTorre

cn=BierSan,ou=Students,ou=Sydney,c=au

When binding, you always have to use the function OpenDSObject() and directly name the correspondent Novell server (and, if applicable, the LDAP port number the server is set up with). Username is the complete LDAP pathname of the user that is to be logged on. Logon flag is always 0:

 

Set dso = GetObject("LDAP:")
Set recipients = dso.OpenDSObject("LDAP://nov-ldap.cerrotorre.de/ou=Karlsruhe,o=CerroTorre", _
                          "cn=PFoeckel,ou=Karlsruhe,o=CerroTorre", "geheim", 0 )

For Each obj In recipients
    WScript.Echo obj.name
Next

 

The logon via unencrypted password is quite unsecure, but if the server provides the appropriate SSL certificate settings, you could use LDAP-SSL on TCP-Port 636. Then, the whole LDAP Communication and thus username and password as well will be encrypted via a SSL tunnel.

 

 

If the logon to the eDirectory shall be anonymous, an empty string is passed over instead of username und password. Novell server allow anonymous logon in general, but then you have got only access where the entry [public] is existing as trustee:

 

Set dso = GetObject("LDAP:")
Set recipients = dso.OpenDSObject("LDAP://nov-ldap.cerrotorre.de/ou=Karlsruhe,o=CerroTorre", "", "", 1)

For Each obj In recipients
    WScript.Echo obj.name
Next


< back o top


back to SelfADSI home

Sprich Freund, und tritt ein...