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

Fix duplicated bind operation, only one is needed #270

Merged
merged 5 commits into from
Sep 19, 2024

Conversation

consideRatio
Copy link
Member

@consideRatio consideRatio commented Sep 17, 2024


To bind is to authenticate as a user against the user, where the user is specified by a DN (Distinguished Name). This operation can prompt inputting one time passwords on a mobile device etc, so its relevant to not do twice in a row.

When we create the connection object, we automatically bind as part of doing so in all cases. Due to that, its not relevant to first acquire the connection and then do conn.bind().

In this PR you'll see how I move logic to get_connection and letting it handle raised errors failing on failing to bind by emitting a warning and returning None. Using get_connection can then be reduced to calling it and checking the return value. Any connectivity or encryption issues will still be raised and not handled by get_connection.

Either we would have bound the connection thanks to auto_bind, or we
would have had an unhandled error. Due to this, we can remove this.
Comment on lines 338 to 339
if not conn.bind():
self.log.warning(
f"Failed to connect to LDAP server with search user '{self.lookup_dn_search_user}'"
)
if not conn:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is right after calling get_connection, which always does a bind operation because we have auto_bind set to a value making it so. This makes the if not conn.bind() too much and it should at most be checking conn.bound property.

This PR updated the get_connection to return none and log a warning if the bind operation failed though, so we now just check if conn is set truthy or not going onwards here.

Comment on lines -488 to -489
if not is_bound:
self.log.warning(f"Invalid password for user '{username}'")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning about incorrect password wasn't always correct. It could say incorrect password even though it failed to bind for another reason, such as not finding a user with the userdn or similar.

I think there have been several issues about invalid password that really wasn't about invalid password, but about failing to bind because the user didn't exist - because the get_connection was passed a userdn that wasn't constructed correctly etc.

self.log.debug(msg)
if is_bound:
conn = self.get_connection(userdn, password)
if conn:
break
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic moved to get_connection, but no longer including logging details about the specific username (but still includes the userdn which should be sufficient).

@minrk
Copy link
Member

minrk commented Sep 19, 2024

Thanks! Go ahead and merge

@consideRatio consideRatio merged commit cd95248 into jupyterhub:main Sep 19, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bind operation happens twice which can lead to 2 multi-factor authentication pushes to users.
2 participants