From 27e134f5131d49b9399bceff3eaf8b18d1023e03 Mon Sep 17 00:00:00 2001 From: Naksen Date: Fri, 19 Dec 2025 09:49:50 +0300 Subject: [PATCH 1/2] fix: improve error handling in Kerberos structure management --- app/ldap_protocol/kerberos/ldap_structure.py | 24 ++++++++++---------- app/ldap_protocol/ldap_requests/add.py | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/ldap_protocol/kerberos/ldap_structure.py b/app/ldap_protocol/kerberos/ldap_structure.py index cba89fe39..45228a3c8 100644 --- a/app/ldap_protocol/kerberos/ldap_structure.py +++ b/app/ldap_protocol/kerberos/ldap_structure.py @@ -57,20 +57,20 @@ async def create_kerberos_structure( :return None. """ async with self._session.begin_nested(): - results = ( - await anext(services.handle(ctx)), - await anext(group.handle(ctx)), - await anext(krb_user.handle(ctx)), - ) - await self._session.flush() + service_result = await anext(services.handle(ctx)) + if service_result.result_code != 0: + raise KerberosConflictError("Service error") - if not all(result.result_code == 0 for result in results): - await self._session.rollback() - raise KerberosConflictError( - "Error creating Kerberos structure in directory", - ) + async with self._session.begin_nested(): + group_result = await anext(group.handle(ctx)) + if group_result.result_code != 0: + raise KerberosConflictError("Group error") + + async with self._session.begin_nested(): await self._role_use_case.create_kerberos_system_role() - await self._session.commit() + user_result = await anext(krb_user.handle(ctx)) + if user_result.result_code != 0: + raise KerberosConflictError("User error") async def rollback_kerberos_structure( self, diff --git a/app/ldap_protocol/ldap_requests/add.py b/app/ldap_protocol/ldap_requests/add.py index 4e15bc75d..f48051e13 100644 --- a/app/ldap_protocol/ldap_requests/add.py +++ b/app/ldap_protocol/ldap_requests/add.py @@ -413,7 +413,7 @@ async def handle( # noqa: C901 parent_directory=parent, directory=new_dir, ) - await ctx.session.flush() + await ctx.session.commit() except IntegrityError: await ctx.session.rollback() yield AddResponse(result_code=LDAPCodes.ENTRY_ALREADY_EXISTS) From ddc72979ff94c6b56ab0ddaa19b5815bc87ffdda Mon Sep 17 00:00:00 2001 From: Naksen Date: Wed, 24 Dec 2025 15:10:52 +0300 Subject: [PATCH 2/2] fix: hotfix LDAP Search --- app/ldap_protocol/filter_interpreter.py | 9 +++++++++ app/ldap_protocol/ldap_requests/search.py | 22 +++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/app/ldap_protocol/filter_interpreter.py b/app/ldap_protocol/filter_interpreter.py index f7cc36f7f..c456fac00 100644 --- a/app/ldap_protocol/filter_interpreter.py +++ b/app/ldap_protocol/filter_interpreter.py @@ -31,6 +31,7 @@ User, ) from ldap_protocol.utils.helpers import ft_to_dt +from ldap_protocol.utils.queries import get_path_filter, get_search_path from repo.pg.tables import groups_table, queryable_attr as qa, users_table from .asn1parser import ASN1Row, TagNumbers @@ -398,6 +399,14 @@ def _cast_item(self, item: ASN1Row) -> UnaryExpression | ColumnElement: # noqa: is_substring = item.tag_id == TagNumbers.SUBSTRING + if attr == "distinguishedname" and not is_substring: + try: + dn_search_path = get_search_path(right.value) + except Exception: # noqa: S110 + pass + else: + return get_path_filter(dn_search_path) + if attr == "anr": if is_substring: expr = right.value[0] diff --git a/app/ldap_protocol/ldap_requests/search.py b/app/ldap_protocol/ldap_requests/search.py index 9bcf9edb9..7aff84a58 100644 --- a/app/ldap_protocol/ldap_requests/search.py +++ b/app/ldap_protocol/ldap_requests/search.py @@ -153,6 +153,10 @@ def is_sid_requested(self) -> bool: def is_guid_requested(self) -> bool: return self.all_attrs or "objectguid" in self.requested_attrs + @property + def is_objectclass_requested(self) -> bool: + return self.all_attrs or "objectclass" in self.requested_attrs + @cached_property def all_attrs(self) -> bool: return "*" in self.requested_attrs or not self.requested_attrs @@ -417,11 +421,16 @@ def _mutate_query_with_attributes_to_load( if attr not in _ATTRS_TO_CLEAN } + cond = or_( + func.lower(Attribute.name).in_(attrs), + func.lower(Attribute.name) == "objectclass", + ) + return query.options( selectinload(qa(Directory.attributes)), with_loader_criteria( Attribute, - func.lower(Attribute.name).in_(attrs), + cond, ), ) @@ -534,7 +543,7 @@ async def _fill_attrs( attrs: dict[str, list[str]], session: AsyncSession, ) -> None: - if "distinguishedname" not in self.requested_attrs or self.all_attrs: + if "distinguishedname" in self.requested_attrs or self.all_attrs: attrs["distinguishedName"].append(distinguished_name) if "whenCreated" in self.requested_attrs or self.all_attrs: @@ -572,10 +581,6 @@ async def _fill_attrs( attrs["memberOf"].append(group.directory.path_dn) if self.token_groups and "user" in obj_classes: - attrs["tokenGroups"].append( - str(string_to_sid(directory.object_sid)), - ) - group_directories = await get_all_parent_group_directories( directory.groups, session, @@ -584,7 +589,7 @@ async def _fill_attrs( if group_directories is not None: async for directory_ in group_directories: attrs["tokenGroups"].append( - str(string_to_sid(directory_.object_sid)), + string_to_sid(directory_.object_sid), # type: ignore ) if self.member and "group" in obj_classes and directory.group: @@ -638,6 +643,9 @@ async def tree_view( # noqa: C901 if attr.name.lower() == "objectclass": obj_classes.append(value) + if self.is_objectclass_requested: + attrs[attr.name].append(value) + continue attrs[attr.name].append(value)