1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-16 00:23:52 +03:00
Files
samba-mirror/python/samba/domain/models/user.py
Gary Lockyer f9d9f559d9 python:domain:user Add altSecurityIdentities
Add altSecurityIdentities to the User domain model so that it can be used by
the key certificate binding enforcement tests.

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Jennifer Sutton <jennifersutton@catalyst.net.nz>
2025-10-10 01:27:31 +00:00

119 lines
4.2 KiB
Python

# Unix SMB/CIFS implementation.
#
# User model.
#
# Copyright (C) Catalyst.Net Ltd. 2023
#
# Written by Rob van der Linde <rob@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
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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 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 .fields import KeyCredentialLinkDnField
from .group import Group
from .org import OrganizationalPerson
from .types import AccountType, UserAccountControl
class User(OrganizationalPerson):
account_name = StringField("sAMAccountName")
account_type = EnumField("sAMAccountType", AccountType)
assigned_policy = DnField("msDS-AssignedAuthNPolicy")
assigned_silo = DnField("msDS-AssignedAuthNPolicySilo")
bad_password_time = NtTimeField("badPasswordTime", readonly=True)
bad_pwd_count = IntegerField("badPwdCount", readonly=True)
code_page = IntegerField("codePage")
display_name = StringField("displayName")
key_credential_link = KeyCredentialLinkDnField("msDS-KeyCredentialLink",
many=True)
alt_security_identities = StringField("altSecurityIdentities", many=True)
last_logoff = NtTimeField("lastLogoff", readonly=True)
last_logon = NtTimeField("lastLogon", readonly=True)
logon_count = IntegerField("logonCount", readonly=True)
primary_group_id = IntegerField("primaryGroupID")
pwd_last_set = NtTimeField("pwdLastSet", readonly=True)
user_account_control = EnumField("userAccountControl", UserAccountControl)
user_principal_name = StringField("userPrincipalName")
def __str__(self):
"""Return sAMAccountName rather than cn for User model."""
return self.account_name
def get_primary_group(self, samdb) -> Group:
"""Returns the primary Group object for this User."""
group_sid = f"{samdb.domain_sid}-{self.primary_group_id}"
return Group.get(samdb, object_sid=group_sid)
@staticmethod
def get_base_dn(samdb):
"""Return the base DN for the User model.
:param samdb: SamDB connection
:return: Dn to use for new objects
"""
return samdb.get_wellknown_dn(samdb.get_default_basedn(),
DS_GUID_USERS_CONTAINER)
@classmethod
def get_search_dn(cls, samdb):
"""Return Dn used for searching so Computers will also be found.
:param samdb: SamDB connection
:return: Dn to use for searching
"""
return samdb.get_root_basedn()
@staticmethod
def get_object_class():
return "user"
@classmethod
def find(cls, samdb, name):
"""Helper function to find a user by Dn, objectSid, or sAMAccountName.
If the Dn or Sid can't be parsed, use sAMAccountName instead.
"""
try:
query = {"dn": Dn(samdb, name)}
except ValueError:
try:
query = {"object_sid": dom_sid(name)}
except ValueError:
query = {"account_name": name}
return cls.get(samdb, **query)
@classmethod
def get_sid_for_principal(cls, samdb, 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(samdb, principal)
if user:
return user.object_sid
else:
raise NotFound(f"Principal {principal} not found.")