Created
July 23, 2021 00:35
-
-
Save grantholle/300e9ddae9fea66e8f6eeb9fd573e008 to your computer and use it in GitHub Desktop.
A simple class that creates an Exchange mailbox using the LdapRecord package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Support\Str; | |
use LdapRecord\Models\ActiveDirectory\Entry; | |
use LdapRecord\Models\ActiveDirectory\User as LdapUser; | |
use LdapTools\Security\GUID; | |
use Ramsey\Uuid\Uuid; | |
class MailboxFactory | |
{ | |
protected $configurationDn; | |
public function createMailbox() | |
{ | |
// Use your organizational unit (OU) | |
$ldapUser = (new LdapUser)->inside('OU=Staff,DC=local'); | |
$email = 'john.doe@example.com'; | |
$username = 'john.doe'; | |
// Populate these values | |
$ldapUser->givenName = 'John'; | |
$ldapUser->sn = 'Doe'; | |
$ldapUser->cn = 'John Doe'; | |
$ldapUser->displayName = 'John Doe'; | |
$ldapUser->name = 'John Doe'; | |
$ldapUser->title = 'Employee'; | |
$ldapUser->department = 'Department'; | |
$ldapUser->manager = 'CN=Boss Man,OU=Staff,DC=com'; | |
$ldapUser->unicodePwd = Str::random(); | |
$ldapUser->samaccountname = $username; | |
$ldapUser->mailNickname = $username; | |
$ldapUser->mail = $email; | |
$ldapUser->userPrincipalName = $email; | |
$ldapUser->company = 'Company Name'; | |
$ldapUser->streetAddress = '123 Main Street'; | |
$ldapUser->l = 'City'; | |
$ldapUser->st = 'ST'; | |
$ldapUser->c = 'Country'; | |
$ldapUser->postalCode = '123456'; | |
$ldapUser->wWWHomePage = 'https://www.example.com'; | |
$ldapUser->telephoneNumber = '123-123-123'; | |
// Exchange attributes | |
// The logic was ported from LdapTools | |
$ldapUser->msExchHomeServerName = $this->getExchangeServerDn(); | |
$ldapUser->legacyExchangeDN = $this->getLegacyExchangeDn($username); | |
$ldapUser->homeMDB = $this->getExchangeDatabaseDn(); | |
$ldapUser->mDBUseDefaults = 'TRUE'; | |
$ldapUser->msExchUserCulture = 'en-US'; | |
$ldapUser->proxyAddresses = "SMTP:{$email}"; | |
$ldapUser->msExchMailboxGUID = (new GUID(Uuid::uuid4()))->toBinary(); | |
$ldapUser->msExchUserAccountControl = 0; | |
$ldapUser->msExchRecipientDisplayType = 1073741824; | |
$ldapUser->msExchRBACPolicyLink = $this->getExchangeRbacPolicyDn(); | |
$ldapUser->msExchRecipientTypeDetails = 1; | |
$ldapUser->msExchVersion = 88218628259840; | |
$ldapUser->showInAddressBook = $this->getAddressBookDns(); | |
$ldapUser->msExchPoliciesIncluded = $this->getRecipientPolicyDn(); | |
// Save the user initially | |
$ldapUser->save(); | |
// Enable their account | |
$ldapUser->userAccountControl = 512; | |
$ldapUser->save(); | |
// Force password reset when the log in | |
$ldapUser->pwdlastset = 0; | |
$ldapUser->save(); | |
return $this; | |
} | |
protected function getExchangeServerDn() | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
$exchangeServer = Entry::in($this->configurationDn) | |
->where('objectclass', 'msExchExchangeServer') | |
->whereHas('serverrole') | |
->first(); | |
if (!$exchangeServer) { | |
throw new \Exception("Exchange server not found."); | |
} | |
return $exchangeServer->getFirstAttribute('distinguishedname'); | |
} | |
protected function getExchangeDatabaseDn() | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
// This is the name of your Exchange mailbox database | |
$database = 'Mailbox-Db-Name'; | |
$exchangeDb = Entry::in($this->configurationDn) | |
->where('objectclass', 'msExchMDB') | |
->where('cn', $database) | |
->first(); | |
if (!$exchangeDb) { | |
throw new \Exception("Exchange database not found."); | |
} | |
return $exchangeDb->getFirstAttribute('distinguishedname'); | |
} | |
protected function getExchangeRbacPolicyDn() | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
$rbacPolicy = Entry::in($this->configurationDn) | |
->where('objectclass', 'msExchRBACPolicy') | |
->where('cn', 'Default Role Assignment Policy') | |
->first(); | |
if (!$rbacPolicy) { | |
throw new \Exception("Exchange RBAC policy not found."); | |
} | |
return $rbacPolicy->getFirstAttribute('distinguishedname'); | |
} | |
protected function getAddressBookDns() | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
return Entry::in($this->configurationDn) | |
->where('objectclass', 'addressBookContainer') | |
->get() | |
->filter(function ($addressBook) { | |
return in_array($addressBook->getFirstAttribute('cn'), [ | |
'All Mailboxes(VLV)', | |
'All Recipients(VLV)', | |
'All Users', | |
'Default Global Address List', | |
'Mailboxes(VLV)', | |
]); | |
}) | |
->pluck('distinguishedname') | |
->flatten() | |
->toArray(); | |
} | |
protected function getRecipientPolicyDn() | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
$policy = Entry::in($this->configurationDn) | |
->where('objectclass', 'msExchRecipientPolicy') | |
->where('cn', 'Default Policy') | |
->first(); | |
if (!$policy) { | |
throw new \Exception('Recipient policy could not be found'); | |
} | |
return $policy->getFirstAttribute('distinguishedname'); | |
} | |
protected function getLegacyExchangeDn(string $username) | |
{ | |
if (!$this->configurationDn) { | |
$this->getConfigurationNamingContext(); | |
} | |
$policy = Entry::in($this->configurationDn) | |
->where('objectclass', 'msExchAdminGroup') | |
->first(); | |
if (!$policy) { | |
throw new \Exception('Recipient policy could not be found'); | |
} | |
$uuid = str_replace('-', '', Uuid::uuid4()); | |
return $policy->getFirstAttribute('legacyexchangedn') | |
. "/cn=Recipients/cn={$uuid}-{$username}"; | |
} | |
/** | |
* Gets the configuration naming context from the root dse | |
* | |
* @return $this | |
*/ | |
protected function getConfigurationNamingContext() | |
{ | |
$rootdse = Entry::in(null) | |
->read() | |
->whereHas('objectclass') | |
->first(); | |
$this->configurationDn = $rootdse->getFirstAttribute('configurationnamingcontext'); | |
return $this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment