CapeSoft.Com
Clarion Accessories
NetTalk
Doc Index
LDAP
CapeSoft Logo

CapeSoft NetTalk
LDAP

Download Latest Version
Installed Version Latest Version

NetTalk LDAP

Available in NetTalk Desktop, NetTalk Server and NetTalk Apps. Applies to Desktop (ABC or Clarion) apps.

Introduction

LDAP (Lightweight Directory Access Protocol) is a binary protocol used to communicate with LDAP servers. LDAP servers are databases which work using a tree structure to store data, rather than rows and tables.

They provide a service, something like a telephone directory, allowing information to be made available about people or other things (computers, printers, or anything really) within the servers domain.

The most common LDAP server on Windows is the Windows Active Directory server. There are however other LDAP server you may need to connect to. Windows Active Directory is an example of an LDAP server, not the only LDAP server.



JumpStart

Terminology

NameDescription
HostThe URL or IP address of the LDAP server you want to talk to. Similar to the URL of a web site.
PortThe port number you are connecting to. The usual value is 389. (This is the also the default used by the class)
Domain Databases on the LDAP server side are organized by "domain". This can be set to anything the administrator likes, it is not bound to a web domain the company owns or anything like that. It may correspond to the HOST address, but does not need to do so.

example of Domain in Active Directory Server
BindWhen a client authenticates with a server this is known as Binding to the server. Typically this requires a valid user name, and password, to access the database, but some servers allow anonymous authentication. NetTalk uses two properties, AuthUser and AuthPassword to contain these items. Not that the user that is BINDed is purely for access to the database - they may be able to extract data from the database for other users in addition to themselves.
AttributesThese are like field names in a normal database.  There are potentially a great many attributes assigned to an object.  For example a user may have attributes like displayName, userPrincipalName, samAccountName, sn (for Surname) and so on.
cnCommon Name. This is a property for each user, set by the Administrator on the server. The cn is the whole name, as displayed in the administrator panel below. (Notice also the Group Name highlighted in the image below.) The cn of the highlighted user is Wilson S. Demaggio.

example of CN in Active Directory Server
Group name The name of a Group in the directory. See the image above for an example of a group called Amazing Accounts.
User LoginThe login of a user is different to their cn. It includes both the user login name, AND the domain. In the picture below, the login of this user is wilson@Test.local. In some systems the cn for the user can be used in place of the user login name.

Active Directory User Name
userPrincipalNameThis is the attribute name which holds the login. In the Active Dreictory Administrator this is referred to as the Logon Name, however when constructing User Filters the correct name of the attribute is userPrincipalName.
ou

Organizational Unit.  This is like a group that is used to organize objects in the directory.  In a large company this might be the users department.  By default in Active Directory Directory Services there is an ou called Users. This may be required in the UserFilter.

Active Directory Directory Services

Active Directory Directory Services (ADDS) is a really big deal for larger organizations which need to administer large groups of people and computers. It is a centralized system that allows for security and permissions to be set in one place, which affect the larger organization.

This section focuses on interacting with an Active Directory server.

Aside: If you need to brush up on Active Directory Directory Services because your client wants you to support it, but you know nothing about it then I recommend this YouTube playlist. Start with item 5 on that list. It's an excellent introduction to Active Directory.

A good example of these features in action is in the \examples\nettalk\LDAP\ActiveDirectory folder.

MessageID

Communications between the server and your program is asynchronous.

This means that you made a call to one of the methods (ValidateUser, UserInGroup etc) a MessageID is returned. You should store this ID for use when results arrive.

When a response to a message is received from the server then the .Done method will be called.
When inspecting the results in the .Done method, the ID of the message being replied to is passed into the method as a parameter. You can use the value stored earlier to determine which message is being replied to.

You do not need to wait for a response before sending another message.

Validating a User Login and Password

You can check to see if a user login and password are valid by using the ValidateUser method.

The user login value is not case sensitive. Can be either the login value Or the Display Name.

Example of calling the method

net.Host = pParms.pHost
net.Port = pParms.pPort
net.SetDomain(pParms.pDomain)
net.AuthUser = pParms.pAuthUser
net.AuthPassword = pParms.pAuthPassword
MessageId = net.ValidateUser()


Remember the call is asynchronous, so the answer will be provided in either the .Done method or the .ErrorTrap method.

Add the following code to the .Done method to get the result.

If pMessageId = MessageId
  ans = self.ValidUser()
End

User Filters

When calling subsequent functions, a User Filter is often used to identify the user you are reading information about. This allows you to identify a user based on any of their (unique) properties. For example;

cn=Wilson S. Demaggio
or
userPrincipalName=wilson@text.local

Hint: The userPrincipalName is the name of the login user attribute.

Complex Filters

The above example is a simple expression. However more complicated search expressions are possible. The syntax of the expression is fairly simple, but may be different to the syntax you are used to.

OR (|)

You can do a search using two conditions by using the OR operator. The symbol for this operator is the pipe symbol (|). the general syntax of the string is

operator(expression)(expression)

So, if we wanted to search for all users with the surname (sn) of Gates or Jobs, the expression would look like this;

|(sn=Gates)(sn=Jobs)

Each expression in the above search could in turn be a complex expression.

AND (&)

The AND operator is represented by the & symbol. A search for all users with the surname (sn) of Jobs and the first name (givenName) of Steve would look like this;

&(sn=Jobs)(givenName=Steve)

As mentioned before each expression in the above could in turn be a complex expression. Let's search for all the users with surname Jobs, where the first name is Steve or Steven.

&(sn=Jobs)(|(givenName=Steve)(givenName=Steven))

some LDAP clients require the whole filter to be wrapped in brackets, so the above would become

(&(sn=Jobs)(|(givenName=Steve)(givenName=Steven)))

NetTalk will handle this fine, but does not require it.

There are many resources on the web for understanding how LDAP search terms are constructed. If you want (or need) to make more complex searches then the following material is recommended;

https://technet.microsoft.com/en-us/library/aa996205(v=exchg.65).aspx


Get Attributes for one (or more) Users

One of the primary uses of Active Directory is to store information about users. Therefore NetTalk LDAP has a GetAttributes method that allows you to read some, or all, the attributes for one (or more) users.

The User parameter is constructed as a user filter.
The Attributes parameter is a comma separated list of the attributes to fetch. If all the attributes should be fetched then set this to '*'.

Example of calling the method

net.AuthUser = pParms.pAuthUser
net.AuthPassword = pParms.pAuthPassword
net.Host = pParms.pHost
net.Port = pParms.pPort
net.SetDomain(pParms.pDomain)
net.SetAttributesQueue(AttributesQueue)
MessageId = net.GetAttributes(pParms.pUser,pParms.attributeList)


The list of attributes is placed into a queue - the queue set using the SetAttributesQueue method.
Each attribute name is placed into the first field in the queue, and the value into the second field.
If SetAttributesQueue is not called, then an internal queue of the object, called AttributesQueue will contain the result.

Another method, GetAttributeValue, allows you to easily retrieve a value from the queue.

Checking if a User is in a Specific Group

A really common request we get is for our program to authenticate a user against active directory before allowing them to access the program. On the administrator (server) side users can then be denied or granted access based on them being in, or out, of a known group.

This can be done in addition to a program security system (like Secwin, or Super Security) or it may operate as a simple login system of its own.

For example;
If you are using this in conjunction with another system then in your program you add a test AFTER the current login is successful, but BEFORE the program menu appears. This test queries the ADDS server with something like "Is WhateverUser in the AmazingAccounts group?". If he is, then keep going, if not, deny access.

If you are using this as your only login system then you can just create a simple window to collect the user name and password from the user. You can then pass these through to the Active Directory Server to see if they are valid. If they are then test to see if the user is in the required group.

It's possible to prime the login field with the Windows Login, but you will need to retrieve the password from the user.

The validation here takes 3 parameters of interest. The AuthUser and AuthPassword are the same as the ones used for the ValidateUser method.

The User parameter is constructed as a user filter.
The InGroup parameter is the name of the group to compare against.

Example of calling the method

net.AuthUser = pParms.pAuthUser
net.AuthPassword = pParms.pAuthPassword
net.Host = pParms.pHost
net.Port = pParms.pPort
net.SetDomain(pParms.pDomain)
MessageId = net.UserInGroup('cn=' & pParms.pUser,pParms.pInGroup)


Again the result will appear in the .Done method

if pMessageId = MessageId
  ans = self.UserIsInGroup
  post(event:closeWindow)
end



LDAP Parameters Group

A group structure has been defined to easily move multiple fields between procedures. Usually this is used when calling an LDAP procedure. You don't have to populate all the fields in the group, the ones you don't need can be left blank.
NameTypeDescription
pHostStringThe URL or IP address of the LDAP server you are connecting to.
pPortStringThe port number of the LDAP server you are connecting to. Defaults to 389.
pAuthUserStringThe user name for the user when authenticating against the LDAP server.
pAuthPasswordStringThe password for the user when authenticating against the LDAP server.
pDomainStringThe domain of the LDAP server.
pUserStringA user filter.
pInGroupStringA group name (used for UserInGroup method.)

Debugging

LDAP uses a binary protocol to talk between the server and the client. This can make the traditional debugging approach (of simply inspecting outgoing packets, and incoming replies) difficult.

DebugPackets

To solve this problem the NetLDAP class has a property called DebugPackets.
This is set to false by default.
If it is set to true then packets going out, and coming in, are converted to a text format before sending them to debugview.

Of course viewing the protocol as text is useful only to the degree to which you understand the protocol, however it certainly makes it a lot easier to see the server response, and hopefully interpret any errors which may be coming from the server.

OpenLDAP

Testing the client side of the connection is only half the problem. If the server is misconfigured, or not accessible at all, then all the changes on the client side won't help. Therefore it is useful to have a command line tool (or tools) which can be used as a reference point - something you can use to connect to a server to determine that the server is working correctly. There are a variety of tools available. The one we use internally are tools supplied by the OpenLDAP project.

The OpenLDAP install can be downloaded from https://www.openldap.org/software/download/ .

Once installed (typically to c:\LDAP) the client tools can be found in the c:\LDAP\ClientTools folder.

Example

Here is a typical request using ldapsearch

ldapsearch -x -LLL -E pr=200/noprompt -h 192.168.2.164 -p 389 -D "wilson@test.local" -w "NetTalk10" -b "cn=users,dc=test,dc=local" -s sub "(sn=Demaggio)" cn mail sn userPrincipalName phone

In the above command;

192.168.2.164 is the name of the server being connected to
389 is the port number
wilson@test.local is the user Logon
NetTalk10 is the password
dc=test,dc=local is the domain. Note the rather unusual way of showing this. If the domain was say capesoft.co.za then this would be dc=capesoft,dc=co,dc=za
Demaggio is the surname (last name) of the user we are getting attributes for. You could use a * here to get the attributes for all users.
cn mail sn userPrincipalName phone are the attributes being fetched. Use a * here for all attributes.

Here is another example

ldapsearch -x -LLL -E pr=200/noprompt -h capesoft.co.za -p 389 -D "wilson@test.local" -w "NetTalk10" -b "cn=users,dc=capesoft,dc=co,dc=za" -s sub "(sn=*)" *

FAQ

G

Class Reference

NetLDAP

Included in NetTalk Desktop

Derivation

  • NetLDAP
    • NetSimple ( NetSimp.Inc / NetSimp.Clw )
      • _NetAll

Properties

PropertyDDescription
AllowAnonymousSet this to true if the LDAP server allows anonymous access. Usually the server does not allow anonymous access, and requires the AuthUser and AuthPassword properties to be set.
AttributesQueueA Queue which holds the results of an attribute search. Populated after a call to GetAttributes. Can be inspected in the SearchDone method, after the parent call.
AuthPasswordThe password, of the user who is requesting data from the server.
AuthUserThe login of the user who is requesting data from the server.
DebugPacketsIf this is set to true then the contents of outgoing packets are sent to Debugview. Used for internal debugging only.
DomainThe domain of the server that you are connecting to. For example test.local or com.capesoft .
HostThe IP address, or DNS name of the LDAP server machine.
PortThe Port of the LDAP server machine. The default port number is 389 for an unencrypted connection. For encrypted connections the port will likely be 636.
SearchPrefixAllows the search for attributes, and users in a group, to be refined to a narrower scope.
UserIsInGroupIf the UserInGroup method is called, then the result can be tested in the Done method.
ValidUserThis is set to true if a request is made, and the AuthUser and AuthPassword properties are valid. If a Login is successful then the Done method will be called.

Methods

MethodDescription
DoneThis method is called when a request to the server has received a response.
ErrorTrapThis method is called if an error occurs while communicating with the server.
GetAttributesGet attributes for a specific user.
GetAttributeValueReads an entry from the Attributes Queue after a call to GetAttributes.
SearchDo an Addhoc search against the LDAP server.
SearchDoneIs called when the results of a search are available.
SetAttributesQueueSet the Queue to receive the results from a call to GetAttributes.
SetDomainSets the domain of the server that the program is connecting to.
StartRReturns the object to a virgin state.
UserInGroupCheck to see if a specific user is in a Group or not.
ValidateUserValidates the authUser and AuthPassword properties against the server, and allows other methods to execute. If another method is called before this method is called, then this method will be called automatically.

Done

Done (Long pMessageId)

Description

This method is called after a request to the server completes. The MessageId parameter indicates which message has just been completed. The location of the results will depend on the method that has been called.

Parameters

ParameterDDescription
MessageIDThe MessageID of the request which has just completed.

Notes

This is where most of your embed code will go, handling the results of the requests you have made.

Return Value

The method returns nothing.

See Also

ErrorTrap, ValidateUser, GetAttributes, UserInGroup

ErrorTrap

ErrorTrap (Long pMessageId, String pErrorCode, String pError)

Description

ErrorTrap is called if a communications error occurs, or if a request is incomplete in some way.
Parameters

ParameterDDescription
MessageIdThe ID of the message being attempted.
ErrorCodeThe NetTalk Error Code
ErrorThe NetTalk Error Message

Notes

You will need to add any error handling code into this method.

Return Value

The method returns nothing.

See Also

DDone

GetAttributes

GetAttributes (String pUser, <String pAttributes>)

Description

Get one or more attributes for a user from an Active Directory server.

Parameters

ParameterDescription
UserA user filter to determine which user(s) to get the attribute(s) for.
AttributesA comma delimited list of the attributes to fetch. If omitted (or blank) then all the attributes for the user are returned.

Example

LocalQueue      QUEUE,PRE(aq) 
Attribute         STRING(255) 
Value             STRING(255) 
                END


net.Host = '192.168.2.164'
net.Port = 389
net.SetDomain('test.local')
net.AuthUser = 'wilson@test.local'
net.AuthPassword = 'NetTalk10'
net.SetAttributesQueue(LocalQueue) 
! this is optional
Free(LocalQueue)
MessageId = net.GetAttributes('sn=Demaggio','userPrincipalName,cn,mail')

Return Value

The method returns a LONG containing the new MessageID.

When the request to the server is complete then the Done method is called.

If the SetAttributesQueue method has been called then the list of returned attributes is in the noted queue. Using a local queue like this is especially useful for displaying the results on a window.

If the SetAttributesQueue method is not called, then an internal property, AttributesQueue, is populated with the result. You can then access the contents of this queue directly. The GetAttributeValue method can be helpful in getting values from the queue.

The Queue is NOT FREEd before the results are added. If items already exist in the queue, then the results of this request will be added to the queue.

See Also

Done, SetAttributesQueue, Get Attributes for one (or more) Users, GetAttributeValue

GetAttributeValue

GetAttributeValue (String pAttribute, Long pInstance=1)

Description

This method helps retrieve a value from the AttributeQueue. The AttributeQueue has to be populated with values using the GetAttributes method in order for this method to work.

Usually this method will be used inside the Done method, after the parent call, after a call to GetAttributes.

Parameters

ParameterDescription
AttributeThe name of the attribute to read out the queue. This parameter is not case sensitive.
InstanceThe instance number to retrieve. If this parameter is omitted then the first instance of the attribute in the queue is returned.

Example

First GetAttributes is called. Notice mail is one of the attributes being fetched.

net.AuthUser = 'wilson@test.local'
net.AuthPassword = 'NetTalk10'
net.Host = '192.168.2.164'
net.Port = 389
net.SetDomain('test.local')
net.SetAttributesQueue(AttributesQueue)
MessageId = net.GetAttributes('sn=Demaggio','userPrincipalName,cn,mail')


then in the net.done method

net.Done PROCEDURE(Long pMessageId)
  CODE
  PARENT.Done(pMessageId)
  If pMessageId = MessageId
    UserEmail = self.GetAttributeValue('mail')
  End


Return Value

The method returns a STRING containing the value requested. If the Attribute parameter does not exist in the Queue then a blank string is returned.

See Also

GetAttributes

Search

Search(String pBase, String pFilter, String pAttributes, String pScope, String pDerefAliases, Long pSizeLimit=0, Long pTimeLimit=0, Long pTypesOnly=false)

Description

Allows an ad-hoc search to be done. The methods GetAttributes, UserInGroup are pre constructed searches which use this method, but which are simpler to use.

Parameters

ParameterDescription
pBasethe root for the search. Most often contains a search prefix, and domain to search.
pFilterThe search term to search on. This filter is a User Filters.
pAttributesThe attributes to be included in the search result. This is a comma separated list.
pScopeThe scope of the search. On of NetLDAP:SCOPE_BASEOBJECT, NetLDAP:SCOPE_ONELEVEL, NetLDAP:SCOPE_SUBTREE, NetLDAP:SCOPE_SUBORDINATE. If not sure try NetLDAP:SCOPE_SUBTREE.
pDerefAliasesOne of NetLDAP:DEREF_NEVER, NetLDAP:DEREF_SEARCHING, NetLDAP:DEREF_FINDING, NetLDAP:DEREF_ALWAYS. If not sure try NetLDAP:DEREF_NEVER.
pSizeLimitIf omitted set to 0. The size limit of the response. If 0 no limit is applied.
pTimeLimitIf omitted set to 0. The time limit for the search. If 0 no limit is applied.
pTypesOnlyIf omitted set to false. If true only types are included in the returned set.

Example



Return Value

The method returns nothing. This method starts an asynchronous search. When the complete result has been received the SearchDone method will be called.

See Also

GetAttributes, UserInGroup, SearchDone

SearchDone

SearchDone(Long pMessageID, Stringtheory ObjectName, StringTheory pAttributes)

Description

Called when a call to Search is completed. This method should only be embedded into when doing a custom search. Calls to UserInGroup and GetAttributes will be returned in the Done method.

Parameters

ParameterDescription
MessageIdThe MessageID of the request which has just completed.
ObjectNameThe object name as returned by the server
pAttributesThe attribute list as returned by the server

Example



Return Value

The method returns nothing.

See Also

Search

SetAttributesQueue

SetAttributesQueue (Queue pAttributesQueue)

Description

If you want the results of a call to GetAttributes to populate a queue you declare, not the internal queue, then use this method to set the result queue. The attribute name is placed in the first field in the queue, and the attribute value in the second field.

Parameters

ParameterDescription
AttributesQueueThe Queue to receive the results of a call to GetAttributes.

Example

See GetAttributes

Return Value

The method returns nothing.

See Also

GetAttributes

SetDomain

SetDomain (String pDomain)

Description

Sets the domain of the server you are connecting to. The internal domain format is ugly, so this method simply transforms a simple domain into the format used internally.

Parameters

ParameterDescription
DomainThe domain, on the ActiveDirectory server, that you are connecting to.

Example

See GetAttributes

Return Value

The method returns nothing.

See Also

GetAttributes, UserInGroup, ValidateUser

Start

Start ()

Description

Returns the object to a virgin state. Call this if you are re-using the object with a different login, or against a different server.

Return Value

The method returns nothing.

See Also



UserInGroup

UserInGroup (String pUser, String pGroup)

Description

This method allows you to check if a user is assigned into a specific group in the Active Directory server.

Parameters

ParameterDescription
UserA user filter to determine which user to check.
GroupThe name of the group to check.

Example

net.Host = '192.168.2.164'
net.Port = 389
net.SetDomain('test.local')
net.AuthUser = 'wilson@test.local'
net.AuthPassword = 'NetTalk10'
MessageID = net.UserInGroup('cn=Wilson Demaggio','NetTalkUsers')

Return Value

The method returns a LONG containing the new MessageID.

When the request to the server is complete then the Done method is called.

If the user is valid then the UserIsInGroup property is set to true. If it is not valid then it is set to false.


See Also

Checking if a User is in a Specific Group, Done, ErrorTrap, ValidateUser, GetAttributes

ValidateUser

ValidateUser()

Description

This method validates the AuthUser and AuthPassword properties against the server.

Parameters

Although it takes no parameters, the AuthUser and AuthPassword properties must be set before this method is called.

Example

net.Host = '192.168.2.164'
net.Port = 389
net.SetDomain('test.local')
net.AuthUser = 'wilson@test.local'
net.AuthPassword = 'NetTalk10'
MessageID = net.ValidateUser()

Return Value

The method returns a LONG containing the new MessageID.

When the request to the server is complete then the Done method is called.

If the user is valid then the ValidUser property is set to true. If it is not valid then it is set to false.

See Also

Validating a User Login and Password, Done, ErrorTrap, GetAttributes, UserInGroup

[End of this document]
Return to NetTalk Documentation Index