Skip to content

[Bug]: LDAP_LOGIN_ATTR=DN documented but not implemented #464

@DagNygren

Description

@DagNygren

Is there an existing issue for this?

  • I have searched the existing issues

Environment

- OS:Ubuntu 24.04
- PHP:8.4
- LDAP Server:OpenLDAP

PLA Code

Github checkout

PLA Version

2.1

Current Behavior

PLA performs an attribute search using DN as the attribute name, finds no results, and rejects the login.

Expected Behavior

PLA binds directly using the supplied DN and password.

Steps To Reproduce

1.Set LDAP_LOGIN_ATTR=DN in .env
2. Attempt login with a full DN, e.g. cn=admin,dc=example,dc=com
3. Observe in LDAP server logs: filter="(?DN=cn=admin,dc=example,dc=com)" with err=0 nentries=0

Relevant log output

You can see in the OpenLDAP log that a search for "(?DN=cn=user,dc=example,dc=com)" is made and nothing found

Anything else?

Description:

Setting LDAP_LOGIN_ATTR=DN in .env is documented in the Configuration Variables
wiki as enabling full DN login. However, the value DN is passed literally as an
LDAP attribute name to LdapUserRepository::findByCredentials(), resulting in a
malformed search filter: (?DN=cn=user,dc=example,dc=com) with nentries=0.

Workaround: Override attemptLogin() in LoginController.php to detect
login_attr_name() === 'DN' and call User::find($dn) directly, bypassing the
attribute search. See patch below.

Environment:

  • phpLDAPadmin v2.x (leenooks fork)
  • Laravel 11.x
  • directorytree/ldaprecord-laravel
  • OpenLDAP with STARTTLS

DN Login Patch

The official documentation states that setting LDAP_LOGIN_ATTR=DN enables login
using a full Distinguished Name. However, this is not implemented in the current
codebase — the value DN is passed literally as an LDAP attribute name, producing
a malformed search filter.

The following patch to app/Http/Controllers/Auth/LoginController.php implements
correct DN login by bypassing the attribute search and performing a direct DN lookup.

Add the use LdapRecord\Models\Model; import at the top of the file, then add the
attemptLogin() method to the LoginController class:

use LdapRecord\Models\Model;

// Add this method to LoginController class:

protected function attemptLogin(Request $request): bool
{
    if (strtoupper(login_attr_name()) === 'DN') {
        $dn = $request->get(login_attr_name());
        $password = $request->get('password');

        $this->guard()->getProvider()->resolveUsersUsing(
            function () use ($dn): ?Model {
                return \App\Ldap\User::find($dn);
            }
        );

        return $this->guard()->attempt(
            ['dn' => $dn, 'password' => $password],
            false
        );
    }

    return $this->guard()->attempt(
        $this->credentials($request),
        false
    );
}

After applying the patch:

php artisan optimize:clear

The patch is tested in production and seems to be working

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions