View
247
Download
0
Category
Tags:
Preview:
Citation preview
DEV-4: OpenEdge® in an LDAP World
Michael JacobsArchitect, Progress OpenEdge
© 2007 Progress Software Corporation2 DEV-4: OpenEdge in an LDAP World
Agenda
Introduction to LDAP Directory Service fundamentals Exploring the LDAP API LDAP Authentication Process Using LDAP from the ABL language
© 2007 Progress Software Corporation3 DEV-4: OpenEdge in an LDAP World
LDAP v3
Client-server wire protocol for accessing and managing objects in a Directory Service
Originated from the X standards as DAP (Directory Access Protocol) and X.500 Directory
Open standard supported by many• Programming languages: C, Perl, Java, …• Software vendors
– Microsoft Active Directory– Sun – Novell– OpenLDAP.org
Lightweight Directory Access Protocol :
© 2007 Progress Software Corporation4 DEV-4: OpenEdge in an LDAP World
LDAP Directory Service
Extensible, general purpose, object storage
Used for storing frequently read, seldom written information
Single unified view of distributed and replicate object storage across multiple servers
Primary OpenEdge application uses• Single point of user authentication
• Access user account information and role membership
• Synchronize user-accounts from LDAP
A network accessible source of enterprise information:
© 2007 Progress Software Corporation5 DEV-4: OpenEdge in an LDAP World
Agenda
Introduction to LDAP Directory Service fundamentals Exploring the LDAP API LDAP Authentication Process Using LDAP from the ABL language
© 2007 Progress Software Corporation6 DEV-4: OpenEdge in an LDAP World
Mastering Directory Services
1. LDAP object storage model
2. LDAP object name-space model
3. Connect and search for data objects
4. Extracting data object’s information
To effectively use LDAP, you need four basic skills :
© 2007 Progress Software Corporation7 DEV-4: OpenEdge in an LDAP World
Directory Service Storage Model
Objects represent real-world concepts• Users• Organizations• Servers, applications, …
Objects support an inheritance model
Object definitions include• The parent object• OID (Object-IDentifier)• Required & allowed data attributes
personParent: topOID: 1.2.3.4Required: a, bAllowed: c, d
organizationalPerson
Parent: personOID: 1.2.3.5Required: a, b, kAllowed: c, d, p
inetOrgPersonParent: organizationalPersonOID: 1.2.3.6Required: a, b, k, mAllowed: c, d, p, r
Directories provide data storage as objects :
© 2007 Progress Software Corporation8 DEV-4: OpenEdge in an LDAP World
Directory Service Storage Model
User accounts• person, inetOrgPerson, user
DNS domain server• domainComponent (dc)
A company & its organizational hierarchy• organization (o) & organizationalUnit (ou)
<private object definition>
Some common Directory objects (objectClass) :
© 2007 Progress Software Corporation9 DEV-4: OpenEdge in an LDAP World
Directory Service Storage Model
Objects store information in Attributes :
An Attribute definition has a• Full name• Object identification (by OID)• Data-type (by OID)
• An Attribute definition may have• Alias name• Description• Suggested max value length
• An Attribute’s data-type definitionhas• Object identification (by OID)• Single/multi-values• Encoding style (strings)• Matching rules
commonName
OID: 2.5.4.3
Type: directoryString
Alias: cn
directoryString: OID: 1.3.6.1.4… Values: Multi-value Format: UTF-8 Match: caseIgnoreMatch
© 2007 Progress Software Corporation10 DEV-4: OpenEdge in an LDAP World
Common Attribute Data Types
DirectoryString (UTF-8 character string) DistinguishedName Boolean Integer NumericString OID OctetString GeneralizedTime
<private data-type>
LDAP data types are defined by their OID description :
© 2007 Progress Software Corporation11 DEV-4: OpenEdge in an LDAP World
User Account Entry Attributes
objectClass commonName (cn) telephoneNumber description locality (l) organization (o) userid (uid) mail country (c) <private attribute>
sAMAccountName* userPrincipalName* mobile* lastLogon* displayName* userWorkstations* userSharedFolder* maxStorage* primaryGroupID* . . .
LDAP user accounts can contain a wealth of information :
* Active Directory onlyCommon user login attribute names
© 2007 Progress Software Corporation12 DEV-4: OpenEdge in an LDAP World
Directory Service Name-space Model
Instances of objects are stored as entries
Entries are arranged in a hierarchical treelike structure
• Every entry is a node in the tree and may contain data
• Any entry may have 0 to n children of any object type
Each entry has a unique distinguished name (DN)• All entries are located and referenced via its
DN• All children of an entry must have a unique
relative distinguished name (RDN), which is relevant to its parent’s DN
Every company’s directory has its own unique design :
© 2007 Progress Software Corporation13 DEV-4: OpenEdge in an LDAP World
ou=people
Directory Service Name-space Model
ou=usou=au
ou=people
ou=doc
uid=robuid=barbuid=aliceuid=bobuid=jim
ou=it
o=acme corp
uid=alice,
Sample Directory Information Tree model
ou=doc,ou=people,ou=us, o=acme corp
© 2007 Progress Software Corporation14 DEV-4: OpenEdge in an LDAP World
Directory Service Entry Example
Extend the schema with your own objects or attributes :
dn: uid=alice,ou=doc,ou=people,ou=us,o=acme corpobjectclass: person objectclass: organizationalPersonobjectclass: inetOrgPersonobjectclass: acmeEmployee uid: alice sn: Smith cn: Alice Smith cn: Alice F Smith telephonenumber: 510-555-1234 o: Acme Corp mail: alice@acme.com homedirectory: /home/asmith loginshell: /usr/local/bin/bash acmedepartment: documentation acmeemployeeid: 034678
© 2007 Progress Software Corporation15 DEV-4: OpenEdge in an LDAP World
LDAP Connections
1. Initialize an LDAP connection contexta. “server[:port][ server[:port] …]”
2. Set the connection context’s network optionsa. LDAP protocol versionb. SSL on/offc. Timeoutsd. …
3. Connect and authenticate* (bind) to the directory asa. Anonymousb. LDAP user account DN & secret (password)
4. Disconnect (“unbind”) when done with the service
Four simple steps :
* Use LDAP simple authentication
© 2007 Progress Software Corporation16 DEV-4: OpenEdge in an LDAP World
Searching a Directory Service
LDAP searches require three components1. The entry’s DN of where to start the search [root]
2. An attribute filter to determine which entries to find and return
3. The scope of the search1. Search root entry
2. Search root’s child entries
3. Search root and its entire sub-tree
LDAP searches return 0 – N entries• Optionally returns each returned entry’s attributes
LDAP searches are used to find and retrieve information :
Tip: always check how many entries were returned
© 2007 Progress Software Corporation17 DEV-4: OpenEdge in an LDAP World
1. Search-root“ou=us,o=acme corp”
2. Filter:“(uid=barb)”
3. Scope:“sub-tree”
ou=people
Searching a Directory Service
ou=usou=au
ou=people
ou=doc
uid=robuid=barbuid=aliceuid=bobuid=jim
ou=it
o=acme corp
Search a sub-tree for Barb’s entry :
© 2007 Progress Software Corporation18 DEV-4: OpenEdge in an LDAP World
Directory Service Security Model
Discretionary access controls applied at run-time
Controls assigned to stored entries & their attributes• Allowed LDAP users & groups
• Allowed user/group actions (read, write, search, … )
For example:• Everyone can connect to LDAP without a user-id or
password
• Certain accounts can search for entries
• Nobody can see a user-account entry’s password
• Only user & administrator changes password
Directory vendors supply security systems :
© 2007 Progress Software Corporation19 DEV-4: OpenEdge in an LDAP World
Retrieving LDAP Entries
1. Complete the LDAP search
2. Get the number of entries returned from the search
3. Use first - next operations to access individual entries
4. Get the entry’s DN for later use
LDAP entries are accessed dynamically :
© 2007 Progress Software Corporation20 DEV-4: OpenEdge in an LDAP World
Retrieving LDAP Attribute Values
1. Get the number of returned attributes
2. Use first - next functions to access individual attributesFor each attribute:
a. Get the number of attribute values
b. Get the array of attribute values
c. Loop through the array of attribute values to retrieve individual values
d. Release the memory allocated by the LDAP API library in step “b”
Entry attributes are accessed dynamically :
© 2007 Progress Software Corporation21 DEV-4: OpenEdge in an LDAP World
Agenda
Introduction to LDAP Directory Service fundamentals Exploring the LDAP API LDAP Authentication Process Using LDAP from the ABL language
© 2007 Progress Software Corporation22 DEV-4: OpenEdge in an LDAP World
LDAP “C” Shared-library API Guidelines
LDAP “C” functions all start with “ldap_”
LDAP has synchronous & asynchronous API calls • ldap_bind() (asynchronous)• ldap_bind_s() (synchronous)
Windows OS• ANSI & WIDE (Unicode) function calls• ldap_bind_sA (ANSI)• ldap_bind_sW (WIDE)
© 2007 Progress Software Corporation23 DEV-4: OpenEdge in an LDAP World
LDAP API Cheat-sheet
Operation LDAP API Use
Initialization ldap_init Initialize LDAP library
ldap_set_optionldap_get_option
Set/get connectionoptions
Connect(binding)
ldap_bind_s
ldap_unbind
Connect/login user-id &
logout/disconnect
Search ldap_searchldap_count_entries
Search for entries &return how many found
Enumerateentries
ldap_first_entryldap_next_entry
Enumerate returned listof searched entries
ABL language LDAP API declarations at the end of the slide deck
© 2007 Progress Software Corporation24 DEV-4: OpenEdge in an LDAP World
LDAP API Cheat-sheet (cont)
Class LDAP API Use
Entry attributes
ldap_get_dn Get returned entry’s fully qualified DN
ldap_first_attributeldap_next_attribute
Enumerate returned entry’s attribute list
Attributevalues
ldap_get_values Return attribute’s list of [multiple] values
ldap_count_values How many attribute values returned
ldap_value_free Free LDAP memory allocation
© 2007 Progress Software Corporation25 DEV-4: OpenEdge in an LDAP World
LDAP Search Filter Examples
All entries: “(objectclass=*)”
All entries with userid starting with “al” “(uid=al*)”
Operators: = ~= <= >= & | ! Entry with object type “user” and user-id “alice”
“( &(objectclass=person) (uid=alice) )”
Entry with user-id “alice” and objectclass “user” or “inetOrgPerson” “( &(uid=alice) ( |(objectclass=person) (objectclass=inetOrgPerson) ) )”
Can use wildcards and logical operators in filters :
Tip: LDAP server implementations may not index all attributes, so some filters may not perform well.
© 2007 Progress Software Corporation26 DEV-4: OpenEdge in an LDAP World
Agenda
Introduction to LDAP Directory Service fundamentals Exploring the LDAP API LDAP Authentication Process Using LDAP from the ABL language
© 2007 Progress Software Corporation27 DEV-4: OpenEdge in an LDAP World
LDAP User Authentication DN
Nobody types in their full DN“uid=alice,ou=doc,ou=people,ou=us,o=acme corp”
LDAP authentication code finds the user’s full DN for them
Search for the user’s entry where the login-id matches one, or more, of the entry’s attribute value
login-id LDAP search filter• alice “(uid=alice)”• alice smith “(cn=alice smith)”• asmith “(sAMAccountName=asmith)”
Do I have to type in my full user account DN?
© 2007 Progress Software Corporation28 DEV-4: OpenEdge in an LDAP World
User-id prompt’s value used in LDAP search for user’s full DN
Can allow multiple forms of login-ids, each a different user object attribute example: uid, cn, or e-mail
Building LDAP Search Filters
Map user account attributes to Login-id prompts :
cSearchTpl = “(&(objectclass=person)(|(uid=%s)(cn=%s)(mail=%s)))”.
cSearchFilter = replace(cSearchTpl, “%s”, cLoginId).
cSearchTpl = “(&(objectclass=person)(uid=%s))”.
cSearchFilter = replace(cSearchTpl, “%s”, cLoginId).
© 2007 Progress Software Corporation29 DEV-4: OpenEdge in an LDAP World
LDAP Authentication Process
After initializing and setting LDAP options :
bind DN
Bind withAnonymousLDAP user
Bind withLDAP DN
successN
S
F
ldap_bind_s()
InitializeDoes Directory
security require user DN to search? Use DN that has
LDAP search privilege
© 2007 Progress Software Corporation30 DEV-4: OpenEdge in an LDAP World
Login: alicePassword: *******
LDAP Authentication Process
Search foruser’s full DN
success
Searching for the user’s LDAP account :
N
Unbindsession
F
V
S
ldap_search()
ldap_unbind()
Build searchfilter from
user’s login-id
Verify search returns exactly 1
“(&(objectclass=person)(uid=%s))” Search sub-tree formatching entry
© 2007 Progress Software Corporation31 DEV-4: OpenEdge in an LDAP World
LDAP Authentication Process
Get user’sattributes &
check values
success
Validating the password and specific user entry attributes :
N F
C
V
ldap_search()ldap_first_attribute()ldap_next_attribute()
ldap_get_values()ldap_free_value()
N
ldap_bind_s()Bind usinguser entry’s
full DN
success F
Execute a second ldap_search() of user’s full DN
Login: alicePassword: *******
Validates user’spassword
© 2007 Progress Software Corporation32 DEV-4: OpenEdge in an LDAP World
LDAP Authentication Process
Failure
Success
CacheAttribute Values
Caching useful LDAP user account information :
home directorysurname
given namecountry
organizationcustom attributes …
C F
Unbindfrom
LDAP
Unbindfrom
LDAP
ldap_unbind()
Do not authenticateon each usercontext switch
© 2007 Progress Software Corporation33 DEV-4: OpenEdge in an LDAP World
Agenda
Introduction to LDAP Directory Service fundamentals Exploring the LDAP API LDAP Authentication Process Using LDAP from the ABL language
© 2007 Progress Software Corporation34 DEV-4: OpenEdge in an LDAP World
Use OS Native LDAP Shared Libraries
All vendors support common LDAP options• Identify and conditionalize vendor specific options
• Option support is relative to the Directory Service, not the LDAP client
Find the operating system’s LDAP shared library• Solaris: /usr/lib/libldap.so
• Windows: wldap32.dll
• Linux: /usr/lib/libldap.so
• HPUX: Mozilla / OpenLDAP / Internet Express
• AIX: OpenLDAP*Tip: OpenLDAP is the most common cross-platform LDAP implementation, and is available on all these systems.
© 2007 Progress Software Corporation35 DEV-4: OpenEdge in an LDAP World
Working With a Native Shared Library
Use a MEMPTR variable (mNULL) Set iPtrSize to hardware’s address size (4 or 8 bytes) Fill MEMPTR with zeros
define variable mNULL as MEMPTR no-undo. define variable iPtrSize as INTEGER INITIAL 4 no-undo. set-size(mNULL) = iPtrSize. do i = 1 to iPtrSize: put-byte(mNULL, i) = 0.
Pass mNULL as INPUT parameter to LDAP function
Native “C” language NULL parameter value :
© 2007 Progress Software Corporation36 DEV-4: OpenEdge in an LDAP World
Working With a Native Shared Library
Extracting attribute value memory-pointers returned from ldap_search() ldap_get_values(… , OUTPUT mAttrValues).
iPtrIndex = 1.
for i = 1 to iNumValues do: if (iPtrSize = 4) then do: set-pointer-value(mValue) = get-long(iPtrIndex, mAttrValues). end. else do: set-pointer-value(mValue) = get-int64(iPtrIndex, mAttrValues). end. iPtrIndex = iPtrIndex + iPtrSize. cAttrValue = get-string(mValue,1).end.
Native “C” language array of memory-pointers :
© 2007 Progress Software Corporation37 DEV-4: OpenEdge in an LDAP World
In Summary
LDAP is a popular choice for managing distributed network services
Used often as a single-point of user authentication
LDAP support is achievable from the OpenEdge ABL
© 2007 Progress Software Corporation38 DEV-4: OpenEdge in an LDAP World
For More Information, go to…
PSDN• White paper: LDAP User Authentication in an
OpenEdge ABL Environment
Internet references:• www.openldap.org• msdn.microsoft.com• docs.sun.com• www.iana.org/assignments• www.alvestrand.no/objectid/
Reference books:• LDAP Programming Directory-Enabled Applications with
Lightweight Directory Access Protocol
© 2007 Progress Software Corporation39 DEV-4: OpenEdge in an LDAP World
Relevant Exchange Sessions
DB-14: OpenEdge Database Run-time Security Revealed
DB-19: OpenEdge Authentication without the _User Table
DB-8: Jump-starting Your OpenEdge Auditing Solution
ARCH-4: A Statefull Application in a Stateless World
© 2007 Progress Software Corporation40 DEV-4: OpenEdge in an LDAP World
Questions?
© 2007 Progress Software Corporation41 DEV-4: OpenEdge in an LDAP World
Thank you foryour time
© 2007 Progress Software Corporation42 DEV-4: OpenEdge in an LDAP World
LDAP API Session Functions (Binding)
Establishing LDAP sessions :
PROCEDURE ldap_init EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_cServerHost AS CHAR. DEFINE INPUT PARAMETER p_mPort AS LONG. DEFINE RETURN PARAMETER p_mLDAPContext AS MEMPTR.END PROCEDURE.
PROCEDURE ldap_set_option EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_iLDAPOption AS LONG. DEFINE INPUT PARAMETER p_mOptionValue AS MEMPTR. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
PROCEDURE ldap_bind_s EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_cBindUserDN AS CHAR. DEFINE INPUT PARAMETER p_cBindUserPwd AS CHAR. DEFINE INPUT PARAMETER p_iAuthMethod AS LONG. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
Configureserver host &
port
Set sessionoptions
Connect &authenticate
user-id
© 2007 Progress Software Corporation43 DEV-4: OpenEdge in an LDAP World
LDAP API Search Functions
PROCEDURE ldap_search_s EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_cSearchRoot AS CHAR. DEFINE INPUT PARAMETER p_iScope AS LONG. DEFINE INPUT PARAMETER p_cSearchFilter AS CHAR. DEFINE INPUT PARAMETER p_mAttrArray AS MEMPTR. DEFINE INPUT PARAMETER p_iAttrsOnly AS LONG. DEFINE OUTPUT PARAMETER p_mLDAPMessage AS HANDLE TO LONG. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
PROCEDURE ldap_count_entries EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
Search forLDAP entries
How manyentries were
found?
Establishing LDAP sessions :
© 2007 Progress Software Corporation44 DEV-4: OpenEdge in an LDAP World
LDAP API Entry Functions
PROCEDURE ldap_first_entry EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE RETURN PARAMETER p_mLDAPEntry AS HANDLE TO LONG.END PROCEDURE.
PROCEDURE ldap_get_dn EXTERNAL "libldap.so" PERSISTENT. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE RETURN PARAMETER p_mAttrName AS MEMPTR.END PROCEDURE.
PROCEDURE ldap_next_entry EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE RETURN PARAMETER p_mLDAPEntry AS HANDLE TO LONG.END PROCEDURE.
Get the firstreturned
LDAP entry
Get entry’sfully qualified
DN
Enumerateremaining
LDAP entries
© 2007 Progress Software Corporation45 DEV-4: OpenEdge in an LDAP World
LDAP API Attribute Functions
PROCEDURE ldap_first_attribute EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE OUTPUT PARAMETER p_mCtxPtr AS MEMPTR. DEFINE RETURN PARAMETER p_mAttrName AS MEMPTR.END PROCEDURE.
PROCEDURE ldap_next_attribute EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE INPUT PARAMETER p_mCtxPtr AS MEMPTR. DEFINE RETURN PARAMETER p_mAttrName AS MEMPTR.END PROCEDURE.
Get the firstLDAP entry
attribute
Enumerateremainingattribues
© 2007 Progress Software Corporation46 DEV-4: OpenEdge in an LDAP World
LDAP API Attribute Value Functions
PROCEDURE ldap_get_values EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_mLDAPMessage AS MEMPTR. DEFINE INPUT PARAMETER p_mAttrName AS MEMPTR. DEFINE RETURN PARAMETER p_mAttrValues AS MEMPTR.END PROCEDURE.
PROCEDURE ldap_count_values EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mValueMemory AS MEMPTR. DEFINE RETURN PARAMETER p_iCount AS LONG.END PROCEDURE.
PROCEDURE ldap_value_free EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mValueMemory AS MEMPTR. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
Get pointer toattribute value
list
How manyvalues in the
list
FREE LDAPAPI MEMORY
© 2007 Progress Software Corporation47 DEV-4: OpenEdge in an LDAP World
LDAP API Session Function (Unbinding)
PROCEDURE ldap_unbind_s EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
End LDAP session
© 2007 Progress Software Corporation48 DEV-4: OpenEdge in an LDAP World
Error Handling
PROCEDURE ldap_get_option EXTERNAL "libldap.so" PERSISTENT CDECL. DEFINE INPUT PARAMETER p_mLDAPContext AS MEMPTR. DEFINE INPUT PARAMETER p_iLDAPOption AS LONG. DEFINE INPUT PARAMETER p_mOptionValue AS MEMPTR. DEFINE RETURN PARAMETER p_iStatus AS LONG.END PROCEDURE.
Get LDAPinformation
p_iLDAPOption LDAP_OPT_ERROR_NUMBER[0x31]
LDAP_OPT_ERROR_STRING[0x32]
© 2007 Progress Software Corporation49 DEV-4: OpenEdge in an LDAP World
LDAP API Session API Parameters
ldap_set_option : LDAP-Option conform to production’s configuration• LDAP_OPT_AREC_EXCLUSIVE [0x98]• LDAP_OPT_SSL [0x0a]• LDAP_OPT_TIMELIMIT [0x04]
• LDAP_OPT_PROTOCOL_VERSION* [0x11]
ldap_set_option : Option-Value for setting & discovering configuration values• LDAP_OPT_ON [0x01]
• LDAP_OPT_OFF [0x00]• LDAP_VERSION3* [0x03]
LDAP connection API notes :
*Required
Recommended