1# Copyright (c) 2003-2016 CORE Security Technologies 2# 3# This software is provided under under a slightly modified version 4# of the Apache Software License. See the accompanying LICENSE file 5# for more information. 6# 7# Author: Alberto Solino (@agsolino) 8# 9# Description: 10# [MS-WKST] Interface implementation 11# 12# Best way to learn how to use these calls is to grab the protocol standard 13# so you understand what the call does, and then read the test case located 14# at https://github.com/CoreSecurity/impacket/tree/master/impacket/testcases/SMB_RPC 15# 16# Some calls have helper functions, which makes it even easier to use. 17# They are located at the end of this file. 18# Helper functions start with "h"<name of the call>. 19# There are test cases for them too. 20# 21from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRENUM, NDRUNION, NDRUniConformantArray, NDRUniFixedArray, \ 22 NDRPOINTER 23from impacket.dcerpc.v5.dtypes import NULL, WSTR, ULONG, LPWSTR, LONG, LARGE_INTEGER, WIDESTR, RPC_UNICODE_STRING, \ 24 LPULONG, LPLONG 25from impacket import system_errors 26from impacket.uuid import uuidtup_to_bin 27from impacket.dcerpc.v5.enum import Enum 28from impacket.dcerpc.v5.rpcrt import DCERPCException 29 30MSRPC_UUID_WKST = uuidtup_to_bin(('6BFFD098-A112-3610-9833-46C3F87E345A', '1.0')) 31 32class DCERPCSessionError(DCERPCException): 33 def __init__(self, error_string=None, error_code=None, packet=None): 34 DCERPCException.__init__(self, error_string, error_code, packet) 35 36 def __str__( self ): 37 key = self.error_code 38 if system_errors.ERROR_MESSAGES.has_key(key): 39 error_msg_short = system_errors.ERROR_MESSAGES[key][0] 40 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 41 return 'WKST SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 42 else: 43 return 'WKST SessionError: unknown error code: 0x%x' % self.error_code 44 45################################################################################ 46# CONSTANTS 47################################################################################ 48 49# 2.2.1.1 JOIN_MAX_PASSWORD_LENGTH 50JOIN_MAX_PASSWORD_LENGTH = 256 51 52# 2.2.1.2 JOIN_OBFUSCATOR_LENGTH 53JOIN_OBFUSCATOR_LENGTH = 8 54 55# 2.2.1.3 MAX_PREFERRED_LENGTH 56MAX_PREFERRED_LENGTH = 0xffffffff 57 58# 2.2.5.22 USE_INFO_1 59USE_OK = 0x00000000 60USE_PAUSED = 0x00000001 61USE_SESSLOST = 0x00000002 62USE_NETERR = 0x00000003 63USE_CONN = 0x00000004 64USE_RECONN = 0x00000005 65 66USE_WILDCARD = 0xFFFFFFFF 67USE_DISKDEV = 0x00000000 68USE_SPOOLDEV = 0x00000001 69USE_CHARDEV = 0x00000002 70USE_IPC = 0x00000003 71 72# 3.2.4.9 NetrUseDel (Opnum 10) 73# Force Level 74USE_NOFORCE = 0x00000000 75USE_FORCE = 0x00000001 76USE_LOTS_OF_FORCE = 0x00000002 77 78# 3.2.4.13 NetrJoinDomain2 (Opnum 22) 79# Options 80NETSETUP_JOIN_DOMAIN = 0x00000001 81NETSETUP_ACCT_CREATE = 0x00000002 82NETSETUP_ACCT_DELETE = 0x00000004 83NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020 84NETSETUP_JOIN_UNSECURE = 0x00000040 85NETSETUP_MACHINE_PWD_PASSED = 0x00000080 86NETSETUP_DEFER_SPN_SET = 0x00000100 87NETSETUP_JOIN_DC_ACCOUNT = 0x00000200 88NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400 89NETSETUP_INSTALL_INVOCATION = 0x00040000 90 91# 3.2.4.14 NetrUnjoinDomain2 (Opnum 23) 92# Options 93NETSETUP_ACCT_DELETE = 0x00000004 94NETSETUP_IGNORE_UNSUPPORTED_FLAGS = 0x10000000 95 96# 3.2.4.15 NetrRenameMachineInDomain2 (Opnum 24) 97# Options 98NETSETUP_ACCT_CREATE = 0x00000002 99NETSETUP_DNS_NAME_CHANGES_ONLY = 0x00001000 100 101################################################################################ 102# STRUCTURES 103################################################################################ 104 105# 2.2.2.1 WKSSVC_IDENTIFY_HANDLE 106class WKSSVC_IDENTIFY_HANDLE(NDRSTRUCT): 107 structure = ( 108 ('Data', WSTR), 109 ) 110 111class LPWKSSVC_IDENTIFY_HANDLE(NDRPOINTER): 112 referent = ( 113 ('Data', WKSSVC_IDENTIFY_HANDLE), 114 ) 115 116# 2.2.2.2 WKSSVC_IMPERSONATE_HANDLE 117class WKSSVC_IMPERSONATE_HANDLE(NDRSTRUCT): 118 structure = ( 119 ('Data',WSTR), 120 ) 121 122class LPWKSSVC_IMPERSONATE_HANDLE(NDRPOINTER): 123 referent = ( 124 ('Data', WKSSVC_IMPERSONATE_HANDLE), 125 ) 126 127# 2.2.3.1 NETSETUP_JOIN_STATUS 128class NETSETUP_JOIN_STATUS(NDRENUM): 129 class enumItems(Enum): 130 NetSetupUnknownStatus = 1 131 NetSetupUnjoined = 2 132 NetSetupWorkgroupName = 3 133 NetSetupDomainName = 4 134 135# 2.2.3.2 NETSETUP_NAME_TYPE 136class NETSETUP_NAME_TYPE(NDRENUM): 137 class enumItems(Enum): 138 NetSetupUnknown = 0 139 NetSetupMachine = 1 140 NetSetupWorkgroup = 2 141 NetSetupDomain = 3 142 NetSetupNonExistentDomain = 4 143 NetSetupDnsMachine = 5 144 145# 2.2.3.3 NET_COMPUTER_NAME_TYPE 146class NET_COMPUTER_NAME_TYPE(NDRENUM): 147 class enumItems(Enum): 148 NetPrimaryComputerName = 0 149 NetAlternateComputerNames = 1 150 NetAllComputerNames = 2 151 NetComputerNameTypeMax = 3 152 153# 2.2.5.1 WKSTA_INFO_100 154class WKSTA_INFO_100(NDRSTRUCT): 155 structure = ( 156 ('wki100_platform_id', ULONG), 157 ('wki100_computername', LPWSTR), 158 ('wki100_langroup', LPWSTR), 159 ('wki100_ver_major', ULONG), 160 ('wki100_ver_minor', ULONG), 161 ) 162 163class LPWKSTA_INFO_100(NDRPOINTER): 164 referent = ( 165 ('Data', WKSTA_INFO_100), 166 ) 167 168# 2.2.5.2 WKSTA_INFO_101 169class WKSTA_INFO_101(NDRSTRUCT): 170 structure = ( 171 ('wki101_platform_id', ULONG), 172 ('wki101_computername', LPWSTR), 173 ('wki101_langroup', LPWSTR), 174 ('wki101_ver_major', ULONG), 175 ('wki101_ver_minor', ULONG), 176 ('wki101_lanroot', LPWSTR), 177 ) 178 179class LPWKSTA_INFO_101(NDRPOINTER): 180 referent = ( 181 ('Data', WKSTA_INFO_101), 182 ) 183 184# 2.2.5.3 WKSTA_INFO_102 185class WKSTA_INFO_102(NDRSTRUCT): 186 structure = ( 187 ('wki102_platform_id', ULONG), 188 ('wki102_computername', LPWSTR), 189 ('wki102_langroup', LPWSTR), 190 ('wki102_ver_major', ULONG), 191 ('wki102_ver_minor', ULONG), 192 ('wki102_lanroot', LPWSTR), 193 ('wki102_logged_on_users', ULONG), 194 ) 195 196class LPWKSTA_INFO_102(NDRPOINTER): 197 referent = ( 198 ('Data', WKSTA_INFO_102), 199 ) 200 201# 2.2.5.4 WKSTA_INFO_502 202class WKSTA_INFO_502(NDRSTRUCT): 203 structure = ( 204 ('wki502_char_wait', ULONG), 205 ('wki502_collection_time', ULONG), 206 ('wki502_maximum_collection_count', ULONG), 207 ('wki502_keep_conn', ULONG), 208 ('wki502_max_cmds', ULONG), 209 ('wki502_sess_timeout', ULONG), 210 ('wki502_siz_char_buf', ULONG), 211 ('wki502_max_threads', ULONG), 212 ('wki502_lock_quota', ULONG), 213 ('wki502_lock_increment', ULONG), 214 ('wki502_lock_maximum', ULONG), 215 ('wki502_pipe_increment', ULONG), 216 ('wki502_pipe_maximum', ULONG), 217 ('wki502_cache_file_timeout', ULONG), 218 ('wki502_dormant_file_limit', ULONG), 219 ('wki502_read_ahead_throughput', ULONG), 220 ('wki502_num_mailslot_buffers', ULONG), 221 ('wki502_num_srv_announce_buffers', ULONG), 222 ('wki502_max_illegal_datagram_events', ULONG), 223 ('wki502_illegal_datagram_event_reset_frequency', ULONG), 224 ('wki502_log_election_packets', LONG), 225 ('wki502_use_opportunistic_locking', LONG), 226 ('wki502_use_unlock_behind', LONG), 227 ('wki502_use_close_behind', LONG), 228 ('wki502_buf_named_pipes', LONG), 229 ('wki502_use_lock_read_unlock', LONG), 230 ('wki502_utilize_nt_caching', LONG), 231 ('wki502_use_raw_read', LONG), 232 ('wki502_use_raw_write', LONG), 233 ('wki502_use_write_raw_data', LONG), 234 ('wki502_use_encryption', LONG), 235 ('wki502_buf_files_deny_write', LONG), 236 ('wki502_buf_read_only_files', LONG), 237 ('wki502_force_core_create_mode', LONG), 238 ('wki502_use_512_byte_max_transfer', LONG), 239 ) 240 241class LPWKSTA_INFO_502(NDRPOINTER): 242 referent = ( 243 ('Data', WKSTA_INFO_502), 244 ) 245 246# 2.2.5.5 WKSTA_INFO_1013 247class WKSTA_INFO_1013(NDRSTRUCT): 248 structure = ( 249 ('wki1013_keep_conn', ULONG), 250 ) 251 252class LPWKSTA_INFO_1013(NDRPOINTER): 253 referent = ( 254 ('Data', WKSTA_INFO_1013), 255 ) 256 257# 2.2.5.6 WKSTA_INFO_1018 258class WKSTA_INFO_1018(NDRSTRUCT): 259 structure = ( 260 ('wki1018_sess_timeout', ULONG), 261 ) 262 263class LPWKSTA_INFO_1018(NDRPOINTER): 264 referent = ( 265 ('Data', WKSTA_INFO_1018), 266 ) 267 268# 2.2.5.7 WKSTA_INFO_1046 269class WKSTA_INFO_1046(NDRSTRUCT): 270 structure = ( 271 ('wki1046_dormant_file_limit', ULONG), 272 ) 273 274class LPWKSTA_INFO_1046(NDRPOINTER): 275 referent = ( 276 ('Data', WKSTA_INFO_1046), 277 ) 278 279# 2.2.4.1 WKSTA_INFO 280class WKSTA_INFO(NDRUNION): 281 commonHdr = ( 282 ('tag', ULONG), 283 ) 284 union = { 285 100: ('WkstaInfo100', LPWKSTA_INFO_100), 286 101: ('WkstaInfo101', LPWKSTA_INFO_101), 287 102: ('WkstaInfo102', LPWKSTA_INFO_102), 288 502: ('WkstaInfo502', LPWKSTA_INFO_502), 289 1013: ('WkstaInfo1013', LPWKSTA_INFO_1013), 290 1018: ('WkstaInfo1018', LPWKSTA_INFO_1018), 291 1046: ('WkstaInfo1046', LPWKSTA_INFO_1046), 292 } 293 294class LPWKSTA_INFO(NDRPOINTER): 295 referent = ( 296 ('Data', WKSTA_INFO), 297 ) 298 299# 2.2.5.8 WKSTA_TRANSPORT_INFO_0 300class WKSTA_TRANSPORT_INFO_0(NDRSTRUCT): 301 structure = ( 302 ('wkti0_quality_of_service', ULONG), 303 ('wkti0_number_of_vcs', ULONG), 304 ('wkti0_transport_name', LPWSTR), 305 ('wkti0_transport_address', LPWSTR), 306 ('wkti0_wan_ish', ULONG), 307 ) 308 309# 2.2.5.9 WKSTA_USER_INFO_0 310class WKSTA_USER_INFO_0(NDRSTRUCT): 311 structure = ( 312 ('wkui0_username', LPWSTR), 313 ) 314 315# 2.2.5.10 WKSTA_USER_INFO_1 316class WKSTA_USER_INFO_1(NDRSTRUCT): 317 structure = ( 318 ('wkui1_username', LPWSTR), 319 ('wkui1_logon_domain', LPWSTR), 320 ('wkui1_oth_domains', LPWSTR), 321 ('wkui1_logon_server', LPWSTR), 322 ) 323 324# 2.2.5.11 STAT_WORKSTATION_0 325class STAT_WORKSTATION_0(NDRSTRUCT): 326 structure = ( 327 ('StatisticsStartTime', LARGE_INTEGER), 328 ('BytesReceived', LARGE_INTEGER), 329 ('SmbsReceived', LARGE_INTEGER), 330 ('PagingReadBytesRequested', LARGE_INTEGER), 331 ('NonPagingReadBytesRequested', LARGE_INTEGER), 332 ('CacheReadBytesRequested', LARGE_INTEGER), 333 ('NetworkReadBytesRequested', LARGE_INTEGER), 334 ('BytesTransmitted', LARGE_INTEGER), 335 ('SmbsTransmitted', LARGE_INTEGER), 336 ('PagingWriteBytesRequested', LARGE_INTEGER), 337 ('NonPagingWriteBytesRequested', LARGE_INTEGER), 338 ('CacheWriteBytesRequested', LARGE_INTEGER), 339 ('NetworkWriteBytesRequested', LARGE_INTEGER), 340 ('InitiallyFailedOperations', ULONG), 341 ('FailedCompletionOperations', ULONG), 342 ('ReadOperations', ULONG), 343 ('RandomReadOperations', ULONG), 344 ('ReadSmbs', ULONG), 345 ('LargeReadSmbs', ULONG), 346 ('SmallReadSmbs', ULONG), 347 ('WriteOperations', ULONG), 348 ('RandomWriteOperations', ULONG), 349 ('WriteSmbs', ULONG), 350 ('LargeWriteSmbs', ULONG), 351 ('SmallWriteSmbs', ULONG), 352 ('RawReadsDenied', ULONG), 353 ('RawWritesDenied', ULONG), 354 ('NetworkErrors', ULONG), 355 ('Sessions', ULONG), 356 ('FailedSessions', ULONG), 357 ('Reconnects', ULONG), 358 ('CoreConnects', ULONG), 359 ('Lanman20Connects', ULONG), 360 ('Lanman21Connects', ULONG), 361 ('LanmanNtConnects', ULONG), 362 ('ServerDisconnects', ULONG), 363 ('HungSessions', ULONG), 364 ('UseCount', ULONG), 365 ('FailedUseCount', ULONG), 366 ('CurrentCommands', ULONG), 367 ) 368 369class LPSTAT_WORKSTATION_0(NDRPOINTER): 370 referent = ( 371 ('Data', STAT_WORKSTATION_0), 372 ) 373 374# 2.2.5.12 WKSTA_USER_INFO_0_CONTAINER 375class WKSTA_USER_INFO_0_ARRAY(NDRUniConformantArray): 376 item = WKSTA_USER_INFO_0 377 378class LPWKSTA_USER_INFO_0_ARRAY(NDRPOINTER): 379 referent = ( 380 ('Data', WKSTA_USER_INFO_0_ARRAY), 381 ) 382 383class WKSTA_USER_INFO_0_CONTAINER(NDRSTRUCT): 384 structure = ( 385 ('EntriesRead', ULONG), 386 ('Buffer', LPWKSTA_USER_INFO_0_ARRAY), 387 ) 388 389class LPWKSTA_USER_INFO_0_CONTAINER(NDRPOINTER): 390 referent = ( 391 ('Data', WKSTA_USER_INFO_0_CONTAINER), 392 ) 393 394# 2.2.5.13 WKSTA_USER_INFO_1_CONTAINER 395class WKSTA_USER_INFO_1_ARRAY(NDRUniConformantArray): 396 item = WKSTA_USER_INFO_1 397 398class LPWKSTA_USER_INFO_1_ARRAY(NDRPOINTER): 399 referent = ( 400 ('Data', WKSTA_USER_INFO_1_ARRAY), 401 ) 402 403class WKSTA_USER_INFO_1_CONTAINER(NDRSTRUCT): 404 structure = ( 405 ('EntriesRead', ULONG), 406 ('Buffer', LPWKSTA_USER_INFO_1_ARRAY), 407 ) 408 409class LPWKSTA_USER_INFO_1_CONTAINER(NDRPOINTER): 410 referent = ( 411 ('Data', WKSTA_USER_INFO_1_CONTAINER), 412 ) 413 414# 2.2.5.14 WKSTA_USER_ENUM_STRUCT 415class WKSTA_USER_ENUM_UNION(NDRUNION): 416 commonHdr = ( 417 ('tag', ULONG), 418 ) 419 420 union = { 421 0: ('Level0', LPWKSTA_USER_INFO_0_CONTAINER), 422 1: ('Level1', LPWKSTA_USER_INFO_1_CONTAINER), 423 } 424 425class WKSTA_USER_ENUM_STRUCT(NDRSTRUCT): 426 structure = ( 427 ('Level', ULONG), 428 ('WkstaUserInfo', WKSTA_USER_ENUM_UNION), 429 ) 430 431 432# 2.2.5.15 WKSTA_TRANSPORT_INFO_0_CONTAINER 433class WKSTA_TRANSPORT_INFO_0_ARRAY(NDRUniConformantArray): 434 item = WKSTA_TRANSPORT_INFO_0 435 436class LPWKSTA_TRANSPORT_INFO_0_ARRAY(NDRPOINTER): 437 referent = ( 438 ('Data', WKSTA_TRANSPORT_INFO_0_ARRAY), 439 ) 440 441class WKSTA_TRANSPORT_INFO_0_CONTAINER(NDRSTRUCT): 442 structure = ( 443 ('EntriesRead', ULONG), 444 ('Buffer', LPWKSTA_TRANSPORT_INFO_0_ARRAY), 445 ) 446 447class LPWKSTA_TRANSPORT_INFO_0_CONTAINER(NDRPOINTER): 448 referent = ( 449 ('Data', WKSTA_TRANSPORT_INFO_0_CONTAINER), 450 ) 451 452# 2.2.5.16 WKSTA_TRANSPORT_ENUM_STRUCT 453class WKSTA_TRANSPORT_ENUM_UNION(NDRUNION): 454 commonHdr = ( 455 ('tag', ULONG), 456 ) 457 458 union = { 459 0: ('Level0', LPWKSTA_TRANSPORT_INFO_0_CONTAINER), 460 } 461 462class WKSTA_TRANSPORT_ENUM_STRUCT(NDRSTRUCT): 463 structure = ( 464 ('Level', ULONG), 465 ('WkstaTransportInfo', WKSTA_TRANSPORT_ENUM_UNION), 466 ) 467 468# 2.2.5.17 JOINPR_USER_PASSWORD 469class WCHAR_ARRAY(WIDESTR): 470 def getDataLen(self, data): 471 return JOIN_MAX_PASSWORD_LENGTH 472 473class CHAR_ARRAY(NDRUniFixedArray): 474 def getDataLen(self, data): 475 return JOIN_OBFUSCATOR_LENGTH 476 477class JOINPR_USER_PASSWORD(NDRSTRUCT): 478 structure = ( 479 ('Obfuscator', CHAR_ARRAY), 480 ('Buffer', WCHAR_ARRAY), 481 ) 482 483# 2.2.5.18 JOINPR_ENCRYPTED_USER_PASSWORD 484class JOINPR_ENCRYPTED_USER_PASSWORD(NDRSTRUCT): 485 structure = ( 486 ('Buffer', '524s=""'), 487 ) 488 def getAlignment(self): 489 return 1 490 491class PJOINPR_ENCRYPTED_USER_PASSWORD(NDRPOINTER): 492 referent = ( 493 ('Data', JOINPR_ENCRYPTED_USER_PASSWORD), 494 ) 495 496# 2.2.5.19 UNICODE_STRING 497UNICODE_STRING = WSTR 498class PUNICODE_STRING(NDRPOINTER): 499 referent = ( 500 ('Data', UNICODE_STRING), 501 ) 502 503# 2.2.5.20 NET_COMPUTER_NAME_ARRAY 504class UNICODE_STRING_ARRAY(NDRUniConformantArray): 505 item = RPC_UNICODE_STRING 506 507class PUNICODE_STRING_ARRAY(NDRPOINTER): 508 referent = ( 509 ('Data', UNICODE_STRING_ARRAY), 510 ) 511 512class NET_COMPUTER_NAME_ARRAY(NDRSTRUCT): 513 structure = ( 514 ('EntriesRead', ULONG), 515 ('ComputerNames', PUNICODE_STRING_ARRAY), 516 ) 517 518class PNET_COMPUTER_NAME_ARRAY(NDRPOINTER): 519 referent = ( 520 ('Data', NET_COMPUTER_NAME_ARRAY), 521 ) 522 523# 2.2.5.21 USE_INFO_0 524class USE_INFO_0(NDRSTRUCT): 525 structure = ( 526 ('ui0_local', LPWSTR), 527 ('ui0_remote', LPWSTR), 528 ) 529 530class LPUSE_INFO_0(NDRPOINTER): 531 referent = ( 532 ('Data', USE_INFO_0), 533 ) 534 535# 2.2.5.22 USE_INFO_1 536class USE_INFO_1(NDRSTRUCT): 537 structure = ( 538 ('ui1_local', LPWSTR), 539 ('ui1_remote', LPWSTR), 540 ('ui1_password', LPWSTR), 541 ('ui1_status', ULONG), 542 ('ui1_asg_type', ULONG), 543 ('ui1_refcount', ULONG), 544 ('ui1_usecount', ULONG), 545 ) 546 547class LPUSE_INFO_1(NDRPOINTER): 548 referent = ( 549 ('Data', USE_INFO_1), 550 ) 551 552# 2.2.5.23 USE_INFO_2 553class USE_INFO_2(NDRSTRUCT): 554 structure = ( 555 ('ui2_useinfo', USE_INFO_1), 556 ('ui2_username', LPWSTR), 557 ('ui2_domainname', LPWSTR), 558 ) 559 560class LPUSE_INFO_2(NDRPOINTER): 561 referent = ( 562 ('Data', USE_INFO_2), 563 ) 564 565# 2.2.5.24 USE_INFO_3 566class USE_INFO_3(NDRSTRUCT): 567 structure = ( 568 ('ui3_ui2', USE_INFO_2), 569 ('ui3_flags', ULONG), 570 ) 571 572class LPUSE_INFO_3(NDRPOINTER): 573 referent = ( 574 ('Data', USE_INFO_3), 575 ) 576 577# 2.2.4.2 USE_INFO 578class USE_INFO(NDRUNION): 579 commonHdr = ( 580 ('tag', ULONG), 581 ) 582 583 union = { 584 0: ('UseInfo0', LPUSE_INFO_0), 585 1: ('UseInfo1', LPUSE_INFO_1), 586 2: ('UseInfo2', LPUSE_INFO_2), 587 3: ('UseInfo3', LPUSE_INFO_3), 588 } 589 590# 2.2.5.25 USE_INFO_0_CONTAINER 591class USE_INFO_0_CONTAINER(NDRSTRUCT): 592 structure = ( 593 ('EntriesRead', ULONG), 594 ('Buffer', LPUSE_INFO_0), 595 ) 596 597class LPUSE_INFO_0_CONTAINER(NDRPOINTER): 598 referent = ( 599 ('Data', USE_INFO_0_CONTAINER), 600 ) 601 602# 2.2.5.26 USE_INFO_1_CONTAINER 603class USE_INFO_1_CONTAINER(NDRSTRUCT): 604 structure = ( 605 ('EntriesRead', ULONG), 606 ('Buffer', LPUSE_INFO_1), 607 ) 608 609class LPUSE_INFO_1_CONTAINER(NDRPOINTER): 610 referent = ( 611 ('Data', USE_INFO_1_CONTAINER), 612 ) 613 614# 2.2.5.27 USE_INFO_2_CONTAINER 615class USE_INFO_2_CONTAINER(NDRSTRUCT): 616 structure = ( 617 ('EntriesRead', ULONG), 618 ('Buffer', LPUSE_INFO_2), 619 ) 620 621class LPUSE_INFO_2_CONTAINER(NDRPOINTER): 622 referent = ( 623 ('Data', USE_INFO_2_CONTAINER), 624 ) 625 626# 2.2.5.28 USE_ENUM_STRUCT 627class USE_ENUM_UNION(NDRUNION): 628 commonHdr = ( 629 ('tag', ULONG), 630 ) 631 632 union = { 633 0: ('Level0', LPUSE_INFO_0_CONTAINER), 634 1: ('Level1', LPUSE_INFO_1_CONTAINER), 635 2: ('Level2', LPUSE_INFO_2_CONTAINER), 636 } 637 638class USE_ENUM_STRUCT(NDRSTRUCT): 639 structure = ( 640 ('Level', ULONG), 641 ('UseInfo', USE_ENUM_UNION), 642 ) 643 644################################################################################ 645# RPC CALLS 646################################################################################ 647 648# 3.2.4.1 NetrWkstaGetInfo (Opnum 0) 649class NetrWkstaGetInfo(NDRCALL): 650 opnum = 0 651 structure = ( 652 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 653 ('Level', ULONG), 654 ) 655 656class NetrWkstaGetInfoResponse(NDRCALL): 657 structure = ( 658 ('WkstaInfo',WKSTA_INFO), 659 ('ErrorCode',ULONG), 660 ) 661 662# 3.2.4.2 NetrWkstaSetInfo (Opnum 1) 663class NetrWkstaSetInfo(NDRCALL): 664 opnum = 1 665 structure = ( 666 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 667 ('Level', ULONG), 668 ('WkstaInfo',WKSTA_INFO), 669 ('ErrorParameter',LPULONG), 670 ) 671 672class NetrWkstaSetInfoResponse(NDRCALL): 673 structure = ( 674 ('ErrorParameter',LPULONG), 675 ('ErrorCode',ULONG), 676 ) 677 678# 3.2.4.3 NetrWkstaUserEnum (Opnum 2) 679class NetrWkstaUserEnum(NDRCALL): 680 opnum = 2 681 structure = ( 682 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 683 ('UserInfo', WKSTA_USER_ENUM_STRUCT), 684 ('PreferredMaximumLength', ULONG), 685 ('ResumeHandle', LPULONG), 686 ) 687 688class NetrWkstaUserEnumResponse(NDRCALL): 689 structure = ( 690 ('UserInfo',WKSTA_USER_ENUM_STRUCT), 691 ('TotalEntries',ULONG), 692 ('ResumeHandle',ULONG), 693 ('ErrorCode',ULONG), 694 ) 695 696# 3.2.4.4 NetrWkstaTransportEnum (Opnum 5) 697class NetrWkstaTransportEnum(NDRCALL): 698 opnum = 5 699 structure = ( 700 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 701 ('TransportInfo', WKSTA_TRANSPORT_ENUM_STRUCT), 702 ('PreferredMaximumLength', ULONG), 703 ('ResumeHandle', LPULONG), 704 ) 705 706class NetrWkstaTransportEnumResponse(NDRCALL): 707 structure = ( 708 ('TransportInfo',WKSTA_TRANSPORT_ENUM_STRUCT), 709 ('TotalEntries',ULONG), 710 ('ResumeHandle',ULONG), 711 ('ErrorCode',ULONG), 712 ) 713 714# 3.2.4.5 NetrWkstaTransportAdd (Opnum 6) 715class NetrWkstaTransportAdd(NDRCALL): 716 opnum = 6 717 structure = ( 718 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 719 ('Level', ULONG), 720 ('TransportInfo',WKSTA_TRANSPORT_INFO_0), 721 ('ErrorParameter',LPULONG), 722 ) 723 724class NetrWkstaTransportAddResponse(NDRCALL): 725 structure = ( 726 ('ErrorParameter',LPULONG), 727 ('ErrorCode',ULONG), 728 ) 729 730# 3.2.4.7 NetrUseAdd (Opnum 8) 731class NetrUseAdd(NDRCALL): 732 opnum = 8 733 structure = ( 734 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 735 ('Level', ULONG), 736 ('InfoStruct',USE_INFO), 737 ('ErrorParameter',LPULONG), 738 ) 739 740class NetrUseAddResponse(NDRCALL): 741 structure = ( 742 ('ErrorParameter',LPULONG), 743 ('ErrorCode',ULONG), 744 ) 745 746# 3.2.4.8 NetrUseGetInfo (Opnum 9) 747class NetrUseGetInfo(NDRCALL): 748 opnum = 9 749 structure = ( 750 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 751 ('UseName', WSTR), 752 ('Level',ULONG), 753 ) 754 755class NetrUseGetInfoResponse(NDRCALL): 756 structure = ( 757 ('InfoStruct',USE_INFO), 758 ('ErrorCode',ULONG), 759 ) 760 761# 3.2.4.9 NetrUseDel (Opnum 10) 762class NetrUseDel(NDRCALL): 763 opnum = 10 764 structure = ( 765 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 766 ('UseName', WSTR), 767 ('ForceLevel',ULONG), 768 ) 769 770class NetrUseDelResponse(NDRCALL): 771 structure = ( 772 ('ErrorCode',ULONG), 773 ) 774 775# 3.2.4.10 NetrUseEnum (Opnum 11) 776class NetrUseEnum(NDRCALL): 777 opnum = 11 778 structure = ( 779 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 780 ('InfoStruct', USE_ENUM_STRUCT), 781 ('PreferredMaximumLength',ULONG), 782 ('ResumeHandle',LPULONG), 783 ) 784 785class NetrUseEnumResponse(NDRCALL): 786 structure = ( 787 ('InfoStruct',USE_ENUM_STRUCT), 788 ('TotalEntries',ULONG), 789 ('ResumeHandle',LPULONG), 790 ('ErrorCode',ULONG), 791 ) 792 793# 3.2.4.11 NetrWorkstationStatisticsGet (Opnum 13) 794class NetrWorkstationStatisticsGet(NDRCALL): 795 opnum = 13 796 structure = ( 797 ('ServerName', LPWKSSVC_IDENTIFY_HANDLE), 798 ('ServiceName', LPWSTR), 799 ('Level',ULONG), 800 ('Options',ULONG), 801 ) 802 803class NetrWorkstationStatisticsGetResponse(NDRCALL): 804 structure = ( 805 ('Buffer',LPSTAT_WORKSTATION_0), 806 ('ErrorCode',ULONG), 807 ) 808 809# 3.2.4.12 NetrGetJoinInformation (Opnum 20) 810class NetrGetJoinInformation(NDRCALL): 811 opnum = 20 812 structure = ( 813 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 814 ('NameBuffer', LPWSTR), 815 ) 816 817class NetrGetJoinInformationResponse(NDRCALL): 818 structure = ( 819 ('NameBuffer',LPWSTR), 820 ('BufferType',NETSETUP_JOIN_STATUS), 821 ('ErrorCode',ULONG), 822 ) 823 824# 3.2.4.13 NetrJoinDomain2 (Opnum 22) 825class NetrJoinDomain2(NDRCALL): 826 opnum = 22 827 structure = ( 828 ('ServerName', LPWSTR), 829 ('DomainNameParam', WSTR), 830 ('MachineAccountOU', LPWSTR), 831 ('AccountName', LPWSTR), 832 ('Password', PJOINPR_ENCRYPTED_USER_PASSWORD), 833 ('Options', ULONG), 834 ) 835 836class NetrJoinDomain2Response(NDRCALL): 837 structure = ( 838 ('ErrorCode',ULONG), 839 ) 840 841# 3.2.4.14 NetrUnjoinDomain2 (Opnum 23) 842class NetrUnjoinDomain2(NDRCALL): 843 opnum = 23 844 structure = ( 845 ('ServerName', LPWSTR), 846 ('AccountName', LPWSTR), 847 ('Password', PJOINPR_ENCRYPTED_USER_PASSWORD), 848 ('Options', ULONG), 849 ) 850 851class NetrUnjoinDomain2Response(NDRCALL): 852 structure = ( 853 ('ErrorCode',ULONG), 854 ) 855 856# 3.2.4.15 NetrRenameMachineInDomain2 (Opnum 24) 857class NetrRenameMachineInDomain2(NDRCALL): 858 opnum = 24 859 structure = ( 860 ('ServerName', LPWSTR), 861 ('MachineName', LPWSTR), 862 ('AccountName', LPWSTR), 863 ('Password', PJOINPR_ENCRYPTED_USER_PASSWORD), 864 ('Options', ULONG), 865 ) 866 867class NetrRenameMachineInDomain2Response(NDRCALL): 868 structure = ( 869 ('ErrorCode',ULONG), 870 ) 871 872# 3.2.4.16 NetrValidateName2 (Opnum 25) 873class NetrValidateName2(NDRCALL): 874 opnum = 25 875 structure = ( 876 ('ServerName', LPWSTR), 877 ('NameToValidate', WSTR), 878 ('AccountName', LPWSTR), 879 ('Password', PJOINPR_ENCRYPTED_USER_PASSWORD), 880 ('NameType', NETSETUP_NAME_TYPE), 881 ) 882 883class NetrValidateName2Response(NDRCALL): 884 structure = ( 885 ('ErrorCode',ULONG), 886 ) 887 888# 3.2.4.17 NetrGetJoinableOUs2 (Opnum 26) 889class NetrGetJoinableOUs2(NDRCALL): 890 opnum = 26 891 structure = ( 892 ('ServerName', LPWSTR), 893 ('DomainNameParam', WSTR), 894 ('AccountName', LPWSTR), 895 ('Password', PJOINPR_ENCRYPTED_USER_PASSWORD), 896 ('OUCount', ULONG), 897 ) 898 899class NetrGetJoinableOUs2Response(NDRCALL): 900 structure = ( 901 ('OUCount', LPLONG), 902 ('OUs',PUNICODE_STRING_ARRAY), 903 ('ErrorCode',ULONG), 904 ) 905 906# 3.2.4.18 NetrAddAlternateComputerName (Opnum 27) 907class NetrAddAlternateComputerName(NDRCALL): 908 opnum = 27 909 structure = ( 910 ('ServerName', LPWSTR), 911 ('AlternateName', LPWSTR), 912 ('DomainAccount', LPWSTR), 913 ('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD), 914 ('Reserved', ULONG), 915 ) 916 917class NetrAddAlternateComputerNameResponse(NDRCALL): 918 structure = ( 919 ('ErrorCode',ULONG), 920 ) 921 922# 3.2.4.19 NetrRemoveAlternateComputerName (Opnum 28) 923class NetrRemoveAlternateComputerName(NDRCALL): 924 opnum = 28 925 structure = ( 926 ('ServerName', LPWSTR), 927 ('AlternateName', LPWSTR), 928 ('DomainAccount', LPWSTR), 929 ('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD), 930 ('Reserved', ULONG), 931 ) 932 933class NetrRemoveAlternateComputerNameResponse(NDRCALL): 934 structure = ( 935 ('ErrorCode',ULONG), 936 ) 937 938# 3.2.4.20 NetrSetPrimaryComputerName (Opnum 29) 939class NetrSetPrimaryComputerName(NDRCALL): 940 opnum = 29 941 structure = ( 942 ('ServerName', LPWSTR), 943 ('PrimaryName', LPWSTR), 944 ('DomainAccount', LPWSTR), 945 ('EncryptedPassword', PJOINPR_ENCRYPTED_USER_PASSWORD), 946 ('Reserved', ULONG), 947 ) 948 949class NetrSetPrimaryComputerNameResponse(NDRCALL): 950 structure = ( 951 ('ErrorCode',ULONG), 952 ) 953 954# 3.2.4.21 NetrEnumerateComputerNames (Opnum 30) 955class NetrEnumerateComputerNames(NDRCALL): 956 opnum = 30 957 structure = ( 958 ('ServerName', LPWKSSVC_IMPERSONATE_HANDLE), 959 ('NameType', NET_COMPUTER_NAME_TYPE), 960 ('Reserved', ULONG), 961 ) 962 963class NetrEnumerateComputerNamesResponse(NDRCALL): 964 structure = ( 965 ('ComputerNames',PNET_COMPUTER_NAME_ARRAY), 966 ('ErrorCode',ULONG), 967 ) 968 969################################################################################ 970# OPNUMs and their corresponding structures 971################################################################################ 972OPNUMS = { 973 0 : (NetrWkstaGetInfo, NetrWkstaGetInfoResponse), 974 1 : (NetrWkstaSetInfo, NetrWkstaSetInfoResponse), 975 2 : (NetrWkstaUserEnum, NetrWkstaUserEnumResponse), 976 5 : (NetrWkstaTransportEnum, NetrWkstaTransportEnumResponse), 977 6 : (NetrWkstaTransportAdd, NetrWkstaTransportAddResponse), 978# 7 : (NetrWkstaTransportDel, NetrWkstaTransportDelResponse), 979 8 : (NetrUseAdd, NetrUseAddResponse), 980 9 : (NetrUseGetInfo, NetrUseGetInfoResponse), 98110 : (NetrUseDel, NetrUseDelResponse), 98211 : (NetrUseEnum, NetrUseEnumResponse), 98313 : (NetrWorkstationStatisticsGet, NetrWorkstationStatisticsGetResponse), 98420 : (NetrGetJoinInformation, NetrGetJoinInformationResponse), 98522 : (NetrJoinDomain2, NetrJoinDomain2Response), 98623 : (NetrUnjoinDomain2, NetrUnjoinDomain2Response), 98724 : (NetrRenameMachineInDomain2, NetrRenameMachineInDomain2Response), 98825 : (NetrValidateName2, NetrValidateName2Response), 98926 : (NetrGetJoinableOUs2, NetrGetJoinableOUs2Response), 99027 : (NetrAddAlternateComputerName, NetrAddAlternateComputerNameResponse), 99128 : (NetrRemoveAlternateComputerName, NetrRemoveAlternateComputerNameResponse), 99229 : (NetrSetPrimaryComputerName, NetrSetPrimaryComputerNameResponse), 99330 : (NetrEnumerateComputerNames, NetrEnumerateComputerNamesResponse), 994} 995 996################################################################################ 997# HELPER FUNCTIONS 998################################################################################ 999def checkNullString(string): 1000 if string == NULL: 1001 return string 1002 1003 if string[-1:] != '\x00': 1004 return string + '\x00' 1005 else: 1006 return string 1007 1008def hNetrWkstaGetInfo(dce, level): 1009 request = NetrWkstaGetInfo() 1010 request['ServerName'] = '\x00'*10 1011 request['Level'] = level 1012 return dce.request(request) 1013 1014def hNetrWkstaUserEnum(dce, level, preferredMaximumLength=0xffffffff): 1015 request = NetrWkstaUserEnum() 1016 request['ServerName'] = '\x00'*10 1017 request['UserInfo']['Level'] = level 1018 request['UserInfo']['WkstaUserInfo']['tag'] = level 1019 request['PreferredMaximumLength'] = preferredMaximumLength 1020 return dce.request(request) 1021 1022def hNetrWkstaTransportEnum(dce, level, resumeHandle = 0, preferredMaximumLength = 0xffffffff): 1023 request = NetrWkstaTransportEnum() 1024 request['ServerName'] = '\x00'*10 1025 request['TransportInfo']['Level'] = level 1026 request['TransportInfo']['WkstaTransportInfo']['tag'] = level 1027 request['ResumeHandle'] = resumeHandle 1028 request['PreferredMaximumLength'] = preferredMaximumLength 1029 return dce.request(request) 1030 1031def hNetrWkstaSetInfo(dce, level, wkstInfo): 1032 request = NetrWkstaSetInfo() 1033 request['ServerName'] = '\x00'*10 1034 request['Level'] = level 1035 request['WkstaInfo']['tag'] = level 1036 request['WkstaInfo']['WkstaInfo%d'% level] = wkstInfo 1037 return dce.request(request) 1038 1039def hNetrWorkstationStatisticsGet(dce, serviceName, level, options): 1040 request = NetrWorkstationStatisticsGet() 1041 request['ServerName'] = '\x00'*10 1042 request['ServiceName'] = serviceName 1043 request['Level'] = level 1044 request['Options'] = options 1045 return dce.request(request) 1046 1047def hNetrGetJoinInformation(dce, nameBuffer): 1048 request = NetrGetJoinInformation() 1049 request['ServerName'] = '\x00'*10 1050 request['NameBuffer'] = nameBuffer 1051 return dce.request(request) 1052 1053def hNetrJoinDomain2(dce, domainNameParam, machineAccountOU, accountName, password, options): 1054 request = NetrJoinDomain2() 1055 request['ServerName'] = '\x00'*10 1056 request['DomainNameParam'] = checkNullString(domainNameParam) 1057 request['MachineAccountOU'] = checkNullString(machineAccountOU) 1058 request['AccountName'] = checkNullString(accountName) 1059 if password == NULL: 1060 request['Password'] = NULL 1061 else: 1062 request['Password']['Buffer'] = password 1063 request['Options'] = options 1064 return dce.request(request) 1065 1066def hNetrUnjoinDomain2(dce, accountName, password, options): 1067 request = NetrUnjoinDomain2() 1068 request['ServerName'] = '\x00'*10 1069 request['AccountName'] = checkNullString(accountName) 1070 if password == NULL: 1071 request['Password'] = NULL 1072 else: 1073 request['Password']['Buffer'] = password 1074 request['Options'] = options 1075 return dce.request(request) 1076 1077def hNetrRenameMachineInDomain2(dce, machineName, accountName, password, options): 1078 request = NetrRenameMachineInDomain2() 1079 request['ServerName'] = '\x00'*10 1080 request['MachineName'] = checkNullString(machineName) 1081 request['AccountName'] = checkNullString(accountName) 1082 if password == NULL: 1083 request['Password'] = NULL 1084 else: 1085 request['Password']['Buffer'] = password 1086 request['Options'] = options 1087 return dce.request(request) 1088 1089def hNetrValidateName2(dce, nameToValidate, accountName, password, nameType): 1090 request = NetrValidateName2() 1091 request['ServerName'] = '\x00'*10 1092 request['NameToValidate'] = checkNullString(nameToValidate) 1093 request['AccountName'] = checkNullString(accountName) 1094 if password == NULL: 1095 request['Password'] = NULL 1096 else: 1097 request['Password']['Buffer'] = password 1098 request['NameType'] = nameType 1099 return dce.request(request) 1100 1101def hNetrGetJoinableOUs2(dce, domainNameParam, accountName, password, OUCount): 1102 request = NetrGetJoinableOUs2() 1103 request['ServerName'] = '\x00'*10 1104 request['DomainNameParam'] = checkNullString(domainNameParam) 1105 request['AccountName'] = checkNullString(accountName) 1106 if password == NULL: 1107 request['Password'] = NULL 1108 else: 1109 request['Password']['Buffer'] = password 1110 request['OUCount'] = OUCount 1111 return dce.request(request) 1112 1113def hNetrAddAlternateComputerName(dce, alternateName, domainAccount, encryptedPassword): 1114 request = NetrAddAlternateComputerName() 1115 request['ServerName'] = '\x00'*10 1116 request['AlternateName'] = checkNullString(alternateName) 1117 request['DomainAccount'] = checkNullString(domainAccount) 1118 if encryptedPassword == NULL: 1119 request['EncryptedPassword'] = NULL 1120 else: 1121 request['EncryptedPassword']['Buffer'] = encryptedPassword 1122 return dce.request(request) 1123 1124def hNetrRemoveAlternateComputerName(dce, alternateName, domainAccount, encryptedPassword): 1125 request = NetrRemoveAlternateComputerName() 1126 request['ServerName'] = '\x00'*10 1127 request['AlternateName'] = checkNullString(alternateName) 1128 request['DomainAccount'] = checkNullString(domainAccount) 1129 if encryptedPassword == NULL: 1130 request['EncryptedPassword'] = NULL 1131 else: 1132 request['EncryptedPassword']['Buffer'] = encryptedPassword 1133 return dce.request(request) 1134 1135def hNetrSetPrimaryComputerName(dce, primaryName, domainAccount, encryptedPassword): 1136 request = NetrSetPrimaryComputerName() 1137 request['ServerName'] = '\x00'*10 1138 request['PrimaryName'] = checkNullString(primaryName) 1139 request['DomainAccount'] = checkNullString(domainAccount) 1140 if encryptedPassword == NULL: 1141 request['EncryptedPassword'] = NULL 1142 else: 1143 request['EncryptedPassword']['Buffer'] = encryptedPassword 1144 return dce.request(request) 1145 1146def hNetrEnumerateComputerNames(dce, nameType): 1147 request = NetrEnumerateComputerNames() 1148 request['ServerName'] = '\x00'*10 1149 request['NameType'] = nameType 1150 return dce.request(request) 1151 1152def hNetrUseAdd(dce, level, infoStruct): 1153 request = NetrUseAdd() 1154 request['ServerName'] = '\x00'*10 1155 request['Level'] = level 1156 request['InfoStruct']['tag'] = level 1157 request['InfoStruct']['UseInfo%d' % level] = infoStruct 1158 return dce.request(request) 1159 1160def hNetrUseEnum(dce, level, resumeHandle = 0, preferredMaximumLength = 0xffffffff): 1161 request = NetrUseEnum() 1162 request['ServerName'] = '\x00'*10 1163 request['InfoStruct']['Level'] = level 1164 request['InfoStruct']['UseInfo']['tag'] = level 1165 request['InfoStruct']['UseInfo']['Level%d'%level]['Buffer'] = NULL 1166 request['PreferredMaximumLength'] = preferredMaximumLength 1167 request['ResumeHandle'] = resumeHandle 1168 return dce.request(request) 1169 1170def hNetrUseGetInfo(dce, useName, level): 1171 request = NetrUseGetInfo() 1172 request['ServerName'] = '\x00'*10 1173 request['UseName'] = checkNullString(useName) 1174 request['Level'] = level 1175 return dce.request(request) 1176 1177def hNetrUseDel(dce, useName, forceLevel=USE_LOTS_OF_FORCE): 1178 request = NetrUseDel() 1179 request['ServerName'] = '\x00'*10 1180 request['UseName'] = checkNullString(useName) 1181 request['ForceLevel'] = forceLevel 1182 return dce.request(request) 1183 1184