diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php
new file mode 100644
index 0000000..8ba0ef1
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php
@@ -0,0 +1,511 @@
+<?php
+
+namespace LdapRecord;
+
+use Carbon\Carbon;
+use Closure;
+use LdapRecord\Auth\Guard;
+use LdapRecord\Configuration\DomainConfiguration;
+use LdapRecord\Events\DispatcherInterface;
+use LdapRecord\Query\Builder;
+use LdapRecord\Query\Cache;
+use Psr\SimpleCache\CacheInterface;
+
+class Connection
+{
+    use DetectsErrors;
+
+    /**
+     * The underlying LDAP connection.
+     *
+     * @var Ldap
+     */
+    protected $ldap;
+
+    /**
+     * The cache driver.
+     *
+     * @var Cache|null
+     */
+    protected $cache;
+
+    /**
+     * The domain configuration.
+     *
+     * @var DomainConfiguration
+     */
+    protected $configuration;
+
+    /**
+     * The event dispatcher;.
+     *
+     * @var DispatcherInterface|null
+     */
+    protected $dispatcher;
+
+    /**
+     * The current host connected to.
+     *
+     * @var string
+     */
+    protected $host;
+
+    /**
+     * The configured domain hosts.
+     *
+     * @var array
+     */
+    protected $hosts = [];
+
+    /**
+     * The attempted hosts that failed connecting to.
+     *
+     * @var array
+     */
+    protected $attempted = [];
+
+    /**
+     * The callback to execute upon total connection failure.
+     *
+     * @var Closure
+     */
+    protected $failed;
+
+    /**
+     * The authentication guard resolver.
+     *
+     * @var Closure
+     */
+    protected $authGuardResolver;
+
+    /**
+     * Whether the connection is retrying the initial connection attempt.
+     *
+     * @var bool
+     */
+    protected $retryingInitialConnection = false;
+
+    /**
+     * Constructor.
+     *
+     * @param array              $config
+     * @param LdapInterface|null $ldap
+     */
+    public function __construct($config = [], LdapInterface $ldap = null)
+    {
+        $this->setConfiguration($config);
+
+        $this->setLdapConnection($ldap ?? new Ldap());
+
+        $this->failed = function () {
+            $this->dispatch(new Events\ConnectionFailed($this));
+        };
+
+        $this->authGuardResolver = function () {
+            return new Guard($this->ldap, $this->configuration);
+        };
+    }
+
+    /**
+     * Set the connection configuration.
+     *
+     * @param array $config
+     *
+     * @throws Configuration\ConfigurationException
+     *
+     * @return $this
+     */
+    public function setConfiguration($config = [])
+    {
+        $this->configuration = new DomainConfiguration($config);
+
+        $this->hosts = $this->configuration->get('hosts');
+
+        $this->host = reset($this->hosts);
+
+        return $this;
+    }
+
+    /**
+     * Set the LDAP connection.
+     *
+     * @param LdapInterface $ldap
+     *
+     * @return $this
+     */
+    public function setLdapConnection(LdapInterface $ldap)
+    {
+        $this->ldap = $ldap;
+
+        return $this;
+    }
+
+    /**
+     * Set the event dispatcher.
+     *
+     * @param DispatcherInterface $dispatcher
+     *
+     * @return $this
+     */
+    public function setDispatcher(DispatcherInterface $dispatcher)
+    {
+        $this->dispatcher = $dispatcher;
+
+        return $this;
+    }
+
+    /**
+     * Initializes the LDAP connection.
+     *
+     * @return void
+     */
+    public function initialize()
+    {
+        $this->configure();
+
+        $this->ldap->connect($this->host, $this->configuration->get('port'));
+    }
+
+    /**
+     * Configure the LDAP connection.
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        if ($this->configuration->get('use_ssl')) {
+            $this->ldap->ssl();
+        } elseif ($this->configuration->get('use_tls')) {
+            $this->ldap->tls();
+        }
+
+        $this->ldap->setOptions(array_replace(
+            $this->configuration->get('options'),
+            [
+                LDAP_OPT_PROTOCOL_VERSION => $this->configuration->get('version'),
+                LDAP_OPT_NETWORK_TIMEOUT => $this->configuration->get('timeout'),
+                LDAP_OPT_REFERRALS => $this->configuration->get('follow_referrals'),
+            ]
+        ));
+    }
+
+    /**
+     * Set the cache store.
+     *
+     * @param CacheInterface $store
+     *
+     * @return $this
+     */
+    public function setCache(CacheInterface $store)
+    {
+        $this->cache = new Cache($store);
+
+        return $this;
+    }
+
+    /**
+     * Get the cache store.
+     *
+     * @return Cache|null
+     */
+    public function getCache()
+    {
+        return $this->cache;
+    }
+
+    /**
+     * Get the LDAP configuration instance.
+     *
+     * @return DomainConfiguration
+     */
+    public function getConfiguration()
+    {
+        return $this->configuration;
+    }
+
+    /**
+     * Get the LDAP connection instance.
+     *
+     * @return Ldap
+     */
+    public function getLdapConnection()
+    {
+        return $this->ldap;
+    }
+
+    /**
+     * Bind to the LDAP server.
+     *
+     * If no username or password is specified, then the configured credentials are used.
+     *
+     * @param string|null $username
+     * @param string|null $password
+     *
+     * @throws Auth\BindException
+     * @throws LdapRecordException
+     *
+     * @return Connection
+     */
+    public function connect($username = null, $password = null)
+    {
+        $attempt = function () use ($username, $password) {
+            $this->dispatch(new Events\Connecting($this));
+
+            is_null($username) && is_null($password)
+                ? $this->auth()->bindAsConfiguredUser()
+                : $this->auth()->bind($username, $password);
+
+            $this->dispatch(new Events\Connected($this));
+
+            $this->retryingInitialConnection = false;
+        };
+
+        try {
+            $this->runOperationCallback($attempt);
+        } catch (LdapRecordException $e) {
+            $this->retryingInitialConnection = true;
+
+            $this->retryOnNextHost($e, $attempt);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Reconnect to the LDAP server.
+     *
+     * @throws Auth\BindException
+     * @throws ConnectionException
+     *
+     * @return void
+     */
+    public function reconnect()
+    {
+        $this->reinitialize();
+
+        $this->connect();
+    }
+
+    /**
+     * Reinitialize the connection.
+     *
+     * @return void
+     */
+    protected function reinitialize()
+    {
+        $this->disconnect();
+
+        $this->initialize();
+    }
+
+    /**
+     * Disconnect from the LDAP server.
+     *
+     * @return void
+     */
+    public function disconnect()
+    {
+        $this->ldap->close();
+    }
+
+    /**
+     * Dispatch an event.
+     *
+     * @param object $event
+     *
+     * @return void
+     */
+    public function dispatch($event)
+    {
+        if (isset($this->dispatcher)) {
+            $this->dispatcher->dispatch($event);
+        }
+    }
+
+    /**
+     * Get the attempted hosts that failed connecting to.
+     *
+     * @return array
+     */
+    public function attempted()
+    {
+        return $this->attempted;
+    }
+
+    /**
+     * Perform the operation on the LDAP connection.
+     *
+     * @param Closure $operation
+     *
+     * @return mixed
+     */
+    public function run(Closure $operation)
+    {
+        try {
+            // Before running the operation, we will check if the current
+            // connection is bound and connect if necessary. Otherwise
+            // some LDAP operations will not be executed properly.
+            if (! $this->isConnected()) {
+                $this->connect();
+            }
+
+            return $this->runOperationCallback($operation);
+        } catch (LdapRecordException $e) {
+            if ($exception = $this->getExceptionForCauseOfFailure($e)) {
+                throw $exception;
+            }
+
+            return $this->tryAgainIfCausedByLostConnection($e, $operation);
+        }
+    }
+
+    /**
+     * Attempt to get an exception for the cause of failure.
+     *
+     * @param LdapRecordException $e
+     *
+     * @return mixed
+     */
+    protected function getExceptionForCauseOfFailure(LdapRecordException $e)
+    {
+        switch (true) {
+            case $this->errorContainsMessage($e->getMessage(), 'Already exists'):
+                return Exceptions\AlreadyExistsException::withDetailedError($e, $e->getDetailedError());
+            case $this->errorContainsMessage($e->getMessage(), 'Insufficient access'):
+                return Exceptions\InsufficientAccessException::withDetailedError($e, $e->getDetailedError());
+            case $this->errorContainsMessage($e->getMessage(), 'Constraint violation'):
+                return Exceptions\ConstraintViolationException::withDetailedError($e, $e->getDetailedError());
+            default:
+                return;
+        }
+    }
+
+    /**
+     * Run the operation callback on the current LDAP connection.
+     *
+     * @param Closure $operation
+     *
+     * @throws LdapRecordException
+     *
+     * @return mixed
+     */
+    protected function runOperationCallback(Closure $operation)
+    {
+        return $operation($this->ldap);
+    }
+
+    /**
+     * Get a new auth guard instance.
+     *
+     * @return Auth\Guard
+     */
+    public function auth()
+    {
+        if (! $this->ldap->isConnected()) {
+            $this->initialize();
+        }
+
+        $guard = call_user_func($this->authGuardResolver);
+
+        $guard->setDispatcher(
+            Container::getInstance()->getEventDispatcher()
+        );
+
+        return $guard;
+    }
+
+    /**
+     * Get a new query builder for the connection.
+     *
+     * @return Query\Builder
+     */
+    public function query()
+    {
+        return (new Builder($this))
+            ->setCache($this->cache)
+            ->setBaseDn($this->configuration->get('base_dn'));
+    }
+
+    /**
+     * Determine if the LDAP connection is bound.
+     *
+     * @return bool
+     */
+    public function isConnected()
+    {
+        return $this->ldap->isBound();
+    }
+
+    /**
+     * Attempt to retry an LDAP operation if due to a lost connection.
+     *
+     * @param LdapRecordException $e
+     * @param Closure             $operation
+     *
+     * @throws LdapRecordException
+     *
+     * @return mixed
+     */
+    protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation)
+    {
+        // If the operation failed due to a lost or failed connection,
+        // we'll attempt reconnecting and running the operation again
+        // underneath the same host, and then move onto the next.
+        if ($this->causedByLostConnection($e->getMessage())) {
+            return $this->retry($operation);
+        }
+
+        throw $e;
+    }
+
+    /**
+     * Retry the operation on the current host.
+     *
+     * @param Closure $operation
+     *
+     * @throws LdapRecordException
+     *
+     * @return mixed
+     */
+    protected function retry(Closure $operation)
+    {
+        try {
+            $this->retryingInitialConnection
+                ? $this->reinitialize()
+                : $this->reconnect();
+
+            return $this->runOperationCallback($operation);
+        } catch (LdapRecordException $e) {
+            return $this->retryOnNextHost($e, $operation);
+        }
+    }
+
+    /**
+     * Attempt the operation again on the next host.
+     *
+     * @param LdapRecordException $e
+     * @param Closure             $operation
+     *
+     * @throws LdapRecordException
+     *
+     * @return mixed
+     */
+    protected function retryOnNextHost(LdapRecordException $e, Closure $operation)
+    {
+        $this->attempted[$this->host] = Carbon::now();
+
+        if (($key = array_search($this->host, $this->hosts)) !== false) {
+            unset($this->hosts[$key]);
+        }
+
+        if ($next = reset($this->hosts)) {
+            $this->host = $next;
+
+            return $this->tryAgainIfCausedByLostConnection($e, $operation);
+        }
+
+        call_user_func($this->failed, $this->ldap);
+
+        throw $e;
+    }
+}
