11078ec26SAndreas Gohr<?php 21078ec26SAndreas Gohr 31078ec26SAndreas Gohrnamespace dokuwiki\plugin\pureldap\classes; 41078ec26SAndreas Gohr 51078ec26SAndreas Gohruse FreeDSx\Ldap\Entry\Entries; 61078ec26SAndreas Gohruse FreeDSx\Ldap\Entry\Entry; 71078ec26SAndreas Gohruse FreeDSx\Ldap\Exception\OperationException; 8*5a3b9122SAndreas Gohruse FreeDSx\Ldap\Exception\ProtocolException; 91078ec26SAndreas Gohruse FreeDSx\Ldap\Operations; 101078ec26SAndreas Gohruse FreeDSx\Ldap\Search\Filters; 111078ec26SAndreas Gohr 121078ec26SAndreas Gohrclass ADClient extends Client 131078ec26SAndreas Gohr{ 141078ec26SAndreas Gohr 151078ec26SAndreas Gohr /** @inheritDoc */ 161078ec26SAndreas Gohr public function getUser($username, $fetchgroups = true) 171078ec26SAndreas Gohr { 181078ec26SAndreas Gohr if (!$this->autoAuth()) return null; 191078ec26SAndreas Gohr 201078ec26SAndreas Gohr $filter = Filters::and( 211078ec26SAndreas Gohr Filters::equal('objectClass', 'user'), 221078ec26SAndreas Gohr Filters::equal('userPrincipalName', $username) 231078ec26SAndreas Gohr ); 241078ec26SAndreas Gohr 251078ec26SAndreas Gohr try { 261078ec26SAndreas Gohr /** @var Entries $entries */ 271078ec26SAndreas Gohr $entries = $this->ldap->search(Operations::search($filter)); 281078ec26SAndreas Gohr } catch (OperationException $e) { 291078ec26SAndreas Gohr $this->debug($e); 301078ec26SAndreas Gohr return null; 311078ec26SAndreas Gohr } 321078ec26SAndreas Gohr if ($entries->count() !== 1) return null; 331078ec26SAndreas Gohr $entry = $entries->first(); 341078ec26SAndreas Gohr 351078ec26SAndreas Gohr return [ 361078ec26SAndreas Gohr 'user' => $username, 371078ec26SAndreas Gohr 'name' => $this->attr2str($entry->get('DisplayName')) ?: $this->attr2str($entry->get('Name')), 381078ec26SAndreas Gohr 'mail' => $this->attr2str($entry->get('mail')), 391078ec26SAndreas Gohr 'dn' => $entry->getDn()->toString(), 401078ec26SAndreas Gohr 'grps' => $this->getUserGroups($entry), // we always return groups because its currently inexpensive 411078ec26SAndreas Gohr ]; 421078ec26SAndreas Gohr } 431078ec26SAndreas Gohr 44*5a3b9122SAndreas Gohr /** @inheritDoc */ 45*5a3b9122SAndreas Gohr public function getGroups() 46*5a3b9122SAndreas Gohr { 47*5a3b9122SAndreas Gohr if (!$this->autoAuth()) return []; 48*5a3b9122SAndreas Gohr 49*5a3b9122SAndreas Gohr $filter = Filters::equal('objectClass', 'group'); 50*5a3b9122SAndreas Gohr $search = Operations::search($filter, 'cn'); 51*5a3b9122SAndreas Gohr $paging = $this->ldap->paging($search); 52*5a3b9122SAndreas Gohr 53*5a3b9122SAndreas Gohr $groups = []; 54*5a3b9122SAndreas Gohr 55*5a3b9122SAndreas Gohr while ($paging->hasEntries()) { 56*5a3b9122SAndreas Gohr try { 57*5a3b9122SAndreas Gohr $entries = $paging->getEntries(); 58*5a3b9122SAndreas Gohr } catch (ProtocolException $e) { 59*5a3b9122SAndreas Gohr $this->debug($e); 60*5a3b9122SAndreas Gohr return $groups; // we return what we got so far 61*5a3b9122SAndreas Gohr } 62*5a3b9122SAndreas Gohr 63*5a3b9122SAndreas Gohr foreach ($entries as $entry) { 64*5a3b9122SAndreas Gohr $groups[] = $this->attr2str($entry->get('cn')); 65*5a3b9122SAndreas Gohr } 66*5a3b9122SAndreas Gohr } 67*5a3b9122SAndreas Gohr 68*5a3b9122SAndreas Gohr return $groups; 69*5a3b9122SAndreas Gohr } 70*5a3b9122SAndreas Gohr 711078ec26SAndreas Gohr /** 721078ec26SAndreas Gohr * Get the list of groups the given user is member of 731078ec26SAndreas Gohr * 741078ec26SAndreas Gohr * This method currently does no LDAP queries and thus is inexpensive. 751078ec26SAndreas Gohr * 761078ec26SAndreas Gohr * @param Entry $userentry 771078ec26SAndreas Gohr * @return array 781078ec26SAndreas Gohr * @todo implement nested group memberships 791078ec26SAndreas Gohr */ 801078ec26SAndreas Gohr protected function getUserGroups(Entry $userentry) 811078ec26SAndreas Gohr { 821078ec26SAndreas Gohr $groups = [$this->config['defaultgroup']]; // always add default 831078ec26SAndreas Gohr 841078ec26SAndreas Gohr // we simply take the first CN= part of the group DN and return it as the group name 851078ec26SAndreas Gohr // this should be correct for ActiveDirectory and saves us additional LDAP queries 861078ec26SAndreas Gohr if ($userentry->has('memberOf')) { 871078ec26SAndreas Gohr foreach ($userentry->get('memberOf')->getValues() as $line) { 881078ec26SAndreas Gohr list($cn) = explode(',', $line, 2); 891078ec26SAndreas Gohr $groups[] = substr($cn, 3); 901078ec26SAndreas Gohr } 911078ec26SAndreas Gohr } 921078ec26SAndreas Gohr 931078ec26SAndreas Gohr // resolving the primary group in AD is complicated but basically never needed 941078ec26SAndreas Gohr // http://support.microsoft.com/?kbid=321360 951078ec26SAndreas Gohr $gid = $userentry->get('primaryGroupID')->firstValue(); 961078ec26SAndreas Gohr if ($gid == 513) { 971078ec26SAndreas Gohr $groups[] = 'Domain Users'; 981078ec26SAndreas Gohr } 991078ec26SAndreas Gohr 1001078ec26SAndreas Gohr return $groups; 1011078ec26SAndreas Gohr } 1021078ec26SAndreas Gohr} 103