Changeset View
Changeset View
Standalone View
Standalone View
src/app/Backends/LDAP.php
<?php | <?php | ||||
namespace App\Backends; | namespace App\Backends; | ||||
use App\Domain; | use App\Domain; | ||||
use App\Group; | |||||
use App\User; | use App\User; | ||||
class LDAP | class LDAP | ||||
{ | { | ||||
/** @const array UserSettings used by the backend */ | /** @const array UserSettings used by the backend */ | ||||
public const USER_SETTINGS = [ | public const USER_SETTINGS = [ | ||||
'first_name', | 'first_name', | ||||
'last_name', | 'last_name', | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | public static function createDomain(Domain $domain): void | ||||
// TODO: Assign kolab-admin role to the owner? | // TODO: Assign kolab-admin role to the owner? | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Create a group in LDAP. | |||||
* | |||||
* @param \App\Group $group The group to create. | |||||
* | |||||
* @throws \Exception | |||||
*/ | |||||
public static function createGroup(Group $group): void | |||||
{ | |||||
$config = self::getConfig('admin'); | |||||
$ldap = self::initLDAP($config); | |||||
list($cn, $domainName) = explode('@', $group->email); | |||||
$domain = $group->domain(); | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
$groupBaseDN = "ou=Groups,{$domainBaseDN}"; | |||||
$dn = "cn={$cn},{$groupBaseDN}"; | |||||
$entry = [ | |||||
'cn' => $cn, | |||||
'mail' => $group->email, | |||||
'objectclass' => [ | |||||
'top', | |||||
'groupofuniquenames', | |||||
'kolabgroupofuniquenames' | |||||
], | |||||
'uniqueMember' => [] | |||||
]; | |||||
self::setGroupAttributes($group, $entry); | |||||
$ldap->add_entry($dn, $entry); | |||||
if (empty(self::$ldap)) { | |||||
$ldap->close(); | |||||
} | |||||
} | |||||
/** | |||||
* Create a user in LDAP. | * Create a user in LDAP. | ||||
* | * | ||||
* Only need to add user if in any of the local domains? Figure that out here for now. Should | * Only need to add user if in any of the local domains? Figure that out here for now. Should | ||||
* have Context-Based Access Controls before the job is queued though, probably. | * have Context-Based Access Controls before the job is queued though, probably. | ||||
* | * | ||||
* Use one of three modes; | * Use one of three modes; | ||||
* | * | ||||
* 1) The authenticated user account. | * 1) The authenticated user account. | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | public static function createUser(User $user): void | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Delete a domain from LDAP. | * Delete a domain from LDAP. | ||||
* | * | ||||
* @param \App\Domain $domain The domain to update. | * @param \App\Domain $domain The domain to delete | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function deleteDomain(Domain $domain): void | public static function deleteDomain(Domain $domain): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
Show All 27 Lines | public static function deleteDomain(Domain $domain): void | ||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Delete a group from LDAP. | |||||
* | |||||
* @param \App\Group $group The group to delete. | |||||
* | |||||
* @throws \Exception | |||||
*/ | |||||
public static function deleteGroup(Group $group): void | |||||
{ | |||||
$config = self::getConfig('admin'); | |||||
$ldap = self::initLDAP($config); | |||||
if (self::getGroupEntry($ldap, $group->email, $dn)) { | |||||
$result = $ldap->delete_entry($dn); | |||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | |||||
"Failed to delete group {$group->email} from LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | |||||
} | |||||
if (empty(self::$ldap)) { | |||||
$ldap->close(); | |||||
} | |||||
} | |||||
/** | |||||
* Delete a user from LDAP. | * Delete a user from LDAP. | ||||
* | * | ||||
* @param \App\User $user The user account to update. | * @param \App\User $user The user account to delete. | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function deleteUser(User $user): void | public static function deleteUser(User $user): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | public static function updateDomain(Domain $domain): void | ||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Update a group in LDAP. | |||||
* | |||||
* @param \App\Group $group The group to update | |||||
* | |||||
* @throws \Exception | |||||
*/ | |||||
public static function updateGroup(Group $group): void | |||||
{ | |||||
$config = self::getConfig('admin'); | |||||
$ldap = self::initLDAP($config); | |||||
list($cn, $domainName) = explode('@', $group->email); | |||||
$domain = $group->domain(); | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
$groupBaseDN = "ou=Groups,{$domainBaseDN}"; | |||||
$dn = "cn={$cn},{$groupBaseDN}"; | |||||
$entry = [ | |||||
'cn' => $cn, | |||||
'mail' => $group->email, | |||||
'objectclass' => [ | |||||
'top', | |||||
'groupofuniquenames', | |||||
'kolabgroupofuniquenames' | |||||
], | |||||
'uniqueMember' => [] | |||||
]; | |||||
$oldEntry = $ldap->get_entry($dn); | |||||
self::setGroupAttributes($group, $entry); | |||||
$ldap->modify_entry($dn, $oldEntry, $entry); | |||||
if (empty(self::$ldap)) { | |||||
$ldap->close(); | |||||
} | |||||
} | |||||
/** | |||||
* Update a user in LDAP. | * Update a user in LDAP. | ||||
* | * | ||||
* @param \App\User $user The user account to update. | * @param \App\User $user The user account to update. | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function updateUser(User $user): void | public static function updateUser(User $user): void | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | class LDAP | ||||
* Set domain attributes | * Set domain attributes | ||||
*/ | */ | ||||
private static function setDomainAttributes(Domain $domain, array &$entry) | private static function setDomainAttributes(Domain $domain, array &$entry) | ||||
{ | { | ||||
$entry['inetdomainstatus'] = $domain->status; | $entry['inetdomainstatus'] = $domain->status; | ||||
} | } | ||||
/** | /** | ||||
* Convert group member addresses in to valid entries. | |||||
*/ | |||||
private static function setGroupAttributes(Group $group, &$entry) | |||||
{ | |||||
$config = self::getConfig('admin'); | |||||
$ldap = self::initLDAP($config); | |||||
$validMembers = []; | |||||
$domain = $group->domain(); | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
foreach ($group->members as $member) { | |||||
list($local, $domainName) = explode('@', $member); | |||||
$memberDN = "uid={$member},ou=People,{$domainBaseDN}"; | |||||
// if the member is in the local domain but doesn't exist, drop it | |||||
if ($domainName == $domain->namespace) { | |||||
if (!$ldap->get_entry($memberDN)) { | |||||
continue; | |||||
} | |||||
} | |||||
// add the member if not in the local domain | |||||
if (!$ldap->get_entry($memberDN)) { | |||||
$memberEntry = [ | |||||
'cn' => $member, | |||||
'mail' => $member, | |||||
'objectclass' => [ | |||||
'top', | |||||
'inetorgperson', | |||||
'organizationalperson', | |||||
'person' | |||||
], | |||||
'sn' => 'unknown' | |||||
]; | |||||
$ldap->add_entry($memberDN, $memberEntry); | |||||
} | |||||
$entry['uniquemember'][] = $memberDN; | |||||
$validMembers[] = $member; | |||||
} | |||||
$group->members = $validMembers; | |||||
} | |||||
/** | |||||
* Set common user attributes | * Set common user attributes | ||||
*/ | */ | ||||
private static function setUserAttributes(User $user, array &$entry) | private static function setUserAttributes(User $user, array &$entry) | ||||
{ | { | ||||
$firstName = $user->getSetting('first_name'); | $firstName = $user->getSetting('first_name'); | ||||
$lastName = $user->getSetting('last_name'); | $lastName = $user->getSetting('last_name'); | ||||
$cn = "unknown"; | $cn = "unknown"; | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | private static function getConfig(string $privilege) | ||||
'vlv' => false, | 'vlv' => false, | ||||
'log_hook' => 'App\Backends\LDAP::logHook', | 'log_hook' => 'App\Backends\LDAP::logHook', | ||||
]; | ]; | ||||
return $config; | return $config; | ||||
} | } | ||||
/** | /** | ||||
* Get group entry from LDAP. | |||||
* | |||||
* @param \Net_LDAP3 $ldap Ldap connection | |||||
* @param string $email Group email (mail) | |||||
* @param string $dn Reference to group DN | |||||
* | |||||
* @return false|null|array Group entry, False on error, NULL if not found | |||||
*/ | |||||
private static function getGroupEntry($ldap, $email, &$dn = null) | |||||
{ | |||||
list($_local, $_domain) = explode('@', $email, 2); | |||||
$domain = $ldap->find_domain($_domain); | |||||
if (!$domain) { | |||||
return $domain; | |||||
} | |||||
$base_dn = $ldap->domain_root_dn($_domain); | |||||
$dn = "cn={$_local},ou=Groups,{$base_dn}"; | |||||
$entry = $ldap->get_entry($dn); | |||||
return $entry ?: null; | |||||
} | |||||
/** | |||||
* Get user entry from LDAP. | * Get user entry from LDAP. | ||||
* | * | ||||
* @param \Net_LDAP3 $ldap Ldap connection | * @param \Net_LDAP3 $ldap Ldap connection | ||||
* @param string $email User email (uid) | * @param string $email User email (uid) | ||||
* @param string $dn Reference to user DN | * @param string $dn Reference to user DN | ||||
* @param bool $full Get extra attributes, e.g. nsroledn | * @param bool $full Get extra attributes, e.g. nsroledn | ||||
* | * | ||||
* @return false|null|array User entry, False on error, NULL if not found | * @return false|null|array User entry, False on error, NULL if not found | ||||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |