1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

netcmd: models: add GroupManagedServiceAccount model

Signed-off-by: Rob van der Linde <rob@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jo Sutton <josutton@catalyst.net.nz>
This commit is contained in:
Rob van der Linde 2024-02-08 23:25:14 +13:00 committed by Andrew Bartlett
parent 5e52e211a9
commit b401502c55
3 changed files with 99 additions and 6 deletions

View File

@ -30,6 +30,7 @@ from .model import MODELS
from .schema import AttributeSchema, ClassSchema
from .site import Site
from .subnet import Subnet
from .types import AccountType, GroupType, SystemFlags, UserAccountControl
from .user import User
from .types import (AccountType, GroupType, SupportedEncryptionTypes,
SystemFlags, UserAccountControl)
from .user import User, GroupManagedServiceAccount
from .value_type import ValueType

View File

@ -22,6 +22,12 @@
from enum import IntFlag
from samba.dcerpc.security import (
KERB_ENCTYPE_FAST_SUPPORTED,
KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED,
KERB_ENCTYPE_CLAIMS_SUPPORTED,
KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED
)
from samba.dsdb import (
ATYPE_SECURITY_GLOBAL_GROUP,
ATYPE_SECURITY_LOCAL_GROUP,
@ -54,6 +60,13 @@ from samba.dsdb import (
UF_NO_AUTH_DATA_REQUIRED,
UF_PARTIAL_SECRETS_ACCOUNT,
UF_USE_AES_KEYS,
ENC_ALL_TYPES,
ENC_CRC32,
ENC_RSA_MD5,
ENC_RC4_HMAC_MD5,
ENC_HMAC_SHA1_96_AES128,
ENC_HMAC_SHA1_96_AES256,
ENC_HMAC_SHA1_96_AES256_SK,
GTYPE_DISTRIBUTION_GLOBAL_GROUP,
GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP,
GTYPE_DISTRIBUTION_UNIVERSAL_GROUP,
@ -134,3 +147,17 @@ class UserAccountControl(IntFlag):
NO_AUTH_DATA_REQUIRED = UF_NO_AUTH_DATA_REQUIRED
PARTIAL_SECRETS_ACCOUNT = UF_PARTIAL_SECRETS_ACCOUNT
USE_AES_KEYS = UF_USE_AES_KEYS
class SupportedEncryptionTypes(IntFlag):
ALL_TYPES = ENC_ALL_TYPES
CRC32 = ENC_CRC32
RSA_MD5 = ENC_RSA_MD5
RC4_HMAC_MD5 = ENC_RC4_HMAC_MD5
HMAC_SHA1_96_AES128 = ENC_HMAC_SHA1_96_AES128
HMAC_SHA1_96_AES256 = ENC_HMAC_SHA1_96_AES256
HMAC_SHA1_96_AES256_SK = ENC_HMAC_SHA1_96_AES256_SK
FAST_SUPPORTED = KERB_ENCTYPE_FAST_SUPPORTED
COMPOUND_IDENTITY_SUPPORTED = KERB_ENCTYPE_COMPOUND_IDENTITY_SUPPORTED
CLAIMS_SUPPORTED = KERB_ENCTYPE_CLAIMS_SUPPORTED
RESOURCE_SID_COMPRESSION_DISABLED = KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED

View File

@ -20,15 +20,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from ldb import Dn
from ldb import FLAG_MOD_ADD, Dn
from samba.dcerpc import security
from samba.dsdb import (DS_GUID_MANAGED_SERVICE_ACCOUNTS_CONTAINER,
DS_GUID_USERS_CONTAINER)
from samba.ndr import ndr_unpack
from .fields import (DnField, EnumField, IntegerField, SIDField, StringField,
NtTimeField)
from .fields import (BinaryField, DnField, EnumField, IntegerField, SDDLField,
SIDField, StringField, NtTimeField)
from .model import Model
from .types import AccountType, UserAccountControl
from .types import AccountType, SupportedEncryptionTypes, UserAccountControl
class User(Model):
@ -91,3 +93,66 @@ class User(Model):
query = {"username": name}
return cls.get(ldb, **query)
class GroupManagedServiceAccount(User):
"""A GroupManagedServiceAccount is a type of User with additional fields."""
managed_password_interval = IntegerField("msDS-ManagedPasswordInterval")
dns_host_name = StringField("dNSHostName")
group_msa_membership = SDDLField("msDS-GroupMSAMembership")
managed_password_id = BinaryField("msDS-ManagedPasswordId",
readonly=True, hidden=True)
managed_password_previous_id = BinaryField("msDS-ManagedPasswordPreviousId",
readonly=True, hidden=True)
supported_encryption_types = EnumField("msDS-SupportedEncryptionTypes",
SupportedEncryptionTypes)
@staticmethod
def get_base_dn(ldb):
"""Return base Dn for Managed Service Accounts.
:param ldb: Ldb connection
:return: Dn to use for searching
"""
return ldb.get_wellknown_dn(ldb.get_default_basedn(),
DS_GUID_MANAGED_SERVICE_ACCOUNTS_CONTAINER)
@staticmethod
def get_object_class():
return "msDS-GroupManagedServiceAccount"
def trustees(self, ldb):
"""Returns list of trustees from the msDS-GroupMSAMembership SDDL.
:return: list of User objects
"""
users = []
field = self.fields["group_msa_membership"]
sddl = self.group_msa_membership
message = field.to_db_value(ldb, sddl, FLAG_MOD_ADD)
desc = ndr_unpack(security.descriptor, message[0])
for ace in desc.dacl.aces:
users.append(User.get(ldb, object_sid=ace.trustee))
return users
@classmethod
def find(cls, ldb, name):
"""Helper function to find a service account first by Dn then username.
If the Dn can't be parsed use sAMAccountName, automatically add the $.
"""
try:
query = {"dn": Dn(ldb, name)}
except ValueError:
if name.endswith("$"):
query = {"username": name}
else:
query = {"username": name + "$"}
return cls.get(ldb, **query)
@staticmethod
def group_sddl(group):
return f"O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;{group.object_sid})"