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.

Updating

12.34

  1. (optional) Build 12.34 introduced an additional parameter to LDAPParametersGroup, and thus (optionally) a change to the code in the ActiveDirectory_ValidateUser procedure in your application. To reduce the potential for changes to this procedure in the future, It is now possible to call the ValidateUser method with the parameters group itself - thus passing parameters set by the Login procedure to the ValidateUser method directly.

    This change is optional, although recommended if you are using Secwin.

    In earlier builds the code to call Validate User may read something like;

    net.Host = pParms.pHost
    net.Port = pParms.pPort
    net.SetDomain(pParms.pDomain) ! allows the user to just enter the "user logon name"
    net.SetAuthUser(pParms.pAuthUser) ! overrides SetDomain above if it contains the UserPrincipalName
    net.AuthPassword = pParms.pAuthPassword
    MessageId = net.ValidateUser()


    this can now be replaced with just

    MessageId = net.ValidateUser(pParms)
  2. (optional, but recommended, especially for Secwin users.)
    The ActiveDirectory_ValidateUser procedure in your application should return either net:userValid or a reason why the login is invalid. The code in net.done in this procedure has been tidied up to make this more explicit.

      If pMessageId = MessageId
        ans = self.ValidUser    ! notice it's not self.usererror
        If self.validUser = net:userValid
          ans = self.ValidUser
        Else
          ans = self.UserError
        End
        Post(event:closeWindow)
      End

11.30

Build 11.30 introduces some changes which you may want to take advantage of in your program. If you added LDAP support to your program before build 11.30 then you may want to make some of these changes.
  1. (optional) : On your LDAP Settings Window, add a parameter to determine that the server is a Windows 2003 R2 Server or later. If this option is on then the recursive group searches can be done.
  2. (optional) : In the Login procedure set the parms.pActiveDirectory property to the setting above. (Similar to how the parms.pHost is being set).
  3. (optional) : In the Login procedure set parms.pUser without the cn=. In other words;
    parms.pUser = 'cn=' & UserName
    becomes
    parms.pUser =  UserName
  4. (optional - this change is unnecessary if applying 12.34 changes) 
    In your application, in the ActiveDirectory_ValidateUser procedure change the line;
    net.AuthUser = pParms.pAuthUser
    to
    net.SetAuthUser(pParms.AuthUser)
  5. (optional) : In your application, in the ActiveDirectory_GetAttributes procedure, add a line to set net.ActiveDirectory. For example;
    net.ActiveDirectory = GetIni('Settings', 'IsActiveDirectory', 0, '.\LDAPDemo.ini')
  6. (optional) : In your application, in the ActiveDirectory_UserInGroup procedure, change the line;
    net.AuthUser = pParms.pAuthUser
    to
    net.SetAuthUser(pParms.AuthUser)
  7. (optional) : In your application, in the ActiveDirectory_UserInGroup procedure, add the line;
    net.ActiveDirectory = pParms.pActiveDirectory

Terminology

Name Description
Host The URL or IP address of the LDAP server you want to talk to. Similar to the URL of a web site.
Port The 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
Bind When 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.
Attributes These 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.
cn
CommonName
 This is a property for each user, set by the Administrator on the server. The Common Name is the whole name, as displayed in the administrator panel below. (Notice also the Group Name highlighted in the image below.) The Common Name of the highlighted user is Wilson S. Demaggio.

You do not change the Common Name by changing any of the properties of the user. (It _defaults_ to FirstName LastName, but changing those names does not change the common name.) To change the name right click on the list, and select the Rename option.

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 Logon Name
UserPrincipalName
sAMAccountName
DisplayName
 There are four common login approaches that are supported by the server.

The first is the userPrincipalName, the second is the sAMAccountName and the third is by using the DisplayName. The more modern (and hence preferred) name is the userPrincipalName.

The fourth approach is to accept the user logon name, and then internally the code uses the Domain to construct the UserPrincipalName from that. (For more on this see What to Use as the User Login.)

The first option uses both the user login name, AND the domain. In the picture below, the userPrincipalName of this user is wilson@Test.local. The sAMAccount name is wilson, but the login would be TESTIRONMAN\wilson

Active Directory User Name Active Directory User Name

The Third approach uses the Display Name. This approach does not include the domain. This approach is not recommended because the display name does not have to be unique. So multiple users could end up with the same display name. If multiple users have the same name then NONE of them can login using this approach.

Active Directory User Name

The Common Name is often the same as the Display Name, but they don't necessarily have to be the same.
userPrincipalName This is the attribute name which holds the login. In the Active Directory Administrator this is referred to as the Logon Name, however when constructing User Filters the correct name of the attribute is userPrincipalName.
sAMAccountName This is an older approach to logins. It consists of the single-name domain, followed by a \ and the user name.
In the picture above this would be TESTIRONMAN\wilson
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.

TLS Connections

You may need to connect to the server over a secure (TLS) connection. A sign this may be required is if the port you connect to is port 636 instead of port 389. Sometimes secure connections are referred to as LDAPS instead of LDAP.

Connecting to a secure port is not difficult. Simply set the SSL property for the object to true. For example;

net.ssl = true

This tells NetTalk to use a TLS connection to the server instead of an insecure connection.
 

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. The messages will be queued by the object so the are sent one at a time.

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)     ! allows the user to just enter the "user logon name" 
net.SetAuthUser(pParms.pAuthUser) ! overrides SetDomain above if it contains the UserPrincipalName
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. If in error then check the UserError property to get details on the failure..

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

If pMessageId = MessageId
  ans = self.ValidUser
End


Add the following code to the ErrorTrap method to get the failed result.

If pMessageId = MessageId
  ans = self.UserError
End


The ValidUser property is either true (if the user is valid) or false (if they are not). If they are not valid then the UserError property contains one of the following values; net:WrongUserOrPassword, net:UserDisabled, net:UserExpired, net:UserLocked          

What to use as the User Login?

In a traditional login system you have a user name, and a password. The user name identifies the user, the password validates that the identification is who they say they are (aka "something they know.")

With Active Directory the identification part is a lot more fluid. You can use a number of ways of identifying the person. Ideally the user name should include the domain, however you can also specify the domain separately and NetTalk will create the identification for you.

UserLogonName
The User Logon Name is the first part of the UserPrincipalName.  If the user name does not contain a domain then the UserPrincipalName will be calculated automatically, (from the SetDomain call) when the SetAuthUser method is called.

UserPrincipalName
This has the form user@some.domain
This is the preferred approach. If no domain is used in the user name, then the domain can be set separately using the SetDomain method.

sAMAccountName
For really old servers (Windows 2000) that do not support the UserPrincipalName, then an alternative is possible. This is the
SERVER\sAMAccountName format.

DisplayName
An alternative to the UserPrincipalName is the DisplayName. This works well, as long as the DisplayName is unique. If it is not unique then users will not be able to login using this name.

To keep things simple, use the UserPrincipalName for the AuthUser.

Note: You can check that the user actually has a UserPrincipalName (UPN) on the user account settings on the server. If no UPN is assigned to the user, then the user cannot use that approach to login.

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;

displayName=Wilson S. Demaggio
or
userPrincipalName=wilson@test.local

Hint: The userPrincipalName is the name usually used when logging a user in.

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

Wildcards

It's possible to use the * character in a filter to specify zero, or more unknown characters. For example;

sn=A*

will return all the users starting with the letter A.

The * can be placed at the front, end or middle of the search. Multiple *'s are also allowed. For example

sn=*der*

will return names like van der Spuy, Lander, der Rensburg and so on.

sn=van*Spuy

will return names like van der Spuy, van Spuy and so on.

Common Filters

User filter Attributes Description
cn=Wilson S. Demaggio distinguishedName,mail Get the distinguisedName and mail attributes for this user.
cn=Wilson S. Demaggio memberof Returns a string containing a list of the groups that the user is in. For example
CN=AmazingAccounts,CN=Users,DC=Test,DC=Local
cn=AmazingAccounts member Returns a queue of users that are members of this group. Each line in the queue contains the member information. For  example
CN=Wilson S. Demaggio,CN=Users,DC=Test,DC=local
cn=Wilson S. Demaggio * Gets all the attributes for a single user, as a queue.
objectClass=group cn Lists the common name for all the groups in the directory.
objectClass=group distinguishedName Lists the CN of each group, and also its location in the tree.
objectClass=group cn,member Lists the groups, and the direct members in each group
objectCategory=user cn Lists all the users in the directory
objectCategory=user distinguishedName Lists the CN of each user, and also their location in the tree.
&(objectclass=group)(cn=EcoTime) cn,member Lists the members in the group called EcoTime.
(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=CN=Wilson S. Demaggio,CN=Users,DC=Test,DC=local)) cn Lists all the groups that Wilson S. Demaggio is a member of. This is a recursive group search (ie supports groups in groups) and is Active Directory (2003 R2 and later) only.
(&(objectCategory=person)(sAMAccountName=wilson))
or
(&(objectClass=user)(sAMAccountName=wilson))
accountExpires The date when the account expires. This value represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). A value of 0 or 0x7FFFFFFFFFFFFFFF (9223372036854775807) indicates that the account never expires.

lockoutTime The date and time (UTC) that this account was locked out. This value is stored as a large integer that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC). A value of zero means that the account is not currently locked out.

userAccountControl Various flags for the account - including (but not limited to)
Net:ADS_UF_ACCOUNTDISABLE
Net:ADS_UF_LOCKOUT
Net:ADS_UF_PASSWORD_EXPIRED

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 UserFilter 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.Host = pParms.pHost
net.Port = pParms.pPort
net.ActiveDirectory = pParms.ActiveDirectory  ! only set to true if Server is Server 2003 R2 or later
net.SetDomain(pParms.pDomain)  ! not needed if the pAuthUser contains the UserPrincipalName
net.SetAuthUser(pParms.pAuthUser)
! overrides SetDomain above if it contains the UserPrincipalName
net.AuthPassword = pParms.pAuthPassword
net.SetAttributesQueue(AttributesQueue)
MessageId = net.GetAttributes(pParms.pUser,pParms.attributeList)


When the response from the server is received than 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.

In other words, there is a queue internal to the object that can be used to hold results, or you can specify your own queue to hold the results using the SetAttributesQueue method.

When the attributes have arrived into the queue then the Done method will be called. So you can process the results there.

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 is for the program to authenticate a user against an Active Directory Group 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 Active Directory server with something like "Is WhateverUser in the Amazing Accounts 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.

Aside - For logins, it is possible to prime the login field with the Windows Login, but you will need to retrieve the password from the user. If you are doing an automatic login, then you can simply test the Windows User name with the group.

The AuthUser and AuthPassword are the same as the ones used for the ValidateUser method, or a known user that is allowed to do group searches.

The User parameter is the UserPrincipalName, sAMAccountName, or DisplayName of the user.
The InGroup parameter is the name of the group to compare against.

Example of calling the method

net.Host = pParms.pHost
net.Port = pParms.pPort
net.ActiveDirectory = pParms.ActiveDirectory
! only if Server 2003 R2 or later
net.SetDomain(pParms.pDomain)     ! not needed if the pAuthUser contains the UserPrincipalName
net.SetAuthUser(pParms.pAuthUser) ! overrides SetDomain above if it contains the UserPrincipalName
net.AuthPassword = pParms.pAuthPassword
net.SetUser(pParms.pUser)
MessageId = net.UserInGroup(pParms.pInGroup)

Again the result will appear in the Done method

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

Groups in Groups

Windows Server 2003 R2 and later support groups-in-groups searches. If the server is Windows Server 2003 R2 or later then set the ActiveDirectory property to true. Setting this property to true for other LDAP servers, or for older Windows Servers, will result in all calls to UserInGroup failing.

Checking if a user is valid, without knowing their password

In some cases it is useful to know about the validity of a user without having to log in as that user. This could happen where say the Windows login was being used (without a password) or where an Administrator needs to gather information on the available users.

As from build 12.34 this is handled using the ValidateUser method with the pDontValidatePassword parameter in the LDAPParmetersGroup set to true. For example;

parms like(LDAPParametersGroupType)

parms.pHost =
parms.pPort =
parms.pDomain =
parms.pActiveDirectory =
parms.pAuthUser =
parms.pAuthPassword =

parms.pUser = UserName
parms.pDontValidatePassword = true
net.ValidateUser(parms)


The result will be returned into the Done method, just like a regular login. In the Done method the self.validUser property will be set to either net:userValid or something else. If something else then the self.UserError property can be examined for the reason the user is invalid.

Common possible reasons include net:WrongUserOrPassword, net:UserDisabled, net:UserExpired, net:UserLocked, net:NoConnectionToServer, net:UserNotFound

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.
Name Type Description
pHost String The URL or IP address of the LDAP server you are connecting to.
pPort String The port number of the LDAP server you are connecting to. Defaults to 389.
pAuthUser String The user name for the user when authenticating against the LDAP server.
pAuthPassword String The password for the user when authenticating against the LDAP server.
pDomain String The domain of the LDAP server.
pUser String A user filter.
pInGroup String A group name (used for UserInGroup method.)
pActiveDirectory Byte New in build 11.30. Set this if the server is Windows Server 2003 R2 or later. This will allow recursive group searches to be done.
pDontValidatePassword Byte New in build 12.34. this allows for ValidateUser to be called without getting the user password, but still checking the account for activeness.

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.86 -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
cn=users is the branch of the Active Directory tree. If there was an Organizational Unit (OU) in the tree then this would become ou=whatever
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 sn (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=*)" *

Here is an example that returns the (non recursive) list of groups the user is in

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

This example returns a list of the users in the group MadHatters, where the group is in an OU called People. (Note that this example is for Active Directory only, other LDAP servers do not support the 1.2.840... filter.) This returns users from all OUs - not just the OU branch.

ldapsearch -h 192.168.2.86 -x -b "DC=test,DC=local" -D "wilson@test.local" -w NetTalk10 "(&(objectCategory=user)(memberof:1.2.840.113556.1.4.1941:=CN=MadHatters,OU=People,DC=test,DC=local))" dn

This example returns a list of users in the group Candles, which is in the normal Users section of the AD tree. (Note that this example is for Active Directory only, other LDAP servers do not support the 1.2.840... filter.) This returns users from all OUs - not just the Users branch.

ldapsearch -h 192.168.2.86 -x -b "DC=test,DC=local" -D "wilson@test.local" -w NetTalk10 "(&(objectCategory=user)(memberof:1.2.840.113556.1.4.1941:=CN=Candles,CN=Users,DC=test,DC=local))" dn

The following example lists the groups that a specific user has access to. Again, this supports groups in groups, and is Active Directory specific.

ldapsearch -h 192.168.2.86 -x -b "DC=test,DC=local" -D "wilson@test.local" -w NetTalk10 "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=cn=Wilson S. Demaggio,cn=Users,DC=test,DC=local))" cn

as before if the user is in an OU instead of the users list, then the filter changes slightly

ldapsearch -h 192.168.2.86 -x -b "DC=test,DC=local" -D "wilson@test.local" -w NetTalk10 "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=cn=Albert Sisulu,OU=EcotimeOU,DC=test,DC=local))" cn

FAQ

 

Class Reference

NetLDAP

Included in NetTalk Desktop

Derivation

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

Properties

Property Description
AccountExpires (real) Set after a call to GetUserActive. Contains the date/time of the user account expiry in Unix Epoch (seconds) format.
ActiveDirectory Set this to true if the LDAP server being used is an Active Directory server. Defaults to true. Allows for some "Active Directory Only" features to be used. Should only be set if the Active Directory Server is on Windows Server 2003 R2 or later.
AllowAnonymous Set 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.
AttributesQueue A 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.
AuthPassword The password, of the user who is requesting data from the server.
AuthUser The login of the user who is requesting data from the server.
DebugPackets If this is set to true then the contents of outgoing packets are sent to Debugview. Used for internal debugging only.
DistinguishedName This is the Distinguished name of the user. Populate this using the GetDistinguishedName method. this field is auto-populated by a call to the UserInGroup method (if it's not already populated.)
Domain The domain of the server that you are connecting to. This is of the form dc=test,dc=local
It is set be a call to SetDomain.
DomainType One of NetLDAP:UserPrincipalName, NetLDAP:DisplayName, NetLDAP:sAMAccountName.
Defaults to NetLDAP:UserPricipalName.
Host The IP address, or DNS name of the LDAP server machine.
LockoutTime Set after a call to GetUserActive. Contains the date/time when the user account was locked in Unix Epoch (seconds) format.
LoginDomain This is of the form c.b.a, for example test.local or com.capesoft.
It is set be a call to SetDomain.
Port The 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.
SearchPrefix Allows the search for attributes, and users in a group, to be refined to a narrower scope.
User The user being checked for in the UserInGroup method.
UserAccountControl Set after a call to GetUserActive. Contains the UserAccountControl property of the user.
UserError If the ValidateUser method is called, and the user login is invalid, then this property contains one of
net:WrongUserOrPassword, net:UserDisabled, net:UserExpired, net:UserLocked
This property can then be used when reporting the error to the user to indicate why the login was refused.
UserIsInGroup If the UserInGroup method is called, then the result can be tested in the Done method.
ValidUser This is set to net:userValid if a request is made to ValidateUser. If the call is successful to the server then the Done method will be called. If the user is not valid then see the UserError property for the reason. It can be one of net:userInvalid,
net:WrongUserOrPassword, net:UserDisabled, net:UserExpired, net:UserLocked  or net:NoConnectionToServer.

Methods

Method Description
Done This method is called when a request to the server has received a response.
ErrorTrap This method is called if an error occurs while communicating with the server.
GetAttributes Get attributes for a specific user.
GetAttributeValue Reads an entry from the Attributes Queue after a call to GetAttributes.
GetUserActive
MessageDone  
Search Do an Addhoc search against the LDAP server.
SearchDone Is called when the results of a search are available.
SetAttributesQueue Set the Queue to receive the results from a call to GetAttributes.
SetAuthUser Sets the AuthUser property, and possibly Domain property.
SetUser Sets the User property
SetDomain Sets the domain of the server that the program is connecting to.
Start RReturns the object to a virgin state.
UserInGroup Check to see if a specific user is in a Group or not.
ValidateUser Validates 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.
NetLDAP

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

Parameter Description
MessageID The 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.

Example

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


Return Value

The method returns nothing.

See Also

ErrorTrap, ValidateUser, GetAttributes, UserInGroup

NetLDAP

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

Parameter DDescription
MessageId The ID of the message being attempted.
ErrorCode The NetTalk Error Code
Error The 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

NetLDAP

GetAttributes

GetAttributes (String pUserFilter, <String pAttributes>)

Description

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

Parameters

Parameter Description
UserFilter A user filter to determine which user(s) to get the attribute(s) for.
Attributes A 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.86'
net.Port = 389
net.SetDomain('test.local')        
! best to call this before SetAuthUser
net.SetAuthUser('wilson@test.local')
net.AuthPassword = 'NetTalk10'
net.ActiveDirectory = true         
! For Windows Server 2003 R2 and later
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

NetLDAP

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

Parameter Description
Attribute The name of the attribute to read out the queue. This parameter is not case sensitive.
Instance The instance number to retrieve. If this parameter is omitted then the first instance of the attribute in the queue is returned.

Notes

The instance number refers to the instance if the attribute in the queue, not the instance number of some "block" in the queue. It is not uncommon for complex queries to return a different number of attributes per block. So, for example, if searching for a number of attributes per user, then if the first user lacks say a department setting then the "first instance" of a department would belong to the second user.

In other words the GetAttributeValue method is useless in cases where the search is returning a variable number of properties per "user".

This method can be useful in cases where you are getting multiple instances of the same property for a single user. For example when returning the list of groups that a user belongs to.


Example

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

net.Host = '192.168.2.86'
net.Port = 389
net.SetDomain('test.local')         ! best to call this before SetAuthUser
net.SetAuthUser('wilson@test.local')
net.AuthPassword = 'NetTalk10'
net.ActiveDirectory = true          ! For Windows Server 2003 R2 and later
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')
    UserPrincipalName = self.GetAttributeValue('userPrincipalName')
  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

NetLDAP

GetUserActive

GetUserActive(String pUser)

Description

This method determines if a user account is valid (ie, not disabled, expired, locked) without using the user's password. This method requires that all the other properties (host, port etc) are set. If they are not set use the ValidateUser method, with pDontValidatePassword field in the LDAPParametersGroup set to true.

Parameters

Parameter Description
pUser A user account name (passed through SetUser for expansion)

Example

MessageId = net.GetUserActive('wilson')

Return Value

The method returns the message ID. This method starts an asynchronous search. When the complete result has been received the Done method will be called.

See Also

SetUser, ValidateUser .

NetLDAP

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

Parameter Description
pBase The root for the search. Most often contains a search prefix, and domain to search.
pFilter The search term to search on. This filter is a User Filters.
pAttributes The attributes to be included in the search result. This is a comma separated list.
pScope The 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.
pDerefAliases One of NetLDAP:DEREF_NEVER, NetLDAP:DEREF_SEARCHING, NetLDAP:DEREF_FINDING, NetLDAP:DEREF_ALWAYS. If not sure try NetLDAP:DEREF_NEVER.
pSizeLimit If omitted set to 0. The size limit of the response. If 0 then no limit is applied.
pTimeLimit If omitted set to 0. The time limit for the search. If 0 then no limit is applied.
pTypesOnly If omitted set to false. If true only types are included in the returned set.

Example

MessageId = net.Search('dc=Test,dc=Local','userPrincipalName=wilson@test.local','sn,mail', NetLDAP:SCOPE_SUBTREE, NetLDAP:DEREF_NEVER)

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

NetLDAP

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

Parameter Description
MessageId The MessageID of the request which has just completed.
ObjectName The object name as returned by the server
pAttributes The attribute list as returned by the server

Example


Return Value

The method returns nothing.

See Also

Search

NetLDAP

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

Parameter Description
AttributesQueue The Queue to receive the results of a call to GetAttributes.

Example

See GetAttributes

Return Value

The method returns nothing.

See Also

GetAttributes

NetLDAP

SetAuthUser

SetAuthUser(String pAuthUser, Long pType=NetLDAP:UserPrincipalName)

Description

Sets the AuthUser property, and also (if available) the Domain and LoginDomain properties.

If the passed in Domain parameter is empty then the properties in the object are NOT cleared.

Parameters

Parameter Description
AuthUser A user name. This may be a UserPrincipalName (of the format user@c.b.a), a sAMAccountName (of the form DOMAIN\USER),  or a simple user displayName.
Type If the preferred login type cannot be auto-detected by the AuthUser (ie it does not include an @ or \ or space symbol) then the type can be set using this parameter. (This parameter is ignored if the login type can be determined from the AuthUser).
This parameter can be omitted or can be one of NetLDAP:UserPrincipalName, NetLDAP:samAccountName or NetLDAP:DisplayNameNetLDAP:UserPrincipalName is recommended.

Example

net.SetAuthUser(pParms.pAuthUser)

Return Value

The method returns nothing.

See Also

SetUser, SetDomain, GetAttributes, UserInGroup, ValidateUser

NetLDAP

SetDomain

SetDomain (String pDomain)

Description

Sets the Domain, and LoginDomain properties in the object. the incoming parameter is of the form c.b.a (for example test.local, or com.capesoft). This is stored as-as in the LoginDomain property and is used principally for constructing the UserPrincipalName when doing a login or group validation. It is also converted to the form dc=test,dc=local which is then stored in the Domain property, and used where needed.

If a UserPrincipalName is passed to SetAuthUser, then SetDomain will be called automatically on that domain. For this reason it's advisable to call SetDomain before calls to SetAuthUser.

If the passed in Domain parameter is empty then the properties in the object are NOT cleared.

Parameters

Parameter Description
Domain The domain, on the LDAP (aka Active Directory) server, that you are connecting to.

Example

net.SetDomain(pParms.pDomain)

Return Value

The method returns nothing.

See Also

SetAuthUser, SetUser, GetAttributes, UserInGroup, ValidateUser

NetLDAP

SetUser

SetUser(String pUser, Long pType=0)

Description

SetUser is similar to SetAuthUser. There are two user fields because one user (the AuthUser) has access rights to the server, but the other user (the User) is being queried. In other words the AuthUser is making the request to get information about the User.
(Obviously in some cases the AuthUser and User may be the same, but they are often different.)

Parameters

Parameter Description
User If this already contains an attribute=value form then the attribute part is removed.
If the value contains just a user id, then it is adjusted to an appropriate attribute=value form.
Values containing an @ symbol are adjusted to
userPrincipalName=user
Values containing an \ symbol are adjusted to
sAMAccountName=user
Values containing a space are adjusted to
displayName=user
If none of these are detected then the login domain of the AuthUser (if it's been set) is used to create the userPrincipalName or samAccountName, based on the Type parameter, or failing that the AuthUser's type.
Type If this is not set then the domain type of the AuthUser is used (if this parameter is used at all.)

Example

net.SetUser(pParms.pUser)

Return Value

The method returns nothing.

See Also

SetAuthUser, SetDomain, GetAttributes, UserInGroup, ValidateUser

NetLDAP

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



NetLDAP

UserInGroup

UserInGroup (String pGroup)
UserInGroup (String pUser, String pGroup, Long pActiveDirectory=false)

Description

This method allows you to check if a user is assigned into a specific group in the LDAP (Active Directory) server.
This method supports groups-in-groups, so if a user is in group B, and group B is in group A, then the user is considered to be in group A.

Parameters

Parameter Description
User A user filter to determine which user to check. If omitted then the current User property is used. (Typically as set by a call to SetUser)
Group The name of the group to check.
ActiveDirectory Set this to true if the LDAP server is a Windows Server 2003 R2 or later server. This switch defaults to false, and allows the class to use some Active-Directory-Only features.

Example

net.Host = '192.168.2.86'
net.Port = 389
net.ActiveDirecory = true
! only for Windows 2003 R2 and later.
net.SetDomain('test.local')
net.SetAuthUser('wilson@test.local')
net.AuthPassword = 'NetTalk10'
net.SetUser('albert')
! or
net.SetUser('mydomain/albert')
! or
net.SetUser('displayName=albert sisulu') ! or
net.SetUser('albert@test.local')
MessageID = net.UserInGroup('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

NetLDAP

ValidateUser

ValidateUser()
ValidateUser(LDAPParametersGroupType pParms)

Description

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

Parameters

Parameter Description
pParms
(optional)
A LDAPParametersGroup containing all the details for the LDAP server, and specifics about the request.

If the parameter is not passed then the object must be primed before making the call. See below for an example.

Example

In this example ValidateUser is called with a parameter.

parms.pHost = '192.168.2.164'
parms.pPort = 389
parms.pDomain = 'test.local'
parms.pActiveDirectory = true    
parms.pDontValidatePassword = DontValidatePassword 
If DontValidatePassword
  parms.pAuthUser =
'wilson@test.local'
  parms.pAuthPassword = 'NetTalk10' 
  parms.pUser = 'bruce'
Else
  parms.pAuthUser = 'bruce'                                    
  parms.pAuthPassword = 'password'
End
MessageID = net.ValidateUser(parms)

Example

In this example the method is called without a parameter, but the object properties are set directly. This approach is not recommended as it could be subject to change in the future, resulting in your existing code needing to be changed. Where possible the above example is preferred.

net.Host = '192.168.2.164'
net.Port = 389
net.SetDomain('test.local')
net.SetAuthUser('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 net:userValid. If it is not valid then it is set to something else.

See Also

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

[End of this document]
Return to NetTalk Documentation Index