summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRob van der Linde <rob@catalyst.net.nz>2023-05-17 23:35:16 +1200
committerAndrew Bartlett <abartlet@samba.org>2023-06-25 23:29:32 +0000
commit8311284224539710b89ae4557951f132620c8553 (patch)
tree324d28f633fc2380039494707c28c57dbf32c1bf /python
parent705e65c16e85da6117d224c7ec26adcdedce83b9 (diff)
downloadsamba-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.py29
-rw-r--r--python/samba/netcmd/domain/models/auth_silo.py42
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"])