Skip to content
Snippets Groups Projects
Commit 5872cfae authored by Julian Rother's avatar Julian Rother
Browse files

User BIND permission and rate limit error handling

API permissions errors on BIND (i.e. lack of scope "checkpassword") are now
reported as insufficientAccessRights (50) and rate limit errors as
unwillingToPerform (53). Previously other (80) was used in both cases, which
confused some clients (Nextcloud to be precise).
parent becac489
Branches catch-checkpassword
Tags
No related merge requests found
......@@ -11,7 +11,7 @@ from cachecontrol import CacheControl
from cachecontrol.heuristics import ExpiresAfter
import ldapserver
from ldapserver.exceptions import LDAPInvalidCredentials
from ldapserver.exceptions import LDAPInvalidCredentials, LDAPInsufficientAccessRights, LDAPUnwillingToPerform
from ldapserver.schema import RFC2307BIS_SCHEMA, RFC2798_SCHEMA
logger = logging.getLogger(__name__)
......@@ -96,8 +96,15 @@ class UffdLDAPRequestHandler(ldapserver.LDAPRequestHandler):
return True
if not dn.is_direct_child_of(self.subschema.DN('ou=users') + self.dn_base) or len(dn[0]) != 1 or dn[0][0].attribute != 'uid':
raise LDAPInvalidCredentials()
try:
if self.api.check_password(loginname=dn[0][0].value, password=password):
return True
except requests.exceptions.HTTPError as exc:
if exc.response.status_code == 403: # We don't have "checkpassword" scope
raise LDAPInsufficientAccessRights() from exc
if exc.response.status_code == 429: # Ratelimited
raise LDAPUnwillingToPerform('Too Many Requests') from exc
raise exc
raise LDAPInvalidCredentials()
supports_sasl_plain = True
......@@ -105,10 +112,16 @@ class UffdLDAPRequestHandler(ldapserver.LDAPRequestHandler):
def do_bind_sasl_plain(self, identity, password, authzid=None):
if authzid is not None and identity != authzid:
raise LDAPInvalidCredentials()
user = self.api.check_password(loginname=identity, password=password)
if user is None:
try:
if self.api.check_password(loginname=identity, password=password):
return True
except requests.exceptions.HTTPError as exc:
if exc.response.status_code == 403: # We don't have "checkpassword" scope
raise LDAPInsufficientAccessRights() from exc
if exc.response.status_code == 429: # Ratelimited
raise LDAPUnwillingToPerform('Too Many Requests') from exc
raise exc
raise LDAPInvalidCredentials()
return user
def do_search(self, baseobj, scope, filterobj):
yield from super().do_search(baseobj, scope, filterobj)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment