# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Author: Alberto Solino (@agsolino)
#
# Description:
#   [MS-LSAD] Interface implementation
#
#   Best way to learn how to use these calls is to grab the protocol standard
#   so you understand what the call does, and then read the test case located
#   at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
#
#   Some calls have helper functions, which makes it even easier to use.
#   They are located at the end of this file. 
#   Helper functions start with "h"<name of the call>.
#   There are test cases for them too. 
#
from __future__ import division
from __future__ import print_function
from aiosmb.dcerpc.v5.ndr import NDRCALL, NDRENUM, NDRUNION, NDRUniConformantVaryingArray, NDRPOINTER, NDR, NDRSTRUCT, \
    NDRUniConformantArray
from aiosmb.dcerpc.v5.dtypes import DWORD, LPWSTR, STR, LUID, LONG, ULONG, RPC_UNICODE_STRING, PRPC_SID, LPBYTE, \
    LARGE_INTEGER, NTSTATUS, RPC_SID, ACCESS_MASK, UCHAR, PRPC_UNICODE_STRING, PLARGE_INTEGER, USHORT, \
    SECURITY_INFORMATION, NULL, MAXIMUM_ALLOWED, GUID, SECURITY_DESCRIPTOR, OWNER_SECURITY_INFORMATION
from aiosmb.dcerpc.v5.uuid import uuidtup_to_bin
from aiosmb.dcerpc.v5.enum import Enum
from aiosmb.dcerpc.v5.rpcrt import DCERPCException

from struct import unpack, pack
from aiosmb import logger as LOG

from aiosmb.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantVaryingArray, NDRUniConformantArray
from aiosmb.dcerpc.v5.dtypes import DWORD, UUID, ULONG, LPULONG, BOOLEAN, SECURITY_INFORMATION, PFILETIME, \
    RPC_UNICODE_STRING, FILETIME, NULL, MAXIMUM_ALLOWED, OWNER_SECURITY_INFORMATION, PWCHAR, PRPC_UNICODE_STRING

from aiosmb.commons.utils.decorators import red, rr

MSRPC_UUID_LSAD  = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AB','0.0'))

class DCERPCSessionError(DCERPCException):
    def __init__(self, error_string=None, error_code=None, packet=None):
        DCERPCException.__init__(self, error_string, error_code, packet)


################################################################################
# CONSTANTS
################################################################################
# 2.2.1.1.2 ACCESS_MASK for Policy Objects
POLICY_VIEW_LOCAL_INFORMATION   = 0x00000001
POLICY_VIEW_AUDIT_INFORMATION   = 0x00000002
POLICY_GET_PRIVATE_INFORMATION  = 0x00000004
POLICY_TRUST_ADMIN              = 0x00000008
POLICY_CREATE_ACCOUNT           = 0x00000010
POLICY_CREATE_SECRET            = 0x00000020
POLICY_CREATE_PRIVILEGE         = 0x00000040
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080
POLICY_SET_AUDIT_REQUIREMENTS   = 0x00000100
POLICY_AUDIT_LOG_ADMIN          = 0x00000200
POLICY_SERVER_ADMIN             = 0x00000400
POLICY_LOOKUP_NAMES             = 0x00000800
POLICY_NOTIFICATION             = 0x00001000

# 2.2.1.1.3 ACCESS_MASK for Account Objects
ACCOUNT_VIEW                 = 0x00000001
ACCOUNT_ADJUST_PRIVILEGES    = 0x00000002
ACCOUNT_ADJUST_QUOTAS        = 0x00000004
ACCOUNT_ADJUST_SYSTEM_ACCESS = 0x00000008

# 2.2.1.1.4 ACCESS_MASK for Secret Objects
SECRET_SET_VALUE   = 0x00000001
SECRET_QUERY_VALUE = 0x00000002

# 2.2.1.1.5 ACCESS_MASK for Trusted Domain Objects
TRUSTED_QUERY_DOMAIN_NAME = 0x00000001
TRUSTED_QUERY_CONTROLLERS = 0x00000002
TRUSTED_SET_CONTROLLERS   = 0x00000004
TRUSTED_QUERY_POSIX       = 0x00000008
TRUSTED_SET_POSIX         = 0x00000010
TRUSTED_SET_AUTH          = 0x00000020
TRUSTED_QUERY_AUTH        = 0x00000040

# 2.2.1.2 POLICY_SYSTEM_ACCESS_MODE
POLICY_MODE_INTERACTIVE             = 0x00000001
POLICY_MODE_NETWORK                 = 0x00000002
POLICY_MODE_BATCH                   = 0x00000004
POLICY_MODE_SERVICE                 = 0x00000010
POLICY_MODE_DENY_INTERACTIVE        = 0x00000040
POLICY_MODE_DENY_NETWORK            = 0x00000080
POLICY_MODE_DENY_BATCH              = 0x00000100
POLICY_MODE_DENY_SERVICE            = 0x00000200
POLICY_MODE_REMOTE_INTERACTIVE      = 0x00000400
POLICY_MODE_DENY_REMOTE_INTERACTIVE = 0x00000800
POLICY_MODE_ALL                     = 0x00000FF7
POLICY_MODE_ALL_NT4                 = 0x00000037

# 2.2.4.4 LSAPR_POLICY_AUDIT_EVENTS_INFO
# EventAuditingOptions
POLICY_AUDIT_EVENT_UNCHANGED = 0x00000000
POLICY_AUDIT_EVENT_NONE      = 0x00000004
POLICY_AUDIT_EVENT_SUCCESS   = 0x00000001
POLICY_AUDIT_EVENT_FAILURE   = 0x00000002

# 2.2.4.19 POLICY_DOMAIN_KERBEROS_TICKET_INFO
# AuthenticationOptions
POLICY_KERBEROS_VALIDATE_CLIENT = 0x00000080

# 2.2.7.21 LSA_FOREST_TRUST_RECORD
# Flags
LSA_TLN_DISABLED_NEW          = 0x00000001
LSA_TLN_DISABLED_ADMIN        = 0x00000002
LSA_TLN_DISABLED_CONFLICT     = 0x00000004
LSA_SID_DISABLED_ADMIN        = 0x00000001
LSA_SID_DISABLED_CONFLICT     = 0x00000002
LSA_NB_DISABLED_ADMIN         = 0x00000004
LSA_NB_DISABLED_CONFLICT      = 0x00000008
LSA_FTRECORD_DISABLED_REASONS = 0x0000FFFF

################################################################################
# STRUCTURES
################################################################################
# 2.2.2.1 LSAPR_HANDLE
class LSAPR_HANDLE(NDRSTRUCT):
    align = 1
    structure =  (
        ('Data','20s=""'),
    )

# 2.2.2.3 LSA_UNICODE_STRING
LSA_UNICODE_STRING = RPC_UNICODE_STRING

# 2.2.3.1 STRING
class STRING(NDRSTRUCT):
    commonHdr = (
        ('MaximumLength','<H=len(Data)-12'),
        ('Length','<H=len(Data)-12'),
        ('ReferentID','<L=0xff'),
    )
    commonHdr64 = (
        ('MaximumLength','<H=len(Data)-24'),
        ('Length','<H=len(Data)-24'),
        ('ReferentID','<Q=0xff'),
    )

    referent = (
        ('Data',STR),
    )

    def dump(self, msg = None, indent = 0):
        if msg is None:
            msg = self.__class__.__name__
        if msg != '':
            print("%s" % msg, end=' ')
        # Here just print the data
        print(" %r" % (self['Data']), end=' ')

    def __setitem__(self, key, value):
        if key == 'Data':
            self.fields['MaximumLength'] = None
            self.fields['Length'] = None
            self.data = None        # force recompute
        return NDR.__setitem__(self, key, value)

# 2.2.3.2 LSAPR_ACL
class LSAPR_ACL(NDRSTRUCT):
    structure =  (
        ('AclRevision', UCHAR),
        ('Sbz1', UCHAR),
        ('AclSize', USHORT),
        ('Dummy1',NDRUniConformantArray),
    )

# 2.2.3.4 LSAPR_SECURITY_DESCRIPTOR
LSAPR_SECURITY_DESCRIPTOR = SECURITY_DESCRIPTOR

class PLSAPR_SECURITY_DESCRIPTOR(NDRPOINTER):
    referent = (
        ('Data', LSAPR_SECURITY_DESCRIPTOR),
    )

# 2.2.3.5 SECURITY_IMPERSONATION_LEVEL
class SECURITY_IMPERSONATION_LEVEL(NDRENUM):
    class enumItems(Enum):
        SecurityAnonymous      = 0
        SecurityIdentification = 1
        SecurityImpersonation  = 2
        SecurityDelegation     = 3

# 2.2.3.6 SECURITY_CONTEXT_TRACKING_MODE
SECURITY_CONTEXT_TRACKING_MODE = UCHAR

# 2.2.3.7 SECURITY_QUALITY_OF_SERVICE
class SECURITY_QUALITY_OF_SERVICE(NDRSTRUCT):
    structure = (
        ('Length', DWORD), 
        ('ImpersonationLevel', SECURITY_IMPERSONATION_LEVEL), 
        ('ContextTrackingMode', SECURITY_CONTEXT_TRACKING_MODE), 
        ('EffectiveOnly', UCHAR), 
    )

class PSECURITY_QUALITY_OF_SERVICE(NDRPOINTER):
    referent = (
        ('Data', SECURITY_QUALITY_OF_SERVICE),
    )

# 2.2.2.4 LSAPR_OBJECT_ATTRIBUTES
class LSAPR_OBJECT_ATTRIBUTES(NDRSTRUCT):
    structure = (
        ('Length', DWORD), 
        ('RootDirectory', LPWSTR), 
        ('ObjectName', LPWSTR), 
        ('Attributes', DWORD), 
        ('SecurityDescriptor', PLSAPR_SECURITY_DESCRIPTOR), 
        ('SecurityQualityOfService', PSECURITY_QUALITY_OF_SERVICE), 
    )

# 2.2.2.5 LSAPR_SR_SECURITY_DESCRIPTOR
class LSAPR_SR_SECURITY_DESCRIPTOR(NDRSTRUCT):
    structure = (
        ('Length', DWORD), 
        ('SecurityDescriptor', LPBYTE), 
    )

class PLSAPR_SR_SECURITY_DESCRIPTOR(NDRPOINTER):
    referent = (
        ('Data', LSAPR_SR_SECURITY_DESCRIPTOR),
    )

# 2.2.3.3 SECURITY_DESCRIPTOR_CONTROL
SECURITY_DESCRIPTOR_CONTROL = ULONG

# 2.2.4.1 POLICY_INFORMATION_CLASS
class POLICY_INFORMATION_CLASS(NDRENUM):
    class enumItems(Enum):
        PolicyAuditLogInformation           = 1
        PolicyAuditEventsInformation        = 2
        PolicyPrimaryDomainInformation      = 3
        PolicyPdAccountInformation          = 4
        PolicyAccountDomainInformation      = 5
        PolicyLsaServerRoleInformation      = 6
        PolicyReplicaSourceInformation      = 7
        PolicyInformationNotUsedOnWire      = 8
        PolicyModificationInformation       = 9
        PolicyAuditFullSetInformation       = 10
        PolicyAuditFullQueryInformation     = 11
        PolicyDnsDomainInformation          = 12
        PolicyDnsDomainInformationInt       = 13
        PolicyLocalAccountDomainInformation = 14
        PolicyLastEntry                     = 15

# 2.2.4.3 POLICY_AUDIT_LOG_INFO
class POLICY_AUDIT_LOG_INFO(NDRSTRUCT):
    structure = (
        ('AuditLogPercentFull', DWORD), 
        ('MaximumLogSize', DWORD), 
        ('AuditRetentionPeriod', LARGE_INTEGER), 
        ('AuditLogFullShutdownInProgress', UCHAR), 
        ('TimeToShutdown', LARGE_INTEGER), 
        ('NextAuditRecordId', DWORD), 
    )

# 2.2.4.4 LSAPR_POLICY_AUDIT_EVENTS_INFO
class DWORD_ARRAY(NDRUniConformantArray):
    item = DWORD

class PDWORD_ARRAY(NDRPOINTER):
    referent = (
        ('Data', DWORD_ARRAY),
    )

class LSAPR_POLICY_AUDIT_EVENTS_INFO(NDRSTRUCT):
    structure = (
        ('AuditingMode', UCHAR), 
        ('EventAuditingOptions', PDWORD_ARRAY), 
        ('MaximumAuditEventCount', DWORD), 
    )

# 2.2.4.5 LSAPR_POLICY_PRIMARY_DOM_INFO
class LSAPR_POLICY_PRIMARY_DOM_INFO(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('Sid', PRPC_SID), 
    )

# 2.2.4.6 LSAPR_POLICY_ACCOUNT_DOM_INFO
class LSAPR_POLICY_ACCOUNT_DOM_INFO(NDRSTRUCT):
    structure = (
        ('DomainName', RPC_UNICODE_STRING), 
        ('DomainSid', PRPC_SID), 
    )

# 2.2.4.7 LSAPR_POLICY_PD_ACCOUNT_INFO
class LSAPR_POLICY_PD_ACCOUNT_INFO(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
    )

# 2.2.4.8 POLICY_LSA_SERVER_ROLE
class POLICY_LSA_SERVER_ROLE(NDRENUM):
    class enumItems(Enum):
        PolicyServerRoleBackup   = 2
        PolicyServerRolePrimary  = 3

# 2.2.4.9 POLICY_LSA_SERVER_ROLE_INFO
class POLICY_LSA_SERVER_ROLE_INFO(NDRSTRUCT):
    structure = (
        ('LsaServerRole', POLICY_LSA_SERVER_ROLE), 
    )

# 2.2.4.10 LSAPR_POLICY_REPLICA_SRCE_INFO
class LSAPR_POLICY_REPLICA_SRCE_INFO(NDRSTRUCT):
    structure = (
        ('ReplicaSource', RPC_UNICODE_STRING), 
        ('ReplicaAccountName', RPC_UNICODE_STRING), 
    )

# 2.2.4.11 POLICY_MODIFICATION_INFO
class POLICY_MODIFICATION_INFO(NDRSTRUCT):
    structure = (
        ('ModifiedId', LARGE_INTEGER), 
        ('DatabaseCreationTime', LARGE_INTEGER), 
    )

# 2.2.4.12 POLICY_AUDIT_FULL_SET_INFO
class POLICY_AUDIT_FULL_SET_INFO(NDRSTRUCT):
    structure = (
        ('ShutDownOnFull', UCHAR), 
    )

# 2.2.4.13 POLICY_AUDIT_FULL_QUERY_INFO
class POLICY_AUDIT_FULL_QUERY_INFO(NDRSTRUCT):
    structure = (
        ('ShutDownOnFull', UCHAR), 
        ('LogIsFull', UCHAR), 
    )

# 2.2.4.14 LSAPR_POLICY_DNS_DOMAIN_INFO
class LSAPR_POLICY_DNS_DOMAIN_INFO(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('DnsDomainName', RPC_UNICODE_STRING), 
        ('DnsForestName', RPC_UNICODE_STRING), 
        ('DomainGuid', GUID), 
        ('Sid', PRPC_SID), 
    )

# 2.2.4.2 LSAPR_POLICY_INFORMATION
class LSAPR_POLICY_INFORMATION(NDRUNION):
    union = {
        POLICY_INFORMATION_CLASS.PolicyAuditLogInformation          : ('PolicyAuditLogInfo', POLICY_AUDIT_LOG_INFO),
        POLICY_INFORMATION_CLASS.PolicyAuditEventsInformation       : ('PolicyAuditEventsInfo', LSAPR_POLICY_AUDIT_EVENTS_INFO),
        POLICY_INFORMATION_CLASS.PolicyPrimaryDomainInformation     : ('PolicyPrimaryDomainInfo', LSAPR_POLICY_PRIMARY_DOM_INFO),
        POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation     : ('PolicyAccountDomainInfo', LSAPR_POLICY_ACCOUNT_DOM_INFO),
        POLICY_INFORMATION_CLASS.PolicyPdAccountInformation         : ('PolicyPdAccountInfo', LSAPR_POLICY_PD_ACCOUNT_INFO),
        POLICY_INFORMATION_CLASS.PolicyLsaServerRoleInformation     : ('PolicyServerRoleInfo', POLICY_LSA_SERVER_ROLE_INFO),
        POLICY_INFORMATION_CLASS.PolicyReplicaSourceInformation     : ('PolicyReplicaSourceInfo', LSAPR_POLICY_REPLICA_SRCE_INFO),
        POLICY_INFORMATION_CLASS.PolicyModificationInformation      : ('PolicyModificationInfo', POLICY_MODIFICATION_INFO),
        POLICY_INFORMATION_CLASS.PolicyAuditFullSetInformation      : ('PolicyAuditFullSetInfo', POLICY_AUDIT_FULL_SET_INFO),
        POLICY_INFORMATION_CLASS.PolicyAuditFullQueryInformation    : ('PolicyAuditFullQueryInfo', POLICY_AUDIT_FULL_QUERY_INFO),
        POLICY_INFORMATION_CLASS.PolicyDnsDomainInformation         : ('PolicyDnsDomainInfo', LSAPR_POLICY_DNS_DOMAIN_INFO),
        POLICY_INFORMATION_CLASS.PolicyDnsDomainInformationInt      : ('PolicyDnsDomainInfoInt', LSAPR_POLICY_DNS_DOMAIN_INFO),
        POLICY_INFORMATION_CLASS.PolicyLocalAccountDomainInformation: ('PolicyLocalAccountDomainInfo', LSAPR_POLICY_ACCOUNT_DOM_INFO),
    }

class PLSAPR_POLICY_INFORMATION(NDRPOINTER):
    referent = (
       ('Data', LSAPR_POLICY_INFORMATION),
    )

# 2.2.4.15 POLICY_DOMAIN_INFORMATION_CLASS
class POLICY_DOMAIN_INFORMATION_CLASS(NDRENUM):
    class enumItems(Enum):
        PolicyDomainQualityOfServiceInformation = 1
        PolicyDomainEfsInformation              = 2
        PolicyDomainKerberosTicketInformation   = 3

# 2.2.4.17 POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO
class POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO(NDRSTRUCT):
    structure = (
        ('QualityOfService', DWORD), 
    )

# 2.2.4.18 LSAPR_POLICY_DOMAIN_EFS_INFO
class LSAPR_POLICY_DOMAIN_EFS_INFO(NDRSTRUCT):
    structure = (
        ('InfoLength', DWORD), 
        ('EfsBlob', LPBYTE), 
    )

# 2.2.4.19 POLICY_DOMAIN_KERBEROS_TICKET_INFO
class POLICY_DOMAIN_KERBEROS_TICKET_INFO(NDRSTRUCT):
    structure = (
        ('AuthenticationOptions', DWORD), 
        ('MaxServiceTicketAge', LARGE_INTEGER), 
        ('MaxTicketAge', LARGE_INTEGER), 
        ('MaxRenewAge', LARGE_INTEGER), 
        ('MaxClockSkew', LARGE_INTEGER), 
        ('Reserved', LARGE_INTEGER), 
    )

# 2.2.4.16 LSAPR_POLICY_DOMAIN_INFORMATION
class LSAPR_POLICY_DOMAIN_INFORMATION(NDRUNION):
    union = {
        POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainQualityOfServiceInformation : ('PolicyDomainQualityOfServiceInfo', POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO ),
        POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainEfsInformation              : ('PolicyDomainEfsInfo', LSAPR_POLICY_DOMAIN_EFS_INFO),
        POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainKerberosTicketInformation   : ('PolicyDomainKerbTicketInfo', POLICY_DOMAIN_KERBEROS_TICKET_INFO),
    }

class PLSAPR_POLICY_DOMAIN_INFORMATION(NDRPOINTER):
    referent = (
        ('Data', LSAPR_POLICY_DOMAIN_INFORMATION),
    )

# 2.2.4.20 POLICY_AUDIT_EVENT_TYPE
class POLICY_AUDIT_EVENT_TYPE(NDRENUM):
    class enumItems(Enum):
        AuditCategorySystem                 = 0
        AuditCategoryLogon                  = 1
        AuditCategoryObjectAccess           = 2
        AuditCategoryPrivilegeUse           = 3
        AuditCategoryDetailedTracking       = 4
        AuditCategoryPolicyChange           = 5
        AuditCategoryAccountManagement      = 6
        AuditCategoryDirectoryServiceAccess = 7
        AuditCategoryAccountLogon           = 8

# 2.2.5.1 LSAPR_ACCOUNT_INFORMATION
class LSAPR_ACCOUNT_INFORMATION(NDRSTRUCT):
    structure = (
        ('Sid', PRPC_SID), 
    )

# 2.2.5.2 LSAPR_ACCOUNT_ENUM_BUFFER
class LSAPR_ACCOUNT_INFORMATION_ARRAY(NDRUniConformantArray):
    item = LSAPR_ACCOUNT_INFORMATION

class PLSAPR_ACCOUNT_INFORMATION_ARRAY(NDRPOINTER):
    referent = (
        ('Data', LSAPR_ACCOUNT_INFORMATION_ARRAY),
    )

class LSAPR_ACCOUNT_ENUM_BUFFER(NDRSTRUCT):
    structure = (
        ('EntriesRead', ULONG), 
        ('Information', PLSAPR_ACCOUNT_INFORMATION_ARRAY), 
    )

# 2.2.5.3 LSAPR_USER_RIGHT_SET
class RPC_UNICODE_STRING_ARRAY(NDRUniConformantArray):
    item = RPC_UNICODE_STRING

class PRPC_UNICODE_STRING_ARRAY(NDRPOINTER):
    referent = (
        ('Data', RPC_UNICODE_STRING_ARRAY),
    )

class LSAPR_USER_RIGHT_SET(NDRSTRUCT):
    structure = (
        ('EntriesRead', ULONG), 
        ('UserRights', PRPC_UNICODE_STRING_ARRAY), 
    )

# 2.2.5.4 LSAPR_LUID_AND_ATTRIBUTES
class LSAPR_LUID_AND_ATTRIBUTES(NDRSTRUCT):
    structure = (
        ('Luid', LUID), 
        ('Attributes', ULONG), 
    )

# 2.2.5.5 LSAPR_PRIVILEGE_SET
class LSAPR_LUID_AND_ATTRIBUTES_ARRAY(NDRUniConformantArray):
    item = LSAPR_LUID_AND_ATTRIBUTES

class LSAPR_PRIVILEGE_SET(NDRSTRUCT):
    structure = (
        ('PrivilegeCount', ULONG), 
        ('Control', ULONG), 
        ('Privilege', LSAPR_LUID_AND_ATTRIBUTES_ARRAY), 
    )

class PLSAPR_PRIVILEGE_SET(NDRPOINTER):
    referent = (
        ('Data', LSAPR_PRIVILEGE_SET),
    )

# 2.2.6.1 LSAPR_CR_CIPHER_VALUE
class PCHAR_ARRAY(NDRPOINTER):
    referent = (
        ('Data', NDRUniConformantVaryingArray),
    )

class LSAPR_CR_CIPHER_VALUE(NDRSTRUCT):
    structure = (
        ('Length', LONG), 
        ('MaximumLength', LONG), 
        ('Buffer', PCHAR_ARRAY), 
    )

class PLSAPR_CR_CIPHER_VALUE(NDRPOINTER):
    referent = (
        ('Data', LSAPR_CR_CIPHER_VALUE), 
    )

class PPLSAPR_CR_CIPHER_VALUE(NDRPOINTER):
    referent = (
        ('Data', PLSAPR_CR_CIPHER_VALUE),
    )

# 2.2.7.1 LSAPR_TRUST_INFORMATION
class LSAPR_TRUST_INFORMATION(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('Sid', PRPC_SID), 
    )

# 2.2.7.2 TRUSTED_INFORMATION_CLASS
class TRUSTED_INFORMATION_CLASS(NDRENUM):
    class enumItems(Enum):
        TrustedDomainNameInformation          = 1
        TrustedControllersInformation         = 2
        TrustedPosixOffsetInformation         = 3
        TrustedPasswordInformation            = 4
        TrustedDomainInformationBasic         = 5
        TrustedDomainInformationEx            = 6
        TrustedDomainAuthInformation          = 7
        TrustedDomainFullInformation          = 8
        TrustedDomainAuthInformationInternal  = 9
        TrustedDomainFullInformationInternal  = 10
        TrustedDomainInformationEx2Internal   = 11
        TrustedDomainFullInformation2Internal = 12
        TrustedDomainSupportedEncryptionTypes = 13

# 2.2.7.4 LSAPR_TRUSTED_DOMAIN_NAME_INFO
class LSAPR_TRUSTED_DOMAIN_NAME_INFO(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
    )

# 2.2.7.5 LSAPR_TRUSTED_CONTROLLERS_INFO
class LSAPR_TRUSTED_CONTROLLERS_INFO(NDRSTRUCT):
    structure = (
        ('Entries', ULONG), 
        ('Names', PRPC_UNICODE_STRING_ARRAY), 
    )

# 2.2.7.6 TRUSTED_POSIX_OFFSET_INFO
class TRUSTED_POSIX_OFFSET_INFO(NDRSTRUCT):
    structure = (
        ('Offset', ULONG), 
    )

# 2.2.7.7 LSAPR_TRUSTED_PASSWORD_INFO
class LSAPR_TRUSTED_PASSWORD_INFO(NDRSTRUCT):
    structure = (
        ('Password', PLSAPR_CR_CIPHER_VALUE), 
        ('OldPassword', PLSAPR_CR_CIPHER_VALUE), 
    )

# 2.2.7.8 LSAPR_TRUSTED_DOMAIN_INFORMATION_BASIC
LSAPR_TRUSTED_DOMAIN_INFORMATION_BASIC = LSAPR_TRUST_INFORMATION

# 2.2.7.9 LSAPR_TRUSTED_DOMAIN_INFORMATION_EX
class LSAPR_TRUSTED_DOMAIN_INFORMATION_EX(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('FlatName', RPC_UNICODE_STRING), 
        ('Sid', PRPC_SID), 
        ('TrustDirection', ULONG), 
        ('TrustType', ULONG), 
        ('TrustAttributes', ULONG), 
    )

# 2.2.7.10 LSAPR_TRUSTED_DOMAIN_INFORMATION_EX2
class LSAPR_TRUSTED_DOMAIN_INFORMATION_EX2(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('FlatName', RPC_UNICODE_STRING), 
        ('Sid', PRPC_SID), 
        ('TrustDirection', ULONG), 
        ('TrustType', ULONG), 
        ('TrustAttributes', ULONG), 
        ('ForestTrustLength', ULONG), 
        ('ForestTrustInfo', LPBYTE), 
    )

# 2.2.7.17 LSAPR_AUTH_INFORMATION
class LSAPR_AUTH_INFORMATION(NDRSTRUCT):
    structure = (
        ('LastUpdateTime', LARGE_INTEGER), 
        ('AuthType', ULONG), 
        ('AuthInfoLength', ULONG), 
        ('AuthInfo', LPBYTE), 
    )

class PLSAPR_AUTH_INFORMATION(NDRPOINTER):
    referent = (
        ('Data', LSAPR_AUTH_INFORMATION),
    )

# 2.2.7.11 LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION
class LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION(NDRSTRUCT):
    structure = (
        ('IncomingAuthInfos', ULONG), 
        ('IncomingAuthenticationInformation', PLSAPR_AUTH_INFORMATION), 
        ('IncomingPreviousAuthenticationInformation', PLSAPR_AUTH_INFORMATION), 
        ('OutgoingAuthInfos', ULONG), 
        ('OutgoingAuthenticationInformation', PLSAPR_AUTH_INFORMATION), 
        ('OutgoingPreviousAuthenticationInformation', PLSAPR_AUTH_INFORMATION), 
    )

# 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB
class LSAPR_TRUSTED_DOMAIN_AUTH_BLOB(NDRSTRUCT):
    structure = (
        ('AuthSize', ULONG), 
        ('AuthBlob', LPBYTE), 
    )

# 2.2.7.12 LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL
class LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL(NDRSTRUCT):
    structure = (
        ('AuthBlob', LSAPR_TRUSTED_DOMAIN_AUTH_BLOB), 
    )

# 2.2.7.13 LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION
class LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION(NDRSTRUCT):
    structure = (
        ('Information', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX), 
        ('PosixOffset', TRUSTED_POSIX_OFFSET_INFO), 
        ('AuthInformation', LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION), 
    )

# 2.2.7.14 LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION_INTERNAL
class LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION_INTERNAL(NDRSTRUCT):
    structure = (
        ('Information', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX), 
        ('PosixOffset', TRUSTED_POSIX_OFFSET_INFO), 
        ('AuthInformation', LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL), 
    )

# 2.2.7.15 LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION2
class LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION2(NDRSTRUCT):
    structure = (
        ('Information', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX), 
        ('PosixOffset', TRUSTED_POSIX_OFFSET_INFO), 
        ('AuthInformation', LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION), 
    )

# 2.2.7.18 TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
class TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES(NDRSTRUCT):
    structure = (
        ('SupportedEncryptionTypes', ULONG), 
    )

# 2.2.7.3 LSAPR_TRUSTED_DOMAIN_INFO
class LSAPR_TRUSTED_DOMAIN_INFO(NDRUNION):
    union = {
        TRUSTED_INFORMATION_CLASS.TrustedDomainNameInformation          : ('TrustedDomainNameInfo', LSAPR_TRUSTED_DOMAIN_NAME_INFO ),
        TRUSTED_INFORMATION_CLASS.TrustedControllersInformation         : ('TrustedControllersInfo', LSAPR_TRUSTED_CONTROLLERS_INFO),
        TRUSTED_INFORMATION_CLASS.TrustedPosixOffsetInformation         : ('TrustedPosixOffsetInfo', TRUSTED_POSIX_OFFSET_INFO),
        TRUSTED_INFORMATION_CLASS.TrustedPasswordInformation            : ('TrustedPasswordInfo', LSAPR_TRUSTED_PASSWORD_INFO ),
        TRUSTED_INFORMATION_CLASS.TrustedDomainInformationBasic         : ('TrustedDomainInfoBasic', LSAPR_TRUSTED_DOMAIN_INFORMATION_BASIC),
        TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx            : ('TrustedDomainInfoEx', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX),
        TRUSTED_INFORMATION_CLASS.TrustedDomainAuthInformation          : ('TrustedAuthInfo', LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION),
        TRUSTED_INFORMATION_CLASS.TrustedDomainFullInformation          : ('TrustedFullInfo', LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION),
        TRUSTED_INFORMATION_CLASS.TrustedDomainAuthInformationInternal  : ('TrustedAuthInfoInternal', LSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL),
        TRUSTED_INFORMATION_CLASS.TrustedDomainFullInformationInternal  : ('TrustedFullInfoInternal', LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION_INTERNAL),
        TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx2Internal   : ('TrustedDomainInfoEx2', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX2),
        TRUSTED_INFORMATION_CLASS.TrustedDomainFullInformation2Internal : ('TrustedFullInfo2', LSAPR_TRUSTED_DOMAIN_FULL_INFORMATION2),
        TRUSTED_INFORMATION_CLASS.TrustedDomainSupportedEncryptionTypes : ('TrustedDomainSETs', TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES),
    }

# 2.2.7.19 LSAPR_TRUSTED_ENUM_BUFFER
class LSAPR_TRUST_INFORMATION_ARRAY(NDRUniConformantArray):
    item = LSAPR_TRUST_INFORMATION

class PLSAPR_TRUST_INFORMATION_ARRAY(NDRPOINTER):
    referent = (
        ('Data', LSAPR_TRUST_INFORMATION_ARRAY),
    )

class LSAPR_TRUSTED_ENUM_BUFFER(NDRSTRUCT):
    structure = (
        ('Entries', ULONG), 
        ('Information', PLSAPR_TRUST_INFORMATION_ARRAY), 
    )

# 2.2.7.20 LSAPR_TRUSTED_ENUM_BUFFER_EX
class LSAPR_TRUSTED_DOMAIN_INFORMATION_EX_ARRAY(NDRUniConformantArray):
    item = LSAPR_TRUSTED_DOMAIN_INFORMATION_EX

class PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX_ARRAY(NDRPOINTER):
    referent = (
        ('Data', LSAPR_TRUSTED_DOMAIN_INFORMATION_EX_ARRAY),
    )

class LSAPR_TRUSTED_ENUM_BUFFER_EX(NDRSTRUCT):
    structure = (
        ('Entries', ULONG), 
        ('EnumerationBuffer', PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX_ARRAY), 
    )

# 2.2.7.22 LSA_FOREST_TRUST_RECORD_TYPE
class LSA_FOREST_TRUST_RECORD_TYPE(NDRENUM):
    class enumItems(Enum):
        ForestTrustTopLevelName   = 0
        ForestTrustTopLevelNameEx = 1
        ForestTrustDomainInfo     = 2

# 2.2.7.24 LSA_FOREST_TRUST_DOMAIN_INFO
class LSA_FOREST_TRUST_DOMAIN_INFO(NDRSTRUCT):
    structure = (
        ('Sid', PRPC_SID), 
        ('DnsName', LSA_UNICODE_STRING), 
        ('NetbiosName', LSA_UNICODE_STRING), 
    )

# 2.2.7.21 LSA_FOREST_TRUST_RECORD
class LSA_FOREST_TRUST_DATA_UNION(NDRUNION):
    union = {
        LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelName   : ('TopLevelName', LSA_UNICODE_STRING ),
        LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelNameEx : ('TopLevelName', LSA_UNICODE_STRING),
        LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustDomainInfo     : ('DomainInfo', LSA_FOREST_TRUST_DOMAIN_INFO),
    }

class LSA_FOREST_TRUST_RECORD(NDRSTRUCT):
    structure = (
        ('Flags', ULONG), 
        ('ForestTrustType', LSA_FOREST_TRUST_RECORD_TYPE), 
        ('Time', LARGE_INTEGER), 
        ('ForestTrustData', LSA_FOREST_TRUST_DATA_UNION), 
    )

class PLSA_FOREST_TRUST_RECORD(NDRPOINTER):
    referent = (
        ('Data', LSA_FOREST_TRUST_RECORD),
    )

# 2.2.7.23 LSA_FOREST_TRUST_BINARY_DATA
class LSA_FOREST_TRUST_BINARY_DATA(NDRSTRUCT):
    structure = (
        ('Length', ULONG), 
        ('Buffer', LPBYTE), 
    )

# 2.2.7.25 LSA_FOREST_TRUST_INFORMATION
class LSA_FOREST_TRUST_RECORD_ARRAY(NDRUniConformantArray):
    item = PLSA_FOREST_TRUST_RECORD

class PLSA_FOREST_TRUST_RECORD_ARRAY(NDRPOINTER):
    referent = (
        ('Data', LSA_FOREST_TRUST_RECORD_ARRAY),
    )

class LSA_FOREST_TRUST_INFORMATION(NDRSTRUCT):
    structure = (
        ('RecordCount', ULONG), 
        ('Entries', PLSA_FOREST_TRUST_RECORD_ARRAY), 
    )

class PLSA_FOREST_TRUST_INFORMATION(NDRPOINTER):
    referent = (
        ('Data', LSA_FOREST_TRUST_INFORMATION),
    )

# 2.2.7.26 LSA_FOREST_TRUST_COLLISION_RECORD_TYPE
class LSA_FOREST_TRUST_COLLISION_RECORD_TYPE(NDRENUM):
    class enumItems(Enum):
        CollisionTdo   = 0
        CollisionXref  = 1
        CollisionOther = 2

# 2.2.7.27 LSA_FOREST_TRUST_COLLISION_RECORD
class LSA_FOREST_TRUST_COLLISION_RECORD(NDRSTRUCT):
    structure = (
        ('Index', ULONG), 
        ('Type', LSA_FOREST_TRUST_COLLISION_RECORD_TYPE), 
        ('Flags', ULONG), 
        ('Name', LSA_UNICODE_STRING), 
    )

# 2.2.8.1 LSAPR_POLICY_PRIVILEGE_DEF
class LSAPR_POLICY_PRIVILEGE_DEF(NDRSTRUCT):
    structure = (
        ('Name', RPC_UNICODE_STRING), 
        ('LocalValue', LUID), 
    )

# 2.2.8.2 LSAPR_PRIVILEGE_ENUM_BUFFER
class LSAPR_POLICY_PRIVILEGE_DEF_ARRAY(NDRUniConformantArray):
    item = LSAPR_POLICY_PRIVILEGE_DEF

class PLSAPR_POLICY_PRIVILEGE_DEF_ARRAY(NDRPOINTER):
    referent = (
        ('Data', LSAPR_POLICY_PRIVILEGE_DEF_ARRAY),
    )

class LSAPR_PRIVILEGE_ENUM_BUFFER(NDRSTRUCT):
    structure = (
        ('Entries', ULONG), 
        ('Privileges', PLSAPR_POLICY_PRIVILEGE_DEF_ARRAY), 
    )


################################################################################
# RPC CALLS
################################################################################
# 3.1.4.4.1 LsarOpenPolicy2 (Opnum 44)
class LsarOpenPolicy2(NDRCALL):
    opnum = 44
    structure = (
       ('SystemName', LPWSTR),
       ('ObjectAttributes',LSAPR_OBJECT_ATTRIBUTES),
       ('DesiredAccess',ACCESS_MASK),
    )

class LsarOpenPolicy2Response(NDRCALL):
    structure = (
       ('PolicyHandle',LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.2 LsarOpenPolicy (Opnum 6)
class LsarOpenPolicy(NDRCALL):
    opnum = 6
    structure = (
       ('SystemName', LPWSTR),
       ('ObjectAttributes',LSAPR_OBJECT_ATTRIBUTES),
       ('DesiredAccess',ACCESS_MASK),
    )

class LsarOpenPolicyResponse(NDRCALL):
    structure = (
       ('PolicyHandle',LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.3 LsarQueryInformationPolicy2 (Opnum 46)
class LsarQueryInformationPolicy2(NDRCALL):
    opnum = 46
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('InformationClass',POLICY_INFORMATION_CLASS),
    )

class LsarQueryInformationPolicy2Response(NDRCALL):
    structure = (
       ('PolicyInformation',PLSAPR_POLICY_INFORMATION),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.4 LsarQueryInformationPolicy (Opnum 7)
class LsarQueryInformationPolicy(NDRCALL):
    opnum = 7
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('InformationClass',POLICY_INFORMATION_CLASS),
    )

class LsarQueryInformationPolicyResponse(NDRCALL):
    structure = (
       ('PolicyInformation',PLSAPR_POLICY_INFORMATION),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.5 LsarSetInformationPolicy2 (Opnum 47)
class LsarSetInformationPolicy2(NDRCALL):
    opnum = 47
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('InformationClass',POLICY_INFORMATION_CLASS),
       ('PolicyInformation',LSAPR_POLICY_INFORMATION),
    )

class LsarSetInformationPolicy2Response(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.6 LsarSetInformationPolicy (Opnum 8)
class LsarSetInformationPolicy(NDRCALL):
    opnum = 8
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('InformationClass',POLICY_INFORMATION_CLASS),
       ('PolicyInformation',LSAPR_POLICY_INFORMATION),
    )

class LsarSetInformationPolicyResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.7 LsarQueryDomainInformationPolicy (Opnum 53)
class LsarQueryDomainInformationPolicy(NDRCALL):
    opnum = 53
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('InformationClass',POLICY_DOMAIN_INFORMATION_CLASS),
    )

class LsarQueryDomainInformationPolicyResponse(NDRCALL):
    structure = (
       ('PolicyDomainInformation',PLSAPR_POLICY_DOMAIN_INFORMATION),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.4.8 LsarSetDomainInformationPolicy (Opnum 54)
# 3.1.4.5.1 LsarCreateAccount (Opnum 10)
class LsarCreateAccount(NDRCALL):
    opnum = 10
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('AccountSid',RPC_SID),
       ('DesiredAccess',ACCESS_MASK),
    )

class LsarCreateAccountResponse(NDRCALL):
    structure = (
       ('AccountHandle',LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.2 LsarEnumerateAccounts (Opnum 11)
class LsarEnumerateAccounts(NDRCALL):
    opnum = 11
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('EnumerationContext',ULONG),
       ('PreferedMaximumLength',ULONG),
    )

class LsarEnumerateAccountsResponse(NDRCALL):
    structure = (
       ('EnumerationContext',ULONG),
       ('EnumerationBuffer',LSAPR_ACCOUNT_ENUM_BUFFER),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.3 LsarOpenAccount (Opnum 17)
class LsarOpenAccount(NDRCALL):
    opnum = 17
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('AccountSid',RPC_SID),
       ('DesiredAccess',ACCESS_MASK),
    )

class LsarOpenAccountResponse(NDRCALL):
    structure = (
       ('AccountHandle',LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.4 LsarEnumeratePrivilegesAccount (Opnum 18)
class LsarEnumeratePrivilegesAccount(NDRCALL):
    opnum = 18
    structure = (
       ('AccountHandle', LSAPR_HANDLE),
    )

class LsarEnumeratePrivilegesAccountResponse(NDRCALL):
    structure = (
       ('Privileges',PLSAPR_PRIVILEGE_SET),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.5 LsarAddPrivilegesToAccount (Opnum 19)
class LsarAddPrivilegesToAccount(NDRCALL):
    opnum = 19
    structure = (
       ('AccountHandle', LSAPR_HANDLE),
       ('Privileges', LSAPR_PRIVILEGE_SET),
    )

class LsarAddPrivilegesToAccountResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.6 LsarRemovePrivilegesFromAccount (Opnum 20)
class LsarRemovePrivilegesFromAccount(NDRCALL):
    opnum = 20
    structure = (
       ('AccountHandle', LSAPR_HANDLE),
       ('AllPrivileges', UCHAR),
       ('Privileges', PLSAPR_PRIVILEGE_SET),
    )

class LsarRemovePrivilegesFromAccountResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.7 LsarGetSystemAccessAccount (Opnum 23)
class LsarGetSystemAccessAccount(NDRCALL):
    opnum = 23
    structure = (
       ('AccountHandle', LSAPR_HANDLE),
    )

class LsarGetSystemAccessAccountResponse(NDRCALL):
    structure = (
       ('SystemAccess', ULONG),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.8 LsarSetSystemAccessAccount (Opnum 24)
class LsarSetSystemAccessAccount(NDRCALL):
    opnum = 24
    structure = (
       ('AccountHandle', LSAPR_HANDLE),
       ('SystemAccess', ULONG),
    )

class LsarSetSystemAccessAccountResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.9 LsarEnumerateAccountsWithUserRight (Opnum 35)
class LsarEnumerateAccountsWithUserRight(NDRCALL):
    opnum = 35
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('UserRight', PRPC_UNICODE_STRING),
    )

class LsarEnumerateAccountsWithUserRightResponse(NDRCALL):
    structure = (
       ('EnumerationBuffer',LSAPR_ACCOUNT_ENUM_BUFFER),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.10 LsarEnumerateAccountRights (Opnum 36)
class LsarEnumerateAccountRights(NDRCALL):
    opnum = 36
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('AccountSid', RPC_SID),
    )

class LsarEnumerateAccountRightsResponse(NDRCALL):
    structure = (
       ('UserRights',LSAPR_USER_RIGHT_SET),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.11 LsarAddAccountRights (Opnum 37)
class LsarAddAccountRights(NDRCALL):
    opnum = 37
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('AccountSid', RPC_SID),
       ('UserRights',LSAPR_USER_RIGHT_SET),
    )

class LsarAddAccountRightsResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.5.12 LsarRemoveAccountRights (Opnum 38)
class LsarRemoveAccountRights(NDRCALL):
    opnum = 38
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('AccountSid', RPC_SID),
       ('AllRights', UCHAR),
       ('UserRights',LSAPR_USER_RIGHT_SET),
    )

class LsarRemoveAccountRightsResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.1 LsarCreateSecret (Opnum 16)
class LsarCreateSecret(NDRCALL):
    opnum = 16
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('SecretName', RPC_UNICODE_STRING),
       ('DesiredAccess', ACCESS_MASK),
    )

class LsarCreateSecretResponse(NDRCALL):
    structure = (
       ('SecretHandle', LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.2 LsarOpenSecret (Opnum 28)
class LsarOpenSecret(NDRCALL):
    opnum = 28
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('SecretName', RPC_UNICODE_STRING),
       ('DesiredAccess', ACCESS_MASK),
    )

class LsarOpenSecretResponse(NDRCALL):
    structure = (
       ('SecretHandle', LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.3 LsarSetSecret (Opnum 29)
class LsarSetSecret(NDRCALL):
    opnum = 29
    structure = (
       ('SecretHandle', LSAPR_HANDLE),
       ('EncryptedCurrentValue', PLSAPR_CR_CIPHER_VALUE),
       ('EncryptedOldValue', PLSAPR_CR_CIPHER_VALUE),
    )

class LsarSetSecretResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.4 LsarQuerySecret (Opnum 30)
class LsarQuerySecret(NDRCALL):
    opnum = 30
    structure = (
       ('SecretHandle', LSAPR_HANDLE),
       ('EncryptedCurrentValue', PPLSAPR_CR_CIPHER_VALUE),
       ('CurrentValueSetTime', PLARGE_INTEGER),
       ('EncryptedOldValue', PPLSAPR_CR_CIPHER_VALUE),
       ('OldValueSetTime', PLARGE_INTEGER),
    )

class LsarQuerySecretResponse(NDRCALL):
    structure = (
       ('EncryptedCurrentValue', PPLSAPR_CR_CIPHER_VALUE),
       ('CurrentValueSetTime', PLARGE_INTEGER),
       ('EncryptedOldValue', PPLSAPR_CR_CIPHER_VALUE),
       ('OldValueSetTime', PLARGE_INTEGER),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.5 LsarStorePrivateData (Opnum 42)
class LsarStorePrivateData(NDRCALL):
    opnum = 42
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('KeyName', RPC_UNICODE_STRING),
       ('EncryptedData', PLSAPR_CR_CIPHER_VALUE),
    )

class LsarStorePrivateDataResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.6.6 LsarRetrievePrivateData (Opnum 43)
class LsarRetrievePrivateData(NDRCALL):
    opnum = 43
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('KeyName', RPC_UNICODE_STRING),
       ('EncryptedData', PLSAPR_CR_CIPHER_VALUE),
    )

class LsarRetrievePrivateDataResponse(NDRCALL):
    structure = (
       ('EncryptedData', PLSAPR_CR_CIPHER_VALUE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.7.1 LsarOpenTrustedDomain (Opnum 25)
# 3.1.4.7.1 LsarQueryInfoTrustedDomain (Opnum 26)
# 3.1.4.7.2 LsarQueryTrustedDomainInfo (Opnum 39)
# 3.1.4.7.3 LsarSetTrustedDomainInfo (Opnum 40)
# 3.1.4.7.4 LsarDeleteTrustedDomain (Opnum 41)
# 3.1.4.7.5 LsarQueryTrustedDomainInfoByName (Opnum 48)
# 3.1.4.7.6 LsarSetTrustedDomainInfoByName (Opnum 49)
# 3.1.4.7.7 LsarEnumerateTrustedDomainsEx (Opnum 50)
class LsarEnumerateTrustedDomainsEx(NDRCALL):
    opnum = 50
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('EnumerationContext', ULONG),
       ('PreferedMaximumLength', ULONG),
    )

class LsarEnumerateTrustedDomainsExResponse(NDRCALL):
    structure = (
       ('EnumerationContext', ULONG),
       ('EnumerationBuffer',LSAPR_TRUSTED_ENUM_BUFFER_EX),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.7.8 LsarEnumerateTrustedDomains (Opnum 13)
class LsarEnumerateTrustedDomains(NDRCALL):
    opnum = 13
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('EnumerationContext', ULONG),
       ('PreferedMaximumLength', ULONG),
    )

class LsarEnumerateTrustedDomainsResponse(NDRCALL):
    structure = (
       ('EnumerationContext', ULONG),
       ('EnumerationBuffer',LSAPR_TRUSTED_ENUM_BUFFER),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.7.9 LsarOpenTrustedDomainByName (Opnum 55)
# 3.1.4.7.10 LsarCreateTrustedDomainEx2 (Opnum 59)
# 3.1.4.7.11 LsarCreateTrustedDomainEx (Opnum 51)
# 3.1.4.7.12 LsarCreateTrustedDomain (Opnum 12)
# 3.1.4.7.14 LsarSetInformationTrustedDomain (Opnum 27)
# 3.1.4.7.15 LsarQueryForestTrustInformation (Opnum 73)
class LsarQueryForestTrustInformation(NDRCALL):
    opnum = 73
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('TrustedDomainName', LSA_UNICODE_STRING),
       ('HighestRecordType', LSA_FOREST_TRUST_RECORD_TYPE),
    )

class LsarQueryForestTrustInformationResponse(NDRCALL):
    structure = (
       ('ForestTrustInfo', PLSA_FOREST_TRUST_INFORMATION),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.7.16 LsarSetForestTrustInformation (Opnum 74)

# 3.1.4.8.1 LsarEnumeratePrivileges (Opnum 2)
class LsarEnumeratePrivileges(NDRCALL):
    opnum = 2
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('EnumerationContext', ULONG),
       ('PreferedMaximumLength', ULONG),
    )

class LsarEnumeratePrivilegesResponse(NDRCALL):
    structure = (
       ('EnumerationContext', ULONG),
       ('EnumerationBuffer', LSAPR_PRIVILEGE_ENUM_BUFFER),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.8.2 LsarLookupPrivilegeValue (Opnum 31)
class LsarLookupPrivilegeValue(NDRCALL):
    opnum = 31
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('Name', RPC_UNICODE_STRING),
    )

class LsarLookupPrivilegeValueResponse(NDRCALL):
    structure = (
       ('Value', LUID),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.8.3 LsarLookupPrivilegeName (Opnum 32)
class LsarLookupPrivilegeName(NDRCALL):
    opnum = 32
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('Value', LUID),
    )

class LsarLookupPrivilegeNameResponse(NDRCALL):
    structure = (
       ('Name', PRPC_UNICODE_STRING),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.8.4 LsarLookupPrivilegeDisplayName (Opnum 33)
class LsarLookupPrivilegeDisplayName(NDRCALL):
    opnum = 33
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('Name', RPC_UNICODE_STRING),
       ('ClientLanguage', USHORT),
       ('ClientSystemDefaultLanguage', USHORT),
    )

class LsarLookupPrivilegeDisplayNameResponse(NDRCALL):
    structure = (
       ('Name', PRPC_UNICODE_STRING),
       ('LanguageReturned', UCHAR),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.9.1 LsarQuerySecurityObject (Opnum 3)
class LsarQuerySecurityObject(NDRCALL):
    opnum = 3
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('SecurityInformation', SECURITY_INFORMATION),
    )

class LsarQuerySecurityObjectResponse(NDRCALL):
    structure = (
       ('SecurityDescriptor', PLSAPR_SR_SECURITY_DESCRIPTOR),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.9.2 LsarSetSecurityObject (Opnum 4)
class LsarSetSecurityObject(NDRCALL):
    opnum = 4
    structure = (
       ('PolicyHandle', LSAPR_HANDLE),
       ('SecurityInformation', SECURITY_INFORMATION),
       ('SecurityDescriptor', LSAPR_SR_SECURITY_DESCRIPTOR),
    )

class LsarSetSecurityObjectResponse(NDRCALL):
    structure = (
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.9.3 LsarDeleteObject (Opnum 34)
class LsarDeleteObject(NDRCALL):
    opnum = 34
    structure = (
       ('ObjectHandle', LSAPR_HANDLE),
    )

class LsarDeleteObjectResponse(NDRCALL):
    structure = (
       ('ObjectHandle', LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

# 3.1.4.9.4 LsarClose (Opnum 0)
class LsarClose(NDRCALL):
    opnum = 0
    structure = (
       ('ObjectHandle', LSAPR_HANDLE),
    )

class LsarCloseResponse(NDRCALL):
    structure = (
       ('ObjectHandle', LSAPR_HANDLE),
       ('ErrorCode', NTSTATUS),
    )

################################################################################
# OPNUMs and their corresponding structures
################################################################################
OPNUMS = {
 0 : (LsarClose, LsarCloseResponse),
 2 : (LsarEnumeratePrivileges, LsarEnumeratePrivilegesResponse),
 3 : (LsarQuerySecurityObject, LsarQuerySecurityObjectResponse),
 4 : (LsarSetSecurityObject, LsarSetSecurityObjectResponse),
 6 : (LsarOpenPolicy, LsarOpenPolicyResponse),
 7 : (LsarQueryInformationPolicy, LsarQueryInformationPolicyResponse),
 8 : (LsarSetInformationPolicy, LsarSetInformationPolicyResponse),
10 : (LsarCreateAccount, LsarCreateAccountResponse),
11 : (LsarEnumerateAccounts, LsarEnumerateAccountsResponse),
#12 : (LsarCreateTrustedDomain, LsarCreateTrustedDomainResponse),
13 : (LsarEnumerateTrustedDomains, LsarEnumerateTrustedDomainsResponse),
16 : (LsarCreateSecret, LsarCreateSecretResponse),
17 : (LsarOpenAccount, LsarOpenAccountResponse),
18 : (LsarEnumeratePrivilegesAccount, LsarEnumeratePrivilegesAccountResponse),
19 : (LsarAddPrivilegesToAccount, LsarAddPrivilegesToAccountResponse),
20 : (LsarRemovePrivilegesFromAccount, LsarRemovePrivilegesFromAccountResponse),
23 : (LsarGetSystemAccessAccount, LsarGetSystemAccessAccountResponse),
24 : (LsarSetSystemAccessAccount, LsarSetSystemAccessAccountResponse),
#25 : (LsarOpenTrustedDomain, LsarOpenTrustedDomainResponse),
#26 : (LsarQueryInfoTrustedDomain, LsarQueryInfoTrustedDomainResponse),
#27 : (LsarSetInformationTrustedDomain, LsarSetInformationTrustedDomainResponse),
28 : (LsarOpenSecret, LsarOpenSecretResponse),
29 : (LsarSetSecret, LsarSetSecretResponse),
30 : (LsarQuerySecret, LsarQuerySecretResponse),
31 : (LsarLookupPrivilegeValue, LsarLookupPrivilegeValueResponse),
32 : (LsarLookupPrivilegeName, LsarLookupPrivilegeNameResponse),
33 : (LsarLookupPrivilegeDisplayName, LsarLookupPrivilegeDisplayNameResponse),
34 : (LsarDeleteObject, LsarDeleteObjectResponse),
35 : (LsarEnumerateAccountsWithUserRight, LsarEnumerateAccountsWithUserRightResponse),
36 : (LsarEnumerateAccountRights, LsarEnumerateAccountRightsResponse),
37 : (LsarAddAccountRights, LsarAddAccountRightsResponse),
38 : (LsarRemoveAccountRights, LsarRemoveAccountRightsResponse),
#39 : (LsarQueryTrustedDomainInfo, LsarQueryTrustedDomainInfoResponse),
#40 : (LsarSetTrustedDomainInfo, LsarSetTrustedDomainInfoResponse),
#41 : (LsarDeleteTrustedDomain, LsarDeleteTrustedDomainResponse),
42 : (LsarStorePrivateData, LsarStorePrivateDataResponse),
43 : (LsarRetrievePrivateData, LsarRetrievePrivateDataResponse),
44 : (LsarOpenPolicy2, LsarOpenPolicy2Response),
46 : (LsarQueryInformationPolicy2, LsarQueryInformationPolicy2Response),
47 : (LsarSetInformationPolicy2, LsarSetInformationPolicy2Response),
#48 : (LsarQueryTrustedDomainInfoByName, LsarQueryTrustedDomainInfoByNameResponse),
#49 : (LsarSetTrustedDomainInfoByName, LsarSetTrustedDomainInfoByNameResponse),
50 : (LsarEnumerateTrustedDomainsEx, LsarEnumerateTrustedDomainsExResponse),
#51 : (LsarCreateTrustedDomainEx, LsarCreateTrustedDomainExResponse),
53 : (LsarQueryDomainInformationPolicy, LsarQueryDomainInformationPolicyResponse),
#54 : (LsarSetDomainInformationPolicy, LsarSetDomainInformationPolicyResponse),
#55 : (LsarOpenTrustedDomainByName, LsarOpenTrustedDomainByNameResponse),
#59 : (LsarCreateTrustedDomainEx2, LsarCreateTrustedDomainEx2Response),
#73 : (LsarQueryForestTrustInformation, LsarQueryForestTrustInformationResponse),
#74 : (LsarSetForestTrustInformation, LsarSetForestTrustInformationResponse),
}

################################################################################
# HELPER FUNCTIONS
################################################################################
async def hLsarOpenPolicy2(dce, desiredAccess = MAXIMUM_ALLOWED):
    request = LsarOpenPolicy2()
    request['SystemName'] = NULL
    request['ObjectAttributes']['RootDirectory'] = NULL
    request['ObjectAttributes']['ObjectName'] = NULL
    request['ObjectAttributes']['SecurityDescriptor'] = NULL
    request['ObjectAttributes']['SecurityQualityOfService'] = NULL
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarOpenPolicy(dce, desiredAccess = MAXIMUM_ALLOWED):
    request = LsarOpenPolicy()
    request['SystemName'] = NULL
    request['ObjectAttributes']['RootDirectory'] = NULL
    request['ObjectAttributes']['ObjectName'] = NULL
    request['ObjectAttributes']['SecurityDescriptor'] = NULL
    request['ObjectAttributes']['SecurityQualityOfService'] = NULL
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarQueryInformationPolicy2(dce, policyHandle, informationClass):
    request = LsarQueryInformationPolicy2()
    request['PolicyHandle'] = policyHandle
    request['InformationClass'] = informationClass
    return await dce.request(request)

async def hLsarQueryInformationPolicy(dce, policyHandle, informationClass):
    request = LsarQueryInformationPolicy()
    request['PolicyHandle'] = policyHandle
    request['InformationClass'] = informationClass
    return await dce.request(request)

async def hLsarQueryDomainInformationPolicy(dce, policyHandle, informationClass):
    request = LsarQueryInformationPolicy()
    request['PolicyHandle'] = policyHandle
    request['InformationClass'] = informationClass
    return await dce.request(request)

async def hLsarEnumerateAccounts(dce, policyHandle, preferedMaximumLength=0xffffffff):
    request = LsarEnumerateAccounts()
    request['PolicyHandle'] = policyHandle
    request['PreferedMaximumLength'] = preferedMaximumLength
    return await dce.request(request)

async def hLsarEnumerateAccountsWithUserRight(dce, policyHandle, UserRight):
    request = LsarEnumerateAccountsWithUserRight()
    request['PolicyHandle'] = policyHandle
    request['UserRight'] = UserRight
    return await dce.request(request)

async def hLsarEnumerateTrustedDomainsEx(dce, policyHandle, enumerationContext=0, preferedMaximumLength=0xffffffff):
    request = LsarEnumerateTrustedDomainsEx()
    request['PolicyHandle'] = policyHandle
    request['EnumerationContext'] = enumerationContext
    request['PreferedMaximumLength'] = preferedMaximumLength
    return await dce.request(request)

async def hLsarEnumerateTrustedDomains(dce, policyHandle, enumerationContext=0, preferedMaximumLength=0xffffffff):
    request = LsarEnumerateTrustedDomains()
    request['PolicyHandle'] = policyHandle
    request['EnumerationContext'] = enumerationContext
    request['PreferedMaximumLength'] = preferedMaximumLength
    return await dce.request(request)

async def hLsarOpenAccount(dce, policyHandle, accountSid, desiredAccess=MAXIMUM_ALLOWED):
    request = LsarOpenAccount()
    request['PolicyHandle'] = policyHandle
    request['AccountSid'].fromCanonical(accountSid)
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarClose(dce, objectHandle):
    request = LsarClose()
    request['ObjectHandle'] = objectHandle
    return await dce.request(request)

async def hLsarCreateAccount(dce, policyHandle, accountSid, desiredAccess=MAXIMUM_ALLOWED):
    request = LsarCreateAccount()
    request['PolicyHandle'] = policyHandle
    request['AccountSid'].fromCanonical(accountSid)
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarDeleteObject(dce, objectHandle):
    request = LsarDeleteObject()
    request['ObjectHandle'] = objectHandle
    return await dce.request(request)

async def hLsarEnumeratePrivilegesAccount(dce, accountHandle):
    request = LsarEnumeratePrivilegesAccount()
    request['AccountHandle'] = accountHandle
    return await dce.request(request)

async def hLsarGetSystemAccessAccount(dce, accountHandle):
    request = LsarGetSystemAccessAccount()
    request['AccountHandle'] = accountHandle
    return await dce.request(request)

async def hLsarSetSystemAccessAccount(dce, accountHandle, systemAccess):
    request = LsarSetSystemAccessAccount()
    request['AccountHandle'] = accountHandle
    request['SystemAccess'] = systemAccess
    return await dce.request(request)

async def hLsarAddPrivilegesToAccount(dce, accountHandle, privileges):
    request = LsarAddPrivilegesToAccount()
    request['AccountHandle'] = accountHandle
    request['Privileges']['PrivilegeCount'] = len(privileges)
    request['Privileges']['Control'] = 0
    for priv in privileges:
        request['Privileges']['Privilege'].append(priv)

    return await dce.request(request)

async def hLsarRemovePrivilegesFromAccount(dce, accountHandle, privileges, allPrivileges = False):
    request = LsarRemovePrivilegesFromAccount()
    request['AccountHandle'] = accountHandle
    request['Privileges']['Control'] = 0
    if privileges != NULL:
        request['Privileges']['PrivilegeCount'] = len(privileges)
        for priv in privileges:
            request['Privileges']['Privilege'].append(priv)
    else:
        request['Privileges']['PrivilegeCount'] = NULL
    request['AllPrivileges'] = allPrivileges

    return await dce.request(request)

async def hLsarEnumerateAccountRights(dce, policyHandle, accountSid):
    request = LsarEnumerateAccountRights()
    request['PolicyHandle'] = policyHandle
    request['AccountSid'].fromCanonical(accountSid)
    return await dce.request(request)

async def hLsarAddAccountRights(dce, policyHandle, accountSid, userRights):
    request = LsarAddAccountRights()
    request['PolicyHandle'] = policyHandle
    request['AccountSid'].fromCanonical(accountSid)
    request['UserRights']['EntriesRead'] = len(userRights)
    for userRight in userRights:
        right = RPC_UNICODE_STRING()
        right['Data'] = userRight
        request['UserRights']['UserRights'].append(right)

    return await dce.request(request)

async def hLsarRemoveAccountRights(dce, policyHandle, accountSid, userRights):
    request = LsarRemoveAccountRights()
    request['PolicyHandle'] = policyHandle
    request['AccountSid'].fromCanonical(accountSid)
    request['UserRights']['EntriesRead'] = len(userRights)
    for userRight in userRights:
        right = RPC_UNICODE_STRING()
        right['Data'] = userRight
        request['UserRights']['UserRights'].append(right)

    return await dce.request(request)

async def hLsarCreateSecret(dce, policyHandle, secretName, desiredAccess=MAXIMUM_ALLOWED):
    request = LsarCreateSecret()
    request['PolicyHandle'] = policyHandle
    request['SecretName'] = secretName
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarOpenSecret(dce, policyHandle, secretName, desiredAccess=MAXIMUM_ALLOWED):
    request = LsarOpenSecret()
    request['PolicyHandle'] = policyHandle
    request['SecretName'] = secretName
    request['DesiredAccess'] = desiredAccess
    return await dce.request(request)

async def hLsarSetSecret(dce, secretHandle, encryptedCurrentValue, encryptedOldValue):
    request = LsarOpenSecret()
    request['SecretHandle'] = secretHandle
    if encryptedCurrentValue != NULL:
        request['EncryptedCurrentValue']['Length'] = len(encryptedCurrentValue)
        request['EncryptedCurrentValue']['MaximumLength'] = len(encryptedCurrentValue)
        request['EncryptedCurrentValue']['Buffer'] = list(encryptedCurrentValue)
    if encryptedOldValue != NULL:
        request['EncryptedOldValue']['Length'] = len(encryptedOldValue)
        request['EncryptedOldValue']['MaximumLength'] = len(encryptedOldValue)
        request['EncryptedOldValue']['Buffer'] = list(encryptedOldValue)
    return await dce.request(request)

async def hLsarQuerySecret(dce, secretHandle):
    request = LsarQuerySecret()
    request['SecretHandle'] = secretHandle
    request['EncryptedCurrentValue']['Buffer'] = NULL
    request['EncryptedOldValue']['Buffer'] = NULL
    request['OldValueSetTime'] = NULL
    return await dce.request(request)

async def hLsarRetrievePrivateData(dce, policyHandle, keyName):
    request = LsarRetrievePrivateData()
    request['PolicyHandle'] = policyHandle
    request['KeyName'] = keyName
    retVal = await dce.request(request)
    return b''.join(retVal['EncryptedData']['Buffer'])

async def hLsarStorePrivateData(dce, policyHandle, keyName, encryptedData):
    request = LsarStorePrivateData()
    request['PolicyHandle'] = policyHandle
    request['KeyName'] = keyName
    if encryptedData != NULL:
        request['EncryptedData']['Length'] = len(encryptedData)
        request['EncryptedData']['MaximumLength'] = len(encryptedData)
        request['EncryptedData']['Buffer'] = list(encryptedData)
    else:
        request['EncryptedData'] = NULL
    return await dce.request(request)

async def hLsarEnumeratePrivileges(dce, policyHandle, enumerationContext = 0, preferedMaximumLength = 0xffffffff):
    request = LsarEnumeratePrivileges()
    request['PolicyHandle'] = policyHandle
    request['EnumerationContext'] = enumerationContext
    request['PreferedMaximumLength'] = preferedMaximumLength
    return await dce.request(request)

async def hLsarLookupPrivilegeValue(dce, policyHandle, name):
    request = LsarLookupPrivilegeValue()
    request['PolicyHandle'] = policyHandle
    request['Name'] = name
    return await dce.request(request)

async def hLsarLookupPrivilegeName(dce, policyHandle, luid):
    request = LsarLookupPrivilegeName()
    request['PolicyHandle'] = policyHandle
    request['Value'] = luid
    return await dce.request(request)

@red
async def hLsarQuerySecurityObject(dce, policyHandle, securityInformation = OWNER_SECURITY_INFORMATION):
    request = LsarQuerySecurityObject()
    request['PolicyHandle'] = policyHandle
    request['SecurityInformation'] = securityInformation
    retVal, _ =  await rr(dce.request(request))
    return b''.join(retVal['SecurityDescriptor']['SecurityDescriptor'])

async def hLsarSetSecurityObject(dce, policyHandle, securityInformation, securityDescriptor):
    request = LsarSetSecurityObject()
    request['PolicyHandle'] = policyHandle
    request['SecurityInformation'] = securityInformation
    request['SecurityDescriptor']['Length'] = len(securityDescriptor)
    request['SecurityDescriptor']['SecurityDescriptor'] = list(securityDescriptor)
    return await dce.request(request)

async def hLsarSetInformationPolicy2(dce, policyHandle, informationClass, policyInformation):
    request = LsarSetInformationPolicy2()
    request['PolicyHandle'] = policyHandle
    request['InformationClass'] = informationClass
    request['PolicyInformation'] = policyInformation
    return await dce.request(request)

async def hLsarSetInformationPolicy(dce, policyHandle, informationClass, policyInformation):
    request = LsarSetInformationPolicy()
    request['PolicyHandle'] = policyHandle
    request['InformationClass'] = informationClass
    request['PolicyInformation'] = policyInformation
    return await dce.request(request)
