-
Notifications
You must be signed in to change notification settings - Fork 671
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
Fix LDAP binding strategies #1149
Merged
Merged
Conversation
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
Instantiate two LDAP servers, one that allows anonymous access, and one that requires authentication for all operations. The JUnit test is parameterized to run all tests with both instances. It uses different settings for each mode.
Add access restrictions to the LDAP test server instances. New modes used a test parameters are ANONYMOUS, DS_MANAGER and USR_MANAGER. ANONYMOUS can bind anonymously and access users and groups. In DS_MANAGER the server requires authentication and will only allow the DIRECTORY_MANAGER user to search for users and groups. In USR_MANAGER only the user can search groups, the USER_MANAGER, which is used to bind in this mode, can not. A third server instance is created because I did fear side effects should the tests be run in parallel, had I tried to configure the access restriction in Before.
…cenarios. Gitblit allows in its configuration to set a "manager" user (and password) which can be used to search for the entry of a user wanting to log in. If they are both not set, an anonymous search is attempted. In the description below, when I say "...as manager", it is either as manager or anonymous. So far the behaviour of Gitblit, with respect to binding to and searching in LDAP, has been the following when a user logs in: **bind as manager** **search for the user** _bind as the user_ _search for the teams_ I'll call this code flow A. Later an additional configuration option had been added: `realm.ldap.bindpattern`. (PR gitblit-org#162) It was meant to allow for not using a manager nor anonymous binds, by searching the directory as the user logging in. This is done in code flow B: **bind as manager** _bind as user_ _search for user_ _search for teams_ Both A and B are flawed, I think. In A, it looks like a mistake to me that the binding stays with the user after authentication. The problem that this causes is, that in LDAP server configurations where normal users are not allowed to read groups, the team information cannot be retrieved. I tried but failed to understand how B is supposed to work. There will always be a bind request as either anonymous or the manager DN when the LDAP connection is created. If neither is possible, the authentication process will fail and the user cannot log in. When synchronizing users and teams from LDAP, the following code flow is exercised: F: **bind as manager** **search for users** **search for teams** This patch fixes both code flows by introducing a new flow. C: **bind as manager** **search for user** _bind as user to authenticate_ **bind as manager** **search for teams** And it changes code flow B to the following code flow D: _bind as user_ _search for user_ _search for teams_ With code flows A, C, D and F the following usage (and authentication) scenarios are covered. They are described from the view of a Gitblit administrator's intent and his LDAP setup. * Users and team should be snychronized with LDAP This means anonymous or a fixed account must be able to read users and groups. => covered by C and F As the above allows for authentication and is required for synchronisation, all the others below do not cover synchronization. * No anonymous binding allowed and no special manager binding required This means that users must be able to read user an group entries. => covered by D * The user DN needs to be searched, e.g. because they are not all under the same parent DN. This means that anonymous or a fixed account must be able to read users. -- anonymous or the "manager" account can also read groups => covered by C -- anonymous or the "manager" account cannot read groups but a user can => covered by A I therefore believe that the new code will cover all common use cases. The implementation either directly binds as the user, when `bindpattern` is not empty, or it binds anonymous or against the manger DN to search for the user DN entry. If it directly bound against the user DN, the user is already authenticated. It will then only check that the user DN it found in the search is identical to the one it is currently bound against. If it was bound against a manager DN (or anonymously) it will bind against the found user DN to authenticate the user logging in, and will then rebind against the manager DN. When searching for groups in LDAP, if the search fails with a result code other than SUCCESS, the implementation will bind against the user DN, if it isn't already bound against it. It will then repeat the search for groups under the user authorization. This is to keep backwards compatible with the original behaviour A, in order to not break cases where the LDAP setup would deny a manager account to search for groups but allow it for normal users. To achieve this the implementation introduces an internal `LdapConnection` class that wraps the connection and keeps bind state, so that a rebind as a user is possible. This also fixes a resource leak where the connection was not closed in case that the initial bind as the manager account did not succeed. This commit would fix gitblit-org#920
Extend the comments for some realm.ldap.* properties to better explain use cases and requirements.
Sweet! Nice job. |
Awesome. We'll have to check this out. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cleaning up the LDAP binding to support clearly defined strategies.
For synchronization, as before, anonymous or a manager account is used.
The default would be to use anonymous or a manager account to search for the user logging in, binding as the user to authenticate her, and then rebind to the previous authorization to search for groups.
To keep backward compatible to the original implementation, if the anonymous/manager bind cannot search teams, a rebind to the user is carried out to search teams under the user authorization.
The option to directly bind and search as the user has been changed to never attempt to bind anonymous or as a manager account if
realm.ldap.bindpattern
is set.This fixes #920 as well as #247.