diff options
| author | Rob van der Linde <rob@catalyst.net.nz> | 2023-05-17 23:35:16 +1200 |
|---|---|---|
| committer | Andrew Bartlett <abartlet@samba.org> | 2023-06-25 23:29:32 +0000 |
| commit | 8311284224539710b89ae4557951f132620c8553 (patch) | |
| tree | 324d28f633fc2380039494707c28c57dbf32c1bf /python | |
| parent | 705e65c16e85da6117d224c7ec26adcdedce83b9 (diff) | |
| download | samba-8311284224539710b89ae4557951f132620c8553.tar.gz samba-8311284224539710b89ae4557951f132620c8553.tar.bz2 samba-8311284224539710b89ae4557951f132620c8553.zip | |
netcmd: domain: silo member add and remove does not write whole list
Writing the whole list at once can lead to data loss if multiple
administrators are doing this at the same time.
Signed-off-by: Rob van der Linde <rob@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Diffstat (limited to 'python')
| -rw-r--r-- | python/samba/netcmd/domain/auth/silo_member.py | 29 | ||||
| -rw-r--r-- | python/samba/netcmd/domain/models/auth_silo.py | 42 |
2 files changed, 49 insertions, 22 deletions
diff --git a/python/samba/netcmd/domain/auth/silo_member.py b/python/samba/netcmd/domain/auth/silo_member.py index 5ec55a1ddc7..981904b948f 100644 --- a/python/samba/netcmd/domain/auth/silo_member.py +++ b/python/samba/netcmd/domain/auth/silo_member.py @@ -72,23 +72,12 @@ class cmd_domain_auth_silo_member_add(Command): if user is None: raise CommandError(f"User '{member}' not found.") - # Check if user isn't already assigned to another silo. - if user.assigned_silo: - assigned_silo = AuthenticationSilo.get(ldb, dn=user.assigned_silo) - raise CommandError( - f"Member '{member}' is already in the {assigned_silo} silo.") - - # Check if the user isn't already in this silo. - if user.dn in silo.members: - raise CommandError( - f"Member '{member}' is already in the {name} silo.") - - # Add user dn to silo members and set the assigned silo. - silo.members.append(user.dn) + # Set the assigned silo. user.assigned_silo = silo.dn + # Add member and save user. try: - silo.save(ldb) + silo.add_member(ldb, user) user.save(ldb) except LdbError as e: raise CommandError(e) @@ -186,16 +175,12 @@ class cmd_domain_auth_silo_member_remove(Command): if user is None: raise CommandError(f"User '{member}' not found.") - # Make sure member is in the silo before removing them. - # Also unset the assigned silo on the User object. - if user.dn in silo.members: - silo.members.remove(user.dn) - user.assigned_silo = None - else: - raise CommandError(f"User '{member}' is not in the {name} silo.") + # Unset the assigned silo. + user.assigned_silo = None + # Remove member and save user. try: - silo.save(ldb) + silo.remove_member(ldb, user) user.save(ldb) except LdbError as e: raise CommandError(e) diff --git a/python/samba/netcmd/domain/models/auth_silo.py b/python/samba/netcmd/domain/models/auth_silo.py index 2cc8f6ed428..4c40027463d 100644 --- a/python/samba/netcmd/domain/models/auth_silo.py +++ b/python/samba/netcmd/domain/models/auth_silo.py @@ -20,6 +20,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +from ldb import FLAG_MOD_ADD, FLAG_MOD_DELETE, Message, MessageElement + from .fields import DnField, BooleanField, StringField from .model import Model @@ -47,3 +49,43 @@ class AuthenticationSilo(Model): @staticmethod def get_object_class(): return "msDS-AuthNPolicySilo" + + def add_member(self, ldb, member): + """Add a member to the Authentication Silo. + + Rather than saving the silo object and writing the entire member + list out again, just add one member only. + + :param ldb: Ldb connection + :param member: Member to add to silo + """ + # Create a message with only an add member operation. + message = Message(dn=self.dn) + message.add(MessageElement(str(member.dn), FLAG_MOD_ADD, + "msDS-AuthNPolicySiloMembers")) + + # Update authentication silo. + ldb.modify(message) + + # If the modify operation was successful refresh members field. + self.refresh(ldb, fields=["members"]) + + def remove_member(self, ldb, member): + """Remove a member to the Authentication Silo. + + Rather than saving the silo object and writing the entire member + list out again, just remove one member only. + + :param ldb: Ldb connection + :param member: Member to remove from silo + """ + # Create a message with only a remove member operation. + message = Message(dn=self.dn) + message.add(MessageElement(str(member.dn), FLAG_MOD_DELETE, + "msDS-AuthNPolicySiloMembers")) + + # Update authentication silo. + ldb.modify(message) + + # If the modify operation was successful refresh members field. + self.refresh(ldb, fields=["members"]) |
