LDAP group membership changes not reflected in Netbox #697

Closed
opened 2025-12-29 16:24:54 +01:00 by adam · 4 comments
Owner

Originally created by @martink2 on GitHub (Feb 7, 2017).

We are using LDAP for authentication
and authorization in Netbox with the
following relevant config parts:

AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    "is_active": "CN=CP_CONV_NETBOX_USE,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx",
    "is_staff": "CN=CP_CONV_NETBOX_OWN,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx",
    "is_superuser": "CN=CP_CONV_NETBOX_OWN,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx"
}

When a member of group CP_CONV_NETBOX_OWN logs in he gets the staff and superuser
flags set correctly. If the user is later removed from the CP_CONV_NETBOX_OWN group
and is only a member of CP_CONV_NETBOX_USE his staff and superuser status is not
removed from Netbox.

Not sure if this is intended behaviour but we were assuming user permissions on
LDAP users can be revoked as well.

Thanks for any advise on the topic.

Originally created by @martink2 on GitHub (Feb 7, 2017). We are using LDAP for authentication and authorization in Netbox with the following relevant config parts: ``` AUTH_LDAP_USER_FLAGS_BY_GROUP = { "is_active": "CN=CP_CONV_NETBOX_USE,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx", "is_staff": "CN=CP_CONV_NETBOX_OWN,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx", "is_superuser": "CN=CP_CONV_NETBOX_OWN,OU=Permissions,OU=xxx,DC=ad,DC=global,DC=cloud,DC=xxx" } ``` When a member of group CP_CONV_NETBOX_OWN logs in he gets the staff and superuser flags set correctly. If the user is later removed from the CP_CONV_NETBOX_OWN group and is only a member of CP_CONV_NETBOX_USE his staff and superuser status is not removed from Netbox. Not sure if this is intended behaviour but we were assuming user permissions on LDAP users can be revoked as well. Thanks for any advise on the topic.
adam closed this issue 2025-12-29 16:24:54 +01:00
Author
Owner

@specialcircumstances commented on GitHub (Feb 14, 2017):

Could it be related to the AUTH_LDAP_MIRROR_GROUPS setting?

AUTH_LDAP_MIRROR_GROUPS

Default: False

If True, LDAPBackend will mirror a user’s LDAP group membership in the Django database. Any time a user authenticates, we will create all of his LDAP groups as Django groups and update his Django group membership to exactly match his LDAP group membership. If the LDAP server has nested groups, the Django database will end up with a flattened representation.

[https://pythonhosted.org/django-auth-ldap/reference.html#std:setting-AUTH_LDAP_MIRROR_GROUPS]

[(https://pythonhosted.org/django-auth-ldap/permissions.html)]

@specialcircumstances commented on GitHub (Feb 14, 2017): Could it be related to the AUTH_LDAP_MIRROR_GROUPS setting? AUTH_LDAP_MIRROR_GROUPS Default: False If True, LDAPBackend will mirror a user’s LDAP group membership in the Django database. Any time a user authenticates, we will create all of his LDAP groups as Django groups and update his Django group membership to exactly match his LDAP group membership. If the LDAP server has nested groups, the Django database will end up with a flattened representation. [https://pythonhosted.org/django-auth-ldap/reference.html#std:setting-AUTH_LDAP_MIRROR_GROUPS] [(https://pythonhosted.org/django-auth-ldap/permissions.html)]
Author
Owner

@martink2 commented on GitHub (Feb 15, 2017):

Hi,

as far as i can see AUTH_LDAP_MIRROR_GROUPS does behave like expected
and mirrors the membership status.

The AUTH_LDAP_USER_FLAGS_BY_GROUP however seem to remain with a user
even if he is later on removed from the group that has given him the flag.

User Login -> Member CP_CONV_NETBOX_OWN -> is SuperUser -> logout -> Remove from CP_CONV_NETBOX_OWN -> login -> still SuperUser.

@martink2 commented on GitHub (Feb 15, 2017): Hi, as far as i can see AUTH_LDAP_MIRROR_GROUPS does behave like expected and mirrors the membership status. The AUTH_LDAP_USER_FLAGS_BY_GROUP however seem to remain with a user even if he is later on removed from the group that has given him the flag. User Login -> Member CP_CONV_NETBOX_OWN -> is SuperUser -> logout -> Remove from CP_CONV_NETBOX_OWN -> login -> still SuperUser.
Author
Owner

@specialcircumstances commented on GitHub (Feb 15, 2017):

I'm far from an expert here, but I had a look through the ldap module code [here]https://bitbucket.org/psagers/django-auth-ldap

The mirror groups function does a compare:

        target_group_names = frozenset(self._get_groups().get_group_names())
        current_group_names = frozenset(self._user.groups.values_list('name', flat=True).iterator())

        if target_group_names != current_group_names:

whereas the AUTH_LDAP_PROFILE_FLAGS_BY_GROUP looks like this:

    def _populate_user_from_group_memberships(self):
        for field, group_dns in self.settings.USER_FLAGS_BY_GROUP.items():
            if isinstance(group_dns, basestring):
                group_dns = [group_dns]
            value = any(self._get_groups().is_member_of(dn) for dn in group_dns)
            setattr(self._user, field, value)

but I think that should work. My understanding it it's steps through the mapped groups in AUTH_USERS_LDAP_FLAGS_BY_GROUP and checks if the mapped LDAP group is present, if there's a match then value = 1, otherwise value = 0

I guess therefore, it's not getting called... working backwards from there....

Can you try setting the following to force the populate and avoid any caching... (although these should be defaults as I understand it)

AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_CACHE_GROUPS = False

Should note this isn't likely to be a Netbox issue, it's more a django-auth-ldap issue, so if we get nowhere it might be worth checking with the author https://bitbucket.org/psagers/

@specialcircumstances commented on GitHub (Feb 15, 2017): I'm far from an expert here, but I had a look through the ldap module code [here]https://bitbucket.org/psagers/django-auth-ldap The mirror groups function does a compare: ``` target_group_names = frozenset(self._get_groups().get_group_names()) current_group_names = frozenset(self._user.groups.values_list('name', flat=True).iterator()) if target_group_names != current_group_names: ``` whereas the AUTH_LDAP_PROFILE_FLAGS_BY_GROUP looks like this: ``` def _populate_user_from_group_memberships(self): for field, group_dns in self.settings.USER_FLAGS_BY_GROUP.items(): if isinstance(group_dns, basestring): group_dns = [group_dns] value = any(self._get_groups().is_member_of(dn) for dn in group_dns) setattr(self._user, field, value) ``` but I think that should work. My understanding it it's steps through the mapped groups in AUTH_USERS_LDAP_FLAGS_BY_GROUP and checks if the mapped LDAP group is present, if there's a match then value = 1, otherwise value = 0 I guess therefore, it's not getting called... working backwards from there.... Can you try setting the following to force the populate and avoid any caching... (although these should be defaults as I understand it) AUTH_LDAP_ALWAYS_UPDATE_USER = True AUTH_LDAP_CACHE_GROUPS = False Should note this isn't likely to be a Netbox issue, it's more a django-auth-ldap issue, so if we get nowhere it might be worth checking with the author https://bitbucket.org/psagers/
Author
Owner

@jeremystretch commented on GitHub (Mar 30, 2017):

Going to close this out as there doesn't seem to be anything actionable from the dev side.

@jeremystretch commented on GitHub (Mar 30, 2017): Going to close this out as there doesn't seem to be anything actionable from the dev side.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#697