= Load LDAP

With 'apoc.load.ldap' you can execute queries on any LDAP v3 enabled directory, the results are turned into a streams of entries.
The entries can then be used to update or create graph structures.

Note this utility requires to have the link:https://mvnrepository.com/artifact/com.novell.ldap/jldap/2009-10-07[jldap] library to be placed the plugin directory.

[separator=¦,opts=header,cols="1,1m,5"]
|===
include::../build/generated-documentation/apoc.load.csv[lines=9..9]
|===

=== parameters
[options="header",cols="a,3m,a"]
|===
|Parameter | Property | Description
|{connectionMap} | ldapHost | the ldapserver:port if port is omitted the default port 389 will be used
|  | loginDN | This is the dn of the ldap server user who has read access on the ldap server
|  | loginPW | This is the password used by the loginDN
|{searchMap} | searchBase | From this entry a search is executed
|  | searchScope | SCOPE_ONE (one level) or
                   SCOPE_SUB (all sub levels) or
                   SCOPE_BASE (only the base node)
|  | searchFilter | Place here a standard ldap search filter for example: (objectClass=*) means that the ldap entry must have an objectClass attribute.
|  | attributes | optional. If omitted all the attributes of the entries will be returned.
                            When specified only the specified attributes will be returned. Regardless the attributes setting a returned entry will always have a "dn" property.
|===

==== load ldap example

.Retrieve group member information from the ldap server
[source,cypher]
---
call apoc.load.ldap({ldapHost : "ldap.forumsys.com", loginDN : "cn=read-only-admin,dc=example,dc=com", loginPW : "password"},
{searchBase : "dc=example,dc=com",searchScope : "SCOPE_SUB"
,attributes : ["uniqueMember","cn","uid","objectClass"]
,searchFilter: "(&(objectClass=*)(uniqueMember=*))"}) yield entry
return entry.dn,  entry.uniqueMember
---
[options="header",cols="3m,a"]
|===
| entry.dn                                      | entry.uniqueMember                                                                                                                                                                                   |
| "ou=mathematicians,dc=example,dc=com"         | ["uid=euclid,dc=example,dc=com", "uid=riemann,dc=example,dc=com", "uid=euler,dc=example,dc=com", "uid=gauss,dc=example,dc=com", "uid=test,dc=example,dc=com"]                                        |
| "ou=scientists,dc=example,dc=com"             | ["uid=einstein,dc=example,dc=com", "uid=galieleo,dc=example,dc=com", "uid=tesla,dc=example,dc=com", "uid=newton,dc=example,dc=com", "uid=training,dc=example,dc=com", "uid=jmacy,dc=example,dc=com"] |
| "ou=italians,ou=scientists,dc=example,dc=com" | "uid=tesla,dc=example,dc=com"                                                                                                                                                                        |
| "ou=chemists,dc=example,dc=com"               | ["uid=curie,dc=example,dc=com", "uid=boyle,dc=example,dc=com", "uid=nobel,dc=example,dc=com", "uid=pasteur,dc=example,dc=com"]                                                                       |
|===
---

.Retrieve group member information from the ldap server and create structure in Neo4j
[source,cypher]
---
call apoc.load.ldap({ldapHost : "ldap.forumsys.com", loginDN : "cn=read-only-admin,dc=example,dc=com", loginPW : "password"},
{searchBase : "dc=example,dc=com",searchScope : "SCOPE_SUB"
,attributes : ["uniqueMember","cn","uid","objectClass"]
,searchFilter: "(&(objectClass=*)(uniqueMember=*))"}) yield entry
merge (g:Group {dn : entry.dn})
on create set g.cn = entry.cn
foreach (member in entry.uniqueMember |
  merge (p:Person { dn : member })
  merge (p)-[:IS_MEMBER]->(g)
)
---


=== credentials

To protect credentials, you can configure aliases in `conf/neo4j.conf`:

----
apoc.loadldap.myldap.config=<host>:<port> <loginDN> <loginPW>
----


==== example neo4j.conf:

----
apoc.loadldap.myldap.config=ldap.forumsys.com:389 cn=read-only-admin,dc=example,dc=com password
----

Then

----
call apoc.load.ldap({ldapHost : "ldap.forumsys.com", loginDN : "cn=read-only-admin,dc=example,dc=com", loginPW : "password"}
, {searchBase : "dc=example,dc=com"
  ,searchScope : "SCOPE_SUB"
  ,attributes : ["cn","uid","objectClass"]
  ,searchFilter: "(&(objectClass=*))"
  }) yield entry
return entry.dn,  entry
----

becomes

----
call apoc.load.ldap("myldap"
,{searchBase : "dc=example,dc=com"
 ,searchScope : "SCOPE_SUB"
 ,attributes : ["cn","uid","objectClass"]
 ,searchFilter: "(&(objectClass=*))"
 }) yield entry
return entry.dn,  entry
----