The branch, master has been updated via da500249fcf tests: gmsa blackbox tests via 7dcc06fa88b tests: models: test additional Computer constructor cases via c004fdd0f34 tests: models: fix username should be account_name via 87cf1a29378 tests: user: create gmsa with models via ea3838b6bcc tests: user: fix PEP8 spacing around operator via 878abe023ed tests: user: gmsa dNSHostName is a required field via 40e0cb2ccaa tests: samdb: Make use of the domain_sid property via 3c022f444a1 python: fix json encoder should handle Exception via 52165b8eada python: models: add Container model via bda232944cf python: models: add kwargs to __json__ and as_dict methods via 7fafb268bf9 python: pep8: fix import sorting after move via f739ef813c0 python: move models out of the netcmd package via 1f511acc133 python: create domain module to move models into via e25c4872034 netcmd: gmsa: show viewers also works if SID is not found via 12adbfc6abf netcmd: gmsa: add and remove don't fetch trustee if it is a SID via 87d00915e96 netcmd: gmsa: add_trustee and remove_trustee change argument to sid via 48c0ed76e02 netcmd: gmsa: fix typo if trustee is not found via a6e79982c90 netcmd: gmsa: create should allow custom SDDL via 200948c172d netcmd: models: improve Computer constructor adding "$" handling via bd79c074e2d netcmd: models: allow scope to be overridden in query via 3e22f8f3034 netcmd: models: add User.get_sid_for_principal helper via 12f3db0109a netcmd: models: User.find also tries object_sid via 4f97df7056b python: samdb: Make connecting_user_sid a property via c221f7080c5 python: samdb: Move get_connecting_user_sid to samdb from b815abe7799 libcli/security: check again for NULL values
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit da500249fcf52629c8d3da4d608b85b96b43cca6 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Fri Mar 1 11:22:03 2024 +1300 tests: gmsa blackbox tests Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Wed Mar 20 04:53:57 UTC 2024 on atb-devel-224 commit 7dcc06fa88b06cedcaa9165536eb47c6fed27fc4 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 6 16:52:53 2024 +1300 tests: models: test additional Computer constructor cases Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c004fdd0f34ec009fa4f24535ffb5773ee506e37 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 6 16:49:21 2024 +1300 tests: models: fix username should be account_name The reason this didn't fail, is because it doesn't save the Computers. This gets fixed in the next commit. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 87cf1a2937837d268de0339f88f02d4304355f75 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 5 16:39:33 2024 +1300 tests: user: create gmsa with models It was fetching the GMSA with the models straight after creating it anyway. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ea3838b6bcc5a60bbef201f016dfecea0af68b54 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 5 16:20:52 2024 +1300 tests: user: fix PEP8 spacing around operator Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 878abe023ed8cabe3e24a998a9ed870de8f64ee1 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 5 12:14:06 2024 +1300 tests: user: gmsa dNSHostName is a required field Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 40e0cb2ccaa659d3ee109949044fe006e7a7d2bb Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Feb 28 17:00:24 2024 +1300 tests: samdb: Make use of the domain_sid property Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 3c022f444a1c8644cdd4011475b2a16f834b18ab Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 20 09:50:49 2024 +1300 python: fix json encoder should handle Exception This happens if --json is used and a CommandError is raised, so will affect other commands too where --json is used. This happens in the print_json_status method. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 52165b8eada72ac2d2e015faba372af8ae9c7284 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 13 23:07:52 2024 +1300 python: models: add Container model Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit bda232944cf7954799792f2587b0ea923545004e Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 13 22:20:39 2024 +1300 python: models: add kwargs to __json__ and as_dict methods Allows passing arguments through Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7fafb268bf9553e21fa511eb6f50ab0b61628981 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 13 20:59:27 2024 +1300 python: pep8: fix import sorting after move Only touch files where samba.domain.models import was moved Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit f739ef813c037ebf201dae0af68d5e9276848145 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 16:47:58 2024 +1300 python: move models out of the netcmd package Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1f511acc1338412cfd8f513b08c5c21a6d839e0a Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 16:28:07 2024 +1300 python: create domain module to move models into Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e25c48720347daeaf7824c2f7c6b3655d26707d3 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 13:06:31 2024 +1300 netcmd: gmsa: show viewers also works if SID is not found Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 12adbfc6abf1dfc4b7d206025f7996bfb5fa86b1 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 12:40:12 2024 +1300 netcmd: gmsa: add and remove don't fetch trustee if it is a SID Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 87d00915e9634c2ba3269d8d437bfa3c74ee7724 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 12:38:13 2024 +1300 netcmd: gmsa: add_trustee and remove_trustee change argument to sid Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 48c0ed76e02567994c1c7069a83c89aec5825101 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 12:33:30 2024 +1300 netcmd: gmsa: fix typo if trustee is not found Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a6e79982c902fffc8dc1b95c56727e60c73cddeb Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 5 12:04:49 2024 +1300 netcmd: gmsa: create should allow custom SDDL gMSA update already supported it but not create Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 200948c172d20de75a3598d244de3f47d91d7bc0 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Mar 6 16:47:29 2024 +1300 netcmd: models: improve Computer constructor adding "$" handling In some cases the previous code would end up creating computers where the account name ended on double "$" Rewrote constructor to handle more cases, for example only an account name is provided, only a name is provided, or both. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit bd79c074e2ddbf434c70f6d2692dd702917309ce Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 12:13:09 2024 +1300 netcmd: models: allow scope to be overridden in query Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 3e22f8f303458efca9bed9a3223d62d2e55aa0a4 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 12 12:23:36 2024 +1300 netcmd: models: add User.get_sid_for_principal helper Unlike User.find, this will not fetch the User if an SID is provided. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 12f3db0109a4dbe5e96425bdff73c874f538ef9e Author: Rob van der Linde <r...@catalyst.net.nz> Date: Tue Mar 5 15:30:47 2024 +1300 netcmd: models: User.find also tries object_sid Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4f97df7056b800afde180a504d96bb3363394dae Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Feb 28 16:59:06 2024 +1300 python: samdb: Make connecting_user_sid a property This is following the same design as other similar properties like samdb.domain_sid, only it doesn't need a setter. Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c221f7080c505fafe8e44a5aff7b7a72bc60be78 Author: Rob van der Linde <r...@catalyst.net.nz> Date: Wed Feb 28 16:57:40 2024 +1300 python: samdb: Move get_connecting_user_sid to samdb Signed-off-by: Rob van der Linde <r...@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: .../dcerpc.py => python/samba/domain/__init__.py | 9 +- .../samba/{netcmd => }/domain/models/__init__.py | 1 + .../{netcmd => }/domain/models/auth_policy.py | 0 .../samba/{netcmd => }/domain/models/auth_silo.py | 0 .../samba/{netcmd => }/domain/models/claim_type.py | 0 .../samba/{netcmd => }/domain/models/computer.py | 37 +++- .../samba/{netcmd => }/domain/models/constants.py | 0 .../constants.py => domain/models/container.py} | 18 +- .../samba/{netcmd => }/domain/models/exceptions.py | 0 python/samba/{netcmd => }/domain/models/fields.py | 0 python/samba/{netcmd => }/domain/models/gmsa.py | 13 +- python/samba/{netcmd => }/domain/models/group.py | 0 python/samba/{netcmd => }/domain/models/model.py | 12 +- python/samba/{netcmd => }/domain/models/person.py | 0 python/samba/{netcmd => }/domain/models/query.py | 0 python/samba/{netcmd => }/domain/models/schema.py | 0 python/samba/{netcmd => }/domain/models/site.py | 0 python/samba/{netcmd => }/domain/models/subnet.py | 0 python/samba/{netcmd => }/domain/models/types.py | 0 python/samba/{netcmd => }/domain/models/user.py | 27 ++- .../samba/{netcmd => }/domain/models/value_type.py | 0 python/samba/netcmd/domain/auth/policy.py | 9 +- python/samba/netcmd/domain/auth/silo.py | 4 +- python/samba/netcmd/domain/auth/silo_member.py | 4 +- python/samba/netcmd/domain/claim/claim_type.py | 5 +- python/samba/netcmd/domain/claim/value_type.py | 4 +- python/samba/netcmd/encoders.py | 2 +- .../netcmd/service_account/group_msa_membership.py | 34 ++-- .../netcmd/service_account/service_account.py | 15 +- python/samba/netcmd/shell.py | 2 +- python/samba/netcmd/sites.py | 13 +- python/samba/netcmd/user/auth/policy.py | 4 +- python/samba/netcmd/user/auth/silo.py | 4 +- python/samba/samdb.py | 8 + python/samba/tests/blackbox/gmsa.py | 202 +++++++++++++++++++++ python/samba/tests/krb5/authn_policy_tests.py | 19 +- python/samba/tests/krb5/kdc_base_test.py | 33 ++-- .../samba/tests/samba_tool/domain_auth_policy.py | 2 +- python/samba/tests/samba_tool/domain_auth_silo.py | 2 +- python/samba/tests/samba_tool/domain_models.py | 34 +++- python/samba/tests/samba_tool/service_account.py | 4 +- python/samba/tests/samba_tool/silo_base.py | 2 +- python/samba/tests/samba_tool/user_auth_policy.py | 2 +- python/samba/tests/samba_tool/user_auth_silo.py | 2 +- .../tests/samba_tool/user_get_kerberos_ticket.py | 13 +- .../tests/samba_tool/user_getpassword_gmsa.py | 64 +++---- selftest/knownfail.d/gmsa | 3 +- source4/selftest/tests.py | 2 + 48 files changed, 435 insertions(+), 174 deletions(-) copy source4/librpc/rpc/dcerpc.py => python/samba/domain/__init__.py (85%) rename python/samba/{netcmd => }/domain/models/__init__.py (97%) rename python/samba/{netcmd => }/domain/models/auth_policy.py (100%) rename python/samba/{netcmd => }/domain/models/auth_silo.py (100%) rename python/samba/{netcmd => }/domain/models/claim_type.py (100%) rename python/samba/{netcmd => }/domain/models/computer.py (64%) copy python/samba/{netcmd => }/domain/models/constants.py (100%) rename python/samba/{netcmd/domain/models/constants.py => domain/models/container.py} (70%) rename python/samba/{netcmd => }/domain/models/exceptions.py (100%) rename python/samba/{netcmd => }/domain/models/fields.py (100%) rename python/samba/{netcmd => }/domain/models/gmsa.py (93%) rename python/samba/{netcmd => }/domain/models/group.py (100%) rename python/samba/{netcmd => }/domain/models/model.py (97%) rename python/samba/{netcmd => }/domain/models/person.py (100%) rename python/samba/{netcmd => }/domain/models/query.py (100%) rename python/samba/{netcmd => }/domain/models/schema.py (100%) rename python/samba/{netcmd => }/domain/models/site.py (100%) rename python/samba/{netcmd => }/domain/models/subnet.py (100%) rename python/samba/{netcmd => }/domain/models/types.py (100%) rename python/samba/{netcmd => }/domain/models/user.py (75%) rename python/samba/{netcmd => }/domain/models/value_type.py (100%) create mode 100644 python/samba/tests/blackbox/gmsa.py Changeset truncated at 500 lines: diff --git a/source4/librpc/rpc/dcerpc.py b/python/samba/domain/__init__.py similarity index 85% copy from source4/librpc/rpc/dcerpc.py copy to python/samba/domain/__init__.py index 64dd6e3a433..40ffa8948b3 100644 --- a/source4/librpc/rpc/dcerpc.py +++ b/python/samba/domain/__init__.py @@ -1,5 +1,10 @@ # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij <jel...@samba.org> 2008 +# +# Domain support +# +# Copyright (C) Catalyst.Net Ltd. 2024 +# +# Written by Rob van der Linde <r...@catalyst.net.nz> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -14,5 +19,3 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # - -from samba.dcerpc.base import * diff --git a/python/samba/netcmd/domain/models/__init__.py b/python/samba/domain/models/__init__.py similarity index 97% rename from python/samba/netcmd/domain/models/__init__.py rename to python/samba/domain/models/__init__.py index 4e100574aaf..fe05bac1482 100644 --- a/python/samba/netcmd/domain/models/__init__.py +++ b/python/samba/domain/models/__init__.py @@ -26,6 +26,7 @@ from .auth_silo import AuthenticationSilo from .claim_type import ClaimType from .computer import Computer from .constants import MODELS +from .container import Container from .gmsa import GroupManagedServiceAccount from .group import Group from .model import Model diff --git a/python/samba/netcmd/domain/models/auth_policy.py b/python/samba/domain/models/auth_policy.py similarity index 100% rename from python/samba/netcmd/domain/models/auth_policy.py rename to python/samba/domain/models/auth_policy.py diff --git a/python/samba/netcmd/domain/models/auth_silo.py b/python/samba/domain/models/auth_silo.py similarity index 100% rename from python/samba/netcmd/domain/models/auth_silo.py rename to python/samba/domain/models/auth_silo.py diff --git a/python/samba/netcmd/domain/models/claim_type.py b/python/samba/domain/models/claim_type.py similarity index 100% rename from python/samba/netcmd/domain/models/claim_type.py rename to python/samba/domain/models/claim_type.py diff --git a/python/samba/netcmd/domain/models/computer.py b/python/samba/domain/models/computer.py similarity index 64% rename from python/samba/netcmd/domain/models/computer.py rename to python/samba/domain/models/computer.py index c9e034a530f..84dddb16a9b 100644 --- a/python/samba/netcmd/domain/models/computer.py +++ b/python/samba/domain/models/computer.py @@ -33,18 +33,39 @@ class Computer(User): def __init__(self, **kwargs): """Computer constructor automatically adds "$" to account_name. - Also applies to GroupManagedServiceAccount subclass. - """ - name = kwargs.get("name", kwargs.get("cn")) + The various ways a Computer can be constructed: + + >>> Computer(name="pc") + >>> Computer(account_name="pc$") + >>> Computer(cn="pc") + >>> Computer(account_name="pc$", name="pc") + + In each case the constructor does its best to ensure the + account name ends with a "$" and the name doesn't. + + Also applies to GroupManagedServiceAccount subclass.""" + name = kwargs.get("name", kwargs.pop("cn", None)) account_name = kwargs.get("account_name") - # If account_name is missing, use name or cn and add a "$". - # If account_name is present but lacking "$", add it automatically. + # First make sure the account_name always has a "$". + if account_name and not account_name.endswith("$"): + account_name += "$" + + # The name is present but not account name. + # If the name already has a "$" don't add two. if name and not account_name: - kwargs["account_name"] = name + "$" - elif account_name and not account_name.endswith("$"): - kwargs["account_name"] = account_name + "$" + if name.endswith("$"): + account_name = name + else: + account_name = name + "$" + + # The account name is present but not the name. + # Use the account name, stripping the "$" character. + elif account_name and not name: + name = account_name.rstrip("$") + kwargs["name"] = name + kwargs["account_name"] = account_name super().__init__(**kwargs) @staticmethod diff --git a/python/samba/netcmd/domain/models/constants.py b/python/samba/domain/models/constants.py similarity index 100% copy from python/samba/netcmd/domain/models/constants.py copy to python/samba/domain/models/constants.py diff --git a/python/samba/netcmd/domain/models/constants.py b/python/samba/domain/models/container.py similarity index 70% rename from python/samba/netcmd/domain/models/constants.py rename to python/samba/domain/models/container.py index aa1b0307445..5d3a0b247a4 100644 --- a/python/samba/netcmd/domain/models/constants.py +++ b/python/samba/domain/models/container.py @@ -1,8 +1,8 @@ # Unix SMB/CIFS implementation. # -# Model constants +# Container model. # -# Copyright (C) Catalyst.Net Ltd. 2023 +# Copyright (C) Catalyst.Net Ltd. 2024 # # Written by Rob van der Linde <r...@catalyst.net.nz> # @@ -20,9 +20,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# Keeps track of registered models. -# This gets populated by the ModelMeta class. -MODELS = {} +from .fields import DnField +from .model import Model -# Default SDDL for GroupManagedServiceAccount msDS-GroupMSAMembership field. -GROUP_MSA_MEMBERSHIP_DEFAULT = "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;LA)" + +class Container(Model): + object_reference = DnField("msDS-ObjectReference") + + @staticmethod + def get_object_class(): + return "container" diff --git a/python/samba/netcmd/domain/models/exceptions.py b/python/samba/domain/models/exceptions.py similarity index 100% rename from python/samba/netcmd/domain/models/exceptions.py rename to python/samba/domain/models/exceptions.py diff --git a/python/samba/netcmd/domain/models/fields.py b/python/samba/domain/models/fields.py similarity index 100% rename from python/samba/netcmd/domain/models/fields.py rename to python/samba/domain/models/fields.py diff --git a/python/samba/netcmd/domain/models/gmsa.py b/python/samba/domain/models/gmsa.py similarity index 93% rename from python/samba/netcmd/domain/models/gmsa.py rename to python/samba/domain/models/gmsa.py index c5c27e3cf51..e13711f22d7 100644 --- a/python/samba/netcmd/domain/models/gmsa.py +++ b/python/samba/domain/models/gmsa.py @@ -28,7 +28,6 @@ from .constants import GROUP_MSA_MEMBERSHIP_DEFAULT from .exceptions import FieldError from .fields import BinaryField, EnumField, IntegerField, SDDLField, StringField from .types import SupportedEncryptionTypes -from .user import User class GroupManagedServiceAccount(Computer): @@ -79,17 +78,19 @@ class GroupManagedServiceAccount(Computer): return allowed - def add_trustee(self, trustee: User): + def add_trustee(self, trustee: str): """Adds the User `trustee` to group_msa_membership. Checking if the trustee already has access is the responsibility of the caller. + + :param trustee: SID of trustee to add """ aces = self.group_msa_membership.dacl.aces ace = security.ace() ace.type = security.SEC_ACE_TYPE_ACCESS_ALLOWED - ace.trustee = security.dom_sid(trustee.object_sid) + ace.trustee = security.dom_sid(trustee) ace.access_mask = security.SEC_ADS_GENERIC_ALL aces.append(ace) @@ -97,14 +98,16 @@ class GroupManagedServiceAccount(Computer): self.group_msa_membership.dacl.aces = aces self.group_msa_membership.dacl.num_aces = len(aces) - def remove_trustee(self, trustee: User): + def remove_trustee(self, trustee: str): """Removes the User 'trustee' from group_msa_membership. If the trustee doesn't have access already then do nothing. + + :param trustee: SID of trustee to remove """ aces = self.group_msa_membership.dacl.aces for ace in aces: - if trustee.object_sid == str(ace.trustee): + if trustee == str(ace.trustee): self.group_msa_membership.dacl_del_ace(ace) break diff --git a/python/samba/netcmd/domain/models/group.py b/python/samba/domain/models/group.py similarity index 100% rename from python/samba/netcmd/domain/models/group.py rename to python/samba/domain/models/group.py diff --git a/python/samba/netcmd/domain/models/model.py b/python/samba/domain/models/model.py similarity index 97% rename from python/samba/netcmd/domain/models/model.py rename to python/samba/domain/models/model.py index a9b10a7b53e..55cada972b6 100644 --- a/python/samba/netcmd/domain/models/model.py +++ b/python/samba/domain/models/model.py @@ -110,9 +110,9 @@ class Model(metaclass=ModelMeta): else: return self.dn == other.dn - def __json__(self): + def __json__(self, **kwargs): """Automatically called by custom JSONEncoder class.""" - return self.as_dict() + return self.as_dict(**kwargs) @staticmethod def get_base_dn(ldb): @@ -182,7 +182,7 @@ class Model(metaclass=ModelMeta): self._apply(ldb, res[0]) - def as_dict(self, include_hidden=False): + def as_dict(self, include_hidden=False, **kwargs): """Returns a dict representation of the model. :param include_hidden: Include fields with hidden=True when set @@ -225,7 +225,8 @@ class Model(metaclass=ModelMeta): return expression @classmethod - def query(cls, ldb, polymorphic=False, base_dn=None, **kwargs): + def query(cls, ldb, polymorphic=False, base_dn=None, scope=SCOPE_SUBTREE, + **kwargs): """Returns a search query for this model. NOTE: If polymorphic is enabled then querying will return instances @@ -238,6 +239,7 @@ class Model(metaclass=ModelMeta): :param ldb: Ldb connection :param polymorphic: If true enables polymorphic querying (see note) :param base_dn: Optional provide base dn for searching or use the model + :param scope: Ldb search scope (default SCOPE_SUBTREE) :param kwargs: Search criteria as keyword args """ if base_dn is None: @@ -246,7 +248,7 @@ class Model(metaclass=ModelMeta): # If the container does not exist produce a friendly error message. try: result = ldb.search(base_dn, - scope=SCOPE_SUBTREE, + scope=scope, expression=cls.build_expression(**kwargs)) except LdbError as e: if e.args[0] == ERR_NO_SUCH_OBJECT: diff --git a/python/samba/netcmd/domain/models/person.py b/python/samba/domain/models/person.py similarity index 100% rename from python/samba/netcmd/domain/models/person.py rename to python/samba/domain/models/person.py diff --git a/python/samba/netcmd/domain/models/query.py b/python/samba/domain/models/query.py similarity index 100% rename from python/samba/netcmd/domain/models/query.py rename to python/samba/domain/models/query.py diff --git a/python/samba/netcmd/domain/models/schema.py b/python/samba/domain/models/schema.py similarity index 100% rename from python/samba/netcmd/domain/models/schema.py rename to python/samba/domain/models/schema.py diff --git a/python/samba/netcmd/domain/models/site.py b/python/samba/domain/models/site.py similarity index 100% rename from python/samba/netcmd/domain/models/site.py rename to python/samba/domain/models/site.py diff --git a/python/samba/netcmd/domain/models/subnet.py b/python/samba/domain/models/subnet.py similarity index 100% rename from python/samba/netcmd/domain/models/subnet.py rename to python/samba/domain/models/subnet.py diff --git a/python/samba/netcmd/domain/models/types.py b/python/samba/domain/models/types.py similarity index 100% rename from python/samba/netcmd/domain/models/types.py rename to python/samba/domain/models/types.py diff --git a/python/samba/netcmd/domain/models/user.py b/python/samba/domain/models/user.py similarity index 75% rename from python/samba/netcmd/domain/models/user.py rename to python/samba/domain/models/user.py index 79a8ecce477..48fcd80a7e1 100644 --- a/python/samba/netcmd/domain/models/user.py +++ b/python/samba/domain/models/user.py @@ -22,8 +22,10 @@ from ldb import Dn +from samba.dcerpc.security import dom_sid from samba.dsdb import DS_GUID_USERS_CONTAINER +from .exceptions import NotFound from .fields import DnField, EnumField, IntegerField, NtTimeField, StringField from .person import OrganizationalPerson from .types import AccountType, UserAccountControl @@ -75,13 +77,32 @@ class User(OrganizationalPerson): @classmethod def find(cls, ldb, name): - """Helper function to find a user first by Dn then sAMAccountName. + """Helper function to find a user by Dn, objectSid, or sAMAccountName. - If the Dn can't be parsed, use sAMAccountName instead. + If the Dn or Sid can't be parsed, use sAMAccountName instead. """ try: query = {"dn": Dn(ldb, name)} except ValueError: - query = {"account_name": name} + try: + query = {"object_sid": dom_sid(name)} + except ValueError: + query = {"account_name": name} return cls.get(ldb, **query) + + @classmethod + def get_sid_for_principal(cls, ldb, principal) -> str: + """Return object_sid for the provided principal. + + If principal is already an object sid then return without fetching, + this is different to `User.find` which must fetch the User. + """ + try: + return str(dom_sid(principal)) + except ValueError: + user = cls.find(ldb, principal) + if user: + return user.object_sid + else: + raise NotFound(f"Principal {principal} not found.") diff --git a/python/samba/netcmd/domain/models/value_type.py b/python/samba/domain/models/value_type.py similarity index 100% rename from python/samba/netcmd/domain/models/value_type.py rename to python/samba/domain/models/value_type.py diff --git a/python/samba/netcmd/domain/auth/policy.py b/python/samba/netcmd/domain/auth/policy.py index d7156510a1c..8cc6598f3fa 100644 --- a/python/samba/netcmd/domain/auth/policy.py +++ b/python/samba/netcmd/domain/auth/policy.py @@ -21,12 +21,11 @@ # import samba.getopt as options +from samba.domain.models import (MAX_TGT_LIFETIME, MIN_TGT_LIFETIME, + AuthenticationPolicy, AuthenticationSilo, + Group, StrongNTLMPolicy) +from samba.domain.models.exceptions import ModelError from samba.netcmd import Command, CommandError, Option, SuperCommand -from samba.netcmd.domain.models import (AuthenticationPolicy, - AuthenticationSilo, Group, - MAX_TGT_LIFETIME, MIN_TGT_LIFETIME, - StrongNTLMPolicy) -from samba.netcmd.domain.models.exceptions import ModelError from samba.netcmd.validators import Range diff --git a/python/samba/netcmd/domain/auth/silo.py b/python/samba/netcmd/domain/auth/silo.py index f792e8a8542..861f47c8e7c 100644 --- a/python/samba/netcmd/domain/auth/silo.py +++ b/python/samba/netcmd/domain/auth/silo.py @@ -21,9 +21,9 @@ # import samba.getopt as options +from samba.domain.models import AuthenticationPolicy, AuthenticationSilo +from samba.domain.models.exceptions import ModelError from samba.netcmd import Command, CommandError, Option, SuperCommand -from samba.netcmd.domain.models import AuthenticationPolicy, AuthenticationSilo -from samba.netcmd.domain.models.exceptions import ModelError from .silo_member import cmd_domain_auth_silo_member diff --git a/python/samba/netcmd/domain/auth/silo_member.py b/python/samba/netcmd/domain/auth/silo_member.py index 9b414006e74..02e5cd53163 100644 --- a/python/samba/netcmd/domain/auth/silo_member.py +++ b/python/samba/netcmd/domain/auth/silo_member.py @@ -21,9 +21,9 @@ # import samba.getopt as options +from samba.domain.models import AuthenticationSilo, User +from samba.domain.models.exceptions import ModelError from samba.netcmd import Command, CommandError, Option, SuperCommand -from samba.netcmd.domain.models import AuthenticationSilo, User -from samba.netcmd.domain.models.exceptions import ModelError class cmd_domain_auth_silo_member_grant(Command): diff --git a/python/samba/netcmd/domain/claim/claim_type.py b/python/samba/netcmd/domain/claim/claim_type.py index 0801f0fd0db..312742fede6 100644 --- a/python/samba/netcmd/domain/claim/claim_type.py +++ b/python/samba/netcmd/domain/claim/claim_type.py @@ -21,10 +21,9 @@ # import samba.getopt as options +from samba.domain.models import AttributeSchema, ClaimType, ClassSchema, ValueType +from samba.domain.models.exceptions import ModelError from samba.netcmd import Command, CommandError, Option, SuperCommand -from samba.netcmd.domain.models import AttributeSchema, ClassSchema,\ - ClaimType, ValueType -from samba.netcmd.domain.models.exceptions import ModelError class cmd_domain_claim_claim_type_create(Command): diff --git a/python/samba/netcmd/domain/claim/value_type.py b/python/samba/netcmd/domain/claim/value_type.py index ca30bd68904..b7f92947f58 100644 --- a/python/samba/netcmd/domain/claim/value_type.py +++ b/python/samba/netcmd/domain/claim/value_type.py @@ -21,9 +21,9 @@ # import samba.getopt as options +from samba.domain.models import ValueType +from samba.domain.models.exceptions import ModelError from samba.netcmd import Command, CommandError, Option, SuperCommand -from samba.netcmd.domain.models import ValueType -from samba.netcmd.domain.models.exceptions import ModelError class cmd_domain_claim_value_type_list(Command): diff --git a/python/samba/netcmd/encoders.py b/python/samba/netcmd/encoders.py index 230309f74d9..87f90a57a5d 100644 --- a/python/samba/netcmd/encoders.py +++ b/python/samba/netcmd/encoders.py @@ -40,7 +40,7 @@ class JSONEncoder(json.JSONEncoder): """ def default(self, obj): - if isinstance(obj, (Decimal, Dn, MessageElement)): + if isinstance(obj, (Decimal, Dn, Exception, MessageElement)): return str(obj) if isinstance(obj, Result): return obj.msgs diff --git a/python/samba/netcmd/service_account/group_msa_membership.py b/python/samba/netcmd/service_account/group_msa_membership.py index da3f950f4e8..34e7fa45b59 100644 --- a/python/samba/netcmd/service_account/group_msa_membership.py +++ b/python/samba/netcmd/service_account/group_msa_membership.py @@ -19,11 +19,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from samba.domain.models import Group, GroupManagedServiceAccount, Model, User +from samba.domain.models.exceptions import ModelError from samba.getopt import CredentialsOptions, HostOptions, Option, SambaOptions from samba.netcmd import Command, CommandError, SuperCommand -from samba.netcmd.domain.models import (Group, GroupManagedServiceAccount, - Model, User) -from samba.netcmd.domain.models.exceptions import ModelError class cmd_service_account_group_msa_membership_show(Command): @@ -59,14 +58,14 @@ class cmd_service_account_group_msa_membership_show(Command): raise CommandError(f"Group managed service account {name} not found.") try: - trustees = [Model.get(ldb, object_sid=sid, polymorphic=True) for sid in gmsa.trustees] + trustees = {sid: Model.get(ldb, object_sid=sid, polymorphic=True) for sid in gmsa.trustees} except ModelError as e: raise CommandError(e) if output_format == "json": self.print_json({ "dn": gmsa.dn, - "trustees": [trustee.dn for trustee in trustees] + "trustees": [trustee.dn if trustee else f"<SID={sid}>" for sid, trustee in trustees.items()] }) else: print(f"Account-DN: {gmsa.dn}", file=self.outf) @@ -74,8 +73,9 @@ class cmd_service_account_group_msa_membership_show(Command): print("Accounts or groups that are able to retrieve this group managed service account password:", file=self.outf) - for trustee in trustees: - print(f" {trustee.dn}", file=self.outf) + for sid, trustee in trustees.items(): + dn = trustee.dn if trustee else f"<SID={sid}>" + print(f" {dn}", file=self.outf) class cmd_service_account_group_msa_membership_add(Command): @@ -114,20 +114,20 @@ class cmd_service_account_group_msa_membership_add(Command): -- Samba Shared Repository