Skip to main content

%SYS.LDAP

Class %SYS.LDAP [ Abstract, System = 4 ]

Requires %syLDAP.INC to be included in your COS routine for some macro definitions.
The class methods described below are built on top of the interfaces OPENLDAP provides. For more information on OPENLDAP, see www.openldap.org.

This class only supports the OPENLDAP version 3 protocols.
It is based on OPENLDAP's source version openldap-2.4.48.
This class allows the user to interface with an LDAP database. The user can use the methods provided to authenticate themselves, Search, Add, Modify, Rename, and Delete entries in the LDAP database.

Error Handling:
Every time an LDAP method is called, a success status or error status is either returned or set into the LDAP session. If the method does not return the error as a result of the call, then the caller needs to retrieve the error with a call to either the GetError method, or the GetLastError method. The caller should test the return values for success or failure after every call.

Example:
s Status=##Class(%SYS.LDAP).AddExts(LD,DN,Attributes)
i Status'=$$$LDAPSUCCESS {
w !,"AddExts error: "_Status_" - "_##Class(%SYS.LDAP).Err2String(Status)
g LDAPError
}

See the LDAP.mac routine for extensive LDAP samples. This routine is available on GitHub at https://github.com/intersystems/Samples-Security

Methods

AddExts

ClassMethod AddExts(LD As %Integer, DN As %String, ATTR As %List, ServerControls As %String = "", ClientControls As %String = "") As %Integer

Add an entry to the LDAP directory tree.

Parameters:

LD - The session handle returned by the Init method.

DN - String that contains the distinguished name of the entry to add.

ATTR - $list formatted with attributes to add to the new entry.
Each element in the list is a separate attribute to be added to the new entry.
Attribute=$lb(op,type,vals)
op - For create, set to 0. However, if the vals parameter is to be treated as binary, then pass in 128 for this parameter.
type - Name of the attribute. Example="Telephone".
vals - $list of the values to assign to the attribute. If this is a single entry attribute, then $lb(Value), Example=$lb("617-621-0600"). If a multi-value entry, then $lb(Value1,Value2,...,Valuen). If the data is to be treated as binary (e.g. jpeg file), then make sure that 128 is passed for the op.

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Examples:

s Attr1=$lb(0,"displayName",$lb(Jim Nilson))
s Attr2=$lb(0,"telephoneNumber",$lb("617-621-0600")
s Attr3=$lb(0,"objectClass",$lb("top","person","organizationalPerson","user")
s Attr4=$lb(128,"Picture",$lb(Jpegbitstring))
s Attributes=$lb(Attr1,Attr2,Attr3,Attr4)
; Note the special character identifier "\" which is needed before the "," in the name
s DN="CN=Nilson\, Jim,OU=Users,OU=England,DC=iscinternal,DC=com"
s Status=##Class(%SYS.LDAP).AddExts(LD,DN,Attributes)

Note: See the ModifyExts method below for how to manipulate passwords on a Windows Active Directory LDAP server.

Binds

ClassMethod Binds(LD As %Integer, DN As %String = "", Cred As %List, Method As %Integer) As %Integer

Authenticate a Windows client to a Windows Active Directory LDAP Server.

Parameters:

LD - The session handle returned by the Init method.

DN - Distinguished name of the entry to bind. Currently always "".

Cred - A $list value that contains the credentials with which to authenticate. Currently only supported credentials are $lb(Username,Domain,Password).

Method - Indicates the authentication method to use. The following are supported:
$$$LDAPAUTHSICILY
$$$LDAPAUTHMSN
$$$LDAPAUTHNTLM
$$$LDAPAUTHDPA
$$$LDAPAUTHNEGOTIATE
$$$LDAPAUTHDIGEST

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This method is valid only for Windows clients talking to a Windows Active Directory LDAP server. Use SimpleBinds for OPENLDAP servers. If you have retrieved full DN of the Windows user using the LDAP search method, then you may use SimpleBinds on the Windows Active Directory LDAP server also.

Examples:

s Status=##Class(%SYS.LDAP).Binds(LD,"",$lb(Username,Domain,Password),$$$LDAPAUTHNEGOTIATE)

See the documentation in SimpleBindS which shows how to handle errors and retry the operation.

CheckFilter

ClassMethod CheckFilter(LD As %Integer, SearchFilter As %String) As %Integer

Verify search filter syntax.

Parameters:

LD - The session handle returned by the Init method.

SearchFilter - String that contains the name of the filter to check.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This method is valid only for Windows clients.

Examples:

s Status=##Class(%SYS.LDAP).CheckFilter(LD,"(objectclass=*)")

CompareExts

ClassMethod CompareExts(LD As %Integer, DN As %String, Attr As %String, Data As %String, ServerControls As %String = "", ClientControls As %String = "") As %Integer

Determine if an attribute, for a given entry, holds a known value.

Parameters:

LD - The session handle returned by the Init method.

DN - String that contains the distinguished name of the entry to compare.

Attr - String that contains the attribute to compare.

Data - String or list value to be compared to the attribute value. If the data is a string, then simply pass in the string. If the data is binary, then pass in $lb(binaryvalue).

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Return Values:

If the function succeeds, and the attribute and known values match, $$$LDAPCOMPARETRUE is returned.
If the values do not match, $$$LDAPCOMPAREFALSE is returned.
If the function fails, an error code is returned.

Examples:

s Status=##Class(%SYS.LDAP).CompareExts(LD,"CN=Nilson,OU=Users,DC=iscinternal,DC=com","mail","nilson@intersystems.com)

Connect

ClassMethod Connect(LD As %Integer, Timeout As %Integer = 0) As %Integer

Establish a connection to an LDAP server.

Parameters:

LD - The session handle returned by the Init method.

Timeout - The number of seconds to spend in an attempt to establish a connection before a timeout. If 0, the function uses a default timeout value.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This method is valid only for Windows clients.
Use this function to force a connection to an LDAP server from a Windows client. This connection would normally be done as part of the LDAP methods (like SimpleBinds). However, when diagnosing problems, performing the connection by itself can help narrow down connection issues versus search issues.

CountEntries

ClassMethod CountEntries(LD As %Integer, SearchResult As %Integer) As %Integer

Count the number of search entries that an LDAP server returned.

Parameters:

LD - The session handle returned by the Init method.

SearchResult - The search result as returned by SearchExts.

Return Values:

If the function succeeds, it returns the number of entries.
If the function fails, the return value is -1. The actual session error can be returned by a call to the GetError method.

Comments:

The CountEntries function returns the number of entries contained, or remaining in a chain of entries. Call the function with the return value from SearchExts.

Examples:

s Status=##Class(%SYS.LDAP).SearchExts(LD,BaseDN,$$$LDAPSCOPESUBTREE,Filter,Attributes,0,"","",2,ServerTimeout,.SearchResult)
i Status'=$$$LDAPSUCCESS q Status
s NumEntries=##Class(%SYS.LDAP).CountEntries(LD,SearchResult)
i NumEntries=-1 s Status=##Class(%SYS.LDAP).GetError(LD) q Status

CountValues

ClassMethod CountValues(Values As %List) As %Integer

Count the number of values returned by a GetValue call.

Parameters:

Values - Values as returned by GetValues.

Return Values:

If the function succeeds, it returns the number of entries in the list.
The actual session error status can be returned by a call to the GetError method.

Examples:

Values=##Class(%SYS.LDAP).GetValues(LD,CurrentEntry,Attr)
s Len=##Class(%SYS.LDAP).CountValues(Values)

CountValuesLen

ClassMethod CountValuesLen(Values As %List) As %Integer

Count the number of values in a binary list returned by a GetValuesLen call.

Parameters:

Values - Values as returned by GetValuesLen.

Return Values:

If the function succeeds, it returns the number of entries in the list.
The actual session error status can be returned by a call to the GetError method.

Examples:

Values=##Class(%SYS.LDAP).GetValuesLen(LD,CurrentEntry,Attr)
s Len=##Class(%SYS.LDAP).CountValuesLen(Values)

DeleteExts

ClassMethod DeleteExts(LD As %Integer, DN As %String, ServerControls As %String = "", ClientControls As %String = "") As %Integer

Remove a leaf entry from the directory tree.

Parameters:

LD - The session handle returned by the Init method.

DN - String that contains the distinguished name of the entry to delete.

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Examples:

s Status=##Class(%SYS.LDAP).DeleteExts(LD,"CN=Nilson\, Jim,OU=Users,OU=England,DC=iscinternal,DC=com")

Err2String

ClassMethod Err2String(Error) As %String

Convert a numeric LDAP error code into a string that describes the error.

Parameters:

Error - Error as returned by LDAP methods, or as returned by the method GetError.

Return Values:

If the method succeeds, a string that describes the error is returned.
If the function fails, "" is returned.
The actual session error status can be returned by a call to the GetError method.

Examples:

s NumEntries=##Class(%SYS.LDAP).CountEntries(LD,SearchResult)
i NumEntries=-1 s Msg=##Class(%SYS.LDAP).Err2String(##Class(%SYS.LDAP).GetError(LD))

EscapeFilter

ClassMethod EscapeFilter(ByRef SearchFilter As %String) As %Integer

Escape a search filter.

Parameters:

SearchFilter (byref) - String that contains the filter to escape.

Return Values:

SearchFilter - Returned filter with the characters escaped.
If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

Search filters need to be escaped according to LDAP rules. See:

https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx

Here is the character substitution this method provides.

* - \2a
( - \28
) - \29
\ - \5c
/ - \2f
NUL - \00

Examples:

s SearchFilter="Markus\, Paul,OU=People,OU=Havens,DC=thehavenshospital,DC=org
s Status=##Class(%SYS.LDAP).EscapeFilter(.SearchFilter)
w !,SearchFilter
Markus\5c, Paul,OU=People,OU=Havens,DC=thehavenshospital,DC=org

FirstEntry

ClassMethod FirstEntry(LD As %Integer, SearchResult As %Integer) As %Integer

Return a pointer to the first entry of a message.

Parameters:

LD - The session handle returned by the Init method.

SearchResult - The search result as returned by SearchExts.

Return Values:

If the method succeeds, it returns the entry.
If no entry exists in the result set, it returns 0, and a call to GetError returns $$$LDAPSUCCESS.
If the function fails, it returns 0 and a call to GetError returns the session error.

Comments:

Use FirstEntry in conjunction with NextEntry to step through and retrieve the list of entries from a search result chain.

Examples:

s Status=##Class(%SYS.LDAP).SearchExts(LD,BaseDN,$$$LDAPSCOPESUBTREE,Filter,Attributes,0,"","",2,ServerTimeout,.SearchResult)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status

GetDN

ClassMethod GetDN(LD As %Integer, Entry As %Integer) As %String

Retrieve the distinguished name for a given entry.

Parameters:

LD - The session handle returned by the Init method.

Entry - Entry whose distinguished name is to be retrieved, as returned by the FirstEntry or NextEntry methods.

Return Values:

If the function succeeds, it returns the distinguished name.
If the function fails, it returns "".
The actual session error status can be returned by a call to the GetError method.

Examples:

s Entry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status
s DN=##Class(%SYS.LDAP).GetDN(LD,Entry)
i DN="" s Status=##Class(%SYS.LDAP).GetError(LD)

GetError

ClassMethod GetError(LD) As %Integer

Retrieve the last error code returned by an LDAP call for a specific session.

Parameters:

LD - The session handle returned by the Init method.

Return Values:

An LDAP error code.

Comments:

Use the GetError method to return the last LDAP error message for a specific session. The value from the GetError method may in turn be passed to the Err2String method to get error text for the error.
Error numbers >= $zh("5000") are ISC internal LDAP errors.

Examples:

s Status=##Class(%SYS.LDAP).GetError(LD)
s Msg=##Class(%SYS.LDAP).Err2String(Status)

GetLastError

ClassMethod GetLastError() As %Integer

Retrieve the last error code returned by an LDAP call.

Return Values:

An LDAP error code.

Comments:

Use the GetLastError method to return the last LDAP error message. The value from the GetLastError method may in turn be passed to the Err2String method to get error text for the error.
Returned errors are only in the LDAP error range and do not include ISC internal errors.

Examples:

s Status=##Class(%SYS.LDAP).GetLastError()
s Msg=##Class(%SYS.LDAP).Err2String(Status)

GetNextPages

ClassMethod GetNextPages(LD As %Integer, Page As %Integer, Timeout As %Integer, PageSize As %Integer, ByRef TotalPages As %Integer, ByRef SearchResult As %Integer) As %Integer

Search the LDAP directory using a pages search and return a requested set of attributes for each entry.

This is a Windows only method.
Parameters:

LD - The session handle returned by the Init method.

Page - Pointer to page of results as returned by SearchInitPage() method. Timeout - Specifies both the local search time-out value in seconds and the operation time limit that is sent to the server within the search request.

PageSize - Number of records to be returned in each page for each call to GetNextPages().

TotalPages (byRef) - Estimated number of pages which will be returned by the search. Depending on the type of the LDAP server, this number may always be 0 (unknown).

SearchResult (byRef) - Contains the results of the search upon completion of the call.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If there are more results to retrieve, then If the function fails, an error code is returned.

Comments:

When done with the search results you need to free the search results the following way:

1) First call the MsgFree(SearchResult) method. 2) Then call the the SearchAbandonPage(LD,Page)() method. Failure to do this before a call to UnBinds may cause your process to core on a future LDAP call.

Note that the caller can have several different searches "open" at the same time by using a different variable for the SearchResult parameter.

Examples:

Search for all users in the LDAP database. Return their display name, e-mail and telephone number. Use a timeout of 10 seconds, and return at most 100 items for each call to the GetNextPages() method.

s Page=##Class(%SYS.LDAP).SearchExts(LD,"DC=mydomain,DC=com",
$$$LDAPSCOPESUBTREE,"sAMAccountname=*",
$lb("displayName","mail","telephoneNumber"),0,"","",10,100,"")
s Status=##Class(%SYS.LDAP).GetNextPages(LD,Page,10,100,.TotalPages,.SearchResult)
While (Status=$$$LDAPSUCCESS) {
; Process page of results here

; Now get the next page of results
s Status=##Class(%SYS.LDAP).GetNextPages(LD,Page,10,100,.TotalPages,.SearchResult)
}
i Status=$$$LDAPNORESULTSRETURNED {w !,"End of search"} else { w !,"Error "_Status}
s Status=##Class(%SYS.LDAP).MsgFree(SearchResult)
s Status=##Class(%SYS.LDAP).SearchAbandonPage(LD, Page)

GetOption

ClassMethod GetOption(LD As %Integer, Option As %Integer, ByRef OutValue As %String) As %Integer

Get options for an LDAP session.

Parameters:

LD - The session handle returned by the Init method.

Option - The name of the option to get. See valid options below.

OutValue - Value of that option.

Return Values:

If the function succeeds, the return value is $$$LDAPSUCCESS.
If the function fails, it returns an error code.

Valid Options:

$$$LDAPOPTERRORNUMBER - Returns the last LDAP error.

$$$LDAPOPTNETWORKTIMEOUT - Returns the network timeout value after which poll/select following a connect returns in case of no activity. Specifying seconds set to 0 results in an infinite timeout, which is the default. Normally there is no need to change the default. This is available on Unix platforms only.

$$$LDAPOPTTIMEOUT - Returns the timeout value for the synchronous API calls. Specifying seconds set to 0 results in an infinite timeout, which is the default. Normally there is no need to change the default. This is available on Unix platforms only.

$$$LDAPOPTSSL - Returns 0/1 whether SSL is enabled on the connection. The connection must have already been established before this will acurately return 0/1. This means calling StartTLS(), or SearchExts(), or additionally on Windows Connect().

$$$LDAPOPTERRORSTRING - When called after a Bind operation, may give additional information about the cause of the bind failure. Additional information is not available on Windows clients or if using an OPENLDAP server.
Examples:

Get last LDAP error on the session.
s Status=##Class(%SYS.LDAP).GetOption(LD,$$$LDAPOPTERRORNUMBER,.ErrorNum)

Note: Previous versions allowed the option $$$LDAPOPTPROTOCOLVERSION and $$$LDAPOPTREFERRALS to be specified. These options are deprecated. SetOption calls using this option will be ignored and always will return success. Version is now always set to 3, and referrals are always turned off.

GetValues

ClassMethod GetValues(LD As %Integer, Entry As %Integer, ByRef Attr As %String) As %List

Return string values for a given attribute. Use GetValuesLen for binary data.

Parameters:

LD - The session handle returned by the Init method.

Entry - Pointer to the search entry as returned by the FirstEntry or NextEntry methods.

Attr - String that contains the attribute whose values are to be retrieved. The passed string can be as returned by FirstAttribute or NextAttribute, or a caller supplied string.

Return Values:

If the function succeeds, a $list element is returned containing the values of the attribute.
If the function fails, it returns "".
The actual session error status can be returned by a call to the GetError method.

Examples:

s Status=##Class(%SYS.LDAP).SearchExts(LD,BaseDN,$$$LDAPSCOPESUBTREE,Filter,Attributes,0,"","",2,ServerTimeout,.SearchResult)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status
s ValueList=##Class(%SYS.LDAP).GetValues(LD,Entry,"sAMAccountname") i ValueList="" q ##Class(%SYS.LDAP).GetError(LD)
w !,"sAMAccountname="_$li(ValueList,1)

GetValuesLen

ClassMethod GetValuesLen(LD As %Integer, Entry As %Integer, ByRef Attr As %String) As %List

Return binary values for a given attribute. Use GetValues to return string values.

Parameters:

LD - The session handle returned by the Init method.

Entry - Pointer to the search entry as returned by the FirstEntry or NextEntry methods.

Attr - String that contains the attribute whose values are to be retrieved. The passed string can be as returned by FirstAttribute or NextAttribute, or a caller supplied string.

Return Values:

If the function succeeds, a $list element is returned containing the values of the attribute.
If the function fails, it returns "".
The actual session error status can be returned by a call to the GetError method.

Examples:

s Status=##Class(%SYS.LDAP).SearchExts(LD,BaseDN,$$$LDAPSCOPESUBTREE,Filter,Attributes,0,"","",2,ServerTimeout,.SearchResult)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status
s ValueList=##Class(%SYS.LDAP).GetValuesLen(LD,Entry,"jpegbinarypicture")
i ValueList="" q ##Class(%SYS.LDAP).GetError(LD)
d Displayjpeg($li(ValueList,1))

Init

ClassMethod Init(HostName As %String = "", PortNumber As %Integer = {$$$LDAPPORT}) As %Integer

Initialize a connection to a LDAP server.

Parameters:

HostName - Space-separated list of host names running an LDAP server to which to connect. Each host name in the list can include an optional port number which is separated from the host itself with a colon (:). The host name must be a fully qualified domain name. A fully qualified domain name (FQDN), sometimes referred to as an absolute domain name, is a domain name that specifies its exact location in the tree hierarchy of the Domain Name System (DNS). It specifies all domain levels, including the top-level domain and the root domain. A fully qualified domain name is distinguished by its unambiguity; it can only be interpreted one way. For example, given a device with a local hostname myhost and a parent domain name example.com, the fully qualified domain name is myhost.example.com. The FQDN therefore uniquely identifies the device; while there may be many hosts in the world called myhost, there can only be one myhost.example.com. When using a Windows Active Directory server as an LDAP server, and a Windows client, a null string will find the default LDAP server for the domain.

PortNumber - Contains the TCP port number to which to connect. This defaults to 389 if not specified. This parameter is ignored if a host name includes a port number.

Return Values:

If the function succeeds, it returns a handle to the LDAP session. The session handle must be freed with a call to UnBinds when it is no longer required.
If the function fails, it returns 0. Use GetLastError to retrieve the error code.

Note that Init does not make an actual connection to the LDAP server, it simply initializes the connection information. The actual connection will happen during the first request for data from the LDAP server.

Examples:

Creates a session to your default LDAP server on port 389.
s LD = ##Class(%SYS.LDAP).Init()

Creates a session to the LDAP server called "ldapserver" on default port 389.
s LD = ##Class(%SYS.LDAP).Init("ldapserver.example.com")

Creates a session to the LDAP server called "ldapserver" on port 389.
s LD = ##Class(%SYS.LDAP).Init("ldapserver.example.com",389)

Creates a session to either the LDAP server called "ldapserver" or if it is unavailable, to LDAP server "backupldapserver" on port 389.
s LD = ##Class(%SYS.LDAP).Init("ldapserver.example.com backupldapserver.example.com")

Secure Connections:
For a Windows client, make sure you have the CA certificates already loaded in the Certificates(local computer)\Trusted Root Certification Authorities certificate store. NOTE: If the certificates are stored in the Certificates(current user)\Trusted Root Certification Authorities certificate store, then the SSL connection may fail with Error code 81 if the process is running in the background. For a Unix client, make sure the protections on the certificate file allow your process to be able to read it, and that any additional certificate or LDAP options are specified in the ldap.conf file.
It is recommended that on the Active Directory Server that the parameter "LDAP server signing requirements" be set to "Require signature". This prevents any LDAP bind command on the server on port 389 to be executed unless the channel is encrypted with StartTLS. See

https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/domain-controller-ldap-server-signing-requirements

To create a secure SSL connection to an LDAP server, here are the calls you need to make for each platform type.

  1. Windows Client to Windows Active Directory LDAP server.
    Using the StartTLSs call
    s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com",389)
    s Status=##Class(%SYS.LDAP).StartTLSs(LD)

or

Using a direct connection to the LDAP SSL port.
s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com",636)

  1. Windows Client to OpenLDAP server
    Using a direct connection to the LDAP SSL port.
    s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com",636)

Or
using the StartTLSs call
s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com")
s Status=##Class(%SYS.LDAP).StartTLSs(LD)

  1. Unix client to Windows Active Directory LDAP server.
    Using the StartTLSs call. If you want to connect directly to port 636 without using StartTLSs, use the ##Class(%SYS.LDAP).Initialize() method.
    Note that there are other options pertaining to certificates which can be specified in the LDAP.CONF file on the Unix client (usually found in /etc/openldap/ldap.conf). The settings in this configuration file will be applied to your LDAP sessions you create. Read the man pages for ldap.conf for more information on the parameters.
    s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com")
    s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,CACertFileName)
    s Status=##Class(%SYS.LDAP).StartTLSs(LD)

  2. Unix client to OpenLDAPserver.
    Using the StartTLSs call. If you want to connect directly to port 636 without using StartTLSs, use the ##Class(%SYS.LDAP).Initialize() method
    Note that there are other options pertaining to certificates which can be specified in the LDAP.CONF file on the Unix client (usually found in /etc/openldap/ldap.conf). The settings in this configuration file will be applied to your LDAP sessions you create. Read the man pages for ldap.conf for more information on the parameters.
    s LD=##Class(%SYS.LDAP).Init("ldapserver.example.com")
    s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,CACertFileName)
    s Status=##Class(%SYS.LDAP).StartTLSs(LD)

Error codes:

When connecting using SSL, several different error codes could be returned when the connection is formed.
-11 or -12 - The certificate is not correct for the LDAP server, or the FQDN host name was not specified correctly. Make sure that you have the CA certificate properly installed on the client, in the correct directory. On a Windows client, make sure it is in local computer certificate store. On a Unix client, make sure the process has read access to the certificate, and that the file specification in the setoption call is correct. Make sure that the LDAP server name specified is the FQDN (e.g. ldapserver.example.com) and not just "ldapserver", or an ip address.
81 - Most likely the certificate is not in the correct Windows certificate store. Import it into the local computer store.
When on a Unix client, if you try to form an SSL connection with one certificate, and the certificate is wrong, or the server is incorrect, your connection may fail even after you have corrected the problem. The issue here is that the process caches the certificate and node information at the O/S level. To correct this, simply log your process out of the system, then log back in.

Initialize

ClassMethod Initialize(ByRef LD As %Integer = "", URL As %String) As %Integer

Connect from a Unix system to a LDAP server.

This sets up a connection from a Unix machine to an LDAP server with or without TLS.

  1. Connect without using TLS to port 389.
    Set Status=##Class(%SYS.LDAP).Initialize(.ld,"ldap://domain.com")
  2. Connect using TLS directly to port 636
    Set Status=##Class(%SYS.LDAP).Initialize(.ld,"ldaps://domain.com")
    Set Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,"/iris/mgr/CACertFile.pem")

Note that the actual connection to the LDAP server will be made when the first operation on the channel which returns data is executed, such as a SimpleBinds().

FirstAttribute

ClassMethod FirstAttribute(LD As %Integer, Entry As %Integer, ByRef Ptr As %Integer) As %String

Return the first attribute of an Entry.

Parameters:

LD - The session handle returned by the Init method.

Entry - The entry whose attributes are to be stepped through, as returned by the FirstEntry or NextEntry methods.

Ptr (ByRef) - Used internally to track the current attribute.
Return Values:

If the function succeeds, a string containing the name of the first attribute is returned.
If the function fails, it returns "".
The actual session error status can be returned by a call to the GetError method.

Comments:

Use the FirstAttribute with the NextAttribute method to step through a list of attributes in the entry. Once the Attribute name is returned, you can call the GetValues or GetValuesLen method to return the values for that attribute.
Pass the Ptr parameter by reference to track the current position in the entry.

Examples:

Loop through all attributes of an entry
s CurrentEntry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s AttrName=##Class(%SYS.LDAP).FirstAttribute(LD,CurrentEntry,.Ptr)
while (AttrName'="") {
s AttrValues=##Class(%SYS.LDAP).GetValues(LD,CurrentEntry,AttrName)
s AttrName=##Class(%SYS.LDAP).NextAttribute(LD,CurrentEntry,.Ptr)
}

ModifyExts

ClassMethod ModifyExts(LD As %Integer, DN As %String, ATTR As %List, ServerControls As %String = "", ClientControls As %String = "") As %Integer

Modify an entry in the directory tree.

Parameters:

LD - The session handle returned by the Init method.

DN - String that contains the distinguished name of the entry to modify.

ATTR - $list formatted with attributes to modify in the new entry.

Each element in the list is a separate attribute to be modified in the new entry.
Attribute=$lb(op,type,vals)
op - Operation to be performed as follows:
0 - Add - The given values are added to the entry, creating the attribute if necessary.
1 - Delete - The given values are deleted from the entry, removing the attribute if no values remain. If the entire attribute is to be deleted, the mod_values field should be set to NULL ($lb("")).
2 - Replace - The attribute will have the listed values after the modification, having been created if necessary. If set to null, then the attribute is deleted.
128 - This value should be combined (ORed) with the Add/Delete/Replace value if the data to be inserted is Binary (e.g. jpeg file.)
type - Name of the attribute. Example="Telephone".
vals - $list of the values to assign to the attribute. If this is a single entry attribute, then $lb(Value), Example=$lb("617-621-0600"). If a multi-value entry, then $lb(Value1,Value2,...,Valuen).

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Examples:

s Attr1=$lb(0,"displayName",$lb(Jim Nilson))
s Attr2=$lb(0,"telephoneNumber",$lb("617-621-0600")
; Replace the Objectclass attribute
s Attr3=$lb(2,"objectClass",$lb("top","person","organizationalPerson","user")
;Replace Binary value for a jpeg photo
s Attr4=$lb(130,"Photo",$lb(jpegphoto))
; Delete Address2 attribute
a Attr5=$lb(1,"Address2","")
s Attributes=$lb(Attr1,Attr2,Attr3,Attr4,Attr5)
s DN="CN=Nilson\, Jim,OU=Users,OU=England,DC=iscinternal,DC=com"
s Status=##Class(%SYS.LDAP).ModifyExts(LD,DN,Attributes)

Note:
Changing a password on a Windows Active Directory LDAP server.
The user must first be created before the password change can take place, and the password change must take place over an encrypted channel. The password is contained in the unicodePwd attribute, and must be formatted in a specific way. When initially creating the user, the unicodePwd attribute must not be specified, or the creation of the user will fail.
To format the password, a leading and trailing double quote must be added to it. Then it must be converted to unicode. Then when passed into the modify function, it must be passed in as a binary value, with the "Replace" operation. It must be the only operation contained in the modify call; No other attribute can be changed at the same time.

s password="NewPassword"
s ChangePassword=$zcvt(""""_password_"""","o","UnicodeLittle")
s Attr1=$lb(130,"unicodePwd",$lb(ChangePassword))
s Attributes=$lb(Attr1)
s Status=##Class(%SYS.LDAP).ModifyExts(LD,DN,Attributes,"","")

Note: In order to change a password, the user must have binded to the LDAP server with an account which has administrator privilege on the system. The password which is set must also pass any length or pattern requirements imposed by the security system on the LDAP server.

Changing your own password on a Windows Active Directory LDAP server is similar to above, except that you need to bind to the LDAP server using your own username, and must also pass in the old password with the delete attribute. These must also be the only two attributes passed in the modify method.

s oldpassword="OldPassword"
s password="NewPassword"
s ChangeOldPassword=$zcvt(""""_oldpassword_"""","o","UnicodeLittle")
s ChangeNewPassword=$zcvt(""""_password_"""","o","UnicodeLittle")
s Attr1=$lb(128,"unicodePwd",$lb(ChangeOldPassword))
s Attr2=$lb(129,"unicodePwd",$lb(ChangePassword))
s Attributes=$lb(Attr1,Attr2)
s Status=##Class(%SYS.LDAP).ModifyExts(LD,DN,Attributes,"","")

MsgFree

ClassMethod MsgFree(SearchResult As %Integer) As %Integer

Free the results of the last LDAP SearchExts method call.

Parameter:

SearchResult - Contains the results of the SearchExts method.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

When done with the search results you must free the search results by calling this method.

Failure to do this before a call to UnBinds may cause your process to core on a future LDAP call.

Examples:

s Status=##Class(%SYS.LDAP).MsgFree(SearchResult)

NextAttribute

ClassMethod NextAttribute(LD As %Integer, Entry As %Integer, ByRef Ptr As %Integer) As %String

Return the next attribute of an Entry.

Parameters:

LD - The session handle returned by the Init method.

Entry - The entry whose attributes are to be stepped through, as returned by the FirstEntry or NextEntry methods.

Ptr (ByRef)- Used internally to track the current attribute.
Return Values:

If the function succeeds, a string containing the name of the next attribute is returned.
If the function fails, it returns "".
The actual session error status can be returned by a call to the GetError method.

Comments:

Use the NextAttribute with the FirstAttribute method to step through a list of attributes in the entry. Once the attribute name is returned, you can call the GetValue or GetValuesLen method to return the values for that attribute.
Pass the Ptr parameter by reference to track the current position in the entry.

Examples:

Loop through all attributes of an entry
s CurrentEntry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s AttrName=##Class(%SYS.LDAP).FirstAttribute(LD,CurrentEntry,.Ptr)
while (AttrName'="") {
s AttrValues=##Class(%SYS.LDAP).GetValues(LD,CurrentEntry,AttrName)
s AttrName=##Class(%SYS.LDAP).NextAttribute(LD,CurrentEntry,.Ptr)

NextEntry

ClassMethod NextEntry(LD As %Integer, Entry As %Integer) As %Integer

Return the next entry of a message.

Parameters:

LD - The session handle returned by the Init method.

Entry - The Entry as previously returned by FirstEntry() or NextEntry().

Return Values:

If the method succeeds, it returns the entry.
If no entry exists in the result set, it returns 0, and a call to GetError returns $$$LDAPSUCCESS.
If the function fails, it returns 0 and a call to GetError returns the session error.

Comments:

Use NextEntry in conjunction with FirstEntry to step through and retrieve the list of entries from a search result chain.

Examples:

s Status=##Class(%SYS.LDAP).SearchExts(LD,BaseDN,$$$LDAPSCOPESUBTREE,Filter,Attributes,0,"","",2,ServerTimeout,.SearchResult)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).FirstEntry(LD,SearchResult)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).NextEntry(LD,Entry)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status
s Entry=##Class(%SYS.LDAP).NextEntry(LD,Entry)
s Status=##Class(%SYS.LDAP).GetError(LD)
i Status'=$$$LDAPSUCCESS q Status

RenameExts

ClassMethod RenameExts(LD As %Integer, DN As %String, NewRDN As %String, NewParent As %String = "", DeleteOldRdn As %Boolean = 1, ServerControls As %String = "", ClientControls As %String = "") As %Integer

Rename the distinguished name of an entry in the directory.

Parameters:

LD - The session handle returned by the Init method.

DN - String that contains the distinguished name of the entry to rename.

NewRDN - String that contains the new relative distinguished name.

NewParent - String that contains the distinguished name of the new parent for this entry or "". This parameter enables you to move the entry to a new parent container.

DeleteOldRdn - 1 if the old relative distinguished name should be deleted; 0 if the old relative distinguished name should be retained.

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Examples:

s Status=##Class(%SYS.LDAP).RenameExts(LD,"CN=Nilson,OU=Users,DC=iscinternal,DC=com","CN=Nelson","",1)

SASLBinds

ClassMethod SASLBinds(LD As %Integer, DN As %String, Mechanism As %String, ByRef ClientCredentials As %String, ServerControls As %String = "", ClientControls As %String = "", ByRef ServerCredentials As %String = "") As %Integer [ Internal ]

Authenticate a client to a server, using a SASL mechanism.

Parameters:

LD - The session handle returned by the Init method.

DN - Full distinguished name of the user to authenticate. This is usually in some form similar to the following:

"CN=testuser,OU=Users,OU=Cambridge,DC=mydomain,DC=com"

Mechanism - Type of SASL authentication to perform. Currently only "EXTERNAL" is supported. Pass "" for the DN and ClientCredentials.
ClientCredentials - Credentials for the DN.
ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

ServerCredentials - Server credentials.
Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This function should only be used on connections which has been encrypted with SSL/TLS.

On a Unix client, use the SetOption calls with $$$LDAPOPTXTLSCERTFILE and $$$LDAPOPTXTLSKEYFILE to pass in the Public and Private key files. Examples:

Initialize a connection to the default Windows domain LDAP server, start the TLS connection, and bind to the server.
s LD=##Class(%SYS.LDAP).Init()
s Status=##Class(%SYS.LDAP).StartTLSs(LD) s Status=##Class(%SYS.LDAP).SASLBinds(LD,"","EXTERNAL","","","",.ServerCredentials)

SearchExts

ClassMethod SearchExts(LD As %Integer, Base As %String, Scope As %Integer, Filter As %String, Attrs As %List, AttrsOnly As %Boolean = 0, ServerControls As %String = "", ClientControls As %String = "", Timeout As %Integer = 0, SizeLimit As %Integer = 0, ByRef SearchResult As %Integer) As %Integer

Search the LDAP directory and return a requested set of attributes for each entry.

Parameters:

LD - The session handle returned by the Init method.

Base - String that contains the distinguished name of the entry at which to start the search.

Scope - Specifies one of the following values to indicate the scope of the search.

$$$LDAPSCOPEBASE -Search the base entry only.
$$$LDAPSCOPEONELEVEL - Search all entries in the first level below the base entry, excluding the base entry.
$$$LDAPSCOPESUBTREE - Search the base entry and all entries in the tree below the base.

Filter - String that specifies the search filter. The search filter may need to be escaped for certain characters. On Unix clients, you may get a "Bad Filter" error. See the EscapeFilter() method.

Attrs - $list containing strings indicating which attributes to return for each matching entry. Pass "" to retrieve all available attributes.

AttrsOnly - A boolean value that should be zero if both attribute types and values are to be returned, 1 if only types are wanted.

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Timeout - Specifies both the local search time-out value in seconds and the operation time limit that is sent to the server within the search request.

SizeLimit - A limit on the number of entries to return from the search. A value of zero means no limit. If you set this to some value, and the number of results returned by the search is more than this, then the search may return a size limit exceeded error. Note that the number of entries able to be returned is also controlled by a parameter on the LDAP server. If the search returns more than this limit, then a size limit exceeded error will also be returned. Microsoft Active Directory servers by default can return up to 1,000 entries for a search. If your search exceeds this size, you can use the SearchInitPage() and GetNextPages() methods to use a paged search. See

https://support.microsoft.com/en-us/help/315071/how-to-view-and-set-ldap-policy-in-active-directory-by-using-ntdsutil for more info.

SearchResult (byRef) - Contains the results of the search upon completion of the call.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

When done with the search results you need to free the search results in one of the following ways:

1) Call the MsgFree(SearchResult) method. 2) Call SearchExts again, and pass the SearchResult parameter back in unchanged.

Failure to do this before a call to UnBinds may cause your process to core on a future LDAP call.

Note that the caller can have several different searches "open" at the same time by using a different variable for the SearchResult parameter.

Examples:

Search for all users whose Windows login name starts with "steve". Return their display name, e-mail and telephone number. Use a timeout of 10 seconds, and return at most 20 items.
s Status=##Class(%SYS.LDAP).SearchExts(LD,"DC=mydomain,DC=com",
$$$LDAPSCOPESUBTREE,"sAMAccountname=steve*",
$lb("displayName","mail","telephoneNumber"),0,"","",10,20,.SearchResult)

After calling this method, the user should test for the success of the search before further examining the search result as follows:
s NumEntries=##Class(%SYS.LDAP).CountEntries(LD,SearchResult)
i NumEntries=-1 s Status=##Class(%SYS.LDAP).GetError(LD) q Status
i NumEntries=0 w !,"No search entries found" g SearchAgain
Note that the SearchResult buffer must be freed with MsgFree(SearchResult) even after a failed search.

See the documentation in SimpleBindS which shows how to handle errors and retry the operation.

SearchInitPage

ClassMethod SearchInitPage(LD As %Integer, Base As %String, Scope As %Integer, Filter As %String, Attrs As %List, AttrsOnly As %Boolean = 0, ServerControls As %String = "", ClientControls As %String = "", Timeout As %Integer = 0, SizeLimit As %Integer = 0, SortKey As %String = "") As %Integer

Search the LDAP directory using a paged search and return a requested set of attributes for each entry.

This is a Windows only method.
Parameters:

LD - The session handle returned by the Init method.

Base - String that contains the distinguished name of the entry at which to start the search.

Scope - Specifies one of the following values to indicate the scope of the search.

$$$LDAPSCOPEBASE -Search the base entry only.
$$$LDAPSCOPEONELEVEL - Search all entries in the first level below the base entry, excluding the base entry.
$$$LDAPSCOPESUBTREE - Search the base entry and all entries in the tree below the base.

Filter - String that specifies the search filter.

Attrs - $list containing strings indicating which attributes to return for each matching entry. Pass "" to retrieve all available attributes.

AttrsOnly - A boolean value that should be zero if both attribute types and values are to be returned, 1 if only types are wanted.

ServerControls - Ignored, pass as "".

ClientControls - Ignored, pass as "".

Timeout - Specifies both the local search time-out value in seconds and the operation time limit that is sent to the server within the search request.

SizeLimit - A limit on the number of entries to return from the search for each page. SortOrder - Ignored, pass as "".

Return Values:

Page - Contains a pointer to the initialized page of results which should be passed to the GetNextPages() method.

Comments:

When done with the search results you need to free the search results and page the following way:

1) First call the MsgFree(SearchResult) method. 2) Then call the the SearchAbandonPage(LD,Page)() method. Failure to do this before a call to UnBinds may cause your process to core on a future LDAP call.

Note that the caller can have several different searches "open" at the same time by using a different variable for the Page parameter.

This method allows the user to perform a single search on the LDAP directory which would enought records to exceed the MaxPageSize parameter (default 1,000) on the LDAP server. An example of this would be to build a phone list of all the employees in the LDAP database, where there are more than 1,000 employees.

Examples:

Search for all users in the LDAP database. Return their display name, e-mail and telephone number. Use a timeout of 5 seconds, and return at most 100 items for each call to the GetNextPages() method.
s Page=##Class(%SYS.LDAP).SearchInitPage(LD,"DC=mydomain,DC=com",
$$$LDAPSCOPESUBTREE,"sAMAccountname=*",
$lb("displayName","mail","telephoneNumber"),0,"","",5,100,"")
; Lets limit each next page to 5 entries
s Status=##Class(%SYS.LDAP).GetNextPages(LD,Page,5,5,.TotalCount,.SearchResult)
While (Status=$$$LDAPSUCCESS) {
Set Result = ##Class(%SYS.LDAP).FirstEntry(LD, SearchResult)
Set DN = ##Class(%SYS.LDAP).GetDN(tLDAPSession, Result)
Write "DN = ",tDN,! ; only print the first DN in each set of 5
Set Status = ##Class(%SYS.LDAP).GetNextPages(LD,Page,5,5,.TotalCount,.SearchResult)
}
i Status=$$$LDAPNORESULTSRETURNED {w !,"End of search"} else { w !,"Error "_Status}
Set Status = ##Class(%SYS.LDAP).SearchAbandonPage(LD, Page)

SearchAbandonPage

ClassMethod SearchAbandonPage(LD As %Integer, Page As %Integer) As %Integer

Free the page pointer returned by the SearchInitPage() method() This is a Windows only method.
Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

When done with the search results you must free the search page by calling this method.

Failure to do this before a call to UnBinds may cause your process to core on a future LDAP call.

Examples:

s Status=##Class(%SYS.LDAP).SearchAbandonPage(LD,Page)

SetOption

ClassMethod SetOption(LD As %Integer, Option As %Integer, InValue As %String) As %Integer

Set options for an LDAP session.

Parameters:

LD - The session handle returned by the Init method.

Option - The name of the option to set. See valid options below.

InValue - Value that the option is to be given. The actual value of this parameter depends on the setting of the option parameter. The constants $$$LDAP_OPT_ON and $$$LDAP_OPT_OFF can be given for options that have on or off settings.

Return Values:

If the function succeeds, the return value is $$$LDAPSUCCESS.
If the function fails, it returns an error code.

$$$LDAPOPTXTLSNEWCTX - Clears the current SSL/TLS context for the process. If you have called SetOption with any of the LDAPOPTXTLS* parameters below, and then need to change that option, you need to first clear the previous SSL/TLS settings with this option.

$$$LDAPOPTXTLSCACERTFILE - Directory and name of TLS certificate. The certificate needed is that of the certificate authority that signed the certificate of the LDAP server. It needs to be in .PEM format. Available on Unix only.

$$$LDAPOPTXTLSCERTFILE - Directory and name of Client X.509 certificate. Available on Unix only.

$$$LDAPOPTXTLSKEYFILE - Directory and name of the Client X.509 certificate private key. Notes: Private keys with passwords are not supported by openldap (see the man pages). Available on Unix only.

$$$LDAPOPTNETWORKTIMEOUT - Sets the network timeout value after which poll/select following a connect returns in case of no activity. Specifying seconds set to 0 results in an infinite timeout, which is the default. Normally there is no need to change the default. This is available on Unix platforms only.

$$$LDAPOPTTIMEOUT - Sets the timeout value for the synchronous API calls. Specifying seconds set to 0 results in an infinite timeout, which is the default. Normally there is no need to change the default. This is available on Unix platforms only.

Examples:

Set location of TLS certificate for TLS connection:
s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,"/usr/share/ssl/certs/ldapserver.pem")

Note: Previous versions allowed the option $$$LDAPOPTPROTOCOLVERSION and $$$LDAPOPTREFERRALS to be specified. These options are deprecated. SetOption calls using this option will be ignored and always will return success. Version is now always set to 3, and referrals are always turned off.

Note: If you set the TLS options on a Unix client, then issue a StartTLS call to an LDAP server then Unbind the connection, the previous TLS settings will remain active even if the SetOption call is subsequently made with a different certificate. Subsequent LDAP StartTLS calls will use the SetOption values from the first StartTLS call until the InterSystems IRIS process exits. To reset to a different certificate, You need to call:
s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSNEWCTX,0) ; Clear prior certificate
s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,"/usr/share/ssl/certs/newcert.pem")

Note that if you have not previously created a SSL connection, the $$$LDAPOPTXTLSNEWCTX option will return an error. Depending on the structure of your code, it might be better to call this immediately before you call UnBind().

SimpleBinds

ClassMethod SimpleBinds(LD As %Integer, DN As %String, Password As %String) As %Integer

Authenticate a client to a server, using a plaintext password.

Parameters:

LD - The session handle returned by the Init method.

DN - Full distinguished name of the user to authenticate. This is usually in some form similar to the following:

"CN=testuser,OU=Users,OU=Cambridge,DC=mydomain,DC=com"

Password - Password for the DN.
NOTE: If the password used is a NULL string, then the SimpleBinds function will attempt to do an "unauthenticated" bind to the LDAP server. If unauthenticated binds are allowed by the server, then SimpleBinds will allways succeed when a NULL password is passed. If you are using this method to authenticate a user entered password, then before calling this function you must make sure that the password entered is not NULL.
if you wish to do an LDAP "anonymous" bind, pass a null username and password into this method.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This function should only be used on connections which has been encrypted with SSL/TLS as it sends plaintext usernames and passwords across the channel.

Examples:

Initialize a connection to the default Windows domain LDAP server, start the TLS connection, and bind to the server.
s LD=##Class(%SYS.LDAP).Init()
s Status=##Class(%SYS.LDAP).StartTLSs(LD)
;If using for authentication of the user, make sure the password entered is not null.
i PW="" w !,"LDAP password cannot be null" q
s Status=##Class(%SYS.LDAP).SimpleBinds(LD,DN,PW)

Perform an Anonymous bind.
s Status=##Class(%SYS.LDAP).SimpleBinds(LD,"","")

Perform an Unauthenticated bind.
s Status=##Class(%SYS.LDAP).SimpleBinds(LD,DN,"")

Sometimes a Bind or other LDAP operation may fail with a "Server Down" error on Unix (-1). This is sometimes because one of the system calls is interrupted by a Unix signal or temporary network glitch. In cases like this, the operation can usually be retried:

RetryInit s LD=##Class(%SYS.LDAP).Init() s Status=##Class(%SYS.LDAP).StartTLSs(LD) s Status=##Class(%SYS.LDAP).SimpleBinds(LD,Username,Password) i Status'=$$$LDAPSUCCESS { d CloseServer i Status=$$$XLDAPSERVERDOWN { i RetryCount<5 { s RetryCount=RetryCount+1 h .5 g RetryInit } } s Status=$$$ERROR($$$LDAPInvalidPassword,Status,##Class(%SYS.LDAP).Err2String(Status)":"$g(ErrString)) g LDAPError } ..... CloseServer #;Make sure we free the search buffers here. If we don't we may crash in the unbind on some #;unix boxes. i $d(SearchResult) { Try { d ##Class(%SYS.LDAP).MsgFree(SearchResult) k SearchResult } catch {} } i $d(LD) { Try { s Status1=##Class(%SYS.LDAP).UnBinds(LD) k LD } catch {} } q

StartTLSs

ClassMethod StartTLSs(LD As %Integer) As %Integer

Start using TLS encryption on an active LDAP session.

Parameters:

LD - The session handle returned by the Init method.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

In order to use TLS, the client needs to have a certificate installed on it. For Windows systems, the certificate needs to be installed in the Windows certificate database.
Note for Unix, the certificate needs to be copied to the system, and the SetOption method must be called to load the certificate. The certificate must be in .PEM format.

Examples:

This example starts a TLS connection on a Unix machine.
s LD=##Class(%SYS.LDAP).Init("myldapserver.example.com")
s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,"/usr/share/ssl/certs/ldapserver.pem")
s Status=##Class(%SYS.LDAP).StartTLSs(LD)

StopTLSs

ClassMethod StopTLSs(LD As %Integer) As %Integer

Stop using TLS encryption on an active LDAP session.

Parameters:

LD - The session handle returned by the Init method.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

This is a Windows only method and is not supported under Unix.

UnBinds

ClassMethod UnBinds(LD As %Integer) As %Integer

End an LDAP session and frees its resources.

Parameters:

LD - The session handle returned by the Init method.

Return Values:

If the function succeeds, $$$LDAPSUCCESS is returned.
If the function fails, an error code is returned.

Comments:

Call this method whenever you are finished with an LDAP session and have an LD handle to pass to it.

Get

ClassMethod Get(Name As %String, ByRef Properties As %String) As %Status [ Internal ]

ListExecute

ClassMethod ListExecute(ByRef %qHandle As %Binary, Names As %String = "*", Flags As %Integer = 0) As %Status [ Internal ]

List of LDAPConfigs.
Names - Comma separated list of LDAP names, "*" = All
Flags - 0 - Use "Startswith" as the selection on the name.
Flags - 1 - Use "Contains" as the selection on the name.
Note: This query may change in future versions

ListFetch

ClassMethod ListFetch(ByRef %qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ Internal, PlaceAfter = ListExecute ]

ListClose

ClassMethod ListClose(ByRef %qHandle As %Binary) As %Status [ Internal, PlaceAfter = ListExecute ]