Changeset View
Changeset View
Standalone View
Standalone View
src/app/Backends/LDAP.php
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | class LDAP | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function createDomain(Domain $domain): void | public static function createDomain(Domain $domain): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$mgmtRootDN = \config('ldap.admin.root_dn'); | $mgmtRootDN = \config('ldap.admin.root_dn'); | ||||
$domainBaseDN = self::baseDN($domain->namespace); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
$aci = [ | $aci = [ | ||||
'(targetattr = "*")' | '(targetattr = "*")' | ||||
. '(version 3.0; acl "Deny Unauthorized"; deny (all)' | . '(version 3.0; acl "Deny Unauthorized"; deny (all)' | ||||
. '(userdn != "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN | . '(userdn != "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN | ||||
. ' || ldap:///ou=People,' . $domainBaseDN . '??sub?(objectclass=inetorgperson)") ' | . ' || ldap:///ou=People,' . $domainBaseDN . '??sub?(objectclass=inetorgperson)") ' | ||||
. 'AND NOT roledn = "ldap:///cn=kolab-admin,' . $mgmtRootDN . '";)', | . 'AND NOT roledn = "ldap:///cn=kolab-admin,' . $mgmtRootDN . '";)', | ||||
Show All 19 Lines | public static function createDomain(Domain $domain): void | ||||
], | ], | ||||
]; | ]; | ||||
$dn = "associateddomain={$domain->namespace},{$config['domain_base_dn']}"; | $dn = "associateddomain={$domain->namespace},{$config['domain_base_dn']}"; | ||||
self::setDomainAttributes($domain, $entry); | self::setDomainAttributes($domain, $entry); | ||||
if (!$ldap->get_entry($dn)) { | if (!$ldap->get_entry($dn)) { | ||||
$result = $ldap->add_entry($dn, $entry); | self::addEntry( | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$dn, | |||||
$entry, | |||||
"Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | "Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
} | |||||
// create ou, roles, ous | // create ou, roles, ous | ||||
$entry = [ | $entry = [ | ||||
'description' => $domain->namespace, | 'description' => $domain->namespace, | ||||
'objectclass' => [ | 'objectclass' => [ | ||||
'top', | 'top', | ||||
'organizationalunit' | 'organizationalunit' | ||||
], | ], | ||||
Show All 27 Lines | public static function createDomain(Domain $domain): void | ||||
. '(userdn = "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN . '");)', | . '(userdn = "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN . '");)', | ||||
'(target = "ldap:///cn=*,' . $domainBaseDN . '")(targetattr="objectclass || cn")' | '(target = "ldap:///cn=*,' . $domainBaseDN . '")(targetattr="objectclass || cn")' | ||||
. '(version 3.0;acl "Allow Domain Role Registration"; allow (add)' | . '(version 3.0;acl "Allow Domain Role Registration"; allow (add)' | ||||
. '(userdn = "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN . '");)', | . '(userdn = "ldap:///uid=kolab-service,ou=Special Users,' . $mgmtRootDN . '");)', | ||||
); | ); | ||||
if (!$ldap->get_entry($domainBaseDN)) { | if (!$ldap->get_entry($domainBaseDN)) { | ||||
$result = $ldap->add_entry($domainBaseDN, $entry); | self::addEntry( | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$domainBaseDN, | |||||
$entry, | |||||
"Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | "Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
} | |||||
foreach (['Groups', 'People', 'Resources', 'Shared Folders'] as $item) { | foreach (['Groups', 'People', 'Resources', 'Shared Folders'] as $item) { | ||||
if (!$ldap->get_entry("ou={$item},{$domainBaseDN}")) { | $itemDN = self::baseDN($domain->namespace, $item); | ||||
$result = $ldap->add_entry( | if (!$ldap->get_entry($itemDN)) { | ||||
"ou={$item},{$domainBaseDN}", | $itemEntry = [ | ||||
[ | |||||
'ou' => $item, | 'ou' => $item, | ||||
'description' => $item, | 'description' => $item, | ||||
'objectclass' => [ | 'objectclass' => [ | ||||
'top', | 'top', | ||||
'organizationalunit' | 'organizationalunit' | ||||
] | ] | ||||
] | ]; | ||||
); | |||||
if (!$result) { | self::addEntry( | ||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$itemDN, | |||||
$itemEntry, | |||||
"Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | "Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
} | |||||
foreach (['kolab-admin'] as $item) { | foreach (['kolab-admin'] as $item) { | ||||
if (!$ldap->get_entry("cn={$item},{$domainBaseDN}")) { | $itemDN = "cn={$item},{$domainBaseDN}"; | ||||
$result = $ldap->add_entry( | if (!$ldap->get_entry($itemDN)) { | ||||
"cn={$item},{$domainBaseDN}", | $itemEntry = [ | ||||
[ | |||||
'cn' => $item, | 'cn' => $item, | ||||
'description' => "{$item} role", | 'description' => "{$item} role", | ||||
'objectclass' => [ | 'objectclass' => [ | ||||
'top', | 'top', | ||||
'ldapsubentry', | 'ldapsubentry', | ||||
'nsmanagedroledefinition', | 'nsmanagedroledefinition', | ||||
'nsroledefinition', | 'nsroledefinition', | ||||
'nssimpleroledefinition' | 'nssimpleroledefinition' | ||||
] | ] | ||||
] | ]; | ||||
); | |||||
if (!$result) { | self::addEntry( | ||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$itemDN, | |||||
$itemEntry, | |||||
"Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | "Failed to create domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
} | |||||
// 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. | * Create a group in LDAP. | ||||
* | * | ||||
* @param \App\Group $group The group to create. | * @param \App\Group $group The group to create. | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function createGroup(Group $group): void | public static function createGroup(Group $group): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
list($cn, $domainName) = explode('@', $group->email); | $domainName = explode('@', $group->email, 2)[1]; | ||||
$cn = $ldap->quote_string($group->name); | |||||
$domain = $group->domain(); | $dn = "cn={$cn}," . self::baseDN($domainName, 'Groups'); | ||||
if (empty($domain)) { | |||||
self::throwException( | |||||
$ldap, | |||||
"Failed to create group {$group->email} in LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
$groupBaseDN = "ou=Groups,{$domainBaseDN}"; | |||||
$dn = "cn={$cn},{$groupBaseDN}"; | |||||
$entry = [ | $entry = [ | ||||
'cn' => $cn, | |||||
'mail' => $group->email, | 'mail' => $group->email, | ||||
'objectclass' => [ | 'objectclass' => [ | ||||
'top', | 'top', | ||||
'groupofuniquenames', | 'groupofuniquenames', | ||||
'kolabgroupofuniquenames' | 'kolabgroupofuniquenames' | ||||
], | ], | ||||
'uniquemember' => [] | |||||
]; | ]; | ||||
self::setGroupAttributes($ldap, $group, $entry); | self::setGroupAttributes($ldap, $group, $entry); | ||||
$result = $ldap->add_entry($dn, $entry); | self::addEntry( | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$dn, | |||||
$entry, | |||||
"Failed to create group {$group->email} in LDAP (" . __LINE__ . ")" | "Failed to create group {$group->email} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | |||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Create a user in LDAP. | * Create a user in LDAP. | ||||
Show All 38 Lines | public static function createUser(User $user): void | ||||
if (!self::getUserEntry($ldap, $user->email, $dn)) { | if (!self::getUserEntry($ldap, $user->email, $dn)) { | ||||
if (empty($dn)) { | if (empty($dn)) { | ||||
self::throwException($ldap, "Failed to create user {$user->email} in LDAP (" . __LINE__ . ")"); | self::throwException($ldap, "Failed to create user {$user->email} in LDAP (" . __LINE__ . ")"); | ||||
} | } | ||||
self::setUserAttributes($user, $entry); | self::setUserAttributes($user, $entry); | ||||
$result = $ldap->add_entry($dn, $entry); | self::addEntry( | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | $ldap, | ||||
$dn, | |||||
$entry, | |||||
"Failed to create user {$user->email} in LDAP (" . __LINE__ . ")" | "Failed to create user {$user->email} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
} | |||||
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 delete | * @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); | ||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | $domainBaseDN = self::baseDN($domain->namespace); | ||||
$mgmtRootDN = \config('ldap.admin.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
if ($ldap->get_entry($domainBaseDN)) { | if ($ldap->get_entry($domainBaseDN)) { | ||||
$result = $ldap->delete_entry_recursive($domainBaseDN); | $result = $ldap->delete_entry_recursive($domainBaseDN); | ||||
if (!$result) { | if (!$result) { | ||||
self::throwException( | self::throwException( | ||||
$ldap, | $ldap, | ||||
"Failed to delete domain {$domain->namespace} from LDAP (" . __LINE__ . ")" | "Failed to delete domain {$domain->namespace} from LDAP (" . __LINE__ . ")" | ||||
▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | class LDAP | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function updateGroup(Group $group): void | public static function updateGroup(Group $group): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
list($cn, $domainName) = explode('@', $group->email); | $newEntry = $oldEntry = self::getGroupEntry($ldap, $group->email, $dn); | ||||
$domain = $group->domain(); | if (empty($oldEntry)) { | ||||
if (empty($domain)) { | |||||
self::throwException( | self::throwException( | ||||
$ldap, | $ldap, | ||||
"Failed to update group {$group->email} in LDAP (group not found)" | "Failed to update group {$group->email} in LDAP (group not found)" | ||||
); | ); | ||||
} | } | ||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | self::setGroupAttributes($ldap, $group, $newEntry); | ||||
$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($ldap, $group, $entry); | |||||
$result = $ldap->modify_entry($dn, $oldEntry, $entry); | $result = $ldap->modify_entry($dn, $oldEntry, $newEntry); | ||||
if (!is_array($result)) { | if (!is_array($result)) { | ||||
self::throwException( | self::throwException( | ||||
$ldap, | $ldap, | ||||
"Failed to update group {$group->email} in LDAP (" . __LINE__ . ")" | "Failed to update group {$group->email} in LDAP (" . __LINE__ . ")" | ||||
); | ); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | class LDAP | ||||
/** | /** | ||||
* Convert group member addresses in to valid entries. | * Convert group member addresses in to valid entries. | ||||
*/ | */ | ||||
private static function setGroupAttributes($ldap, Group $group, &$entry) | private static function setGroupAttributes($ldap, Group $group, &$entry) | ||||
{ | { | ||||
$settings = $group->getSettings(['sender_policy']); | $settings = $group->getSettings(['sender_policy']); | ||||
$entry['kolaballowsmtpsender'] = json_decode($settings['sender_policy'] ?: '[]', true); | $entry['kolaballowsmtpsender'] = json_decode($settings['sender_policy'] ?: '[]', true); | ||||
$entry['cn'] = $group->name; | |||||
$entry['uniquemember'] = []; | |||||
$groupDomain = explode('@', $group->email, 2)[1]; | |||||
$domainBaseDN = self::baseDN($groupDomain); | |||||
$validMembers = []; | $validMembers = []; | ||||
$domain = $group->domain(); | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | |||||
foreach ($group->members as $member) { | foreach ($group->members as $member) { | ||||
list($local, $domainName) = explode('@', $member); | list($local, $domainName) = explode('@', $member); | ||||
$memberDN = "uid={$member},ou=People,{$domainBaseDN}"; | $memberDN = "uid={$member},ou=People,{$domainBaseDN}"; | ||||
$memberEntry = $ldap->get_entry($memberDN); | $memberEntry = $ldap->get_entry($memberDN); | ||||
// if the member is in the local domain but doesn't exist, drop it | // if the member is in the local domain but doesn't exist, drop it | ||||
if ($domainName == $domain->namespace && !$memberEntry) { | if ($domainName == $groupDomain && !$memberEntry) { | ||||
continue; | continue; | ||||
} | } | ||||
// add the member if not in the local domain | // add the member if not in the local domain | ||||
if (!$memberEntry) { | if (!$memberEntry) { | ||||
$memberEntry = [ | $memberEntry = [ | ||||
'cn' => $member, | 'cn' => $member, | ||||
'mail' => $member, | 'mail' => $member, | ||||
Show All 10 Lines | private static function setGroupAttributes($ldap, Group $group, &$entry) | ||||
} | } | ||||
$entry['uniquemember'][] = $memberDN; | $entry['uniquemember'][] = $memberDN; | ||||
$validMembers[] = $member; | $validMembers[] = $member; | ||||
} | } | ||||
// Update members in sql (some might have been removed), | // Update members in sql (some might have been removed), | ||||
// skip model events to not invoke another update job | // skip model events to not invoke another update job | ||||
if ($group->members !== $validMembers) { | |||||
$group->members = $validMembers; | $group->members = $validMembers; | ||||
Group::withoutEvents(function () use ($group) { | Group::withoutEvents(function () use ($group) { | ||||
$group->save(); | $group->save(); | ||||
}); | }); | ||||
} | } | ||||
} | |||||
/** | /** | ||||
* Set common user attributes | * Set common user attributes | ||||
*/ | */ | ||||
private static function setUserAttributes(User $user, array &$entry) | private static function setUserAttributes(User $user, array &$entry) | ||||
{ | { | ||||
$settings = $user->getSettings(['first_name', 'last_name', 'organization']); | $settings = $user->getSettings(['first_name', 'last_name', 'organization']); | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | class LDAP | ||||
* @param \Net_LDAP3 $ldap Ldap connection | * @param \Net_LDAP3 $ldap Ldap connection | ||||
* @param string $email Group email (mail) | * @param string $email Group email (mail) | ||||
* @param string $dn Reference to group DN | * @param string $dn Reference to group DN | ||||
* | * | ||||
* @return false|null|array Group entry, False on error, NULL if not found | * @return false|null|array Group entry, False on error, NULL if not found | ||||
*/ | */ | ||||
private static function getGroupEntry($ldap, $email, &$dn = null) | private static function getGroupEntry($ldap, $email, &$dn = null) | ||||
{ | { | ||||
list($_local, $_domain) = explode('@', $email, 2); | $domainName = explode('@', $email, 2)[1]; | ||||
$base_dn = self::baseDN($domainName, 'Groups'); | |||||
$domain = $ldap->find_domain($_domain); | $attrs = ['dn', 'cn', 'mail', 'uniquemember', 'objectclass', 'kolaballowsmtpsender']; | ||||
if (!$domain) { | // For groups we're using search() instead of get_entry() because | ||||
return $domain; | // a group name is not constant, so e.g. on update we might have | ||||
} | // the new name, but not the old one. Email address is constant. | ||||
$result = $ldap->search($base_dn, "(mail=$email)", "sub", $attrs); | |||||
$base_dn = $ldap->domain_root_dn($_domain); | if ($result && $result->count() == 1) { | ||||
$dn = "cn={$_local},ou=Groups,{$base_dn}"; | $entries = $result->entries(true); | ||||
$dn = key($entries); | |||||
$entry = $entries[$dn]; | |||||
$entry['dn'] = $dn; | |||||
$entry = $ldap->get_entry($dn); | return $entry; | ||||
} | |||||
return $entry ?: null; | return 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 ?array User entry, NULL if not found | ||||
*/ | */ | ||||
private static function getUserEntry($ldap, $email, &$dn = null, $full = false) | private static function getUserEntry($ldap, $email, &$dn = null, $full = false) | ||||
{ | { | ||||
list($_local, $_domain) = explode('@', $email, 2); | $domainName = explode('@', $email, 2)[1]; | ||||
$domain = $ldap->find_domain($_domain); | $dn = "uid={$email}," . self::baseDN($domainName, 'People'); | ||||
if (!$domain) { | |||||
return $domain; | |||||
} | |||||
$base_dn = $ldap->domain_root_dn($_domain); | |||||
$dn = "uid={$email},ou=People,{$base_dn}"; | |||||
$entry = $ldap->get_entry($dn); | $entry = $ldap->get_entry($dn); | ||||
if ($entry && $full) { | if ($entry && $full) { | ||||
if (!array_key_exists('nsroledn', $entry)) { | if (!array_key_exists('nsroledn', $entry)) { | ||||
$roles = $ldap->get_entry_attributes($dn, ['nsroledn']); | $roles = $ldap->get_entry_attributes($dn, ['nsroledn']); | ||||
if (!empty($roles)) { | if (!empty($roles)) { | ||||
$entry['nsroledn'] = (array) $roles['nsroledn']; | $entry['nsroledn'] = (array) $roles['nsroledn']; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | public static function logHook($level, $msg): void | ||||
} | } | ||||
$msg = '[LDAP] ' . $msg; | $msg = '[LDAP] ' . $msg; | ||||
\Log::{$function}($msg); | \Log::{$function}($msg); | ||||
} | } | ||||
/** | /** | ||||
* A wrapper for Net_LDAP3::add_entry() with error handler | |||||
* | |||||
* @param \Net_LDAP3 $ldap Ldap connection | |||||
* @param string $dn Entry DN | |||||
* @param array $entry Entry attributes | |||||
* @param ?string $errorMsg A message to throw as an exception on error | |||||
* | |||||
* @throws \Exception | |||||
*/ | |||||
private static function addEntry($ldap, string $dn, array $entry, $errorMsg = null) | |||||
{ | |||||
// try/catch because Laravel converts warnings into exceptions | |||||
// and we want more human-friendly error message than that | |||||
try { | |||||
$result = $ldap->add_entry($dn, $entry); | |||||
} catch (\Exception $e) { | |||||
$result = false; | |||||
} | |||||
if (!$result) { | |||||
if (!$errorMsg) { | |||||
$errorMsg = "LDAP Error (" . __LINE__ . ")"; | |||||
} | |||||
if (isset($e)) { | |||||
$errorMsg .= ": " . $e->getMessage(); | |||||
} | |||||
self::throwException($ldap, $errorMsg); | |||||
} | |||||
} | |||||
/** | |||||
* Throw exception and close the connection when needed | * Throw exception and close the connection when needed | ||||
* | * | ||||
* @param \Net_LDAP3 $ldap Ldap connection | * @param \Net_LDAP3 $ldap Ldap connection | ||||
* @param string $message Exception message | * @param string $message Exception message | ||||
* | * | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
private static function throwException($ldap, string $message): void | private static function throwException($ldap, string $message): void | ||||
{ | { | ||||
if (empty(self::$ldap) && !empty($ldap)) { | if (empty(self::$ldap) && !empty($ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
throw new \Exception($message); | throw new \Exception($message); | ||||
} | } | ||||
/** | |||||
* Create a base DN string for specified object | |||||
* | |||||
* @param string $domainName Domain namespace | |||||
* @param ?string $ouName Optional name of the sub-tree (OU) | |||||
* | |||||
* @return string Full base DN | |||||
*/ | |||||
private static function baseDN(string $domainName, string $ouName = null): string | |||||
{ | |||||
$hostedRootDN = \config('ldap.hosted.root_dn'); | |||||
$dn = "ou={$domainName},{$hostedRootDN}"; | |||||
if ($ouName) { | |||||
$dn = "ou={$ouName},{$dn}"; | |||||
} | |||||
return $dn; | |||||
} | |||||
} | } |