Skip to content
This repository was archived by the owner on Jul 24, 2023. It is now read-only.
This repository was archived by the owner on Jul 24, 2023. It is now read-only.

Can't contact LDAP server in Job Queue (Supervisor) #823

Open
@chucky2361

Description

@chucky2361
  • Laravel Version: 5.7.28

  • Adldap2-Laravel Version: v6.0.8

  • Adldap2 Version: v10.2.1

  • PHP Version: 7.2.24

  • LDAP Type: ActiveDirectory

Description:

The connection to the Active Directory server works fine when I call it up normally.
When I try to run LDAP queries in a job, I get the error "Can't contact Ldap server".
This only happens if the queue has nothing to do for a while. I haven't been able to find out the exact time so far.
If I start several jobs in a row, I don't get this error (very rarely).

There are no error messages in the event log from the Active Directory server.

I've been fighting for several weeks and unfortunately I can't find a way to fix the error.

Ldap_auth.php (Config)
`<?php

return [

/*
|--------------------------------------------------------------------------
| Connection
|--------------------------------------------------------------------------
|
| The LDAP connection to use for Laravel authentication.
|
| You must specify connections in your `config/ldap.php` configuration file.
|
*/

'connection' => env('LDAP_CONNECTION', 'default'),

/*
|--------------------------------------------------------------------------
| Provider
|--------------------------------------------------------------------------
|
| The LDAP authentication provider to use depending
| if you require database synchronization.
|
| For synchronizing LDAP users to your local applications database, use the provider:
|
| Adldap\Laravel\Auth\DatabaseUserProvider::class
|
| Otherwise, if you just require LDAP authentication, use the provider:
|
| Adldap\Laravel\Auth\NoDatabaseUserProvider::class
|
*/

'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,

/*
|--------------------------------------------------------------------------
| Model
|--------------------------------------------------------------------------
|
| The model to utilize for authentication and importing.
|
| This option is only applicable to the DatabaseUserProvider.
|
*/

'model' => App\User::class,

/*
|--------------------------------------------------------------------------
| Rules
|--------------------------------------------------------------------------
|
| Rules allow you to control user authentication requests depending on scenarios.
|
| You can create your own rules and insert them here.
|
| All rules must extend from the following class:
|
|   Adldap\Laravel\Validation\Rules\Rule
|
*/

'rules' => [

    // Denys deleted users from authenticating.

    Adldap\Laravel\Validation\Rules\DenyTrashed::class,

    // Allows only manually imported users to authenticate.

    // Adldap\Laravel\Validation\Rules\OnlyImported::class,

],

/*
|--------------------------------------------------------------------------
| Scopes
|--------------------------------------------------------------------------
|
| Scopes allow you to restrict the LDAP query that locates
| users upon import and authentication.
|
| All scopes must implement the following interface:
|
|   Adldap\Laravel\Scopes\ScopeInterface
|
*/

'scopes' => [

    // Only allows users with a user principal name to authenticate.
    // Suitable when using ActiveDirectory.
    Adldap\Laravel\Scopes\UpnScope::class,

    // Only allows users with a uid to authenticate.
    // Suitable when using OpenLDAP.
    // Adldap\Laravel\Scopes\UidScope::class,

],

'identifiers' => [

    /*
    |--------------------------------------------------------------------------
    | LDAP
    |--------------------------------------------------------------------------
    |
    | Locate Users By:
    |
    |   This value is the users attribute you would like to locate LDAP
    |   users by in your directory.
    |
    |   For example, using the default configuration below, if you're
    |   authenticating users with an email address, your LDAP server
    |   will be queried for a user with the a `userprincipalname`
    |   equal to the entered email address.
    |
    | Bind Users By:
    |
    |   This value is the users attribute you would
    |   like to use to bind to your LDAP server.
    |
    |   For example, when a user is located by the above attribute,
    |   the users attribute you specify below will be used as
    |   the 'username' to bind to your LDAP server.
    |
    |   This is usually their distinguished name.
    |
    */

    'ldap' => [

        'locate_users_by' => 'userprincipalname',

        'bind_users_by' => 'distinguishedname',

    ],

    'database' => [

        /*
        |--------------------------------------------------------------------------
        | GUID Column
        |--------------------------------------------------------------------------
        |
        | The value of this option is the database column that will contain the
        | LDAP users global identifier. This column does not need to be added
        | to the sync attributes below. It is synchronized automatically.
        |
        | This option is only applicable to the DatabaseUserProvider.
        |
        */

        'guid_column' => 'objectGUID',

        /*
        |--------------------------------------------------------------------------
        | Username Column
        |--------------------------------------------------------------------------
        |
        | The value of this option is the database column that contains your
        | users login username.
        |
        | This column must be added to your sync attributes below to be
        | properly synchronized.
        |
        | This option is only applicable to the DatabaseUserProvider.
        |
        */

        'username_column' => 'email',

    ],

    /*
    |--------------------------------------------------------------------------
    | Windows Authentication Middleware (SSO)
    |--------------------------------------------------------------------------
    |
    | Local Users By:
    |
    |   This value is the users attribute you would like to locate LDAP
    |   users by in your directory.
    |
    |   For example, if 'samaccountname' is the value, then your LDAP server is
    |   queried for a user with the 'samaccountname' equal to the value of
    |   $_SERVER['AUTH_USER'].
    |
    |   If a user is found, they are imported (if using the DatabaseUserProvider)
    |   into your local database, then logged in.
    |
    | Server Key:
    |
    |    This value represents the 'key' of the $_SERVER
    |    array to pull the users account name from.
    |
    |    For example, $_SERVER['AUTH_USER'].
    |
    */

    'windows' => [

        'locate_users_by' => 'samaccountname',

        'server_key' => 'AUTH_USER',

    ],

],

'passwords' => [

    /*
    |--------------------------------------------------------------------------
    | Password Sync
    |--------------------------------------------------------------------------
    |
    | The password sync option allows you to automatically synchronize users
    | LDAP passwords to your local database. These passwords are hashed
    | natively by Laravel using the Hash::make() method.
    |
    | Enabling this option would also allow users to login to their accounts
    | using the password last used when an LDAP connection was present.
    |
    | If this option is disabled, the local database account is applied a
    | random 16 character hashed password upon first login, and will
    | lose access to this account upon loss of LDAP connectivity.
    |
    | This option is only applicable to the DatabaseUserProvider.
    |
    */

    'sync' => env('LDAP_PASSWORD_SYNC', false),

    /*
    |--------------------------------------------------------------------------
    | Column
    |--------------------------------------------------------------------------
    |
    | This is the column of your users database table
    | that is used to store passwords.
    |
    | Set this to `null` if you do not have a password column.
    |
    | This option is only applicable to the DatabaseUserProvider.
    |
    */

    'column' => 'password',

],

/*
|--------------------------------------------------------------------------
| Login Fallback
|--------------------------------------------------------------------------
|
| The login fallback option allows you to login as a user located in the
| local database if active directory authentication fails.
|
| Set this to true if you would like to enable it.
|
| This option is only applicable to the DatabaseUserProvider.
|
*/

'login_fallback' => env('LDAP_LOGIN_FALLBACK', false),

/*
|--------------------------------------------------------------------------
| Sync Attributes
|--------------------------------------------------------------------------
|
| Attributes specified here will be added / replaced on the user model
| upon login, automatically synchronizing and keeping the attributes
| up to date.
|
| The array key represents the users Laravel model key, and
| the value represents the users LDAP attribute.
|
| You **must** include the users login attribute here.
|
| This option is only applicable to the DatabaseUserProvider.
|
*/

'sync_attributes' => [

    'email' => 'userprincipalname',
    'name' => 'displayname',
    'first_name' => 'givenname',
    'last_name' => 'sn',
    App\Handlers\LdapAttributeHandler::class,

],

/*
|--------------------------------------------------------------------------
| Logging
|--------------------------------------------------------------------------
|
| User authentication attempts will be logged using Laravel's
| default logger if this setting is enabled.
|
| No credentials are logged, only usernames.
|
| This is usually stored in the '/storage/logs' directory
| in the root of your application.
|
| This option is useful for debugging as well as auditing.
|
| You can freely remove any events you would not like to log below,
| as well as use your own listeners if you would prefer.
|
*/

'logging' => [

    'enabled' => env('LDAP_LOGGING', true),

    'events' => [

        \Adldap\Laravel\Events\Importing::class                 => \Adldap\Laravel\Listeners\LogImport::class,
        \Adldap\Laravel\Events\Synchronized::class              => \Adldap\Laravel\Listeners\LogSynchronized::class,
        \Adldap\Laravel\Events\Synchronizing::class             => \Adldap\Laravel\Listeners\LogSynchronizing::class,
        \Adldap\Laravel\Events\Authenticated::class             => \Adldap\Laravel\Listeners\LogAuthenticated::class,
        \Adldap\Laravel\Events\Authenticating::class            => \Adldap\Laravel\Listeners\LogAuthentication::class,
        \Adldap\Laravel\Events\AuthenticationFailed::class      => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
        \Adldap\Laravel\Events\AuthenticationRejected::class    => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
        \Adldap\Laravel\Events\AuthenticationSuccessful::class  => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
        \Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
        \Adldap\Laravel\Events\AuthenticatedWithWindows::class  => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
        \Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,

    ],
],

];

Ldap.php (Config)<?php

return [

/*
|--------------------------------------------------------------------------
| Logging
|--------------------------------------------------------------------------
|
| This option enables logging all LDAP operations on all configured
| connections such as bind requests and CRUD operations.
|
| Log entries will be created in your default logging stack.
|
| This option is extremely helpful for debugging connectivity issues.
|
*/

'logging' => env('LDAP_LOGGING', false),

/*
|--------------------------------------------------------------------------
| Connections
|--------------------------------------------------------------------------
|
| This array stores the connections that are added to Adldap. You can add
| as many connections as you like.
|
| The key is the name of the connection you wish to use and the value is
| an array of configuration settings.
|
*/

'connections' => [
    'default' => [

        /*
        |--------------------------------------------------------------------------
        | Auto Connect
        |--------------------------------------------------------------------------
        |
        | If auto connect is true, Adldap will try to automatically connect to
        | your LDAP server in your configuration. This allows you to assume
        | connectivity rather than having to connect manually
        | in your application.
        |
        | If this is set to false, you **must** connect manually before running
        | LDAP operations. Otherwise, you will receive exceptions.
        |
        */

        'auto_connect' => env('LDAP_AUTO_CONNECT', true),

        /*
        |--------------------------------------------------------------------------
        | Connection
        |--------------------------------------------------------------------------
        |
        | The connection class to use to run raw LDAP operations on.
        |
        | Custom connection classes must implement:
        |
        |  Adldap\Connections\ConnectionInterface
        |
        */

        'connection' => Adldap\Connections\Ldap::class,

        /*
        |--------------------------------------------------------------------------
        | Connection Settings
        |--------------------------------------------------------------------------
        |
        | This connection settings array is directly passed into the Adldap constructor.
        |
        | Feel free to add or remove settings you don't need.
        |
        */

        'settings' => [

            /*
            |--------------------------------------------------------------------------
            | Schema
            |--------------------------------------------------------------------------
            |
            | The schema class to use for retrieving attributes and generating models.
            |
            | You can also set this option to `null` to use the default schema class.
            |
            | For OpenLDAP, you must use the schema:
            |
            |   Adldap\Schemas\OpenLDAP::class
            |
            | For FreeIPA, you must use the schema:
            |
            |   Adldap\Schemas\FreeIPA::class
            |
            | Custom schema classes must implement Adldap\Schemas\SchemaInterface
            |
            */

            'schema' => Adldap\Schemas\ActiveDirectory::class,

            /*
            |--------------------------------------------------------------------------
            | Account Prefix
            |--------------------------------------------------------------------------
            |
            | The account prefix option is the prefix of your user accounts in LDAP directory.
            |
            | This string is prepended to all authenticating users usernames.
            |
            */

            'account_prefix' => env('LDAP_ACCOUNT_PREFIX', ''),

            /*
            |--------------------------------------------------------------------------
            | Account Suffix
            |--------------------------------------------------------------------------
            |
            | The account suffix option is the suffix of your user accounts in your LDAP directory.
            |
            | This string is appended to all authenticating users usernames.
            |
            */

            'account_suffix' => env('LDAP_ACCOUNT_SUFFIX', ''),

            /*
            |--------------------------------------------------------------------------
            | Domain Controllers
            |--------------------------------------------------------------------------
            |
            | The domain controllers option is an array of servers located on your
            | network that serve Active Directory. You can insert as many servers or
            | as little as you'd like depending on your forest (with the
            | minimum of one of course).
            |
            | These can be IP addresses of your server(s), or the host name.
            |
            */

            'hosts' => explode(' ', env('LDAP_HOSTS', '10.244.0.10')),

            /*
            |--------------------------------------------------------------------------
            | Port
            |--------------------------------------------------------------------------
            |
            | The port option is used for authenticating and binding to your LDAP server.
            |
            */

            'port' => env('LDAP_PORT', 636),

            /*
            |--------------------------------------------------------------------------
            | Timeout
            |--------------------------------------------------------------------------
            |
            | The timeout option allows you to configure the amount of time in
            | seconds that your application waits until a response
            | is received from your LDAP server.
            |
            */

            'timeout' => env('LDAP_TIMEOUT', 60),

            /*
            |--------------------------------------------------------------------------
            | Base Distinguished Name
            |--------------------------------------------------------------------------
            |
            | The base distinguished name is the base distinguished name you'd
            | like to perform query operations on. An example base DN would be:
            |
            |        dc=corp,dc=acme,dc=org
            |
            | A correct base DN is required for any query results to be returned.
            |
            */

            'base_dn' => env('LDAP_BASE_DN', 'OU=Kunden,DC=o2c,DC=at'),

            /*
            |--------------------------------------------------------------------------
            | LDAP Username & Password
            |--------------------------------------------------------------------------
            |
            | When connecting to your LDAP server, a username and password is required
            | to be able to query and run operations on your server(s). You can
            | use any user account that has these permissions. This account
            | does not need to be a domain administrator unless you
            | require changing and resetting user passwords.
            |
            */

            'username' => env('LDAP_USERNAME', '********'),
            'password' => env('LDAP_PASSWORD', '********'),

            /*
            |--------------------------------------------------------------------------
            | Follow Referrals
            |--------------------------------------------------------------------------
            |
            | The follow referrals option is a boolean to tell active directory
            | to follow a referral to another server on your network if the
            | server queried knows the information your asking for exists,
            | but does not yet contain a copy of it locally.
            |
            | This option is defaulted to false.
            |
            */

            'follow_referrals' => false,

            /*
            |--------------------------------------------------------------------------
            | SSL & TLS
            |--------------------------------------------------------------------------
            |
            | If you need to be able to change user passwords on your server, then an
            | SSL or TLS connection is required. All other operations are allowed
            | on unsecured protocols.
            |
            | One of these options are definitely recommended if you
            | have the ability to connect to your server securely.
            |
            */

            'use_ssl' => env('LDAP_USE_SSL', true),
            'use_tls' => env('LDAP_USE_TLS', false),

            'custom_options'   => [
                // See: http://php.net/ldap_set_option
                LDAP_OPT_X_TLS_REQUIRE_CERT => LDAP_OPT_X_TLS_NEVER
            ]

        ],

    ],

],

];
`

Stacktrace:
Next Adldap\\Auth\\BindException: Can't contact LDAP server in /var/www/********************/vendor/adldap2/adldap2/src/Auth/Guard.php:107 Stack trace: #0 /var/www/********************/vendor/adldap2/adldap2/src/Auth/Guard.php(119): Adldap\\Auth\\Guard->bind('********', '*********') #1 /var/www/********************/vendor/adldap2/adldap2/src/Connections/Provider.php(261): Adldap\\Auth\\Guard->bindAsAdministrator() #2 /var/www/********************/vendor/adldap2/adldap2/src/Adldap.php(147): Adldap\\Connections\\Provider->connect(NULL, NULL) #3 /var/www/********************/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(237): Adldap\\Adldap->connect() #4 /var/www/********************/app/Libraries/o2cRegistrationLib.php(927): Illuminate\\Support\\Facades\\Facade::__callStatic('connect', Array) #5 /var/www/********************/app/Libraries/o2cRegistrationLib.php(267): App\\Libraries\\o2cRegistrationLib->createUserDefaultRole() #6 /var/www/********************/app/Jobs/RegisterNewUser.php(88): App\\Libraries\\o2cRegistrationLib->runRegistrationProcess() #7 [internal function]: App\\Jobs\\RegisterNewUser->handle() #8 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array) #9 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}() #10 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure)) #11 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/Container.php(572): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL) #12 /var/www/********************/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\\Container\\Container->call(Array) #13 /var/www/********************/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}(Object(App\\Jobs\\RegisterNewUser)) #14 /var/www/********************/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\RegisterNewUser)) #15 /var/www/********************/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\\Pipeline\\Pipeline->then(Object(Closure)) #16 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(49): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(App\\Jobs\\RegisterNewUser), false) #17 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(83): Illuminate\\Queue\\CallQueuedHandler->call(Object(Illuminate\\Queue\\Jobs\\RedisJob), Array) #18 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(327): Illuminate\\Queue\\Jobs\\Job->fire() #19 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(277): Illuminate\\Queue\\Worker->process('redis', Object(Illuminate\\Queue\\Jobs\\RedisJob), Object(Illuminate\\Queue\\WorkerOptions)) #20 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(118): Illuminate\\Queue\\Worker->runJob(Object(Illuminate\\Queue\\Jobs\\RedisJob), 'redis', Object(Illuminate\\Queue\\WorkerOptions)) #21 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(102): Illuminate\\Queue\\Worker->daemon('redis', 'default', Object(Illuminate\\Queue\\WorkerOptions)) #22 /var/www/********************/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(86): Illuminate\\Queue\\Console\\WorkCommand->runWorker('redis', 'default') #23 /var/www/********************/vendor/laravel/horizon/src/Console/WorkCommand.php(46): Illuminate\\Queue\\Console\\WorkCommand->handle() #24 [internal function]: Laravel\\Horizon\\Console\\WorkCommand->handle() #25 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array) #26 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}() #27 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure)) #28 /var/www/********************/vendor/laravel/framework/src/Illuminate/Container/Container.php(572): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL) #29 /var/www/********************/vendor/laravel/framework/src/Illuminate/Console/Command.php(183): Illuminate\\Container\\Container->call(Array) #30 /var/www/********************/vendor/symfony/console/Command/Command.php(255): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle)) #31 /var/www/********************/vendor/laravel/framework/src/Illuminate/Console/Command.php(170): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\O utputStyle)) #32 /var/www/********************/vendor/symfony/console/Application.php(1011): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput)) #33 /var/www/********************/vendor/symfony/console/Application.php(272): Symfony\\Component\\Console\\Application->doRunCommand(Object(Laravel\\Horizon\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput) , Object(Symfony\\Component\\Console\\Output\\ConsoleOutput)) #34 /var/www/********************/vendor/symfony/console/Application.php(148): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOu tput)) #35 /var/www/********************/vendor/laravel/framework/src/Illuminate/Console/Application.php(89): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Cons ole\\Output\\ConsoleOutput)) #36 /var/www/********************/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(122): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Conso le\\Output\\ConsoleOutput)) #37 /var/www/********************/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput)) #38 {main} at /var/www/********************/app/Libraries/o2cRegistrationLib.php:947)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions