xref: /plugin/pureldap/classes/ADClient.php (revision 5a3b912293b77009ff72b70b480eb77929df5103)
1<?php
2
3namespace dokuwiki\plugin\pureldap\classes;
4
5use FreeDSx\Ldap\Entry\Entries;
6use FreeDSx\Ldap\Entry\Entry;
7use FreeDSx\Ldap\Exception\OperationException;
8use FreeDSx\Ldap\Exception\ProtocolException;
9use FreeDSx\Ldap\Operations;
10use FreeDSx\Ldap\Search\Filters;
11
12class ADClient extends Client
13{
14
15    /** @inheritDoc */
16    public function getUser($username, $fetchgroups = true)
17    {
18        if (!$this->autoAuth()) return null;
19
20        $filter = Filters::and(
21            Filters::equal('objectClass', 'user'),
22            Filters::equal('userPrincipalName', $username)
23        );
24
25        try {
26            /** @var Entries $entries */
27            $entries = $this->ldap->search(Operations::search($filter));
28        } catch (OperationException $e) {
29            $this->debug($e);
30            return null;
31        }
32        if ($entries->count() !== 1) return null;
33        $entry = $entries->first();
34
35        return [
36            'user' => $username,
37            'name' => $this->attr2str($entry->get('DisplayName')) ?: $this->attr2str($entry->get('Name')),
38            'mail' => $this->attr2str($entry->get('mail')),
39            'dn' => $entry->getDn()->toString(),
40            'grps' => $this->getUserGroups($entry), // we always return groups because its currently inexpensive
41        ];
42    }
43
44    /** @inheritDoc */
45    public function getGroups()
46    {
47        if (!$this->autoAuth()) return [];
48
49        $filter = Filters::equal('objectClass', 'group');
50        $search = Operations::search($filter, 'cn');
51        $paging = $this->ldap->paging($search);
52
53        $groups = [];
54
55        while ($paging->hasEntries()) {
56            try {
57                $entries = $paging->getEntries();
58            } catch (ProtocolException $e) {
59                $this->debug($e);
60                return $groups; // we return what we got so far
61            }
62
63            foreach ($entries as $entry) {
64                $groups[] = $this->attr2str($entry->get('cn'));
65            }
66        }
67
68        return $groups;
69    }
70
71    /**
72     * Get the list of groups the given user is member of
73     *
74     * This method currently does no LDAP queries and thus is inexpensive.
75     *
76     * @param Entry $userentry
77     * @return array
78     * @todo implement nested group memberships
79     */
80    protected function getUserGroups(Entry $userentry)
81    {
82        $groups = [$this->config['defaultgroup']]; // always add default
83
84        // we simply take the first CN= part of the group DN and return it as the group name
85        // this should be correct for ActiveDirectory and saves us additional LDAP queries
86        if ($userentry->has('memberOf')) {
87            foreach ($userentry->get('memberOf')->getValues() as $line) {
88                list($cn) = explode(',', $line, 2);
89                $groups[] = substr($cn, 3);
90            }
91        }
92
93        // resolving the primary group in AD is complicated but basically never needed
94        // http://support.microsoft.com/?kbid=321360
95        $gid = $userentry->get('primaryGroupID')->firstValue();
96        if ($gid == 513) {
97            $groups[] = 'Domain Users';
98        }
99
100        return $groups;
101    }
102}
103