Commit 35d6fb7 TESTS: Add an integration test for renaming incomplete groups during initgroups

1 file Authored by jhrozek 4 months ago , Committed by fidencio 4 months ago ,
TESTS: Add an integration test for renaming incomplete groups during initgroups

As we implemented the group renaming heuristics to rename only if we can
use another "hint" like the original DN or the SID to know the group is
the same, this patch adds two tests (positive and negative) to make sure
a group with a totally different RDN and hence different originalDN
cannot be renamed but a group whose name changed but the RDN stays the
same can be renamed.

Related:
https://pagure.io/SSSD/sssd/issue/3282

Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>

    
  1 @@ -94,10 +94,11 @@
  2       request.addfinalizer(lambda: cleanup_ldap_entries(ldap_conn, ent_list))
  3   
  4   
  5 - def create_ldap_fixture(request, ldap_conn, ent_list=None):
  6 + def create_ldap_fixture(request, ldap_conn, ent_list=None, cleanup=True):
  7       """Add LDAP entries and add teardown for removing them"""
  8       create_ldap_entries(ldap_conn, ent_list)
  9 -     create_ldap_cleanup(request, ldap_conn, ent_list)
 10 +     if cleanup:
 11 +         create_ldap_cleanup(request, ldap_conn, ent_list)
 12   
 13   
 14   SCHEMA_RFC2307 = "rfc2307"
 15 @@ -1437,3 +1438,147 @@
 16               ", ".join(["%s" % s for s in sorted(gids)]),
 17               ", ".join(["%s" % s for s in sorted(user1_expected_gids)])
 18           )
 19 + 
 20 + 
 21 + def rename_setup_no_cleanup(request, ldap_conn, cleanup_ent=None):
 22 +     ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
 23 +     ent_list.add_user("user1", 1001, 2001)
 24 +     ent_list.add_group_bis("user1_private", 2001)
 25 + 
 26 +     ent_list.add_user("user2", 1002, 2002)
 27 +     ent_list.add_group_bis("user2_private", 2002)
 28 + 
 29 +     ent_list.add_group_bis("group1", 2015, ["user1", "user2"])
 30 + 
 31 +     if cleanup_ent is None:
 32 +         create_ldap_fixture(request, ldap_conn, ent_list)
 33 +     else:
 34 +         # Since the entries were renamed, we need to clean up
 35 +         # the renamed entries..
 36 +         create_ldap_fixture(request, ldap_conn, ent_list, cleanup=False)
 37 +         create_ldap_cleanup(request, ldap_conn, None)
 38 + 
 39 + 
 40 + @pytest.fixture
 41 + def rename_setup_cleanup(request, ldap_conn):
 42 +     cleanup_ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
 43 +     cleanup_ent_list.add_user("user1", 1001, 2001)
 44 +     cleanup_ent_list.add_group_bis("new_user1_private", 2001)
 45 + 
 46 +     cleanup_ent_list.add_user("user2", 1002, 2002)
 47 +     cleanup_ent_list.add_group_bis("new_user2_private", 2002)
 48 + 
 49 +     cleanup_ent_list.add_group_bis("new_group1", 2015, ["user1", "user2"])
 50 + 
 51 +     rename_setup_no_cleanup(request, ldap_conn, cleanup_ent_list)
 52 + 
 53 +     conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS)
 54 +     create_conf_fixture(request, conf)
 55 +     create_sssd_fixture(request)
 56 +     return None
 57 + 
 58 + 
 59 + @pytest.fixture
 60 + def rename_setup_with_name(request, ldap_conn):
 61 +     rename_setup_no_cleanup(request, ldap_conn)
 62 + 
 63 +     conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
 64 +         unindent("""
 65 +             [nss]
 66 +             [domain/LDAP]
 67 +             ldap_group_name                = name
 68 +             timeout = 3000
 69 +         """).format(**locals())
 70 +     create_conf_fixture(request, conf)
 71 +     create_sssd_fixture(request)
 72 +     return None
 73 + 
 74 + 
 75 + def test_rename_incomplete_group_same_dn(ldap_conn, rename_setup_with_name):
 76 +     """
 77 +     Test that if a group's name attribute changes, but the DN stays the same,
 78 +     the incomplete group object will be renamed.
 79 + 
 80 +     Because the RDN attribute must be present in the entry, we add another
 81 +     attribute "name" that is purposefully different from the CN and make
 82 +     sure the group names are reflected in name
 83 + 
 84 +     Regression test for https://pagure.io/SSSD/sssd/issue/3282
 85 +     """
 86 +     pvt_dn1 = 'cn=user1_private,ou=Groups,' + ldap_conn.ds_inst.base_dn
 87 +     pvt_dn2 = 'cn=user2_private,ou=Groups,' + ldap_conn.ds_inst.base_dn
 88 +     group1_dn = 'cn=group1,ou=Groups,' + ldap_conn.ds_inst.base_dn
 89 + 
 90 +     # Add the name we want for both private and secondary group
 91 +     old = {'name': []}
 92 +     new = {'name': [b"user1_group1"]}
 93 +     ldif = ldap.modlist.modifyModlist(old, new)
 94 +     ldap_conn.modify_s(group1_dn, ldif)
 95 + 
 96 +     new = {'name': [b"pvt_user1"]}
 97 +     ldif = ldap.modlist.modifyModlist(old, new)
 98 +     ldap_conn.modify_s(pvt_dn1, ldif)
 99 + 
100 +     new = {'name': [b"pvt_user2"]}
101 +     ldif = ldap.modlist.modifyModlist(old, new)
102 +     ldap_conn.modify_s(pvt_dn2, ldif)
103 + 
104 +     # Make sure the old name shows up in the id output
105 +     (res, errno, grp_list) = sssd_id.get_user_groups("user1")
106 +     assert res == sssd_id.NssReturnCode.SUCCESS, \
107 +         "Could not find groups for user1, %d" % errno
108 + 
109 +     assert sorted(grp_list) == sorted(["pvt_user1", "user1_group1"])
110 + 
111 +     # Rename the group by changing the cn attribute, but keep the DN the same
112 +     old = {'name': [b"user1_group1"]}
113 +     new = {'name': [b"new_user1_group1"]}
114 +     ldif = ldap.modlist.modifyModlist(old, new)
115 +     ldap_conn.modify_s(group1_dn, ldif)
116 + 
117 +     (res, errno, grp_list) = sssd_id.get_user_groups("user2")
118 +     assert res == sssd_id.NssReturnCode.SUCCESS, \
119 +         "Could not find groups for user2, %d" % errno
120 + 
121 +     assert sorted(grp_list) == sorted(["pvt_user2", "new_user1_group1"])
122 + 
123 +     (res, errno, grp_list) = sssd_id.get_user_groups("user1")
124 +     assert res == sssd_id.NssReturnCode.SUCCESS, \
125 +         "Could not find groups for user1, %d" % errno
126 + 
127 +     assert sorted(grp_list) == sorted(["pvt_user1", "new_user1_group1"])
128 + 
129 + 
130 + def test_rename_incomplete_group_rdn_changed(ldap_conn, rename_setup_cleanup):
131 +     """
132 +     Test that if a group's name attribute changes, and the DN changes with
133 +     the RDN. Then adding the second group will fail because we can't tell if
134 +     there are two duplicate groups in LDAP when saving the group or if the
135 +     group was renamed.
136 + 
137 +     Please note that with many directories (AD, IPA), the code can rely on
138 +     other heuristics (SID, UUID) to find out the group is in fact the same.
139 + 
140 +     Regression test for https://pagure.io/SSSD/sssd/issue/3282
141 +     """
142 +     pvt_dn = 'cn=user1_private,ou=Groups,' + ldap_conn.ds_inst.base_dn
143 +     group1_dn = 'cn=group1,ou=Groups,' + ldap_conn.ds_inst.base_dn
144 + 
145 +     # Make sure the old name shows up in the id output
146 +     (res, errno, grp_list) = sssd_id.get_user_groups("user1")
147 +     assert res == sssd_id.NssReturnCode.SUCCESS, \
148 +         "Could not find groups for user1, %d" % errno
149 + 
150 +     assert sorted(grp_list) == sorted(["user1_private", "group1"])
151 + 
152 +     # Rename the groups, changing the RDN
153 +     ldap_conn.rename_s(group1_dn, "cn=new_group1")
154 +     ldap_conn.rename_s(pvt_dn, "cn=new_user1_private")
155 + 
156 +     (res, errno, grp_list) = sssd_id.get_user_groups("user2")
157 +     assert res == sssd_id.NssReturnCode.SUCCESS, \
158 +         "Could not find groups for user2, %d" % errno
159 + 
160 +     # The initgroups succeeds, but because saving the new group fails,
161 +     # SSSD will revert to the cache contents and return what's in the cache
162 +     assert sorted(grp_list) == sorted(["user2_private", "group1"])