Learning
Documentation
Community
Open Exchange
Global Masters
Home / Class Reference / %SYS namespace / %SYS.LDAP
Private  Storage   

%SYS.LDAP


abstract class %SYS.LDAP

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.11.
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 in the SAMPLES namespace for extensive LDAP examples.

Inventory


Parameters Properties Methods Queries Indices ForeignKeys Triggers
40 1


Summary


Methods
AddExts Binds CheckFilter CompareExts
Connect CountEntries CountValues CountValuesLen
DeleteExts Err2String EscapeFilter FirstAttribute
FirstEntry GetDN GetError GetLastError
GetNextPages GetOption GetValues GetValuesLen
Init ModifyExts MsgFree NextAttribute
NextEntry RenameExts SearchAbandonPage SearchExts
SearchInitPage SetOption SimpleBinds StartTLSs
StopTLSs UnBinds


Methods


• 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.
• 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)
• 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=*)")
• 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)

• 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.
• 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
• 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)
• 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)
• 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")

• 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))
• 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
• 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)
}
• 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
• 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)
• 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)
• 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)
• 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.

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)
}
;Now check if the search ended ok
i Status=94 { Return 1} else { Return 0} ; Status code 94 means no more results
• 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.

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.
• 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)
• 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))
• 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)

2) 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)

3) Unix client to Windows Active Directory LDAP server.
Using the StartTLSs call. Directly connecting to 636 is not supported.
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)

4) Unix client to OpenLDAPserver.
Using the StartTLSs call. Directly connecting to 636 is not supported.
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 for some reason 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.
• 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,"","")

• 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)
• 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)

• 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
• 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)

• 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)
• 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.
• 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. 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. 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.

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 page pointer returned with the SearchAbandonPage(LD,Page)method.
Failure to do this before a call to UnBinds may cause your process to core or hang on a future LDAP call or when the process halts.

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 10 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,"","",10,100,"")
s Status=##Class(%SYS.LDAP).GetNextPages(LD,Page,10,100,.TotalPages,.SearchResult)

• 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.


$$$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.
• 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,"")

• 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)
• 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.
• 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.

Queries


• query List(Names As %String = "*", Flags As %Integer = 0)
Selects Name As %String, LDAP Enabled As %String, Description
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