Changeset View
Changeset View
Standalone View
Standalone View
src/app/Backends/LDAP.php
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 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); | $result = $ldap->add_entry($dn, $entry); | ||||
if (!$result) { | if (!$result) { | ||||
self::throwException($ldap, "Failed to create domain {$domain->namespace} in LDAP"); | self::throwException( | ||||
$ldap, | |||||
"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', | ||||
Show All 29 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)) { | ||||
$ldap->add_entry($domainBaseDN, $entry); | $result = $ldap->add_entry($domainBaseDN, $entry); | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | |||||
"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}")) { | if (!$ldap->get_entry("ou={$item},{$domainBaseDN}")) { | ||||
$ldap->add_entry( | $result = $ldap->add_entry( | ||||
"ou={$item},{$domainBaseDN}", | "ou={$item},{$domainBaseDN}", | ||||
[ | [ | ||||
'ou' => $item, | 'ou' => $item, | ||||
'description' => $item, | 'description' => $item, | ||||
'objectclass' => [ | 'objectclass' => [ | ||||
'top', | 'top', | ||||
'organizationalunit' | 'organizationalunit' | ||||
] | ] | ||||
] | ] | ||||
); | ); | ||||
if (!$result) { | |||||
self::throwException( | |||||
$ldap, | |||||
"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}")) { | if (!$ldap->get_entry("cn={$item},{$domainBaseDN}")) { | ||||
$ldap->add_entry( | $result = $ldap->add_entry( | ||||
"cn={$item},{$domainBaseDN}", | "cn={$item},{$domainBaseDN}", | ||||
[ | [ | ||||
'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::throwException( | |||||
$ldap, | |||||
"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(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | public static function createUser(User $user): void | ||||
]; | ]; | ||||
if (!self::getUserEntry($ldap, $user->email, $dn) && $dn) { | if (!self::getUserEntry($ldap, $user->email, $dn) && $dn) { | ||||
self::setUserAttributes($user, $entry); | self::setUserAttributes($user, $entry); | ||||
$result = $ldap->add_entry($dn, $entry); | $result = $ldap->add_entry($dn, $entry); | ||||
if (!$result) { | if (!$result) { | ||||
self::throwException($ldap, "Failed to create user {$user->email} in LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to create user {$user->email} in LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
Show All 13 Lines | public static function deleteDomain(Domain $domain): void | ||||
$mgmtRootDN = \config('ldap.admin.root_dn'); | $mgmtRootDN = \config('ldap.admin.root_dn'); | ||||
$domainBaseDN = "ou={$domain->namespace},{$hostedRootDN}"; | $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($ldap, "Failed to delete domain {$domain->namespace} from LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to delete domain {$domain->namespace} from LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
} | } | ||||
if ($ldap_domain = $ldap->find_domain($domain->namespace)) { | if ($ldap_domain = $ldap->find_domain($domain->namespace)) { | ||||
if ($ldap->get_entry($ldap_domain['dn'])) { | if ($ldap->get_entry($ldap_domain['dn'])) { | ||||
$result = $ldap->delete_entry($ldap_domain['dn']); | $result = $ldap->delete_entry($ldap_domain['dn']); | ||||
if (!$result) { | if (!$result) { | ||||
self::throwException($ldap, "Failed to delete domain {$domain->namespace} from LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to delete domain {$domain->namespace} from LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
Show All 9 Lines | class LDAP | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
if (self::getUserEntry($ldap, $user->email, $dn)) { | if (self::getUserEntry($ldap, $user->email, $dn)) { | ||||
$result = $ldap->delete_entry($dn); | $result = $ldap->delete_entry($dn); | ||||
if (!$result) { | if (!$result) { | ||||
self::throwException($ldap, "Failed to delete user {$user->email} from LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to delete user {$user->email} from LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | class LDAP | ||||
public static function updateDomain(Domain $domain): void | public static function updateDomain(Domain $domain): void | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
$ldapDomain = $ldap->find_domain($domain->namespace); | $ldapDomain = $ldap->find_domain($domain->namespace); | ||||
if (!$ldapDomain) { | if (!$ldapDomain) { | ||||
self::throwException($ldap, "Failed to update domain {$domain->namespace} in LDAP (domain not found)"); | self::throwException( | ||||
$ldap, | |||||
"Failed to update domain {$domain->namespace} in LDAP (domain not found)" | |||||
); | |||||
} | } | ||||
$oldEntry = $ldap->get_entry($ldapDomain['dn']); | $oldEntry = $ldap->get_entry($ldapDomain['dn']); | ||||
$newEntry = $oldEntry; | $newEntry = $oldEntry; | ||||
self::setDomainAttributes($domain, $newEntry); | self::setDomainAttributes($domain, $newEntry); | ||||
if (array_key_exists('inetdomainstatus', $newEntry)) { | if (array_key_exists('inetdomainstatus', $newEntry)) { | ||||
$newEntry['inetdomainstatus'] = (string) $newEntry['inetdomainstatus']; | $newEntry['inetdomainstatus'] = (string) $newEntry['inetdomainstatus']; | ||||
} | } | ||||
$result = $ldap->modify_entry($ldapDomain['dn'], $oldEntry, $newEntry); | $result = $ldap->modify_entry($ldapDomain['dn'], $oldEntry, $newEntry); | ||||
if (!is_array($result)) { | if (!is_array($result)) { | ||||
self::throwException($ldap, "Failed to update domain {$domain->namespace} in LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to update domain {$domain->namespace} in LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $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 | ||||
{ | { | ||||
$config = self::getConfig('admin'); | $config = self::getConfig('admin'); | ||||
$ldap = self::initLDAP($config); | $ldap = self::initLDAP($config); | ||||
$newEntry = $oldEntry = self::getUserEntry($ldap, $user->email, $dn, true); | $newEntry = $oldEntry = self::getUserEntry($ldap, $user->email, $dn, true); | ||||
if (!$oldEntry) { | if (!$oldEntry) { | ||||
self::throwException($ldap, "Failed to update user {$user->email} in LDAP (user not found)"); | self::throwException( | ||||
$ldap, | |||||
"Failed to update user {$user->email} in LDAP (user not found)" | |||||
); | |||||
} | } | ||||
self::setUserAttributes($user, $newEntry); | self::setUserAttributes($user, $newEntry); | ||||
if (array_key_exists('objectclass', $newEntry)) { | if (array_key_exists('objectclass', $newEntry)) { | ||||
if (!in_array('inetuser', $newEntry['objectclass'])) { | if (!in_array('inetuser', $newEntry['objectclass'])) { | ||||
$newEntry['objectclass'][] = 'inetuser'; | $newEntry['objectclass'][] = 'inetuser'; | ||||
} | } | ||||
} | } | ||||
if (array_key_exists('inetuserstatus', $newEntry)) { | if (array_key_exists('inetuserstatus', $newEntry)) { | ||||
$newEntry['inetuserstatus'] = (string) $newEntry['inetuserstatus']; | $newEntry['inetuserstatus'] = (string) $newEntry['inetuserstatus']; | ||||
} | } | ||||
if (array_key_exists('mailquota', $newEntry)) { | if (array_key_exists('mailquota', $newEntry)) { | ||||
$newEntry['mailquota'] = (string) $newEntry['mailquota']; | $newEntry['mailquota'] = (string) $newEntry['mailquota']; | ||||
} | } | ||||
$result = $ldap->modify_entry($dn, $oldEntry, $newEntry); | $result = $ldap->modify_entry($dn, $oldEntry, $newEntry); | ||||
if (!is_array($result)) { | if (!is_array($result)) { | ||||
self::throwException($ldap, "Failed to update user {$user->email} in LDAP"); | self::throwException( | ||||
$ldap, | |||||
"Failed to update user {$user->email} in LDAP (" . __LINE__ . ")" | |||||
); | |||||
} | } | ||||
if (empty(self::$ldap)) { | if (empty(self::$ldap)) { | ||||
$ldap->close(); | $ldap->close(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Initialize connection to LDAP | * Initialize connection to LDAP | ||||
*/ | */ | ||||
private static function initLDAP(array $config, string $privilege = 'admin') | private static function initLDAP(array $config, string $privilege = 'admin') | ||||
{ | { | ||||
if (self::$ldap) { | if (self::$ldap) { | ||||
return self::$ldap; | return self::$ldap; | ||||
} | } | ||||
$ldap = new \Net_LDAP3($config); | $ldap = new \Net_LDAP3($config); | ||||
$connected = $ldap->connect(); | $connected = $ldap->connect(); | ||||
if (!$connected) { | if (!$connected) { | ||||
throw new \Exception("Failed to connect to LDAP"); | throw new \Exception("Failed to connect to LDAP"); | ||||
} | } | ||||
$bound = $ldap->bind(\config("ldap.{$privilege}.bind_dn"), \config("ldap.{$privilege}.bind_pw")); | $bound = $ldap->bind( | ||||
\config("ldap.{$privilege}.bind_dn"), | |||||
\config("ldap.{$privilege}.bind_pw") | |||||
); | |||||
if (!$bound) { | if (!$bound) { | ||||
throw new \Exception("Failed to bind to LDAP"); | throw new \Exception("Failed to bind to LDAP"); | ||||
} | } | ||||
return $ldap; | return $ldap; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 210 Lines • Show Last 20 Lines |