Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LDAP sync works - login/test fails if user not in base DN #12331

Open
2 tasks done
dvdp opened this issue Jan 10, 2023 · 11 comments · May be fixed by #13972
Open
2 tasks done

LDAP sync works - login/test fails if user not in base DN #12331

dvdp opened this issue Jan 10, 2023 · 11 comments · May be fixed by #13972
Assignees

Comments

@dvdp
Copy link

dvdp commented Jan 10, 2023

Debug mode

Describe the bug

I'm trying to get LDAP login working on my freshly installed Snipe-IT v6.0.14 build 9038.
Configured the LDAP server settings (we're using 389-DS with ldaps) and the 'Test LDAP synchronizaton' works fine, however if I try to authenticate any user, I get " Login Failed. did not successfully bind to LDAP. "
So I did some more testing to make sure I got the settings correct and found out that I can get authentication to work if the user is in the base bind DN and not in one of the sub-OU's of that DN. E.g.:
user 'Danny' is in ou=ICT,ou=authorized,dc=foo,dc=bar
If I set base bind dn to ou=authorized,dc=foo,dc=bar, authentication fails (LDAP user sync lists the user though)
If I set base bind dn to ou=ICT,ou=authorized,dc=foo,dc=bar, authentication works ....
That looks like a bug to me - if sync (which does an LDAP search) nicely lists all users of the sub-OUs, authentication should also work for a user in one of those sub-OUs.

Reproduction steps

  1. Create an ou (e.g. authorized) with a sub-OU (e.g. ICT)
  2. Enter a user in that sub-OU
  3. Set LDAP base bind DN to the top OU
  4. Test LDAP sync (should work)
  5. Test LDAP user authentication -> fails
  6. Set LDAP base bind DN to the sub-OU
  7. Test LDAP user authentication -> works

Expected behavior

authentication should also work for any user in a sub-OUs of the base bind DN (regardless of the number of levels below that OU)

Screenshots

No response

Snipe-IT Version

v6.0.14 build 9038

Operating System

Ubuntu

Web Server

apache

PHP Version

8.4.33

Operating System

No response

Browser

No response

Version

No response

Device

No response

Operating System

No response

Browser

No response

Version

No response

Error messages

No response

Additional context

No response

@welcome
Copy link

welcome bot commented Jan 10, 2023

👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

@nsty
Copy link

nsty commented Jan 11, 2023

This doesn't sound like a bug to me. Typically a freshly created user is not allowed to log in if I remember right. The user either needs to be marked manually with login enabled or using an LDAP flag. The LDAP Active Flag might be configured wrong in your settings. You can check the /users page to see if login is actually enabled for each user.
If this is not the problem, I think you should name the LDAP server you are using. Might also be a server setting.

@dvdp
Copy link
Author

dvdp commented Jan 11, 2023 via email

@nsty
Copy link

nsty commented Jan 11, 2023

You are right. I can just tell you that it's working for me. We use several levels of OUs and nested group filters. I also tested with a new user on our AD (regarding #12296 ). But I just noticed, we are still on 6.0.13 on production because of #12288 . Might be all the same issue with the default LDAP group introduced in 6.0.14.

@dvdp
Copy link
Author

dvdp commented Jan 22, 2023

Well, I found this in App/Models/Ldap.php on line 98:
$userDn = $ldap_username_field.'='.$username.','.$settings->ldap_basedn;
I guess that explains - that restricts things to users only in the base DN

Imho the better option is to first search the user in the base dn and then grab the user dn from the search result

@dvdp
Copy link
Author

dvdp commented Jan 22, 2023

... so this is my workaround - added this after line 118 $filterQuery = "({$filter}({$filterQuery}))";
(so basically use the filter to search for the user first and then get the user dn from the search result)

$res = ldap_search($connection, $baseDn, $filterQuery);
$first = ldap_first_entry($connection, $res);
$userDn = ldap_get_dn($connection, $first);

@xuanfm
Copy link

xuanfm commented Feb 6, 2023

i think you should downgrade your php version.youd better dont use more then 8.1(include),my php 8.1 down to 8.0 it works

@dvdp
Copy link
Author

dvdp commented Feb 6, 2023

If you analyze what I changed to fix things you'll see that this is very unrelated to the php version. Just go through the details of my findings, you'll see that things depend on how you have setup LDAP in terms of OUs. Bottom line: if your user dn does not reflect a dn in the base OU, authentication fails but user sync still works because of the search filter.
Grabbing the correct user DN using a search first fixes that (= my fix)
(for the record: to make the code work for both LDAP and AD, those lines should be inserted a little bit higher then I mentioned, just before the line " if ($settings->is_ad == '1') {" )
My guess is that either your users are in the base DN and not in some sub-OU of it or you have an earlier Snipe-IT version which doesn't have this problem (at least that is what I'm told).

@sangdrax8
Copy link

This explains exactly what I have experienced on the latest version. I was able to set the base DN to match where my users are, since this currently works for my structure. However that is just luck, there isn't any requirement that this would have been true.

@Miguel23-06
Copy link

... so this is my workaround - added this after line 118 $filterQuery = "({$filter}({$filterQuery}))"; (so basically use the filter to search for the user first and then get the user dn from the search result)

$res = ldap_search($connection, $baseDn, $filterQuery); $first = ldap_first_entry($connection, $res); $userDn = ldap_get_dn($connection, $first);

Friend, thank you very much, I had been trying to solve this for days.

@dhumpf
Copy link

dhumpf commented Jun 21, 2023

Same issue here, I changed the workaround a little bit:
I moved lines 143-153 to line 122 in app/Models/Ldap.php,
then added another if statement to get the userDn.

So now it's really findAndBindUserLdap as the Function name suggests.

Lines 122-138 look like that block:

    if (! $results = ldap_search($connection, $baseDn, $filterQuery)) {
        throw new Exception('Could not search LDAP: ');
    }

    if (! $entry = ldap_first_entry($connection, $results)) {
        return false;
    }

    if (! $userDn = ldap_get_dn($connection, $entry)) {
        return false;
    }

    if (! $user = ldap_get_attributes($connection, $entry)) {
        return false;
    }

    if (! $ldapbind = @ldap_bind($connection, $userDn, $password)) { ....

Edit: Maybe solved within the following issue #9903 ?

P-EB added a commit to P-EB/snipe-it that referenced this issue Nov 29, 2023
Currently, snipe-it relies on a manually crafted user DN to bind a user
and therefore check if they exist, and *then*, it searches in LDAP if
the user is found when applying the filter.

This works nicely when the base_dn is "fixed". In a company with
multiple business lines or business units, though, there might be more
than one OU for LDAP users, and in that case, crafting the DN manually
might fail.

This patch aims at crafting the userDn from a ldap_search, assuming the
user field is unique. If more than 1 user is found, the user field is
not unique and the login method will throw.

This increases significantly the LDAP login flexibility.

Fixes snipe#12331
@P-EB P-EB linked a pull request Nov 29, 2023 that will close this issue
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants