Responder/tools/MultiRelay/impacket-dev/impacket/dcerpc/v5/wkst.py

1183 lines
34 KiB
Python

# 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-WKST] 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 impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRENUM, NDRUNION, NDRUniConformantArray, NDRUniFixedArray, \
NDRPOINTER
from impacket.dcerpc.v5.dtypes import NULL, WSTR, ULONG, LPWSTR, LONG, LARGE_INTEGER, WIDESTR, RPC_UNICODE_STRING, \
LPULONG, LPLONG
from impacket import system_errors
from impacket.uuid import uuidtup_to_bin
from impacket.dcerpc.v5.enum import Enum
from impacket.dcerpc.v5.rpcrt import DCERPCException
MSRPC_UUID_WKST = uuidtup_to_bin(('6BFFD098-A112-3610-9833-46C3F87E345A', '1.0'))
class DCERPCSessionError(DCERPCException):
def __init__(self, error_string=None, error_code=None, packet=None):
DCERPCException.__init__(self, error_string, error_code, packet)
def __str__( self ):
key = self.error_code
if key in system_errors.ERROR_MESSAGES:
error_msg_short = system_errors.ERROR_MESSAGES[key][0]
error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]
return 'WKST SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
else:
return 'WKST SessionError: unknown error code: 0x%x' % self.error_code
################################################################################
# CONSTANTS
################################################################################
# 2.2.1.1 JOIN_MAX_PASSWORD_LENGTH
JOIN_MAX_PASSWORD_LENGTH = 256
# 2.2.1.2 JOIN_OBFUSCATOR_LENGTH
JOIN_OBFUSCATOR_LENGTH = 8
# 2.2.1.3 MAX_PREFERRED_LENGTH
MAX_PREFERRED_LENGTH = 0xffffffff
# 2.2.5.22 USE_INFO_1
USE_OK = 0x00000000
USE_PAUSED = 0x00000001
USE_SESSLOST = 0x00000002
USE_NETERR = 0x00000003
USE_CONN = 0x00000004
USE_RECONN = 0x00000005
USE_WILDCARD = 0xFFFFFFFF
USE_DISKDEV = 0x00000000
USE_SPOOLDEV = 0x00000001
USE_CHARDEV = 0x00000002
USE_IPC = 0x00000003
# 3.2.4.9 NetrUseDel (Opnum 10)
# Force Level
USE_NOFORCE = 0x00000000
USE_FORCE = 0x00000001
USE_LOTS_OF_FORCE = 0x00000002
# 3.2.4.13 NetrJoinDomain2 (Opnum 22)
# Options
NETSETUP_JOIN_DOMAIN = 0x00000001
NETSETUP_ACCT_CREATE = 0x00000002
NETSETUP_ACCT_DELETE = 0x00000004
NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020
NETSETUP_JOIN_UNSECURE = 0x00000040
NETSETUP_MACHINE_PWD_PASSED = 0x00000080
NETSETUP_DEFER_SPN_SET = 0x00000100
NETSETUP_JOIN_DC_ACCOUNT = 0x00000200
NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400
NETSETUP_INSTALL_INVOCATION = 0x00040000
# 3.2.4.14 NetrUnjoinDomain2 (Opnum 23)
# Options
NETSETUP_ACCT_DELETE = 0x00000004
NETSETUP_IGNORE_UNSUPPORTED_FLAGS = 0x10000000
# 3.2.4.15 NetrRenameMachineInDomain2 (Opnum 24)
# Options
NETSETUP_ACCT_CREATE = 0x00000002
NETSETUP_DNS_NAME_CHANGES_ONLY = 0x00001000
################################################################################
# STRUCTURES
################################################################################
# 2.2.2.1 WKSSVC_IDENTIFY_HANDLE
class WKSSVC_IDENTIFY_HANDLE(NDRSTRUCT):
structure = (
('Data', WSTR),
)
class LPWKSSVC_IDENTIFY_HANDLE(NDRPOINTER):
referent = (
('Data', WKSSVC_IDENTIFY_HANDLE),
)
# 2.2.2.2 WKSSVC_IMPERSONATE_HANDLE
class WKSSVC_IMPERSONATE_HANDLE(NDRSTRUCT):
structure = (
('Data',WSTR),
)
class LPWKSSVC_IMPERSONATE_HANDLE(NDRPOINTER):
referent = (
('Data', WKSSVC_IMPERSONATE_HANDLE),
)
# 2.2.3.1 NETSETUP_JOIN_STATUS
class NETSETUP_JOIN_STATUS(NDRENUM):
class enumItems(Enum):
NetSetupUnknownStatus = 0
NetSetupUnjoined = 1
NetSetupWorkgroupName = 2
NetSetupDomainName = 3
# 2.2.3.2 NETSETUP_NAME_TYPE
class NETSETUP_NAME_TYPE(NDRENUM):
class enumItems(Enum):
NetSetupUnknown = 0
NetSetupMachine = 1
NetSetupWorkgroup = 2
NetSetupDomain = 3
NetSetupNonExistentDomain = 4
NetSetupDnsMachine = 5
# 2.2.3.3 NET_COMPUTER_NAME_TYPE
class NET_COMPUTER_NAME_TYPE(NDRENUM):
class enumItems(Enum):
NetPrimaryComputerName = 0
NetAlternateComputerNames = 1
NetAllComputerNames = 2
NetComputerNameTypeMax = 3
# 2.2.5.1 WKSTA_INFO_100
class WKSTA_INFO_100(NDRSTRUCT):
structure = (
('wki100_platform_id', ULONG),
('wki100_computername', LPWSTR),
('wki100_langroup', LPWSTR),
('wki100_ver_major', ULONG),
('wki100_ver_minor', ULONG),
)
class LPWKSTA_INFO_100(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_100),
)
# 2.2.5.2 WKSTA_INFO_101
class WKSTA_INFO_101(NDRSTRUCT):
structure = (
('wki101_platform_id', ULONG),
('wki101_computername', LPWSTR),
('wki101_langroup', LPWSTR),
('wki101_ver_major', ULONG),
('wki101_ver_minor', ULONG),
('wki101_lanroot', LPWSTR),
)
class LPWKSTA_INFO_101(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_101),
)
# 2.2.5.3 WKSTA_INFO_102
class WKSTA_INFO_102(NDRSTRUCT):
structure = (
('wki102_platform_id', ULONG),
('wki102_computername', LPWSTR),
('wki102_langroup', LPWSTR),
('wki102_ver_major', ULONG),
('wki102_ver_minor', ULONG),
('wki102_lanroot', LPWSTR),
('wki102_logged_on_users', ULONG),
)
class LPWKSTA_INFO_102(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_102),
)
# 2.2.5.4 WKSTA_INFO_502
class WKSTA_INFO_502(NDRSTRUCT):
structure = (
('wki502_char_wait', ULONG),
('wki502_collection_time', ULONG),
('wki502_maximum_collection_count', ULONG),
('wki502_keep_conn', ULONG),
('wki502_max_cmds', ULONG),
('wki502_sess_timeout', ULONG),
('wki502_siz_char_buf', ULONG),
('wki502_max_threads', ULONG),
('wki502_lock_quota', ULONG),
('wki502_lock_increment', ULONG),
('wki502_lock_maximum', ULONG),
('wki502_pipe_increment', ULONG),
('wki502_pipe_maximum', ULONG),
('wki502_cache_file_timeout', ULONG),
('wki502_dormant_file_limit', ULONG),
('wki502_read_ahead_throughput', ULONG),
('wki502_num_mailslot_buffers', ULONG),
('wki502_num_srv_announce_buffers', ULONG),
('wki502_max_illegal_datagram_events', ULONG),
('wki502_illegal_datagram_event_reset_frequency', ULONG),
('wki502_log_election_packets', LONG),
('wki502_use_opportunistic_locking', LONG),
('wki502_use_unlock_behind', LONG),
('wki502_use_close_behind', LONG),
('wki502_buf_named_pipes', LONG),
('wki502_use_lock_read_unlock', LONG),
('wki502_utilize_nt_caching', LONG),
('wki502_use_raw_read', LONG),
('wki502_use_raw_write', LONG),
('wki502_use_write_raw_data', LONG),
('wki502_use_encryption', LONG),
('wki502_buf_files_deny_write', LONG),
('wki502_buf_read_only_files', LONG),
('wki502_force_core_create_mode', LONG),
('wki502_use_512_byte_max_transfer', LONG),
)
class LPWKSTA_INFO_502(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_502),
)
# 2.2.5.5 WKSTA_INFO_1013
class WKSTA_INFO_1013(NDRSTRUCT):
structure = (
('wki1013_keep_conn', ULONG),
)
class LPWKSTA_INFO_1013(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_1013),
)
# 2.2.5.6 WKSTA_INFO_1018
class WKSTA_INFO_1018(NDRSTRUCT):
structure = (
('wki1018_sess_timeout', ULONG),
)
class LPWKSTA_INFO_1018(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_1018),
)
# 2.2.5.7 WKSTA_INFO_1046
class WKSTA_INFO_1046(NDRSTRUCT):
structure = (
('wki1046_dormant_file_limit', ULONG),
)
class LPWKSTA_INFO_1046(NDRPOINTER):
referent = (
('Data', WKSTA_INFO_1046),
)
# 2.2.4.1 WKSTA_INFO
class WKSTA_INFO(NDRUNION):
commonHdr = (
('tag', ULONG),
)
union = {
100: ('WkstaInfo100', LPWKSTA_INFO_100),
101: ('WkstaInfo101', LPWKSTA_INFO_101),
102: ('WkstaInfo102', LPWKSTA_INFO_102),
502: ('WkstaInfo502', LPWKSTA_INFO_502),
1013: ('WkstaInfo1013', LPWKSTA_INFO_1013),
1018: ('WkstaInfo1018', LPWKSTA_INFO_1018),
1046: ('WkstaInfo1046', LPWKSTA_INFO_1046),
}
class LPWKSTA_INFO(NDRPOINTER):
referent = (
('Data', WKSTA_INFO),
)
# 2.2.5.8 WKSTA_TRANSPORT_INFO_0
class WKSTA_TRANSPORT_INFO_0(NDRSTRUCT):
structure = (
('wkti0_quality_of_service', ULONG),
('wkti0_number_of_vcs', ULONG),
('wkti0_transport_name', LPWSTR),
('wkti0_transport_address', LPWSTR),
('wkti0_wan_ish', ULONG),
)
# 2.2.5.9 WKSTA_USER_INFO_0
class WKSTA_USER_INFO_0(NDRSTRUCT):
structure = (
('wkui0_username', LPWSTR),
)
# 2.2.5.10 WKSTA_USER_INFO_1
class WKSTA_USER_INFO_1(NDRSTRUCT):
structure = (
('wkui1_username', LPWSTR),
('wkui1_logon_domain', LPWSTR),
('wkui1_oth_domains', LPWSTR),
('wkui1_logon_server', LPWSTR),
)
# 2.2.5.11 STAT_WORKSTATION_0
class STAT_WORKSTATION_0(NDRSTRUCT):
structure = (
('StatisticsStartTime', LARGE_INTEGER),
('BytesReceived', LARGE_INTEGER),
('SmbsReceived', LARGE_INTEGER),
('PagingReadBytesRequested', LARGE_INTEGER),
('NonPagingReadBytesRequested', LARGE_INTEGER),
('CacheReadBytesRequested', LARGE_INTEGER),
('NetworkReadBytesRequested', LARGE_INTEGER),
('BytesTransmitted', LARGE_INTEGER),
('SmbsTransmitted', LARGE_INTEGER),
('PagingWriteBytesRequested', LARGE_INTEGER),
('NonPagingWriteBytesRequested', LARGE_INTEGER),
('CacheWriteBytesRequested', LARGE_INTEGER),
('NetworkWriteBytesRequested', LARGE_INTEGER),
('InitiallyFailedOperations', ULONG),
('FailedCompletionOperations', ULONG),
('ReadOperations', ULONG),
('RandomReadOperations', ULONG),
('ReadSmbs', ULONG),
('LargeReadSmbs', ULONG),
('SmallReadSmbs', ULONG),
('WriteOperations', ULONG),
('RandomWriteOperations', ULONG),
('WriteSmbs', ULONG),
('LargeWriteSmbs', ULONG),
('SmallWriteSmbs', ULONG),
('RawReadsDenied', ULONG),
('RawWritesDenied', ULONG),
('NetworkErrors', ULONG),
('Sessions', ULONG),
('FailedSessions', ULONG),
('Reconnects', ULONG),
('CoreConnects', ULONG),
('Lanman20Connects', ULONG),
('Lanman21Connects', ULONG),
('LanmanNtConnects', ULONG),
('ServerDisconnects', ULONG),
('HungSessions', ULONG),
('UseCount', ULONG),
('FailedUseCount', ULONG),
('CurrentCommands', ULONG),
)
class LPSTAT_WORKSTATION_0(NDRPOINTER):
referent = (
('Data', STAT_WORKSTATION_0),
)
# 2.2.5.12 WKSTA_USER_INFO_0_CONTAINER
class WKSTA_USER_INFO_0_ARRAY(NDRUniConformantArray):
item = WKSTA_USER_INFO_0
class LPWKSTA_USER_INFO_0_ARRAY(NDRPOINTER):
referent = (
('Data', WKSTA_USER_INFO_0_ARRAY),
)
class WKSTA_USER_INFO_0_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPWKSTA_USER_INFO_0_ARRAY),
)
class LPWKSTA_USER_INFO_0_CONTAINER(NDRPOINTER):
referent = (
('Data', WKSTA_USER_INFO_0_CONTAINER),
)
# 2.2.5.13 WKSTA_USER_INFO_1_CONTAINER
class WKSTA_USER_INFO_1_ARRAY(NDRUniConformantArray):
item = WKSTA_USER_INFO_1
class LPWKSTA_USER_INFO_1_ARRAY(NDRPOINTER):
referent = (
('Data', WKSTA_USER_INFO_1_ARRAY),
)
class WKSTA_USER_INFO_1_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPWKSTA_USER_INFO_1_ARRAY),
)
class LPWKSTA_USER_INFO_1_CONTAINER(NDRPOINTER):
referent = (
('Data', WKSTA_USER_INFO_1_CONTAINER),
)
# 2.2.5.14 WKSTA_USER_ENUM_STRUCT
class WKSTA_USER_ENUM_UNION(NDRUNION):
commonHdr = (
('tag', ULONG),
)
union = {
0: ('Level0', LPWKSTA_USER_INFO_0_CONTAINER),
1: ('Level1', LPWKSTA_USER_INFO_1_CONTAINER),
}
class WKSTA_USER_ENUM_STRUCT(NDRSTRUCT):
structure = (
('Level', ULONG),
('WkstaUserInfo', WKSTA_USER_ENUM_UNION),
)
# 2.2.5.15 WKSTA_TRANSPORT_INFO_0_CONTAINER
class WKSTA_TRANSPORT_INFO_0_ARRAY(NDRUniConformantArray):
item = WKSTA_TRANSPORT_INFO_0
class LPWKSTA_TRANSPORT_INFO_0_ARRAY(NDRPOINTER):
referent = (
('Data', WKSTA_TRANSPORT_INFO_0_ARRAY),
)
class WKSTA_TRANSPORT_INFO_0_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPWKSTA_TRANSPORT_INFO_0_ARRAY),
)
class LPWKSTA_TRANSPORT_INFO_0_CONTAINER(NDRPOINTER):
referent = (
('Data', WKSTA_TRANSPORT_INFO_0_CONTAINER),
)
# 2.2.5.16 WKSTA_TRANSPORT_ENUM_STRUCT
class WKSTA_TRANSPORT_ENUM_UNION(NDRUNION):
commonHdr = (
('tag', ULONG),
)
union = {
0: ('Level0', LPWKSTA_TRANSPORT_INFO_0_CONTAINER),
}
class WKSTA_TRANSPORT_ENUM_STRUCT(NDRSTRUCT):
structure = (
('Level', ULONG),
('WkstaTransportInfo', WKSTA_TRANSPORT_ENUM_UNION),
)
# 2.2.5.17 JOINPR_USER_PASSWORD
class WCHAR_ARRAY(WIDESTR):
def getDataLen(self, data, offset=0):
return JOIN_MAX_PASSWORD_LENGTH
class CHAR_ARRAY(NDRUniFixedArray):
def getDataLen(self, data, offset=0):
return JOIN_OBFUSCATOR_LENGTH
class JOINPR_USER_PASSWORD(NDRSTRUCT):
structure = (
('Obfuscator', CHAR_ARRAY),
('Buffer', WCHAR_ARRAY),
)
# 2.2.5.18 JOINPR_ENCRYPTED_USER_PASSWORD
class JOINPR_ENCRYPTED_USER_PASSWORD(NDRSTRUCT):
structure = (
('Buffer', '524s=b""'),
)
def getAlignment(self):
return 1
class PJOINPR_ENCRYPTED_USER_PASSWORD(NDRPOINTER):
referent = (
('Data', JOINPR_ENCRYPTED_USER_PASSWORD),
)
# 2.2.5.19 UNICODE_STRING
UNICODE_STRING = WSTR
class PUNICODE_STRING(NDRPOINTER):
referent = (
('Data', UNICODE_STRING),
)
# 2.2.5.20 NET_COMPUTER_NAME_ARRAY
class UNICODE_STRING_ARRAY(NDRUniConformantArray):
item = RPC_UNICODE_STRING
class PUNICODE_STRING_ARRAY(NDRPOINTER):
referent = (
('Data', UNICODE_STRING_ARRAY),
)
class NET_COMPUTER_NAME_ARRAY(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('ComputerNames', PUNICODE_STRING_ARRAY),
)
class PNET_COMPUTER_NAME_ARRAY(NDRPOINTER):
referent = (
('Data', NET_COMPUTER_NAME_ARRAY),
)
# 2.2.5.21 USE_INFO_0
class USE_INFO_0(NDRSTRUCT):
structure = (
('ui0_local', LPWSTR),
('ui0_remote', LPWSTR),
)
class LPUSE_INFO_0(NDRPOINTER):
referent = (
('Data', USE_INFO_0),
)
# 2.2.5.22 USE_INFO_1
class USE_INFO_1(NDRSTRUCT):
structure = (
('ui1_local', LPWSTR),
('ui1_remote', LPWSTR),
('ui1_password', LPWSTR),
('ui1_status', ULONG),
('ui1_asg_type', ULONG),
('ui1_refcount', ULONG),
('ui1_usecount', ULONG),
)
class LPUSE_INFO_1(NDRPOINTER):
referent = (
('Data', USE_INFO_1),
)
# 2.2.5.23 USE_INFO_2
class USE_INFO_2(NDRSTRUCT):
structure = (
('ui2_useinfo', USE_INFO_1),
('ui2_username', LPWSTR),
('ui2_domainname', LPWSTR),
)
class LPUSE_INFO_2(NDRPOINTER):
referent = (
('Data', USE_INFO_2),
)
# 2.2.5.24 USE_INFO_3
class USE_INFO_3(NDRSTRUCT):
structure = (
('ui3_ui2', USE_INFO_2),
('ui3_flags', ULONG),
)
class LPUSE_INFO_3(NDRPOINTER):
referent = (
('Data', USE_INFO_3),
)
# 2.2.4.2 USE_INFO
class USE_INFO(NDRUNION):
commonHdr = (
('tag', ULONG),
)
union = {
0: ('UseInfo0', LPUSE_INFO_0),
1: ('UseInfo1', LPUSE_INFO_1),
2: ('UseInfo2', LPUSE_INFO_2),
3: ('UseInfo3', LPUSE_INFO_3),
}
# 2.2.5.25 USE_INFO_0_CONTAINER
class USE_INFO_0_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPUSE_INFO_0),
)
class LPUSE_INFO_0_CONTAINER(NDRPOINTER):
referent = (
('Data', USE_INFO_0_CONTAINER),
)
# 2.2.5.26 USE_INFO_1_CONTAINER
class USE_INFO_1_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPUSE_INFO_1),
)
class LPUSE_INFO_1_CONTAINER(NDRPOINTER):
referent = (
('Data', USE_INFO_1_CONTAINER),
)
# 2.2.5.27 USE_INFO_2_CONTAINER
class USE_INFO_2_CONTAINER(NDRSTRUCT):
structure = (
('EntriesRead', ULONG),
('Buffer', LPUSE_INFO_2),
)
class LPUSE_INFO_2_CONTAINER(NDRPOINTER):
referent = (
('Data', USE_INFO_2_CONTAINER),
)
# 2.2.5.28 USE_ENUM_STRUCT
class USE_ENUM_UNION(NDRUNION):
commonHdr = (
('tag', ULONG),
)
union = {
0: ('Level0', LPUSE_INFO_0_CONTAINER),
1: ('Level1', LPUSE_INFO_1_CONTAINER),
2: ('Level2', LPUSE_INFO_2_CONTAINER),
}
class USE_ENUM_STRUCT(NDRSTRUCT):
structure = (
('Level', ULONG),
('UseInfo', USE_ENUM_UNION),
)
################################################################################
# RPC CALLS
################################################################################
# 3.2.4.1 NetrWkstaGetInfo (Opnum 0)
class NetrWkstaGetInfo(NDRCALL):
opnum = 0
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('Level', ULONG),
)
class NetrWkstaGetInfoResponse(NDRCALL):
structure = (
('WkstaInfo',WKSTA_INFO),
('ErrorCode',ULONG),
)
# 3.2.4.2 NetrWkstaSetInfo (Opnum 1)
class NetrWkstaSetInfo(NDRCALL):
opnum = 1
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('Level', ULONG),
('WkstaInfo',WKSTA_INFO),
('ErrorParameter',LPULONG),
)
class NetrWkstaSetInfoResponse(NDRCALL):
structure = (
('ErrorParameter',LPULONG),
('ErrorCode',ULONG),
)
# 3.2.4.3 NetrWkstaUserEnum (Opnum 2)
class NetrWkstaUserEnum(NDRCALL):
opnum = 2
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('UserInfo', WKSTA_USER_ENUM_STRUCT),
('PreferredMaximumLength', ULONG),
('ResumeHandle', LPULONG),
)
class NetrWkstaUserEnumResponse(NDRCALL):
structure = (
('UserInfo',WKSTA_USER_ENUM_STRUCT),
('TotalEntries',ULONG),
('ResumeHandle',ULONG),
('ErrorCode',ULONG),
)
# 3.2.4.4 NetrWkstaTransportEnum (Opnum 5)
class NetrWkstaTransportEnum(NDRCALL):
opnum = 5
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('TransportInfo', WKSTA_TRANSPORT_ENUM_STRUCT),
('PreferredMaximumLength', ULONG),
('ResumeHandle', LPULONG),
)
class NetrWkstaTransportEnumResponse(NDRCALL):
structure = (
('TransportInfo',WKSTA_TRANSPORT_ENUM_STRUCT),
('TotalEntries',ULONG),
('ResumeHandle',ULONG),
('ErrorCode',ULONG),
)
# 3.2.4.5 NetrWkstaTransportAdd (Opnum 6)
class NetrWkstaTransportAdd(NDRCALL):
opnum = 6
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('Level', ULONG),
('TransportInfo',WKSTA_TRANSPORT_INFO_0),
('ErrorParameter',LPULONG),
)
class NetrWkstaTransportAddResponse(NDRCALL):
structure = (
('ErrorParameter',LPULONG),
('ErrorCode',ULONG),
)
# 3.2.4.7 NetrUseAdd (Opnum 8)
class NetrUseAdd(NDRCALL):
opnum = 8
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('Level', ULONG),
('InfoStruct',USE_INFO),
('ErrorParameter',LPULONG),
)
class NetrUseAddResponse(NDRCALL):
structure = (
('ErrorParameter',LPULONG),
('ErrorCode',ULONG),
)
# 3.2.4.8 NetrUseGetInfo (Opnum 9)
class NetrUseGetInfo(NDRCALL):
opnum = 9
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('UseName', WSTR),
('Level',ULONG),
)
class NetrUseGetInfoResponse(NDRCALL):
structure = (
('InfoStruct',USE_INFO),
('ErrorCode',ULONG),
)
# 3.2.4.9 NetrUseDel (Opnum 10)
class NetrUseDel(NDRCALL):
opnum = 10
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('UseName', WSTR),
('ForceLevel',ULONG),
)
class NetrUseDelResponse(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.10 NetrUseEnum (Opnum 11)
class NetrUseEnum(NDRCALL):
opnum = 11
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('InfoStruct', USE_ENUM_STRUCT),
('PreferredMaximumLength',ULONG),
('ResumeHandle',LPULONG),
)
class NetrUseEnumResponse(NDRCALL):
structure = (
('InfoStruct',USE_ENUM_STRUCT),
('TotalEntries',ULONG),
('ResumeHandle',LPULONG),
('ErrorCode',ULONG),
)
# 3.2.4.11 NetrWorkstationStatisticsGet (Opnum 13)
class NetrWorkstationStatisticsGet(NDRCALL):
opnum = 13
structure = (
('ServerName', LPWKSSVC_IDENTIFY_HANDLE),
('ServiceName', LPWSTR),
('Level',ULONG),
('Options',ULONG),
)
class NetrWorkstationStatisticsGetResponse(NDRCALL):
structure = (
('Buffer',LPSTAT_WORKSTATION_0),
('ErrorCode',ULONG),
)
# 3.2.4.12 NetrGetJoinInformation (Opnum 20)
class NetrGetJoinInformation(NDRCALL):
opnum = 20
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('NameBuffer', LPWSTR),
)
class NetrGetJoinInformationResponse(NDRCALL):
structure = (
('NameBuffer',LPWSTR),
('BufferType',NETSETUP_JOIN_STATUS),
('ErrorCode',ULONG),
)
# 3.2.4.13 NetrJoinDomain2 (Opnum 22)
class NetrJoinDomain2(NDRCALL):
opnum = 22
structure = (
('ServerName', LPWSTR),
('DomainNameParam', WSTR),
('MachineAccountOU', LPWSTR),
('AccountName', LPWSTR),
('Password', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Options', ULONG),
)
class NetrJoinDomain2Response(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.14 NetrUnjoinDomain2 (Opnum 23)
class NetrUnjoinDomain2(NDRCALL):
opnum = 23
structure = (
('ServerName', LPWSTR),
('AccountName', LPWSTR),
('Password', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Options', ULONG),
)
class NetrUnjoinDomain2Response(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.15 NetrRenameMachineInDomain2 (Opnum 24)
class NetrRenameMachineInDomain2(NDRCALL):
opnum = 24
structure = (
('ServerName', LPWSTR),
('MachineName', LPWSTR),
('AccountName', LPWSTR),
('Password', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Options', ULONG),
)
class NetrRenameMachineInDomain2Response(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.16 NetrValidateName2 (Opnum 25)
class NetrValidateName2(NDRCALL):
opnum = 25
structure = (
('ServerName', LPWSTR),
('NameToValidate', WSTR),
('AccountName', LPWSTR),
('Password', PJOINPR_ENCRYPTED_USER_PASSWORD),
('NameType', NETSETUP_NAME_TYPE),
)
class NetrValidateName2Response(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.17 NetrGetJoinableOUs2 (Opnum 26)
class NetrGetJoinableOUs2(NDRCALL):
opnum = 26
structure = (
('ServerName', LPWSTR),
('DomainNameParam', WSTR),
('AccountName', LPWSTR),
('Password', PJOINPR_ENCRYPTED_USER_PASSWORD),
('OUCount', ULONG),
)
class NetrGetJoinableOUs2Response(NDRCALL):
structure = (
('OUCount', LPLONG),
('OUs',PUNICODE_STRING_ARRAY),
('ErrorCode',ULONG),
)
# 3.2.4.18 NetrAddAlternateComputerName (Opnum 27)
class NetrAddAlternateComputerName(NDRCALL):
opnum = 27
structure = (
('ServerName', LPWSTR),
('AlternateName', LPWSTR),
('DomainAccount', LPWSTR),
('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Reserved', ULONG),
)
class NetrAddAlternateComputerNameResponse(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.19 NetrRemoveAlternateComputerName (Opnum 28)
class NetrRemoveAlternateComputerName(NDRCALL):
opnum = 28
structure = (
('ServerName', LPWSTR),
('AlternateName', LPWSTR),
('DomainAccount', LPWSTR),
('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Reserved', ULONG),
)
class NetrRemoveAlternateComputerNameResponse(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.20 NetrSetPrimaryComputerName (Opnum 29)
class NetrSetPrimaryComputerName(NDRCALL):
opnum = 29
structure = (
('ServerName', LPWSTR),
('PrimaryName', LPWSTR),
('DomainAccount', LPWSTR),
('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD),
('Reserved', ULONG),
)
class NetrSetPrimaryComputerNameResponse(NDRCALL):
structure = (
('ErrorCode',ULONG),
)
# 3.2.4.21 NetrEnumerateComputerNames (Opnum 30)
class NetrEnumerateComputerNames(NDRCALL):
opnum = 30
structure = (
('ServerName', LPWKSSVC_IMPERSONATE_HANDLE),
('NameType', NET_COMPUTER_NAME_TYPE),
('Reserved', ULONG),
)
class NetrEnumerateComputerNamesResponse(NDRCALL):
structure = (
('ComputerNames',PNET_COMPUTER_NAME_ARRAY),
('ErrorCode',ULONG),
)
################################################################################
# OPNUMs and their corresponding structures
################################################################################
OPNUMS = {
0 : (NetrWkstaGetInfo, NetrWkstaGetInfoResponse),
1 : (NetrWkstaSetInfo, NetrWkstaSetInfoResponse),
2 : (NetrWkstaUserEnum, NetrWkstaUserEnumResponse),
5 : (NetrWkstaTransportEnum, NetrWkstaTransportEnumResponse),
6 : (NetrWkstaTransportAdd, NetrWkstaTransportAddResponse),
# 7 : (NetrWkstaTransportDel, NetrWkstaTransportDelResponse),
8 : (NetrUseAdd, NetrUseAddResponse),
9 : (NetrUseGetInfo, NetrUseGetInfoResponse),
10 : (NetrUseDel, NetrUseDelResponse),
11 : (NetrUseEnum, NetrUseEnumResponse),
13 : (NetrWorkstationStatisticsGet, NetrWorkstationStatisticsGetResponse),
20 : (NetrGetJoinInformation, NetrGetJoinInformationResponse),
22 : (NetrJoinDomain2, NetrJoinDomain2Response),
23 : (NetrUnjoinDomain2, NetrUnjoinDomain2Response),
24 : (NetrRenameMachineInDomain2, NetrRenameMachineInDomain2Response),
25 : (NetrValidateName2, NetrValidateName2Response),
26 : (NetrGetJoinableOUs2, NetrGetJoinableOUs2Response),
27 : (NetrAddAlternateComputerName, NetrAddAlternateComputerNameResponse),
28 : (NetrRemoveAlternateComputerName, NetrRemoveAlternateComputerNameResponse),
29 : (NetrSetPrimaryComputerName, NetrSetPrimaryComputerNameResponse),
30 : (NetrEnumerateComputerNames, NetrEnumerateComputerNamesResponse),
}
################################################################################
# HELPER FUNCTIONS
################################################################################
def checkNullString(string):
if string == NULL:
return string
if string[-1:] != '\x00':
return string + '\x00'
else:
return string
def hNetrWkstaGetInfo(dce, level):
request = NetrWkstaGetInfo()
request['ServerName'] = '\x00'*10
request['Level'] = level
return dce.request(request)
def hNetrWkstaUserEnum(dce, level, preferredMaximumLength=0xffffffff):
request = NetrWkstaUserEnum()
request['ServerName'] = '\x00'*10
request['UserInfo']['Level'] = level
request['UserInfo']['WkstaUserInfo']['tag'] = level
request['PreferredMaximumLength'] = preferredMaximumLength
return dce.request(request)
def hNetrWkstaTransportEnum(dce, level, resumeHandle = 0, preferredMaximumLength = 0xffffffff):
request = NetrWkstaTransportEnum()
request['ServerName'] = '\x00'*10
request['TransportInfo']['Level'] = level
request['TransportInfo']['WkstaTransportInfo']['tag'] = level
request['ResumeHandle'] = resumeHandle
request['PreferredMaximumLength'] = preferredMaximumLength
return dce.request(request)
def hNetrWkstaSetInfo(dce, level, wkstInfo):
request = NetrWkstaSetInfo()
request['ServerName'] = '\x00'*10
request['Level'] = level
request['WkstaInfo']['tag'] = level
request['WkstaInfo']['WkstaInfo%d'% level] = wkstInfo
return dce.request(request)
def hNetrWorkstationStatisticsGet(dce, serviceName, level, options):
request = NetrWorkstationStatisticsGet()
request['ServerName'] = '\x00'*10
request['ServiceName'] = serviceName
request['Level'] = level
request['Options'] = options
return dce.request(request)
def hNetrGetJoinInformation(dce, nameBuffer):
request = NetrGetJoinInformation()
request['ServerName'] = '\x00'*10
request['NameBuffer'] = nameBuffer
return dce.request(request)
def hNetrJoinDomain2(dce, domainNameParam, machineAccountOU, accountName, password, options):
request = NetrJoinDomain2()
request['ServerName'] = '\x00'*10
request['DomainNameParam'] = checkNullString(domainNameParam)
request['MachineAccountOU'] = checkNullString(machineAccountOU)
request['AccountName'] = checkNullString(accountName)
if password == NULL:
request['Password'] = NULL
else:
request['Password']['Buffer'] = password
request['Options'] = options
return dce.request(request)
def hNetrUnjoinDomain2(dce, accountName, password, options):
request = NetrUnjoinDomain2()
request['ServerName'] = '\x00'*10
request['AccountName'] = checkNullString(accountName)
if password == NULL:
request['Password'] = NULL
else:
request['Password']['Buffer'] = password
request['Options'] = options
return dce.request(request)
def hNetrRenameMachineInDomain2(dce, machineName, accountName, password, options):
request = NetrRenameMachineInDomain2()
request['ServerName'] = '\x00'*10
request['MachineName'] = checkNullString(machineName)
request['AccountName'] = checkNullString(accountName)
if password == NULL:
request['Password'] = NULL
else:
request['Password']['Buffer'] = password
request['Options'] = options
return dce.request(request)
def hNetrValidateName2(dce, nameToValidate, accountName, password, nameType):
request = NetrValidateName2()
request['ServerName'] = '\x00'*10
request['NameToValidate'] = checkNullString(nameToValidate)
request['AccountName'] = checkNullString(accountName)
if password == NULL:
request['Password'] = NULL
else:
request['Password']['Buffer'] = password
request['NameType'] = nameType
return dce.request(request)
def hNetrGetJoinableOUs2(dce, domainNameParam, accountName, password, OUCount):
request = NetrGetJoinableOUs2()
request['ServerName'] = '\x00'*10
request['DomainNameParam'] = checkNullString(domainNameParam)
request['AccountName'] = checkNullString(accountName)
if password == NULL:
request['Password'] = NULL
else:
request['Password']['Buffer'] = password
request['OUCount'] = OUCount
return dce.request(request)
def hNetrAddAlternateComputerName(dce, alternateName, domainAccount, encryptedPassword):
request = NetrAddAlternateComputerName()
request['ServerName'] = '\x00'*10
request['AlternateName'] = checkNullString(alternateName)
request['DomainAccount'] = checkNullString(domainAccount)
if encryptedPassword == NULL:
request['EncryptedPassword'] = NULL
else:
request['EncryptedPassword']['Buffer'] = encryptedPassword
return dce.request(request)
def hNetrRemoveAlternateComputerName(dce, alternateName, domainAccount, encryptedPassword):
request = NetrRemoveAlternateComputerName()
request['ServerName'] = '\x00'*10
request['AlternateName'] = checkNullString(alternateName)
request['DomainAccount'] = checkNullString(domainAccount)
if encryptedPassword == NULL:
request['EncryptedPassword'] = NULL
else:
request['EncryptedPassword']['Buffer'] = encryptedPassword
return dce.request(request)
def hNetrSetPrimaryComputerName(dce, primaryName, domainAccount, encryptedPassword):
request = NetrSetPrimaryComputerName()
request['ServerName'] = '\x00'*10
request['PrimaryName'] = checkNullString(primaryName)
request['DomainAccount'] = checkNullString(domainAccount)
if encryptedPassword == NULL:
request['EncryptedPassword'] = NULL
else:
request['EncryptedPassword']['Buffer'] = encryptedPassword
return dce.request(request)
def hNetrEnumerateComputerNames(dce, nameType):
request = NetrEnumerateComputerNames()
request['ServerName'] = '\x00'*10
request['NameType'] = nameType
return dce.request(request)
def hNetrUseAdd(dce, level, infoStruct):
request = NetrUseAdd()
request['ServerName'] = '\x00'*10
request['Level'] = level
request['InfoStruct']['tag'] = level
request['InfoStruct']['UseInfo%d' % level] = infoStruct
return dce.request(request)
def hNetrUseEnum(dce, level, resumeHandle = 0, preferredMaximumLength = 0xffffffff):
request = NetrUseEnum()
request['ServerName'] = '\x00'*10
request['InfoStruct']['Level'] = level
request['InfoStruct']['UseInfo']['tag'] = level
request['InfoStruct']['UseInfo']['Level%d'%level]['Buffer'] = NULL
request['PreferredMaximumLength'] = preferredMaximumLength
request['ResumeHandle'] = resumeHandle
return dce.request(request)
def hNetrUseGetInfo(dce, useName, level):
request = NetrUseGetInfo()
request['ServerName'] = '\x00'*10
request['UseName'] = checkNullString(useName)
request['Level'] = level
return dce.request(request)
def hNetrUseDel(dce, useName, forceLevel=USE_LOTS_OF_FORCE):
request = NetrUseDel()
request['ServerName'] = '\x00'*10
request['UseName'] = checkNullString(useName)
request['ForceLevel'] = forceLevel
return dce.request(request)