. */ namespace SP\Providers\Auth\Ldap; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; /** * Class LdapStd * * LDAP authentication based on an standard implementation * * @package SP\Auth\Ldap */ final class LdapStd extends Ldap { const DEFAULT_FILTER_USER_OBJECT = '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))'; const DEFAULT_FILTER_GROUP_OBJECT = '(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group))'; const DEFAULT_FILTER_USER_ATTRIBUTES = ['samaccountname', 'cn', 'uid', 'userPrincipalName']; const DEFAULT_FILTER_GROUP_ATTRIBUTES = ['memberOf', 'groupMembership']; /** * @inheritDoc * @throws LdapException */ public function getGroupMembershipIndirectFilter(): string { $filter = $this->getUserObjectFilter(); if (empty($this->ldapParams->getGroup())) { return $filter; } if (empty($this->ldapParams->getFilterGroupAttributes())) { $attributes = self::DEFAULT_FILTER_GROUP_ATTRIBUTES; } else { $attributes = $this->ldapParams->getFilterGroupAttributes(); } return '(&(|' . LdapUtil::getAttributesForFilter( $attributes, $this->getGroupDn()) . ')' . $filter . ')'; } /** * @return string */ private function getUserObjectFilter(): string { if (empty($this->ldapParams->getFilterUserObject())) { return self::DEFAULT_FILTER_USER_OBJECT; } return $this->ldapParams->getFilterUserObject(); } /** * @inheritDoc */ public function getUserDnFilter(string $userLogin): string { if (empty($this->ldapParams->getFilterUserAttributes())) { $attributes = self::DEFAULT_FILTER_USER_ATTRIBUTES; } else { $attributes = $this->ldapParams->getFilterUserAttributes(); } $filter = $this->getUserObjectFilter(); return '(&(|' . LdapUtil::getAttributesForFilter($attributes, $userLogin) . ')' . $filter . ')'; } /** * @inheritDoc * @throws LdapException */ public function isUserInGroup(string $userDn, string $userLogin, array $groupsDn): bool { // Comprobar si está establecido el filtro de grupo o el grupo coincide con // los grupos del usuario if (empty($this->ldapParams->getGroup()) || $this->ldapParams->getGroup() === '*' || in_array($this->getGroupDn(), $groupsDn) ) { $this->eventDispatcher->notifyEvent('ldap.check.group', new Event($this, EventMessage::factory() ->addDescription(__u('User in group verified')) ->addDetail(__u('User'), $userDn) ->addDetail(__u('Group'), $this->ldapParams->getGroup()))); return true; } return $this->checkUserInGroupByFilter($userDn); } /** * @param string $userDn * * @return bool * @throws LdapException */ private function checkUserInGroupByFilter(string $userDn): bool { $filter = $this->getGroupMembershipDirectFilter($userDn); $searchResults = $this->ldapActions->getObjects($filter, ['dn']); if (isset($searchResults['count']) && (int)$searchResults['count'] === 0 ) { $this->eventDispatcher->notifyEvent('ldap.check.group', new Event($this, EventMessage::factory() ->addDescription(__u('User does not belong to the group')) ->addDetail(__u('User'), $userDn) ->addDetail(__u('Group'), $this->getGroupFromParams()) ->addDetail('LDAP FILTER', $filter))); return false; } return true; } /** * @inheritDoc */ public function getGroupMembershipDirectFilter(?string $userDn = null): string { $groupName = ldap_escape($this->getGroupFromParams(), null, LDAP_ESCAPE_FILTER); $member = $userDn !== null ? ldap_escape($userDn, null, LDAP_ESCAPE_FILTER) : '*'; if (empty($groupName)) { return $this->getUserObjectFilter(); } return '(&(cn=' . $groupName . ')' . '(|(memberUid=' . $member . ')(member=' . $member . ')(uniqueMember=' . $member . '))' . $this->getGroupObjectFilter() . ')'; } /** * @inheritDoc */ public function getGroupObjectFilter(): string { if (empty($this->ldapParams->getFilterGroupObject())) { return self::DEFAULT_FILTER_GROUP_OBJECT; } return $this->ldapParams->getFilterGroupObject(); } /** * Obtener el servidor de LDAP a utilizar * * @return mixed */ protected function pickServer() { return $this->ldapParams->getServer(); } }