1# FreeDSx LDAP ![](https://github.com/FreeDSx/LDAP/workflows/Analysis/badge.svg) ![](https://github.com/FreeDSx/LDAP/workflows/Build/badge.svg) [![codecov](https://codecov.io/gh/FreeDSx/LDAP/branch/master/graph/badge.svg)](https://codecov.io/gh/FreeDSx/LDAP)
2FreeDSx LDAP is a pure PHP LDAP library. It has no requirement on the core PHP LDAP extension. This library currently implements
3most client functionality described in [RFC 4511](https://tools.ietf.org/html/rfc4511) and some very limited LDAP server
4functionality. It also implements some other client features from various RFCs:
5
6* Paging Control Support ([RFC 2696](https://tools.ietf.org/html/rfc2696))
7* VLV Control Support ([draft-ietf-ldapext-ldapv3-vlv-09](https://www.ietf.org/archive/id/draft-ietf-ldapext-ldapv3-vlv-09.txt))
8* Server Side Sort Control ([RFC 2891](https://tools.ietf.org/html/rfc2891))
9* Password Modify Request ([RFC 3062](https://tools.ietf.org/html/rfc3062))
10* String Representation of Search Filters ([RFC 4515](https://tools.ietf.org/search/rfc4515))
11* SASL authentication / integrity layer support for certain mechanisms ([RFC 4513](https://tools.ietf.org/search/rfc4513))
12
13It supports encryption of the LDAP connection through TLS via the OpenSSL extension if available.
14
15# Documentation
16
17* [LDAP Client](/docs/Client)
18  * [Configuration](/docs/Client/Configuration.md)
19  * [SASL Bind Authentication](/docs/Client/SASL-Bind-Authentication.md)
20  * [General Usage](/docs/Client/General-Usage.md)
21  * [Entries](/docs/Client/Entries.md)
22  * [Operations](/docs/Client/Operations.md)
23  * [Controls](/docs/Client/Controls.md)
24  * [Searching and Filters](/docs/Client/Searching-and-Filters.md)
25  * [Range Retrieval](/docs/Client/Range-Retrieval.md)
26  * [DirSync](/docs/Client/DirSync.md)
27* [LDAP Server](/docs/Server)
28  * [Configuration](/docs/Server/Configuration.md)
29  * [General Usage](/docs/Server/General-Usage.md)
30
31# Getting Started
32
33Install via [composer](https://getcomposer.org/download/):
34
35```bash
36composer require freedsx/ldap
37```
38
39Use the LdapClient class and the helper classes:
40
41```php
42use FreeDSx\Ldap\LdapClient;
43use FreeDSx\Ldap\Operations;
44use FreeDSx\Ldap\Search\Filters;
45
46$ldap = new LdapClient([
47    # Servers are tried in order until one connects
48    'servers' => ['dc1', 'dc2'],
49    # The base_dn is used as the default for searches
50    'base_dn' => 'dc=example,dc=local'
51]);
52
53# Encrypt the connection prior to binding
54$ldap->startTls();
55
56# Bind to LDAP with a specific user.
57$ldap->bind('user@example.local', '12345');
58
59# Build up a LDAP filter using the helper methods
60$filter = Filters::and(
61    Filters::equal('objectClass', 'user'),
62    Filters::startsWith('cn', 'S'),
63    # Add a filter object based off a raw string filter...
64    Filters::raw('(telephoneNumber=*)')
65);
66# Create a search operation to be used based on the above filter
67$search = Operations::search($filter, 'cn');
68
69# Create a paged search, 100 results at a time
70$paging = $ldap->paging($search, 100);
71
72while ($paging->hasEntries()) {
73    $entries = $paging->getEntries();
74    var_dump(count($entries));
75
76    foreach ($entries as $entry) {
77        echo "Entry: ".$entry->getDn().PHP_EOL;
78    }
79}
80```
81
82# CRUD Operations:
83
84* [Create](#create)
85* [Read](#read)
86* [Update](#update)
87* [Delete](#delete)
88
89## Create
90
91```php
92use FreeDSx\Ldap\Entry\Entry;
93use FreeDSx\Ldap\Exception\OperationException;
94
95# Create a new LDAP entry object
96$entry = (new Entry('cn=foo,dc=domain,dc=local'))
97   ->set('objectClass','top', 'group')
98   ->set('sAMAccountName', 'foo');
99
100# Create the entry with the LDAP client
101try {
102    $ldap->create($entry);
103} catch (OperationException $e) {
104    echo sprintf('Error adding entry (%s): %s', $e->getCode(), $e->getMessage()).PHP_EOL;
105}
106```
107
108## Read
109
110```php
111# Use the read() method of the LDAP client to search for a specific entry.
112# Optionally pass an array of attributes to select as the second argument.
113$entry = $ldap->read('cn=foo,dc=domain,dc=local');
114
115# Entry will be null if it doesn't exist
116if ($entry) {
117    echo $entry.PHP_EOL;
118    var_dump($entry->toArray());
119}
120```
121
122## Update
123
124```php
125use FreeDSx\Ldap\Exception\OperationException;
126
127# Search for an entry object to get its current attributes / values
128$entry = $ldap->read('cn=foo,dc=domain,dc=local');
129
130# Add a value to an attribute
131if (!$entry->get('telephoneNumber')) {
132    $entry->add('telephoneNumber', '555-5555');
133}
134# Remove any values an attribute may have
135if ($entry->has('title')) {
136    $entry->reset('title');
137}
138# Delete a specific value for an attribute
139if ($entry->get('ipPhone')->has('12345')) {
140    $entry->delete('ipPhone', '12345');
141}
142# Set a value for an attribute. This replaces any value it may, or may not, have.
143$entry->set('description', 'Employee');
144
145# Send the built up changes back to LDAP to update the entry via the LDAP client update method.
146try {
147    $ldap->update($entry);
148} catch (OperationException $e) {
149    echo sprintf('Error modifying entry (%s): %s', $e->getCode(), $e->getMessage()).PHP_EOL;;
150}
151```
152
153## Delete
154
155```php
156use FreeDSx\Ldap\Exception\OperationException;
157
158# Search for the entry object to delete
159$entry = $ldap->read('cn=foo,dc=domain,dc=local');
160
161# Pass the entry object to the delete method of the LDAP client if it was found.
162# You could also pass a DN object or a simple DN as a string.
163if ($entry) {
164    try {
165        $ldap->delete($entry);
166    } catch (OperationException $e) {
167        echo sprintf('Error deleting entry (%s): %s', $e->getCode(), $e->getMessage()).PHP_EOL;;
168    }
169}
170```
171